CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/DQM/TrackingMonitor/plugins/TrackEfficiencyMonitor.cc

Go to the documentation of this file.
00001 /*
00002  *  See header file for a description of this class.
00003  *
00004  *  $Date: 2010/08/06 20:24:23 $
00005  *  $Revision: 1.10 $
00006  *  \author Jeremy Andrea
00007  */
00008 
00009 #include "DataFormats/TrackReco/interface/Track.h"
00010 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00011 //#include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
00012 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
00013 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00014 #include "MagneticField/Engine/interface/MagneticField.h"
00015 
00016 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00017 #include "FWCore/Utilities/interface/InputTag.h"
00018 #include "DQMServices/Core/interface/DQMStore.h"
00019 #include "DQM/TrackingMonitor/plugins/TrackEfficiencyMonitor.h"
00020 #include <string>
00021 
00022 // needed to compute the efficiency
00023 
00024 #include "DataFormats/TrackCandidate/interface/TrackCandidate.h"
00025 #include "DataFormats/TrackCandidate/interface/TrackCandidateCollection.h"
00026 #include "DataFormats/MuonReco/interface/Muon.h"
00027 #include "TrackingTools/GeomPropagators/interface/Propagator.h"
00028 #include "TrackingTools/PatternTools/interface/TwoTrackMinimumDistance.h"
00029 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00030 
00031 #include "TrackPropagation/SteppingHelixPropagator/interface/SteppingHelixPropagator.h"
00032 #include "TrackingTools/GeomPropagators/interface/SmartPropagator.h"
00033 #include "DataFormats/Math/interface/Vector3D.h"
00034 #include "DataFormats/GeometrySurface/interface/Plane.h"
00035 #include "DataFormats/GeometrySurface/interface/BoundPlane.h"
00036 #include "DataFormats/GeometrySurface/interface/RectangularPlaneBounds.h"
00037 
00038 #include "CommonTools/UtilAlgos/interface/TFileService.h"
00039 #include "DataFormats/GeometrySurface/interface/Cylinder.h"
00040 
00041 #include "RecoTracker/Record/interface/TrackerRecoGeometryRecord.h"
00042 #include <RecoTracker/TkDetLayers/interface/GeometricSearchTracker.h>
00043 
00044 #include "RecoTracker/Record/interface/CkfComponentsRecord.h"
00045 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00046 #include "RecoTracker/TkNavigation/interface/CosmicNavigationSchool.h"
00047 #include "RecoTracker/Record/interface/NavigationSchoolRecord.h"
00048 #include "TrackingTools/DetLayers/interface/NavigationSetter.h"
00049 
00050 
00051 
00052 //-----------------------------------------------------------------------------------
00053 TrackEfficiencyMonitor::TrackEfficiencyMonitor(const edm::ParameterSet& iConfig) 
00054 //-----------------------------------------------------------------------------------
00055 {
00056   dqmStore_            = edm::Service<DQMStore>().operator->(); 
00057  
00058   theRadius_           = iConfig.getParameter<double>("theRadius");
00059   theMaxZ_             = iConfig.getParameter<double>("theMaxZ");
00060   isBFieldOff_         = iConfig.getParameter<bool>("isBFieldOff");
00061   trackEfficiency_     = iConfig.getParameter<bool>("trackEfficiency");
00062   theTKTracksLabel_    = iConfig.getParameter<edm::InputTag>("TKTrackCollection");
00063   theSTATracksLabel_   = iConfig.getParameter<edm::InputTag>("STATrackCollection");
00064   
00065  
00066   conf_ = iConfig;
00067 }
00068 
00069 
00070 
00071 //-----------------------------------------------------------------------------------
00072 TrackEfficiencyMonitor::~TrackEfficiencyMonitor() 
00073 //-----------------------------------------------------------------------------------
00074 {}
00075 
00076 
00077 
00078 
00079 //-----------------------------------------------------------------------------------
00080 void TrackEfficiencyMonitor::beginJob(void) 
00081 //-----------------------------------------------------------------------------------
00082 {
00083   std::string MEFolderName = conf_.getParameter<std::string>("FolderName"); 
00084   std::string AlgoName     = conf_.getParameter<std::string>("AlgoName");
00085   
00086   
00087   dqmStore_->setCurrentFolder(MEFolderName);
00088   
00089   //
00090   int    muonXBin = conf_.getParameter<int>   ("muonXBin");
00091   double muonXMin = conf_.getParameter<double>("muonXMin");
00092   double muonXMax = conf_.getParameter<double>("muonXMax");
00093  
00094   histname = "muonX_";
00095   muonX = dqmStore_->book1D(histname+AlgoName, histname+AlgoName, muonXBin, muonXMin, muonXMax);
00096   muonX->setAxisTitle("");
00097   
00098   //
00099   int    muonYBin = conf_.getParameter<int>   ("muonYBin");
00100   double muonYMin = conf_.getParameter<double>("muonYMin");
00101   double muonYMax = conf_.getParameter<double>("muonYMax");
00102  
00103   histname = "muonY_";
00104   muonY = dqmStore_->book1D(histname+AlgoName, histname+AlgoName, muonYBin, muonYMin, muonYMax);
00105   muonY->setAxisTitle("");
00106   
00107   //
00108   int    muonZBin = conf_.getParameter<int>   ("muonZBin");
00109   double muonZMin = conf_.getParameter<double>("muonZMin");
00110   double muonZMax = conf_.getParameter<double>("muonZMax");
00111  
00112   histname = "muonZ_";
00113   muonZ = dqmStore_->book1D(histname+AlgoName, histname+AlgoName, muonZBin, muonZMin, muonZMax);
00114   muonZ->setAxisTitle("");
00115   
00116   //
00117   int    muonEtaBin = conf_.getParameter<int>   ("muonEtaBin");
00118   double muonEtaMin = conf_.getParameter<double>("muonEtaMin");
00119   double muonEtaMax = conf_.getParameter<double>("muonEtaMax");
00120  
00121   histname = "muonEta_";
00122   muonEta = dqmStore_->book1D(histname+AlgoName, histname+AlgoName, muonEtaBin, muonEtaMin, muonEtaMax);
00123   muonEta->setAxisTitle("");
00124   
00125   //
00126   int    muonPhiBin = conf_.getParameter<int>   ("muonPhiBin");
00127   double muonPhiMin = conf_.getParameter<double>("muonPhiMin");
00128   double muonPhiMax = conf_.getParameter<double>("muonPhiMax");
00129  
00130   histname = "muonPhi_";
00131   muonPhi = dqmStore_->book1D(histname+AlgoName, histname+AlgoName, muonPhiBin, muonPhiMin, muonPhiMax);
00132   muonPhi->setAxisTitle("");
00133   
00134   //
00135   int    muonD0Bin = conf_.getParameter<int>   ("muonD0Bin");
00136   double muonD0Min = conf_.getParameter<double>("muonD0Min");
00137   double muonD0Max = conf_.getParameter<double>("muonD0Max");
00138  
00139   histname = "muonD0_";
00140   muonD0 = dqmStore_->book1D(histname+AlgoName, histname+AlgoName, muonD0Bin, muonD0Min, muonD0Max);
00141   muonD0->setAxisTitle("");
00142   
00143   //
00144   int    muonCompatibleLayersBin = conf_.getParameter<int>   ("muonCompatibleLayersBin");
00145   double muonCompatibleLayersMin = conf_.getParameter<double>("muonCompatibleLayersMin");
00146   double muonCompatibleLayersMax = conf_.getParameter<double>("muonCompatibleLayersMax");
00147  
00148   histname = "muonCompatibleLayers_";
00149   muonCompatibleLayers = dqmStore_->book1D(histname+AlgoName, histname+AlgoName, muonCompatibleLayersBin, muonCompatibleLayersMin, muonCompatibleLayersMax);
00150   muonCompatibleLayers->setAxisTitle("");
00151 
00152   //------------------------------------------------------------------------------------
00153   
00154   //
00155   int    trackXBin = conf_.getParameter<int>   ("trackXBin");
00156   double trackXMin = conf_.getParameter<double>("trackXMin");
00157   double trackXMax = conf_.getParameter<double>("trackXMax");
00158  
00159   histname = "trackX_";
00160   trackX = dqmStore_->book1D(histname+AlgoName, histname+AlgoName, trackXBin, trackXMin, trackXMax);
00161   trackX->setAxisTitle("");
00162   
00163   //
00164   int    trackYBin = conf_.getParameter<int>   ("trackYBin");
00165   double trackYMin = conf_.getParameter<double>("trackYMin");
00166   double trackYMax = conf_.getParameter<double>("trackYMax");
00167  
00168   histname = "trackY_";
00169   trackY = dqmStore_->book1D(histname+AlgoName, histname+AlgoName, trackYBin, trackYMin, trackYMax);
00170   trackY->setAxisTitle("");
00171   
00172   //
00173   int    trackZBin = conf_.getParameter<int>   ("trackZBin");
00174   double trackZMin = conf_.getParameter<double>("trackZMin");
00175   double trackZMax = conf_.getParameter<double>("trackZMax");
00176  
00177   histname = "trackZ_";
00178   trackZ = dqmStore_->book1D(histname+AlgoName, histname+AlgoName, trackZBin, trackZMin, trackZMax);
00179   trackZ->setAxisTitle("");
00180   
00181   //
00182   int    trackEtaBin = conf_.getParameter<int>   ("trackEtaBin");
00183   double trackEtaMin = conf_.getParameter<double>("trackEtaMin");
00184   double trackEtaMax = conf_.getParameter<double>("trackEtaMax");
00185  
00186   histname = "trackEta_";
00187   trackEta = dqmStore_->book1D(histname+AlgoName, histname+AlgoName, trackEtaBin, trackEtaMin, trackEtaMax);
00188   trackEta->setAxisTitle("");
00189   
00190   //
00191   int    trackPhiBin = conf_.getParameter<int>   ("trackPhiBin");
00192   double trackPhiMin = conf_.getParameter<double>("trackPhiMin");
00193   double trackPhiMax = conf_.getParameter<double>("trackPhiMax");
00194  
00195   histname = "trackPhi_";
00196   trackPhi = dqmStore_->book1D(histname+AlgoName, histname+AlgoName, trackPhiBin, trackPhiMin, trackPhiMax);
00197   trackPhi->setAxisTitle("");
00198   
00199   //
00200   int    trackD0Bin = conf_.getParameter<int>   ("trackD0Bin");
00201   double trackD0Min = conf_.getParameter<double>("trackD0Min");
00202   double trackD0Max = conf_.getParameter<double>("trackD0Max");
00203  
00204   histname = "trackD0_";
00205   trackD0 = dqmStore_->book1D(histname+AlgoName, histname+AlgoName, trackD0Bin, trackD0Min, trackD0Max);
00206   trackD0->setAxisTitle("");
00207   
00208   //
00209   int    trackCompatibleLayersBin = conf_.getParameter<int>   ("trackCompatibleLayersBin");
00210   double trackCompatibleLayersMin = conf_.getParameter<double>("trackCompatibleLayersMin");
00211   double trackCompatibleLayersMax = conf_.getParameter<double>("trackCompatibleLayersMax");
00212  
00213   histname = "trackCompatibleLayers_";
00214   trackCompatibleLayers = dqmStore_->book1D(histname+AlgoName, histname+AlgoName, trackCompatibleLayersBin, trackCompatibleLayersMin, trackCompatibleLayersMax);
00215   trackCompatibleLayers->setAxisTitle("");
00216 
00217   //------------------------------------------------------------------------------------
00218  
00219   //
00220   int    deltaXBin = conf_.getParameter<int>   ("deltaXBin");
00221   double deltaXMin = conf_.getParameter<double>("deltaXMin");
00222   double deltaXMax = conf_.getParameter<double>("deltaXMax");
00223  
00224   histname = "deltaX_";
00225   deltaX = dqmStore_->book1D(histname+AlgoName, histname+AlgoName, deltaXBin, deltaXMin, deltaXMax);
00226   deltaX->setAxisTitle("");
00227   
00228   //
00229   int    deltaYBin = conf_.getParameter<int>   ("deltaYBin");
00230   double deltaYMin = conf_.getParameter<double>("deltaYMin");
00231   double deltaYMax = conf_.getParameter<double>("deltaYMax");
00232  
00233   histname = "deltaY_";
00234   deltaY = dqmStore_->book1D(histname+AlgoName, histname+AlgoName, deltaYBin, deltaYMin, deltaYMax);
00235   deltaY->setAxisTitle("");
00236   
00237   //
00238   int    signDeltaXBin = conf_.getParameter<int>   ("signDeltaXBin");
00239   double signDeltaXMin = conf_.getParameter<double>("signDeltaXMin");
00240   double signDeltaXMax = conf_.getParameter<double>("signDeltaXMax");
00241  
00242   histname = "signDeltaX_";
00243   signDeltaX = dqmStore_->book1D(histname+AlgoName, histname+AlgoName, signDeltaXBin, signDeltaXMin, signDeltaXMax);
00244   signDeltaX->setAxisTitle("");
00245   
00246   //
00247   int    signDeltaYBin = conf_.getParameter<int>   ("signDeltaYBin");
00248   double signDeltaYMin = conf_.getParameter<double>("signDeltaYMin");
00249   double signDeltaYMax = conf_.getParameter<double>("signDeltaYMax");
00250  
00251   histname = "signDeltaY_";
00252   signDeltaY = dqmStore_->book1D(histname+AlgoName, histname+AlgoName, signDeltaYBin, signDeltaYMin, signDeltaYMax);
00253   signDeltaY->setAxisTitle("");
00254   
00255 }
00256 
00257 
00258 
00259 //-----------------------------------------------------------------------------------
00260 void TrackEfficiencyMonitor::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) 
00261 //-----------------------------------------------------------------------------------
00262 {
00263    
00264 
00265   edm::Handle<reco::TrackCollection> tkTracks;
00266   iEvent.getByLabel(theTKTracksLabel_, tkTracks);
00267   edm::Handle<reco::TrackCollection> staTracks;
00268   iEvent.getByLabel(theSTATracksLabel_, staTracks);
00269   edm::ESHandle<NavigationSchool> nav;
00270   iSetup.get<NavigationSchoolRecord>().get("CosmicNavigationSchool", nav); 
00271   NavigationSetter setter(*nav.product());
00272   iSetup.get<CkfComponentsRecord>().get(measurementTrackerHandle);
00273  
00274   nCompatibleLayers = 0; 
00275   
00276   iSetup.get<TransientTrackRecord>().get("TransientTrackBuilder",theTTrackBuilder);
00277   iSetup.get<TrackingComponentsRecord>().get("SteppingHelixPropagatorAny",thePropagator);
00278   iSetup.get<IdealMagneticFieldRecord>().get(bField); 
00279   iSetup.get<TrackerRecoGeometryRecord>().get(theTracker);
00280   theNavigation = new DirectTrackerNavigation(theTracker);
00281   
00282   
00283   if(trackEfficiency_){
00284   //---------------------------------------------------
00285   // Select muons with good quality
00286   // If B field is on, no up-down matching between the muons
00287   //---------------------------------------------------  
00288   bool isGoodMuon = false;
00289   double mudd0 = 0., mudphi = 0., muddsz = 0., mudeta = 0.;
00290   if(isBFieldOff_)
00291   {
00292     if ( staTracks->size() == 2 )
00293     {
00294       for ( unsigned int bindex = 0; bindex < staTracks->size(); ++bindex ) 
00295       {
00296         
00297         if (0 == bindex){
00298            mudd0+=(*staTracks)[bindex].d0(); 
00299            mudphi+=(*staTracks)[bindex].phi();
00300            muddsz+=(*staTracks)[bindex].dsz(); 
00301            mudeta+=(*staTracks)[bindex].eta();}
00302         if (1 == bindex){
00303            mudd0-=(*staTracks)[bindex].d0(); 
00304            mudphi-=(*staTracks)[bindex].phi();
00305            muddsz-=(*staTracks)[bindex].dsz(); 
00306            mudeta-=(*staTracks)[bindex].eta();}
00307        }
00308       if ((fabs(mudd0)<15.0)&&(fabs(mudphi)<0.045)&&(fabs(muddsz)<20.0)&&(fabs(mudeta)<0.060))  isGoodMuon = true;
00309      }
00310      
00311     if(isGoodMuon) testTrackerTracks(tkTracks,staTracks);
00312   
00313   }
00314   else if ( staTracks->size() == 1 || staTracks->size() == 2) testTrackerTracks(tkTracks,staTracks);
00315   }
00316   
00317   
00318   if(!trackEfficiency_ && tkTracks->size() == 1 ){
00319     if( (tkTracks->front()).normalizedChi2() < 5 &&
00320     (tkTracks->front()).hitPattern().numberOfValidHits() > 8)
00321      testSTATracks(tkTracks,staTracks);  
00322   }
00323   
00324   
00325   delete theNavigation;
00326    
00327 }
00328 
00329 
00330 
00331 //-----------------------------------------------------------------------------------
00332 void TrackEfficiencyMonitor::endJob(void) 
00333 //-----------------------------------------------------------------------------------
00334 { 
00335   bool outputMEsInRootFile = conf_.getParameter<bool>("OutputMEsInRootFile");
00336   std::string outputFileName = conf_.getParameter<std::string>("OutputFileName");
00337   if(outputMEsInRootFile){
00338     dqmStore_->showDirStructure(); 
00339     dqmStore_->save(outputFileName); 
00340     }
00341 
00342   //if ( theNavigation ) delete theNavigation; 
00343 
00344 }
00345 
00346 
00347 
00348 //-----------------------------------------------------------------------------------
00349 void TrackEfficiencyMonitor::testTrackerTracks(edm::Handle<reco::TrackCollection> tkTracks, edm::Handle<reco::TrackCollection> staTracks)
00350 //-----------------------------------------------------------------------------------
00351 {
00352   
00353   const std::string metname = "testStandAloneMuonTracks";
00354 
00355   //---------------------------------------------------
00356   // get the index of the "up" muon
00357   // histograms will only be computed for the "up" muon
00358   //---------------------------------------------------
00359  
00360   int nUpMuon = 0;
00361   int idxUpMuon = -1;
00362   for(unsigned int i =0; i< staTracks->size(); i++){
00363      if( checkSemiCylinder((*staTracks)[i]) == TrackEfficiencyMonitor::Up ){
00364         nUpMuon++;
00365         idxUpMuon = i;
00366      }
00367   }
00368     
00369    
00370   if( nUpMuon == 1)
00371   {
00372     
00373     //---------------------------------------------------
00374     //get the muon informations
00375     //---------------------------------------------------
00376     
00377     reco::TransientTrack staTT = theTTrackBuilder->build((*staTracks)[idxUpMuon]);
00378     double ipX   = staTT.impactPointState().globalPosition().x();
00379     double ipY   = staTT.impactPointState().globalPosition().y();
00380     double ipZ   = staTT.impactPointState().globalPosition().z();
00381     double eta   = staTT.impactPointState().globalDirection().eta();
00382     double phi   = staTT.impactPointState().globalDirection().phi();
00383     double d0    = (*staTracks)[idxUpMuon].d0();
00384     
00385     TrajectoryStateOnSurface theTSOS = staTT.outermostMeasurementState(); 
00386     TrajectoryStateOnSurface theTSOSCompLayers = staTT.outermostMeasurementState(); 
00387     
00388     
00389     //---------------------------------------------------
00390     //check if the muon is in the tracker acceptance
00391     //---------------------------------------------------    
00392     bool isInTrackerAcceptance = false;   
00393     isInTrackerAcceptance = trackerAcceptance( theTSOS, theRadius_ , theMaxZ_ );
00394     
00395     //---------------------------------------------------st
00396     //count the number of compatible layers
00397     //---------------------------------------------------       
00398     nCompatibleLayers = compatibleLayers(theTSOSCompLayers);
00399     
00400     if(isInTrackerAcceptance && (*staTracks)[idxUpMuon].hitPattern().numberOfValidHits() > 28)
00401     {
00402       //---------------------------------------------------
00403       //count the number of good muon candidates
00404       //---------------------------------------------------   
00405         
00406       TrajectoryStateOnSurface staState;      
00407       LocalVector diffLocal;   
00408      
00409          
00410       bool isTrack = false;
00411       if(!tkTracks->empty())
00412       {
00413        //---------------------------------------------------   
00414        //look for associated tracks
00415        //---------------------------------------------------   
00416         float DR2min = 1000;
00417         reco::TrackCollection::const_iterator closestTrk = tkTracks->end();
00418 
00419        for(reco::TrackCollection::const_iterator tkTrack = tkTracks->begin(); tkTrack != tkTracks->end(); ++tkTrack)
00420        {
00421           reco::TransientTrack tkTT = theTTrackBuilder->build(*tkTrack);
00422           TrajectoryStateOnSurface tkInner = tkTT.innermostMeasurementState();
00423           staState = thePropagator->propagate(staTT.outermostMeasurementState(),tkInner.surface());      
00424           failedToPropagate = 1;
00425             
00426           if(staState.isValid())
00427           {
00428             failedToPropagate = 0;
00429             diffLocal = tkInner.localPosition() - staState.localPosition();
00430             double DR2 = diffLocal.x()*diffLocal.x()+diffLocal.y()*diffLocal.y();
00431             if (DR2<DR2min) { DR2min = DR2; closestTrk = tkTrack;}
00432             if ( pow(DR2,0.5) < 100. ) isTrack = true;
00433             }
00434           }
00435          
00436           
00437           if (DR2min != 1000) 
00438           { 
00439             
00440             reco::TransientTrack tkTT = theTTrackBuilder->build(*closestTrk);
00441             TrajectoryStateOnSurface tkInner = tkTT.innermostMeasurementState();
00442             staState = thePropagator->propagate(staTT.outermostMeasurementState(),tkInner.surface());
00443             deltaX->Fill(diffLocal.x());
00444             deltaY->Fill(diffLocal.y());
00445             signDeltaX->Fill(diffLocal.x()/(tkInner.localError().positionError().xx() + staState.localError().positionError().xx()));
00446             signDeltaY->Fill(diffLocal.y()/(tkInner.localError().positionError().yy() + staState.localError().positionError().yy()));
00447                    
00448            } 
00449         }
00450       
00451       
00452       if(failedToPropagate == 0)
00453       {       
00454          muonX->Fill(ipX);
00455          muonY->Fill(ipY);
00456          muonZ->Fill(ipZ);
00457          muonEta->Fill(eta);
00458          muonPhi->Fill(phi);
00459          muonD0->Fill(d0);
00460          muonCompatibleLayers->Fill(nCompatibleLayers);
00461 
00462          if(isTrack)
00463          { 
00464             trackX->Fill(ipX);
00465             trackY->Fill(ipY);
00466             trackZ->Fill(ipZ);
00467             trackEta->Fill(eta);
00468             trackPhi->Fill(phi);
00469             trackD0->Fill(d0);
00470             trackCompatibleLayers->Fill(nCompatibleLayers);
00471           }     
00472         }
00473      }
00474    }
00475     
00476 }
00477 
00478 
00479 
00480 
00481 
00482 
00483 
00484 
00485 
00486 
00487 
00488 //-----------------------------------------------------------------------------------
00489 void TrackEfficiencyMonitor::testSTATracks(edm::Handle<reco::TrackCollection> tkTracks, edm::Handle<reco::TrackCollection> staTracks)
00490 //-----------------------------------------------------------------------------------
00491 {
00492 
00493    
00494    reco::TransientTrack tkTT = theTTrackBuilder->build(tkTracks->front());
00495    double ipX   = tkTT.impactPointState().globalPosition().x();
00496    double ipY   = tkTT.impactPointState().globalPosition().y();
00497    double ipZ   = tkTT.impactPointState().globalPosition().z();
00498    double eta   = tkTT.impactPointState().globalDirection().eta();
00499    double phi   = tkTT.impactPointState().globalDirection().phi();
00500    double d0    = (*tkTracks)[0].d0();
00501 
00502    TrajectoryStateOnSurface tkInner = tkTT.innermostMeasurementState();
00503    LocalVector diffLocal;   
00504    TrajectoryStateOnSurface staState;      
00505    bool isTrack = false;
00506    
00507    
00508    if(!staTracks->empty()){     
00509         
00510        //---------------------------------------------------   
00511        //look for associated muons
00512        //---------------------------------------------------   
00513        
00514     float DR2min = 1000;
00515     reco::TrackCollection::const_iterator closestTrk = staTracks->end();
00516        //----------------------loop on tracker tracks:
00517     for(reco::TrackCollection::const_iterator staTrack = staTracks->begin(); staTrack != staTracks->end(); ++staTrack){
00518       if(checkSemiCylinder(*staTrack) == TrackEfficiencyMonitor::Up){
00519       
00520         reco::TransientTrack staTT = theTTrackBuilder->build(*staTrack); 
00521         failedToPropagate = 1;  
00522         staState = thePropagator->propagate(staTT.outermostMeasurementState(),tkInner.surface());       
00523 
00524        
00525           if(staState.isValid())
00526           {
00527             failedToPropagate = 0;
00528             diffLocal = tkInner.localPosition() - staState.localPosition();
00529                
00530             double DR2 = diffLocal.x()*diffLocal.x()+diffLocal.y()*diffLocal.y();
00531             if (DR2<DR2min) { DR2min = DR2; closestTrk = staTrack;}
00532             if ( pow(DR2,0.5) < 100. ) isTrack = true;
00533            }
00534           }     
00535       }
00536     }
00537    
00538    if(failedToPropagate == 0)
00539       {         
00540          
00541          trackX->Fill(ipX);
00542          trackY->Fill(ipY);
00543          trackZ->Fill(ipZ);
00544          trackEta->Fill(eta);
00545          trackPhi->Fill(phi);
00546          trackD0->Fill(d0);
00547 
00548          if(isTrack)
00549          { 
00550             muonX->Fill(ipX);
00551             muonY->Fill(ipY);
00552             muonZ->Fill(ipZ);
00553             muonEta->Fill(eta);
00554             muonPhi->Fill(phi);
00555             muonD0->Fill(d0);
00556           }     
00557         }
00558 
00559 
00560 
00561 }
00562 
00563 
00564 
00565 
00566 
00567 
00568 
00569 
00570 
00571 
00572 
00573 
00574 
00575 
00576 
00577 
00578 
00579 //-----------------------------------------------------------------------------------
00580 TrackEfficiencyMonitor::SemiCylinder TrackEfficiencyMonitor::checkSemiCylinder(const reco::Track& tk)
00581 //-----------------------------------------------------------------------------------
00582 {
00583   return tk.innerPosition().phi() > 0 ? TrackEfficiencyMonitor::Up : TrackEfficiencyMonitor::Down;
00584 }
00585 
00586   
00587   
00588 //-----------------------------------------------------------------------------------
00589 bool TrackEfficiencyMonitor::trackerAcceptance( TrajectoryStateOnSurface theTSOS, double theRadius, double theMaxZ)
00590 //-----------------------------------------------------------------------------------
00591 {
00592 
00593   //---------------------------------------------------  
00594   // check if the muon is in the tracker acceptance    
00595   // check the compatibility with a cylinder of radius "theRadius"
00596   //---------------------------------------------------   
00597       
00598   //Propagator*  theTmpPropagator = new SteppingHelixPropagator(&*bField,anyDirection);
00599   
00600   //Propagator*  theTmpPropagator = &*thePropagator;
00601   Propagator* theTmpPropagator = &*thePropagator->clone();
00602   
00603   if (theTSOS.globalPosition().y() <0 ) theTmpPropagator->setPropagationDirection(oppositeToMomentum);
00604   else                                  theTmpPropagator->setPropagationDirection(alongMomentum);
00605   
00606   Cylinder::PositionType pos0;
00607   Cylinder::RotationType rot0;
00608   const Cylinder::CylinderPointer cyl = Cylinder::build(pos0, rot0, theRadius);
00609   TrajectoryStateOnSurface tsosAtCyl  = theTmpPropagator->propagate(*theTSOS.freeState(), *cyl);  
00610   double accept = false;
00611   if ( tsosAtCyl.isValid() ) {
00612     if (fabs(tsosAtCyl.globalPosition().z())<theMaxZ ) {
00613       Cylinder::PositionType pos02;
00614       Cylinder::RotationType rot02;
00615       const Cylinder::CylinderPointer cyl2 = Cylinder::build(pos02, rot02, theRadius -10);
00616       TrajectoryStateOnSurface tsosAtCyl2 = theTmpPropagator->propagate(*tsosAtCyl.freeState(), *cyl2);
00617       if ( tsosAtCyl2.isValid() ) {
00618         Cylinder::PositionType pos03;
00619         Cylinder::RotationType rot03;
00620         const Cylinder::CylinderPointer cyl3 = Cylinder::build(pos03, rot03, theRadius );
00621         TrajectoryStateOnSurface tsosAtCyl3 = theTmpPropagator->propagate(*tsosAtCyl2.freeState(), *cyl3);
00622         if ( tsosAtCyl3.isValid() ) {
00623           accept=true;
00624         }
00625       }
00626       
00627     }
00628   }
00629   delete theTmpPropagator;
00630   //muon propagated to the barrel cylinder
00631   return accept;
00632 
00633 }
00634 
00635 
00636 
00637 //-----------------------------------------------------------------------------------
00638 int TrackEfficiencyMonitor::compatibleLayers( TrajectoryStateOnSurface theTSOS)
00639 //-----------------------------------------------------------------------------------
00640 {  
00641   //---------------------------------------------------   
00642   // check the number of compatible layers
00643   //---------------------------------------------------   
00644   
00645   std::vector< BarrelDetLayer*> barrelTOBLayers = measurementTrackerHandle->geometricSearchTracker()->tobLayers() ;
00646   
00647   unsigned int layers = 0;
00648   for ( unsigned int k=0 ; k < barrelTOBLayers.size() ; k++ ) 
00649   {  
00650     const DetLayer* firstLay = barrelTOBLayers[barrelTOBLayers.size() -1 - k];  
00651     
00652     //Propagator*  theTmpPropagator = new SteppingHelixPropagator(&*bField,anyDirection);
00653     
00654     
00655     
00656     Propagator* theTmpPropagator = &*thePropagator->clone();
00657     theTmpPropagator->setPropagationDirection(alongMomentum); 
00658     
00659     TrajectoryStateOnSurface startTSOS = theTmpPropagator->propagate(*theTSOS.freeState(),firstLay->surface());
00660     
00661     std::vector< const DetLayer*> trackCompatibleLayers;
00662     
00663     findDetLayer      = true;
00664     bool isUpMuon     = false;
00665     bool firstdtep    = true; 
00666     
00667     if(startTSOS.isValid())
00668     {
00669       
00670       if(firstdtep) layers++; 
00671       
00672       int nwhile = 0;
00673       
00674       //for other compatible layers 
00675       while ( startTSOS.isValid() &&  firstLay && findDetLayer)
00676       {
00677         
00678         if(firstdtep && startTSOS.globalPosition().y()> 0) isUpMuon = true;
00679         
00680         if(firstdtep){
00681           std::vector< const DetLayer*> firstCompatibleLayers;
00682           firstCompatibleLayers.push_back(firstLay);
00683           std::pair<TrajectoryStateOnSurface, const  DetLayer* > nextLayer = findNextLayer(theTSOS, firstCompatibleLayers, isUpMuon );
00684           firstdtep = false;
00685         }
00686         else{
00687           trackCompatibleLayers =  firstLay->nextLayers(*(startTSOS.freeState()),alongMomentum);
00688           if (trackCompatibleLayers.size()!=0 ){ 
00689             std::pair<TrajectoryStateOnSurface, const  DetLayer* > nextLayer = findNextLayer(startTSOS, trackCompatibleLayers, isUpMuon );
00690             if (firstLay != nextLayer.second ){
00691               firstLay  = nextLayer.second;
00692               startTSOS = nextLayer.first;
00693               layers++;         
00694             }
00695             else firstLay=0;
00696           }
00697         }
00698         nwhile++;
00699         if(nwhile > 100) break;
00700                 
00701       }
00702       delete theTmpPropagator;
00703       break;
00704     }
00705     delete theTmpPropagator;
00706   }
00707   return layers;
00708   
00709 }
00710 
00711 
00712 
00713 
00714 //-----------------------------------------------------------------------------------
00715 std::pair<TrajectoryStateOnSurface,  const DetLayer*>  TrackEfficiencyMonitor::findNextLayer( TrajectoryStateOnSurface sTSOS, std::vector< const DetLayer*> trackCompatibleLayers , bool isUpMuon )
00716 //-----------------------------------------------------------------------------------
00717 {
00718   
00719   //Propagator*  theTmpPropagator = new SteppingHelixPropagator(&*bField,anyDirection);
00720   
00721   
00722   Propagator* theTmpPropagator = &*thePropagator->clone();
00723   theTmpPropagator->setPropagationDirection(alongMomentum); 
00724   
00725   
00726   std::vector<const DetLayer*>::iterator itl;
00727   findDetLayer = false;
00728   for (itl=trackCompatibleLayers.begin();itl!=trackCompatibleLayers.end();++itl) {
00729     TrajectoryStateOnSurface tsos = theTmpPropagator->propagate(*(sTSOS.freeState()),(**itl).surface());
00730     if (tsos.isValid()) 
00731     {
00732       sTSOS = tsos;
00733       findDetLayer = true; 
00734       
00735       break;
00736     }
00737   }
00738   std::pair<TrajectoryStateOnSurface,  const DetLayer* >  blabla;
00739   blabla.first = sTSOS;
00740   blabla.second = &**itl;
00741   delete theTmpPropagator;
00742   return blabla;
00743 }
00744 
00745 
00746 DEFINE_FWK_MODULE(TrackEfficiencyMonitor);