CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/DQM/DTMonitorModule/src/DTChamberEfficiency.cc

Go to the documentation of this file.
00001 /******* \class DTEffAnalyzer *******
00002  *
00003  * Description:
00004  *  
00005  *  detailed description
00006  *
00007  * \author : Mario Pelliccioni, pellicci@cern.ch
00008  * $date   : 20/11/2008 16:50:57 CET $
00009  *
00010  * Modification:
00011  *
00012  *********************************/
00013 
00014 #include "DTChamberEfficiency.h"
00015 
00016 #include "FWCore/Framework/interface/Event.h"
00017 #include "FWCore/Framework/interface/EventSetup.h"
00018 #include "FWCore/ServiceRegistry/interface/Service.h"
00019 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00020 
00021 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00022 
00023 #include "Geometry/Records/interface/MuonGeometryRecord.h"
00024 
00025 #include "DataFormats/DTRecHit/interface/DTRecSegment4D.h"
00026 #include "DataFormats/MuonDetId/interface/MuonSubdetId.h"
00027 
00028 #include "DQMServices/Core/interface/DQMStore.h"
00029 #include "DQMServices/Core/interface/MonitorElement.h"
00030 
00031 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00032 
00033 #include "RecoMuon/Navigation/interface/DirectMuonNavigation.h"
00034 
00035 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
00036 
00037 #include "TrackPropagation/SteppingHelixPropagator/interface/SteppingHelixPropagator.h"
00038 
00039 
00040 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00041 #include "TrackingTools/TransientTrackingRecHit/interface/TransientTrackingRecHit.h"
00042 #include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimator.h" 
00043 #include "RecoMuon/TrackingTools/interface/MuonServiceProxy.h"
00044 
00045 #include "DataFormats/DetId/interface/DetId.h"
00046 #include "TrackingTools/DetLayers/interface/DetLayer.h"
00047 #include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h"
00048 #include "DataFormats/Common/interface/RefToBase.h" 
00049 
00050 #include "TrackingTools/DetLayers/interface/NavigationSetter.h"
00051 
00052 #include <cmath>
00053 
00054 using namespace std;
00055 using namespace edm;
00056 
00057 DTChamberEfficiency::DTChamberEfficiency(const ParameterSet& pSet)
00058 {
00059   // Get the debug parameter for verbose output
00060   debug = pSet.getUntrackedParameter<bool>("debug",false);
00061   
00062   LogVerbatim("DTDQM|DTMonitorModule|DTChamberEfficiency")
00063     << "DTChamberEfficiency: constructor called";
00064 
00065   // Get the DQM needed services
00066   theDbe = Service<DQMStore>().operator->();
00067   theDbe->setCurrentFolder("DT/05-ChamberEff/Task");
00068 
00069   // service parameters
00070   ParameterSet serviceParameters = pSet.getParameter<ParameterSet>("ServiceParameters");
00071   theService = new MuonServiceProxy(serviceParameters);
00072 
00073   theTracksLabel = pSet.getParameter<InputTag>("TrackCollection");
00074 
00075   theMaxChi2 = static_cast<unsigned int>(pSet.getParameter<double>("theMaxChi2"));
00076   theNSigma = pSet.getParameter<double>("theNSigma");
00077   theMinNrec = static_cast<int>(pSet.getParameter<double>("theMinNrec"));
00078 
00079   labelRPCRecHits = pSet.getParameter<InputTag>("theRPCRecHits");
00080 
00081   thedt4DSegments = pSet.getParameter<InputTag>("dt4DSegments");
00082   thecscSegments = pSet.getParameter<InputTag>("cscSegments");
00083 
00084   theMeasurementExtractor = new MuonDetLayerMeasurements(thedt4DSegments,thecscSegments,
00085                                                          labelRPCRecHits,true,false,false); 
00086 
00087   theNavigationType = pSet.getParameter<string>("NavigationType");
00088 
00089   theEstimator = new Chi2MeasurementEstimator(theMaxChi2,theNSigma); 
00090 }
00091 
00092 
00093 DTChamberEfficiency::~DTChamberEfficiency()
00094 {
00095   LogTrace("DTDQM|DTMonitorModule|DTChamberEfficiency")
00096     << "DTChamberEfficiency: destructor called";
00097 
00098   // free memory
00099   delete theService;
00100   delete theMeasurementExtractor;
00101   delete theEstimator;
00102 }
00103 
00104 void DTChamberEfficiency::beginJob() {
00105 
00106   LogTrace("DTDQM|DTMonitorModule|DTChamberEfficiency")
00107     << "DTChamberEfficiency: beginOfJob";
00108 
00109   bookHistos();
00110 
00111   return;
00112 }
00113 
00114 void DTChamberEfficiency::beginRun(const Run& run, const EventSetup& setup)
00115 {
00116   // Get the DT Geometry
00117   setup.get<MuonGeometryRecord>().get(dtGeom);
00118 
00119   setup.get<IdealMagneticFieldRecord>().get(magfield);
00120   setup.get<GlobalTrackingGeometryRecord>().get(theTrackingGeometry);
00121 
00122   return;
00123 }
00124 
00125 void DTChamberEfficiency::endJob()
00126 {
00127   LogTrace("DTDQM|DTMonitorModule|DTChamberEfficiency")
00128     << "DTChamberEfficiency: endOfJob";
00129 
00130   return;
00131 }
00132 
00133 // Book a set of histograms for a given Layer
00134 void DTChamberEfficiency::bookHistos()
00135 {
00136   LogTrace("DTDQM|DTMonitorModule|DTChamberEfficiency")
00137     << "DTChamberEfficiency: booking histos";
00138 
00139   // Create the monitor elements
00140   theDbe->setCurrentFolder("DT/05-ChamberEff/Task");
00141 
00142   for(int wheel=-2;wheel<=2;wheel++){
00143 
00144     vector<MonitorElement *> histos;
00145 
00146     stringstream wheel_str; wheel_str << wheel; 
00147 
00148     histos.push_back(theDbe->book2D("hCountSectVsChamb_All_W"+ wheel_str.str(),
00149                                     "Countings for wheel " + wheel_str.str(),14,1.,15.,4,1.,5.));
00150 
00151     histos.push_back(theDbe->book2D("hCountSectVsChamb_Qual_W"+ wheel_str.str(),
00152                                     "Countings for wheel " + wheel_str.str(),14,1.,15.,4,1.,5.));
00153 
00154 
00155     histos.push_back(theDbe->book2D("hExtrapSectVsChamb_W"+ wheel_str.str(),
00156                                     "Extrapolations for wheel " + wheel_str.str(),14,1.,15.,4,1.,5.));
00157 
00158     histosPerW.push_back(histos);
00159   }
00160 
00161   return;
00162 }
00163 
00164 void DTChamberEfficiency::analyze(const Event & event,
00165                             const EventSetup& eventSetup)
00166 {
00167 
00168   LogTrace("DTDQM|DTMonitorModule|DTChamberEfficiency") <<
00169     "--- [DTChamberEfficiency] Event analysed #Run: " <<
00170     event.id().run() << " #Event: " << event.id().event() << endl;
00171 
00172   theService->update(eventSetup);
00173   theMeasurementExtractor->setEvent(event); 
00174   // set navigation school
00175   NavigationSetter setter(*theService->muonNavigationSchool());
00176 
00177   //Read tracks from event
00178   Handle<reco::TrackCollection> tracks;
00179   event.getByLabel(theTracksLabel, tracks);
00180   
00181   if(tracks.isValid()) { // check the validity of the collection
00182 
00183     //loop over the muons
00184     for(reco::TrackCollection::const_iterator track = tracks->begin(); track!=tracks->end(); ++track) {
00185 
00186       
00187       reco::TransientTrack trans_track(*track,magfield.product(),theTrackingGeometry);
00188       const int recHitsize = (int)trans_track.recHitsSize();
00189       if(recHitsize < theMinNrec) continue;
00190 
00191       // printout the DT rechits used by the track
00192       if (debug) {
00193         LogTrace("DTDQM|DTMonitorModule|DTChamberEfficiency") << "--- New track" << endl;
00194         set<DTChamberId> chAlrUsed;
00195         for(trackingRecHit_iterator rHit = trans_track.recHitsBegin();
00196             rHit != trans_track.recHitsEnd(); ++rHit) {
00197           DetId rHitid = (*rHit)->geographicalId();
00198           if(!(rHitid.det() == DetId::Muon && rHitid.subdetId() == MuonSubdetId::DT)) continue;
00199           DTChamberId wId(rHitid.rawId());
00200           if(chAlrUsed.find(wId) !=  chAlrUsed.end()) continue;
00201           chAlrUsed.insert(wId);
00202           LogTrace("DTDQM|DTMonitorModule|DTChamberEfficiency") << "   " << wId << endl;
00203         }
00204       }
00205 
00206       // Get the layer on which the seed relies
00207       DetId id = trans_track.track().innerDetId();
00208       const DetLayer *initialLayer = theService->detLayerGeometry()->idToLayer(id);
00209 
00210       TrajectoryStateOnSurface init_fs = trans_track.innermostMeasurementState();
00211       FreeTrajectoryState *init_fs_free = init_fs.freeState();
00212 
00213       //get the list of compatible layers
00214       vector<const DetLayer*> layer_list = compatibleLayers(initialLayer,*init_fs_free,alongMomentum);
00215       vector<const DetLayer*> layer_list_2 = compatibleLayers(initialLayer,*init_fs_free,oppositeToMomentum);
00216 
00217       layer_list.insert(layer_list.end(),layer_list_2.begin(),layer_list_2.end());
00218       
00219       set<DTChamberId> alreadyCheckedCh;
00220 
00221       //loop over the list of compatible layers
00222       for(int i=0;i< (int)layer_list.size();i++) {
00223 
00224         //propagate the track to the i-th layer
00225         TrajectoryStateOnSurface tsos = propagator()->propagate(init_fs,layer_list.at(i)->surface()); 
00226         if(!tsos.isValid()) continue;
00227 
00228         //determine the chambers kinematically compatible with the track on the i-th layer
00229         vector<DetWithState> dss = layer_list.at(i)->compatibleDets(tsos, *propagator(), *theEstimator);
00230         
00231         if(dss.size() == 0) continue;
00232 
00233         // get the first det (it's the most compatible)
00234         const DetWithState detWithState = dss.front();
00235         const DetId idDetLay = detWithState.first->geographicalId(); 
00236 
00237         // check if this is a DT and the track has the needed quality
00238         if(!chamberSelection(idDetLay,trans_track)) continue;
00239 
00240         DTChamberId DTid = (DTChamberId) idDetLay;
00241 
00242         // check if the chamber has already been counted
00243         if(alreadyCheckedCh.find(DTid) != alreadyCheckedCh.end()) continue;
00244         alreadyCheckedCh.insert(DTid);
00245         
00246         // get the compatible measurements
00247         MeasurementContainer detMeasurements_initial = theMeasurementExtractor->measurements(layer_list.at(i),
00248                                                                                              detWithState.first,
00249                                                                                              detWithState.second,
00250                                                                                              *theEstimator, event);
00251         LogTrace("DTDQM|DTMonitorModule|DTChamberEfficiency") << "     chamber: " << DTid
00252                                                               << " has: " << detMeasurements_initial.size() << " comp. meas." << endl;
00253 
00254 
00255         //we want to be more picky about the quality of the segments:
00256         //exclude the segments with less than 12 hits
00257         MeasurementContainer detMeasurements = segQualityCut(detMeasurements_initial);
00258         
00259         // get the histos for this chamber
00260         vector<MonitorElement *> histos =  histosPerW[DTid.wheel()+2];  
00261         // fill them
00262         if (detMeasurements_initial.size() != 0) histos[0]->Fill(DTid.sector(),DTid.station(),1.);
00263         if (detMeasurements.size() != 0) histos[1]->Fill(DTid.sector(),DTid.station(),1.);
00264         histos[2]->Fill(DTid.sector(),DTid.station(),1.);
00265         
00266 
00267       }
00268     }
00269   } else {
00270     LogInfo("DTDQM|DTMonitorModule|DTChamberEfficiency") << "[DTChamberEfficiency] Collection: " << theTracksLabel
00271                                                          << " is not valid!" << endl;
00272   }
00273   return;
00274 }
00275 
00276 bool DTChamberEfficiency::chamberSelection(const DetId& idDetLay, reco::TransientTrack& trans_track) const
00277 {
00278   //check that we have a muon and that is a DT detector
00279   if(!(idDetLay.det() == DetId::Muon && idDetLay.subdetId() == MuonSubdetId::DT)) return false;
00280 
00281   if(trans_track.recHitsSize() == 2)
00282     if(trans_track.recHit(0)->geographicalId() == idDetLay ||
00283        trans_track.recHit(1)->geographicalId() == idDetLay) return false;
00284 
00285   return true;
00286 }
00287 
00288 //riempi una per ogni segmento e una per segmento sopra 12 hit
00289 
00290 MeasurementContainer DTChamberEfficiency::segQualityCut(const MeasurementContainer seg_list) const
00291 {
00292 
00293   MeasurementContainer result;
00294 
00295   for(MeasurementContainer::const_iterator mescont_Itr = seg_list.begin();
00296       mescont_Itr != seg_list.end(); ++mescont_Itr){
00297 
00298     //get the rechits of the segment
00299     TransientTrackingRecHit::ConstRecHitContainer recHit_list = mescont_Itr->recHit()->transientHits();
00300 
00301     //loop over the rechits and get the number of hits
00302     int nhit_seg(0);
00303     for(TransientTrackingRecHit::ConstRecHitContainer::const_iterator recList_Itr = recHit_list.begin();
00304         recList_Itr != recHit_list.end(); ++recList_Itr){
00305 
00306       nhit_seg += (int)(*recList_Itr)->transientHits().size();
00307     }
00308 
00309     DTChamberId tmpId = (DTChamberId)mescont_Itr->recHit()->hit()->geographicalId();
00310 
00311     if(tmpId.station() < 4 && nhit_seg >= 12) result.push_back(*mescont_Itr);
00312     if(tmpId.station() == 4 && nhit_seg >= 8) result.push_back(*mescont_Itr);
00313   }
00314 
00315   return result;
00316 }
00317 
00318 vector<const DetLayer*> DTChamberEfficiency::compatibleLayers(const DetLayer *initialLayer,
00319                                 const FreeTrajectoryState& fts, PropagationDirection propDir)
00320 {
00321 
00322 vector<const DetLayer*> detLayers;
00323 
00324 if(theNavigationType == "Standard"){
00325    // ask for compatible layers
00326    detLayers = initialLayer->compatibleLayers(fts,propDir);
00327     // I have to fit by hand the first layer until the seedTSOS is defined on the first rechit layer
00328    // In fact the first layer is not returned by initialLayer->compatibleLayers.
00329 
00330    // Not accounting for the layer where the seed resides, causing bias.
00331    // detLayers.insert(detLayers.begin(),initialLayer);
00332 
00333    }
00334  else if (theNavigationType == "Direct"){
00335 
00336    DirectMuonNavigation navigation(ESHandle<MuonDetLayerGeometry>(&*theService->detLayerGeometry()));
00337    detLayers = navigation.compatibleLayers(fts,propDir);
00338      }
00339  else
00340    LogError("DTDQM|DTMonitorModule|DTChamberEfficiency") << "No Properly Navigation Selected!!"<<endl;
00341 
00342  return detLayers;
00343 } 
00344 
00345 inline ESHandle<Propagator> DTChamberEfficiency::propagator() const {
00346   return theService->propagator("SteppingHelixPropagatorAny");
00347 }