CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/Validation/RecoMuon/src/RecoMuonValidator.cc

Go to the documentation of this file.
00001 #include "Validation/RecoMuon/src/RecoMuonValidator.h"
00002 
00003 #include "DataFormats/TrackReco/interface/Track.h"
00004 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00005 #include "DataFormats/MuonReco/interface/Muon.h"
00006 #include "DataFormats/MuonReco/interface/MuonFwd.h"
00007 #include "SimDataFormats/TrackingAnalysis/interface/TrackingParticle.h"
00008 
00009 #include "SimTracker/Records/interface/TrackAssociatorRecord.h"
00010 #include "SimTracker/TrackAssociation/interface/TrackAssociatorByChi2.h"
00011 #include "SimTracker/TrackAssociation/interface/TrackAssociatorByHits.h"
00012 
00013 #include "FWCore/ServiceRegistry/interface/Service.h"
00014 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00015 #include "DQMServices/Core/interface/DQMStore.h"
00016 #include "DQMServices/Core/interface/MonitorElement.h"
00017 
00018 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00019 #include "RecoMuon/TrackingTools/interface/MuonServiceProxy.h"
00020 
00021 #include "TMath.h"
00022 
00023 using namespace std;
00024 using namespace edm;
00025 using namespace reco;
00026 
00027 typedef TrajectoryStateOnSurface TSOS;
00028 typedef FreeTrajectoryState FTS;
00029 
00030 struct HistoDimensions {
00031   unsigned int nBinP;
00032   double minP, maxP;
00033 
00034   unsigned int nBinPt;
00035   double minPt, maxPt;
00036 
00037   bool doAbsEta;
00038   unsigned int nBinEta;
00039   double minEta, maxEta;
00040 
00041   unsigned int nBinPhi;
00042   double minPhi, maxPhi;
00043 
00044   unsigned int nBinPull;
00045   double wPull;
00046 
00047   unsigned int nBinErr;
00048   double minErrP, maxErrP;
00049   double minErrPt, maxErrPt;
00050   double minErrQPt, maxErrQPt;
00051   double minErrEta, maxErrEta;
00052   double minErrPhi, maxErrPhi;
00053   double minErrDxy, maxErrDxy;
00054   double minErrDz, maxErrDz;
00055 
00056   unsigned int nTrks, nAssoc;
00057   unsigned int nDof;
00058 };
00059 
00060 struct RecoMuonValidator::MuonME {
00061   void bookHistograms(DQMStore* dqm, const string& dirName, const HistoDimensions& hDim)
00062   {
00063     dqm->cd();
00064     dqm->setCurrentFolder(dirName.c_str());
00065 
00066     doAbsEta_ = hDim.doAbsEta;
00067 
00068     hP_   = dqm->book1D("P"  , "p of recoTracks"    , hDim.nBinP  , hDim.minP  , hDim.maxP  );
00069     hPt_  = dqm->book1D("Pt" , "p_{T} of recoTracks", hDim.nBinPt , hDim.minPt , hDim.maxPt );
00070     hEta_ = dqm->book1D("Eta", "#eta of recoTracks" , hDim.nBinEta, hDim.minEta, hDim.maxEta);
00071     hPhi_ = dqm->book1D("Phi", "#phi of recoTracks" , hDim.nBinPhi, hDim.minPhi, hDim.maxPhi);
00072 
00073     // - Resolutions
00074     hErrP_   = dqm->book1D("ErrP"  , "#Delta(p)/p"        , hDim.nBinErr, hDim.minErrP  , hDim.maxErrP  );
00075     hErrPBarrel_   = dqm->book1D("ErrP_barrel"  , "#Delta(p)/p"        , hDim.nBinErr, hDim.minErrP  , hDim.maxErrP  );
00076     hErrPOverlap_   = dqm->book1D("ErrP_overlap"  , "#Delta(p)/p"        , hDim.nBinErr, hDim.minErrP  , hDim.maxErrP  );
00077     hErrPEndcap_   = dqm->book1D("ErrP_endcap"  , "#Delta(p)/p"        , hDim.nBinErr, hDim.minErrP  , hDim.maxErrP  );
00078     hErrPt_  = dqm->book1D("ErrPt" , "#Delta(p_{T})/p_{T}", hDim.nBinErr, hDim.minErrPt , hDim.maxErrPt );
00079     hErrPtBarrel_  = dqm->book1D("ErrPt_barrel" , "#Delta(p_{T})/p_{T}", hDim.nBinErr, hDim.minErrPt , hDim.maxErrPt );
00080     hErrPtOverlap_  = dqm->book1D("ErrPt_overlap" , "#Delta(p_{T})/p_{T}", hDim.nBinErr, hDim.minErrPt , hDim.maxErrPt );
00081     hErrPtEndcap_  = dqm->book1D("ErrPt_endcap" , "#Delta(p_{T})/p_{T}", hDim.nBinErr, hDim.minErrPt , hDim.maxErrPt );
00082     hErrEta_ = dqm->book1D("ErrEta", "#sigma(#eta))"      , hDim.nBinErr, hDim.minErrEta, hDim.maxErrEta);
00083     hErrPhi_ = dqm->book1D("ErrPhi", "#sigma(#phi)"       , hDim.nBinErr, hDim.minErrPhi, hDim.maxErrPhi);
00084     hErrDxy_ = dqm->book1D("ErrDxy", "#sigma(d_{xy})"     , hDim.nBinErr, hDim.minErrDxy, hDim.maxErrDxy);
00085     hErrDz_  = dqm->book1D("ErrDz" , "#sigma(d_{z})"      , hDim.nBinErr, hDim.minErrDz , hDim.maxErrDz );
00086 
00087     // -- Resolutions vs Eta
00088     hErrP_vs_Eta_   = dqm->book2D("ErrP_vs_Eta", "#Delta(p)/p vs #eta",
00089                                   hDim.nBinEta, hDim.minEta, hDim.maxEta, hDim.nBinErr, hDim.minErrP, hDim.maxErrP);
00090     hErrPt_vs_Eta_  = dqm->book2D("ErrPt_vs_Eta", "#Delta(p_{T})/p_{T} vs #eta",
00091                                   hDim.nBinEta, hDim.minEta, hDim.maxEta, hDim.nBinErr, hDim.minErrPt, hDim.maxErrPt);
00092     hErrQPt_vs_Eta_ = dqm->book2D("ErrQPt_vs_Eta", "#Delta(q/p_{T})/(q/p_{T}) vs #eta",
00093                                   hDim.nBinEta, hDim.minEta, hDim.maxEta, hDim.nBinErr, hDim.minErrQPt, hDim.maxErrQPt);
00094     hErrEta_vs_Eta_ = dqm->book2D("ErrEta_vs_Eta", "#sigma(#eta) vs #eta",
00095                                   hDim.nBinEta, hDim.minEta, hDim.maxEta, hDim.nBinErr, hDim.minErrEta, hDim.maxErrEta);
00096 
00097     // -- Resolutions vs momentum
00098     hErrP_vs_P_    = dqm->book2D("ErrP_vs_P", "#Delta(p)/p vs p",
00099                                  hDim.nBinP, hDim.minP, hDim.maxP, hDim.nBinErr, hDim.minErrP, hDim.maxErrP);
00100 
00101     hErrPt_vs_Pt_  = dqm->book2D("ErrPt_vs_Pt", "#Delta(p_{T})/p_{T} vs p_{T}",
00102                                  hDim.nBinPt, hDim.minPt, hDim.maxPt, hDim.nBinErr, hDim.minErrPt, hDim.maxErrPt);
00103     hErrQPt_vs_Pt_ = dqm->book2D("ErrQPt_vs_Pt", "#Delta(q/p_{T})/(q/p_{T}) vs p_{T}",
00104                                  hDim.nBinPt, hDim.minPt, hDim.maxPt, hDim.nBinErr, hDim.minErrQPt, hDim.maxErrQPt);
00105 
00106 
00107     // - Pulls
00108     hPullPt_  = dqm->book1D("PullPt" , "Pull(#p_{T})" , hDim.nBinPull, -hDim.wPull, hDim.wPull);
00109     hPullEta_ = dqm->book1D("PullEta", "Pull(#eta)"   , hDim.nBinPull, -hDim.wPull, hDim.wPull);
00110     hPullPhi_ = dqm->book1D("PullPhi", "Pull(#phi)"   , hDim.nBinPull, -hDim.wPull, hDim.wPull);
00111     hPullQPt_ = dqm->book1D("PullQPt", "Pull(q/p_{T})", hDim.nBinPull, -hDim.wPull, hDim.wPull);
00112     hPullDxy_ = dqm->book1D("PullDxy", "Pull(D_{xy})" , hDim.nBinPull, -hDim.wPull, hDim.wPull);
00113     hPullDz_  = dqm->book1D("PullDz" , "Pull(D_{z})"  , hDim.nBinPull, -hDim.wPull, hDim.wPull);
00114 
00115     // -- Pulls vs Eta
00116     hPullPt_vs_Eta_  = dqm->book2D("PullPt_vs_Eta", "Pull(p_{T}) vs #eta",
00117                                    hDim.nBinEta, hDim.minEta, hDim.maxEta, hDim.nBinPull, -hDim.wPull, hDim.wPull);
00118     hPullEta_vs_Eta_ = dqm->book2D("PullEta_vs_Eta", "Pull(#eta) vs #eta",
00119                                    hDim.nBinEta, hDim.minEta, hDim.maxEta, hDim.nBinPull, -hDim.wPull, hDim.wPull);
00120     hPullPhi_vs_Eta_ = dqm->book2D("PullPhi_vs_Eta", "Pull(#phi) vs #eta",
00121                                    hDim.nBinEta, hDim.minEta, hDim.maxEta, hDim.nBinPull, -hDim.wPull, hDim.wPull);
00122 
00123     // -- Pulls vs Pt
00124     hPullPt_vs_Pt_ = dqm->book2D("PullPt_vs_Pt", "Pull(p_{T}) vs p_{T}",
00125                                  hDim.nBinPt, hDim.minPt, hDim.maxPt, hDim.nBinPull, -hDim.wPull, hDim.wPull);
00126     hPullEta_vs_Pt_ = dqm->book2D("PullEta_vs_Pt", "Pull(#eta) vs p_{T}",
00127                                   hDim.nBinPt, hDim.minPt, hDim.maxPt, hDim.nBinPull, -hDim.wPull, hDim.wPull);
00128 
00129     // - Misc. variables
00130     hNTrks_ = dqm->book1D("NTrks", "Number of reco tracks per event", hDim.nTrks, 0, hDim.nTrks);
00131     hNTrksEta_ = dqm->book1D("NTrksEta", "Number of reco tracks vs #eta", hDim.nBinEta, hDim.minEta, hDim.maxEta);
00132     hNTrksPt_ = dqm->book1D("NTrksPt", "Number of reco tracks vs p_{T}", hDim.nBinPt, hDim.minPt, hDim.maxPt);
00133 
00134     hMisQPt_  = dqm->book1D("MisQPt" , "Charge mis-id vs Pt" , hDim.nBinPt , hDim.minPt , hDim.maxPt );
00135     hMisQEta_ = dqm->book1D("MisQEta", "Charge mis-id vs Eta", hDim.nBinEta, hDim.minEta, hDim.maxEta);
00136 
00137     // -- Number of Hits
00138     const int nHits = 80;
00139     hNHits_ = dqm->book1D("NHits", "Number of hits", nHits, 0, nHits);
00140     hNHits_vs_Pt_  = dqm->book2D("NHits_vs_Pt", "Number of hits vs p_{T}",
00141                                  hDim.nBinPt, hDim.minPt, hDim.maxPt, nHits/4, 0, nHits);
00142     hNHits_vs_Eta_ = dqm->book2D("NHits_vs_Eta", "Number of hits vs #eta",
00143                                  hDim.nBinEta, hDim.minEta, hDim.maxEta, nHits/4, 0, nHits);
00144 
00145     hNSimHits_ = dqm->book1D("NSimHits", "Number of simHits", nHits, 0, nHits);
00146 
00147     const int nLostHits = 5;
00148     hNLostHits_ = dqm->book1D("NLostHits", "Number of Lost hits", nLostHits, 0, nLostHits);
00149     hNLostHits_vs_Pt_  = dqm->book2D("NLostHits_vs_Pt", "Number of lost Hits vs p_{T}",
00150                                      hDim.nBinPt, hDim.minPt, hDim.maxPt, nLostHits, 0, nLostHits);
00151     hNLostHits_vs_Eta_ = dqm->book2D("NLostHits_vs_Eta", "Number of lost Hits vs #eta",
00152                                      hDim.nBinEta, hDim.minEta, hDim.maxEta, nLostHits, 0, nLostHits);
00153 
00154     const int nTrackerHits = 40;
00155     hNTrackerHits_ = dqm->book1D("NTrackerHits", "Number of valid tracker hits", nTrackerHits, 0, nTrackerHits);
00156     hNTrackerHits_vs_Pt_ = dqm->book2D("NTrackerHits_vs_Pt", "Number of valid traker hits vs p_{T}",
00157                                        hDim.nBinPt, hDim.minPt, hDim.maxPt, nTrackerHits/4, 0, nTrackerHits);
00158     hNTrackerHits_vs_Eta_ = dqm->book2D("NTrackerHits_vs_Eta", "Number of valid tracker hits vs #eta",
00159                                         hDim.nBinEta, hDim.minEta, hDim.maxEta, nTrackerHits/4, 0, nTrackerHits);
00160 
00161     const int nMuonHits = 40;
00162     hNMuonHits_ = dqm->book1D("NMuonHits", "Number of valid muon hits", nMuonHits, 0, nMuonHits);
00163     hNMuonHits_vs_Pt_  = dqm->book2D("NMuonHits_vs_Pt", "Number of valid muon hits vs p_{T}",
00164                                      hDim.nBinPt, hDim.minPt, hDim.maxPt, nMuonHits/4, 0, nMuonHits);
00165     hNMuonHits_vs_Eta_ = dqm->book2D("NMuonHits_vs_Eta", "Number of valid muon hits vs #eta",
00166                                      hDim.nBinEta, hDim.minEta, hDim.maxEta, nMuonHits/4, 0, nMuonHits);
00167 
00168     hNDof_ = dqm->book1D("NDof", "Number of DoF", hDim.nDof, 0, hDim.nDof);
00169     hChi2_ = dqm->book1D("Chi2", "#Chi^{2}", hDim.nBinErr, 0, 200);
00170     hChi2Norm_ = dqm->book1D("Chi2Norm", "Normalized #Chi^{2}", hDim.nBinErr, 0, 50);
00171     hChi2Prob_ = dqm->book1D("Chi2Prob", "Prob(#Chi^{2})", hDim.nBinErr, 0, 1);
00172 
00173     hNDof_vs_Eta_ = dqm->book2D("NDof_vs_Eta", "Number of DoF vs #eta",
00174                                 hDim.nBinEta, hDim.minEta, hDim.maxEta, hDim.nBinErr, 0, hDim.nDof);
00175     hChi2_vs_Eta_ = dqm->book2D("Chi2_vs_Eta", "#Chi^{2} vs #eta",
00176                                 hDim.nBinEta, hDim.minEta, hDim.maxEta, hDim.nBinErr, 0, 200);
00177     hChi2Norm_vs_Eta_ = dqm->book2D("Chi2Norm_vs_Eta", "Normalized #Chi^{2} vs #eta",
00178                                     hDim.nBinEta, hDim.minEta, hDim.maxEta, hDim.nBinErr, 0, 100);
00179     hChi2Prob_vs_Eta_ = dqm->book2D("Chi2Prob_vs_Eta", "Prob(#Chi^{2}) vs #eta",
00180                                     hDim.nBinEta, hDim.minEta, hDim.maxEta, hDim.nBinErr, 0, 1);
00181 
00182     hNSimToReco_ = dqm->book1D("NSimToReco", "Number of associated reco tracks", hDim.nAssoc, 0, hDim.nAssoc);
00183     hNRecoToSim_ = dqm->book1D("NRecoToSim", "Number of associated sim TP's", hDim.nAssoc, 0, hDim.nAssoc);
00184   };
00185 
00186   void fill(const TrackingParticle* simRef, const Track* recoRef)
00187   {
00188     const double simP   = simRef->p();
00189     const double simPt  = simRef->pt();
00190     const double simEta = doAbsEta_ ? fabs(simRef->eta()) : simRef->eta();
00191     const double simPhi = simRef->phi();
00192     const double simQ   = simRef->charge();
00193     const double simQPt = simQ/simPt;
00194 
00195     GlobalPoint  simVtx(simRef->vertex().x(), simRef->vertex().y(), simRef->vertex().z());
00196     GlobalVector simMom(simRef->momentum().x(), simRef->momentum().y(), simRef->momentum().z());
00197     const double simDxy = -simVtx.x()*sin(simPhi)+simVtx.y()*cos(simPhi);
00198     const double simDz  = simVtx.z() - (simVtx.x()*simMom.x()+simVtx.y()*simMom.y())*simMom.z()/simMom.perp2();
00199 
00200     const unsigned int nSimHits = simRef->pSimHit_end() - simRef->pSimHit_begin();
00201 
00202     // Histograms for efficiency plots
00203     hP_  ->Fill(simP  );
00204     hPt_ ->Fill(simPt );
00205     hEta_->Fill(simEta);
00206     hPhi_->Fill(simPhi);
00207     hNSimHits_->Fill(nSimHits);
00208 
00209     // Number of reco-hits
00210     const int nRecoHits = recoRef->numberOfValidHits();
00211     const int nLostHits = recoRef->numberOfLostHits();
00212 
00213     hNHits_->Fill(nRecoHits);
00214     hNHits_vs_Pt_ ->Fill(simPt , nRecoHits);
00215     hNHits_vs_Eta_->Fill(simEta, nRecoHits);
00216 
00217     hNLostHits_->Fill(nLostHits);
00218     hNLostHits_vs_Pt_ ->Fill(simPt , nLostHits);
00219     hNLostHits_vs_Eta_->Fill(simEta, nLostHits);
00220 
00221     const double recoNDof = recoRef->ndof();
00222     const double recoChi2 = recoRef->chi2();
00223     const double recoChi2Norm = recoRef->normalizedChi2();
00224     const double recoChi2Prob = TMath::Prob(recoRef->chi2(), static_cast<int>(recoRef->ndof()));
00225 
00226     hNDof_->Fill(recoNDof);
00227     hChi2_->Fill(recoChi2);
00228     hChi2Norm_->Fill(recoChi2Norm);
00229     hChi2Prob_->Fill(recoChi2Prob);
00230 
00231     hNDof_vs_Eta_->Fill(simEta, recoNDof);
00232     hChi2_vs_Eta_->Fill(simEta, recoChi2);
00233     hChi2Norm_vs_Eta_->Fill(simEta, recoChi2Norm);
00234     hChi2Prob_vs_Eta_->Fill(simEta, recoChi2Prob);
00235 
00236     const double recoQ   = recoRef->charge();
00237     if ( simQ*recoQ < 0 ) {
00238       hMisQPt_ ->Fill(simPt );
00239       hMisQEta_->Fill(simEta);
00240     }
00241 
00242     const double recoP   = sqrt(recoRef->momentum().mag2());
00243     const double recoPt  = sqrt(recoRef->momentum().perp2());
00244     const double recoEta = recoRef->momentum().eta();
00245     const double recoPhi = recoRef->momentum().phi();
00246     const double recoQPt = recoQ/recoPt;
00247 
00248     const double recoDxy = recoRef->dxy();
00249     const double recoDz  = recoRef->dz();
00250 
00251     const double errP   = (recoP-simP)/simP;
00252     const double errPt  = (recoPt-simPt)/simPt;
00253     const double errEta = (recoEta-simEta)/simEta;
00254     const double errPhi = (recoPhi-simPhi)/simPhi;
00255     const double errQPt = (recoQPt-simQPt)/simQPt;
00256 
00257     const double errDxy = (recoDxy-simDxy)/simDxy;
00258     const double errDz  = (recoDz-simDz)/simDz;
00259 
00260     hErrP_  ->Fill(errP  );
00261     hErrPt_ ->Fill(errPt );
00262     hErrEta_->Fill(errEta);
00263     hErrPhi_->Fill(errPhi);
00264     hErrDxy_->Fill(errDxy);
00265     hErrDz_ ->Fill(errDz );
00266 
00267     if(fabs(simEta) > 0. && fabs(simEta) < 0.8) {
00268       hErrPBarrel_->Fill(errP);
00269       hErrPtBarrel_->Fill(errPt);
00270     } else if (fabs(simEta) > 0.8 && fabs(simEta) < 1.2) {
00271       hErrPOverlap_->Fill(errP);
00272       hErrPtOverlap_->Fill(errPt);
00273     } else if (fabs(simEta) > 1.2 ){
00274       hErrPEndcap_->Fill(errP);
00275       hErrPtEndcap_->Fill(errPt);
00276     }
00277 
00278     hErrP_vs_Eta_  ->Fill(simEta, errP  );
00279     hErrPt_vs_Eta_ ->Fill(simEta, errPt );
00280     hErrQPt_vs_Eta_->Fill(simEta, errQPt);
00281 
00282     hErrP_vs_P_   ->Fill(simP  , errP  );
00283     hErrPt_vs_Pt_ ->Fill(simPt , errPt );
00284     hErrQPt_vs_Pt_->Fill(simQPt, errQPt);
00285 
00286     hErrEta_vs_Eta_->Fill(simEta, errEta);
00287 
00288     const double pullPt  = (recoPt-simPt)/recoRef->ptError();
00289     const double pullQPt = (recoQPt-simQPt)/recoRef->qoverpError();
00290     const double pullEta = (recoEta-simEta)/recoRef->etaError();
00291     const double pullPhi = (recoPhi-simPhi)/recoRef->phiError();
00292     const double pullDxy = (recoDxy-simDxy)/recoRef->dxyError();
00293     const double pullDz  = (recoDz-simDz)/recoRef->dzError();
00294 
00295     hPullPt_ ->Fill(pullPt );
00296     hPullEta_->Fill(pullEta);
00297     hPullPhi_->Fill(pullPhi);
00298     hPullQPt_->Fill(pullQPt);
00299     hPullDxy_->Fill(pullDxy);
00300     hPullDz_ ->Fill(pullDz );
00301 
00302     hPullPt_vs_Eta_->Fill(simEta, pullPt);
00303     hPullPt_vs_Pt_ ->Fill(simPt, pullPt);
00304 
00305     hPullEta_vs_Eta_->Fill(simEta, pullEta);
00306     hPullPhi_vs_Eta_->Fill(simEta, pullPhi);
00307 
00308     hPullEta_vs_Pt_->Fill(simPt, pullEta);
00309 
00310 
00311   };
00312 
00313   bool doAbsEta_;
00314 
00315   typedef MonitorElement* MEP;
00316 
00317   MEP hP_, hPt_, hEta_, hPhi_;
00318   MEP hErrP_, hErrPt_, hErrEta_, hErrPhi_;
00319   MEP hErrPBarrel_, hErrPOverlap_, hErrPEndcap_;
00320   MEP hErrPtBarrel_, hErrPtOverlap_, hErrPtEndcap_;
00321   MEP hErrDxy_, hErrDz_;
00322 
00323   MEP hErrP_vs_Eta_, hErrPt_vs_Eta_, hErrQPt_vs_Eta_;
00324   MEP hErrP_vs_P_, hErrPt_vs_Pt_, hErrQPt_vs_Pt_, hErrEta_vs_Eta_;
00325 
00326   MEP hPullPt_, hPullEta_, hPullPhi_, hPullQPt_, hPullDxy_, hPullDz_;
00327   MEP hPullPt_vs_Eta_, hPullPt_vs_Pt_, hPullEta_vs_Eta_, hPullPhi_vs_Eta_, hPullEta_vs_Pt_;
00328 
00329   MEP hNDof_, hChi2_, hChi2Norm_, hChi2Prob_;
00330   MEP hNDof_vs_Eta_, hChi2_vs_Eta_, hChi2Norm_vs_Eta_, hChi2Prob_vs_Eta_;
00331 
00332   MEP hNTrks_, hNTrksEta_,  hNTrksPt_;
00333 
00334   MEP hMisQPt_, hMisQEta_;
00335 
00336   MEP hNSimHits_;
00337   MEP hNHits_, hNLostHits_, hNTrackerHits_, hNMuonHits_;
00338   MEP hNHits_vs_Pt_, hNHits_vs_Eta_;
00339   MEP hNLostHits_vs_Pt_, hNLostHits_vs_Eta_;
00340   MEP hNTrackerHits_vs_Pt_, hNTrackerHits_vs_Eta_;
00341   MEP hNMuonHits_vs_Pt_, hNMuonHits_vs_Eta_;
00342 
00343   MEP hNSimToReco_, hNRecoToSim_;
00344 };
00345 
00346 struct RecoMuonValidator::CommonME {
00347   typedef MonitorElement* MEP;
00348 
00349   MEP hSimP_, hSimPt_, hSimEta_, hSimPhi_;
00350   MEP hNSim_, hNMuon_;
00351   MEP hNSimHits_;
00352 
00353   MEP hTrkToGlbDiffNTrackerHits_, hStaToGlbDiffNMuonHits_;
00354   MEP hTrkToGlbDiffNTrackerHitsEta_, hStaToGlbDiffNMuonHitsEta_;
00355   MEP hTrkToGlbDiffNTrackerHitsPt_, hStaToGlbDiffNMuonHitsPt_;
00356 };
00357 
00358 RecoMuonValidator::RecoMuonValidator(const ParameterSet& pset)
00359 {
00360   verbose_ = pset.getUntrackedParameter<unsigned int>("verbose", 0);
00361 
00362   outputFileName_ = pset.getUntrackedParameter<string>("outputFileName", "");
00363 
00364   // Set histogram dimensions
00365   HistoDimensions hDim;
00366 
00367   hDim.nBinP = pset.getUntrackedParameter<unsigned int>("nBinP");
00368   hDim.minP = pset.getUntrackedParameter<double>("minP");
00369   hDim.maxP = pset.getUntrackedParameter<double>("maxP");
00370 
00371   hDim.nBinPt = pset.getUntrackedParameter<unsigned int>("nBinPt");
00372   hDim.minPt = pset.getUntrackedParameter<double>("minPt");
00373   hDim.maxPt = pset.getUntrackedParameter<double>("maxPt");
00374 
00375   doAbsEta_ = pset.getUntrackedParameter<bool>("doAbsEta");
00376   hDim.doAbsEta = doAbsEta_;
00377   hDim.nBinEta  = pset.getUntrackedParameter<unsigned int>("nBinEta");
00378   hDim.minEta = pset.getUntrackedParameter<double>("minEta");
00379   hDim.maxEta = pset.getUntrackedParameter<double>("maxEta");
00380 
00381   hDim.nBinPhi  = pset.getUntrackedParameter<unsigned int>("nBinPhi");
00382   hDim.minPhi = pset.getUntrackedParameter<double>("minPhi", -TMath::Pi());
00383   hDim.maxPhi = pset.getUntrackedParameter<double>("maxPhi",  TMath::Pi());
00384 
00385   hDim.nBinErr  = pset.getUntrackedParameter<unsigned int>("nBinErr");
00386   hDim.nBinPull = pset.getUntrackedParameter<unsigned int>("nBinPull");
00387 
00388   hDim.wPull = pset.getUntrackedParameter<double>("wPull");
00389 
00390   hDim.minErrP = pset.getUntrackedParameter<double>("minErrP");
00391   hDim.maxErrP = pset.getUntrackedParameter<double>("maxErrP");
00392 
00393   hDim.minErrPt = pset.getUntrackedParameter<double>("minErrPt");
00394   hDim.maxErrPt = pset.getUntrackedParameter<double>("maxErrPt");
00395 
00396   hDim.minErrQPt = pset.getUntrackedParameter<double>("minErrQPt");
00397   hDim.maxErrQPt = pset.getUntrackedParameter<double>("maxErrQPt");
00398 
00399   hDim.minErrEta = pset.getUntrackedParameter<double>("minErrEta");
00400   hDim.maxErrEta = pset.getUntrackedParameter<double>("maxErrEta");
00401 
00402   hDim.minErrPhi = pset.getUntrackedParameter<double>("minErrPhi");
00403   hDim.maxErrPhi = pset.getUntrackedParameter<double>("maxErrPhi");
00404 
00405   hDim.minErrDxy = pset.getUntrackedParameter<double>("minErrDxy");
00406   hDim.maxErrDxy = pset.getUntrackedParameter<double>("maxErrDxy");
00407 
00408   hDim.minErrDz  = pset.getUntrackedParameter<double>("minErrDz" );
00409   hDim.maxErrDz  = pset.getUntrackedParameter<double>("maxErrDz" );
00410 
00411   hDim.nTrks = pset.getUntrackedParameter<unsigned int>("nTrks");
00412   hDim.nAssoc = pset.getUntrackedParameter<unsigned int>("nAssoc");
00413   hDim.nDof = pset.getUntrackedParameter<unsigned int>("nDof", 55);
00414 
00415   // Labels for simulation and reconstruction tracks
00416   simLabel_  = pset.getParameter<InputTag>("simLabel" );
00417   trkMuLabel_ = pset.getParameter<InputTag>("trkMuLabel");
00418   staMuLabel_ = pset.getParameter<InputTag>("staMuLabel");
00419   glbMuLabel_ = pset.getParameter<InputTag>("glbMuLabel");
00420   muonLabel_ = pset.getParameter<InputTag>("muonLabel");
00421 
00422   // Labels for sim-reco association
00423   doAssoc_ = pset.getUntrackedParameter<bool>("doAssoc", true);
00424   trkMuAssocLabel_ = pset.getParameter<InputTag>("trkMuAssocLabel");
00425   staMuAssocLabel_ = pset.getParameter<InputTag>("staMuAssocLabel");
00426   glbMuAssocLabel_ = pset.getParameter<InputTag>("glbMuAssocLabel");
00427 
00428 //  seedPropagatorName_ = pset.getParameter<string>("SeedPropagator");
00429 
00430   ParameterSet tpset = pset.getParameter<ParameterSet>("tpSelector");
00431   tpSelector_ = TrackingParticleSelector(tpset.getParameter<double>("ptMin"),
00432                                          tpset.getParameter<double>("minRapidity"),
00433                                          tpset.getParameter<double>("maxRapidity"),
00434                                          tpset.getParameter<double>("tip"),
00435                                          tpset.getParameter<double>("lip"),
00436                                          tpset.getParameter<int>("minHit"),
00437                                          tpset.getParameter<bool>("signalOnly"),
00438                                          tpset.getParameter<bool>("chargedOnly"),
00439                                          tpset.getParameter<std::vector<int> >("pdgId"));
00440 
00441   // the service parameters
00442   ParameterSet serviceParameters 
00443     = pset.getParameter<ParameterSet>("ServiceParameters");
00444   theMuonService = new MuonServiceProxy(serviceParameters);
00445 
00446   // retrieve the instance of DQMService
00447   theDQM = 0;
00448   theDQM = Service<DQMStore>().operator->();
00449 
00450   if ( ! theDQM ) {
00451     LogError("RecoMuonValidator") << "DQMService not initialized\n";
00452     return;
00453   }
00454 
00455   subDir_ = pset.getUntrackedParameter<string>("subDir");
00456   if ( subDir_.empty() ) subDir_ = "RecoMuonV";
00457   if ( subDir_[subDir_.size()-1] == '/' ) subDir_.erase(subDir_.size()-1);
00458 
00459   // book histograms
00460   theDQM->cd();
00461 
00462   theDQM->setCurrentFolder(subDir_+"/Muons");
00463 
00464   commonME_ = new CommonME;
00465   trkMuME_ = new MuonME;
00466   staMuME_ = new MuonME;
00467   glbMuME_ = new MuonME;
00468 
00469   commonME_->hSimP_   = theDQM->book1D("SimP"  , "p of simTracks"    , hDim.nBinP  , hDim.minP  , hDim.maxP  );
00470   commonME_->hSimPt_  = theDQM->book1D("SimPt" , "p_{T} of simTracks", hDim.nBinPt , hDim.minPt , hDim.maxPt );
00471   commonME_->hSimEta_ = theDQM->book1D("SimEta", "#eta of simTracks" , hDim.nBinEta, hDim.minEta, hDim.maxEta);
00472   commonME_->hSimPhi_ = theDQM->book1D("SimPhi", "#phi of simTracks" , hDim.nBinPhi, hDim.minPhi, hDim.maxPhi);
00473 
00474   commonME_->hNSim_  = theDQM->book1D("NSim" , "Number of particles per event", hDim.nTrks, 0, hDim.nTrks);
00475   commonME_->hNMuon_ = theDQM->book1D("NMuon", "Number of muons per event"    , hDim.nTrks, 0, hDim.nTrks);
00476 
00477   const int nHits = 201;
00478   commonME_->hNSimHits_ = theDQM->book1D("NSimHits", "Number of simHits", nHits, -100.5, 100.5);
00479 
00480   commonME_->hTrkToGlbDiffNTrackerHits_ = theDQM->book1D("TrkGlbDiffNTrackerHits", "Difference of number of tracker hits (tkMuon - globalMuon)", nHits, -100.5, 100.5);
00481   commonME_->hStaToGlbDiffNMuonHits_ = theDQM->book1D("StaGlbDiffNMuonHits", "Difference of number of muon hits (staMuon - globalMuon)", nHits, -100.5, 100.5);
00482 
00483   commonME_->hTrkToGlbDiffNTrackerHitsEta_ = theDQM->book2D("TrkGlbDiffNTrackerHitsEta", "Difference of number of tracker hits (tkMuon - globalMuon)",   hDim.nBinEta, hDim.minEta, hDim.maxEta,nHits, -100.5, 100.5);
00484   commonME_->hStaToGlbDiffNMuonHitsEta_ = theDQM->book2D("StaGlbDiffNMuonHitsEta", "Difference of number of muon hits (staMuon - globalMuon)",   hDim.nBinEta, hDim.minEta, hDim.maxEta,nHits, -100.5, 100.5);
00485 
00486   commonME_->hTrkToGlbDiffNTrackerHitsPt_ = theDQM->book2D("TrkGlbDiffNTrackerHitsPt", "Difference of number of tracker hits (tkMuon - globalMuon)",  hDim.nBinPt, hDim.minPt, hDim.maxPt,nHits, -100.5, 100.5);
00487   commonME_->hStaToGlbDiffNMuonHitsPt_ = theDQM->book2D("StaGlbDiffNMuonHitsPt", "Difference of number of muon hits (staMuon - globalMuon)",  hDim.nBinPt, hDim.minPt, hDim.maxPt,nHits, -100.5, 100.5);
00488 
00489   // - histograms on tracking variables
00490   theDQM->setCurrentFolder(subDir_+"/Trk");
00491   theDQM->bookString("TrackLabel", trkMuLabel_.label()+"_"+trkMuLabel_.instance());
00492   theDQM->bookString("AssocLabel", trkMuAssocLabel_.label());
00493 
00494   theDQM->setCurrentFolder(subDir_+"/Sta");
00495   theDQM->bookString("TrackLabel", staMuLabel_.label()+"_"+staMuLabel_.instance());
00496   theDQM->bookString("AssocLabel", staMuAssocLabel_.label());
00497 
00498   theDQM->setCurrentFolder(subDir_+"/Glb");
00499   theDQM->bookString("TrackLabel", glbMuLabel_.label()+"_"+glbMuLabel_.instance());
00500   theDQM->bookString("AssocLabel", glbMuAssocLabel_.label());
00501   
00502   trkMuME_->bookHistograms(theDQM, subDir_+"/Trk", hDim);
00503   staMuME_->bookHistograms(theDQM, subDir_+"/Sta", hDim);
00504   glbMuME_->bookHistograms(theDQM, subDir_+"/Glb", hDim);
00505 
00506   if ( verbose_ > 0 ) theDQM->showDirStructure();
00507 
00508 }
00509 
00510 RecoMuonValidator::~RecoMuonValidator()
00511 {
00512   if ( theMuonService ) delete theMuonService;
00513 }
00514 
00515 void RecoMuonValidator::beginRun(const edm::Run& , const EventSetup& eventSetup)
00516 {
00517   if ( theMuonService ) theMuonService->update(eventSetup);
00518 
00519   trkMuAssociator_ = 0;
00520   staMuAssociator_ = 0;
00521   glbMuAssociator_ = 0;
00522   if ( doAssoc_ ) {
00523     ESHandle<TrackAssociatorBase> trkMuAssocHandle;
00524     eventSetup.get<TrackAssociatorRecord>().get(trkMuAssocLabel_.label(), trkMuAssocHandle);
00525     trkMuAssociator_ = const_cast<TrackAssociatorBase*>(trkMuAssocHandle.product());
00526 
00527     ESHandle<TrackAssociatorBase> staMuAssocHandle;
00528     eventSetup.get<TrackAssociatorRecord>().get(staMuAssocLabel_.label(), staMuAssocHandle);
00529     staMuAssociator_ = const_cast<TrackAssociatorBase*>(staMuAssocHandle.product());
00530 
00531     ESHandle<TrackAssociatorBase> glbMuAssocHandle;
00532     eventSetup.get<TrackAssociatorRecord>().get(glbMuAssocLabel_.label(), glbMuAssocHandle);
00533     glbMuAssociator_ = const_cast<TrackAssociatorBase*>(glbMuAssocHandle.product());
00534   }
00535 }
00536 
00537 void RecoMuonValidator::endRun()
00538 {
00539   if ( theDQM && ! outputFileName_.empty() ) theDQM->save(outputFileName_);
00540 }
00541 
00542 void RecoMuonValidator::analyze(const Event& event, const EventSetup& eventSetup)
00543 {
00544   if ( ! theDQM ) {
00545     LogError("RecoMuonValidator") << "DQMService not initialized\n";
00546     return;
00547   }
00548 
00549   // Get TrackingParticles
00550   Handle<TrackingParticleCollection> simHandle;
00551   event.getByLabel(simLabel_, simHandle);
00552   const TrackingParticleCollection simColl = *(simHandle.product());
00553 
00554   // Get Muon Tracks
00555   Handle<View<Track> > trkMuHandle;
00556   event.getByLabel(trkMuLabel_, trkMuHandle);
00557   View<Track> trkMuColl = *(trkMuHandle.product());
00558 
00559   Handle<View<Track> > staMuHandle;
00560   event.getByLabel(staMuLabel_, staMuHandle);
00561   View<Track> staMuColl = *(staMuHandle.product());
00562 
00563   Handle<View<Track> > glbMuHandle;
00564   event.getByLabel(glbMuLabel_, glbMuHandle);
00565   View<Track> glbMuColl = *(glbMuHandle.product());
00566 
00567   // Get Muons
00568   Handle<View<Muon> > muonHandle;
00569   event.getByLabel(muonLabel_, muonHandle);
00570   View<Muon> muonColl = *(muonHandle.product());
00571 
00572   // Get Association maps
00573   SimToRecoCollection simToTrkMuColl;
00574   SimToRecoCollection simToStaMuColl;
00575   SimToRecoCollection simToGlbMuColl;
00576 
00577   RecoToSimCollection trkMuToSimColl;
00578   RecoToSimCollection staMuToSimColl;
00579   RecoToSimCollection glbMuToSimColl;
00580 
00581   if ( doAssoc_ ) {
00582     // SimToReco associations
00583     simToTrkMuColl = trkMuAssociator_->associateSimToReco(trkMuHandle, simHandle, &event);
00584     simToStaMuColl = staMuAssociator_->associateSimToReco(staMuHandle, simHandle, &event);
00585     simToGlbMuColl = glbMuAssociator_->associateSimToReco(glbMuHandle, simHandle, &event);
00586 
00587     // // RecoToSim associations
00588     trkMuToSimColl = trkMuAssociator_->associateRecoToSim(trkMuHandle, simHandle, &event);
00589     staMuToSimColl = staMuAssociator_->associateRecoToSim(staMuHandle, simHandle, &event);
00590     glbMuToSimColl = glbMuAssociator_->associateRecoToSim(glbMuHandle, simHandle, &event);
00591   }
00592   else {
00593     // SimToReco associations
00594     Handle<SimToRecoCollection> simToTrkMuHandle;
00595     event.getByLabel(trkMuAssocLabel_, simToTrkMuHandle);
00596     simToTrkMuColl = *(simToTrkMuHandle.product());
00597 
00598     Handle<SimToRecoCollection> simToStaMuHandle;
00599     event.getByLabel(staMuAssocLabel_, simToStaMuHandle);
00600     simToStaMuColl = *(simToStaMuHandle.product());
00601 
00602     Handle<SimToRecoCollection> simToGlbMuHandle;
00603     event.getByLabel(glbMuAssocLabel_, simToGlbMuHandle);
00604     simToGlbMuColl = *(simToGlbMuHandle.product());
00605 
00606     // RecoToSim associations
00607     Handle<RecoToSimCollection> trkMuToSimHandle;
00608     event.getByLabel(trkMuAssocLabel_, trkMuToSimHandle);
00609     trkMuToSimColl = *(trkMuToSimHandle.product());
00610 
00611     Handle<RecoToSimCollection> staMuToSimHandle;
00612     event.getByLabel(staMuAssocLabel_, staMuToSimHandle);
00613     staMuToSimColl = *(staMuToSimHandle.product());
00614 
00615     Handle<RecoToSimCollection> glbMuToSimHandle;
00616     event.getByLabel(glbMuAssocLabel_, glbMuToSimHandle);
00617     glbMuToSimColl = *(glbMuToSimHandle.product());
00618   }
00619 
00620   const TrackingParticleCollection::size_type nSim = simColl.size();
00621   commonME_->hNSim_->Fill(nSim);
00622 
00623   commonME_->hNMuon_->Fill(muonColl.size());
00624 
00625   trkMuME_->hNTrks_->Fill(trkMuColl.size());
00626   staMuME_->hNTrks_->Fill(staMuColl.size());
00627   glbMuME_->hNTrks_->Fill(glbMuColl.size());
00628 
00629   // Analyzer reco::Muon
00630   for(View<Muon>::const_iterator iMuon = muonColl.begin();
00631       iMuon != muonColl.end(); ++iMuon) {
00632     int trkNTrackerHits = 0, glbNTrackerHits = 0;
00633     int staNMuonHits = 0, glbNMuonHits = 0;
00634 
00635     if ( iMuon->isTrackerMuon() ) {
00636       const TrackRef trkTrack = iMuon->track();
00637 
00638       trkNTrackerHits = countTrackerHits(*trkTrack);
00639 
00640       trkMuME_->hNTrackerHits_->Fill(trkNTrackerHits);
00641       trkMuME_->hNTrackerHits_vs_Pt_->Fill(trkTrack->pt(), trkNTrackerHits);
00642       trkMuME_->hNTrackerHits_vs_Eta_->Fill(trkTrack->eta(), trkNTrackerHits);
00643     }
00644 
00645     if ( iMuon->isStandAloneMuon() ) {
00646       const TrackRef staTrack = iMuon->standAloneMuon();
00647 
00648       staNMuonHits = countMuonHits(*staTrack);
00649 
00650       staMuME_->hNMuonHits_->Fill(staNMuonHits);
00651       staMuME_->hNMuonHits_vs_Pt_->Fill(staTrack->pt(), staNMuonHits);
00652       staMuME_->hNMuonHits_vs_Eta_->Fill(staTrack->eta(), staNMuonHits);
00653 
00654       staMuME_->hNTrksEta_->Fill(staTrack->eta());
00655       staMuME_->hNTrksPt_->Fill(staTrack->pt());
00656       
00657     }
00658 
00659     if ( iMuon->isGlobalMuon() ) {
00660       const TrackRef glbTrack = iMuon->combinedMuon();
00661 
00662       glbNTrackerHits = countTrackerHits(*glbTrack);
00663       glbNMuonHits = countMuonHits(*glbTrack);
00664 
00665       glbMuME_->hNTrackerHits_->Fill(glbNTrackerHits);
00666       glbMuME_->hNTrackerHits_vs_Pt_->Fill(glbTrack->pt(), glbNTrackerHits);
00667       glbMuME_->hNTrackerHits_vs_Eta_->Fill(glbTrack->eta(), glbNTrackerHits);
00668 
00669       glbMuME_->hNMuonHits_->Fill(glbNMuonHits);
00670       glbMuME_->hNMuonHits_vs_Pt_->Fill(glbTrack->pt(), glbNMuonHits);
00671       glbMuME_->hNMuonHits_vs_Eta_->Fill(glbTrack->eta(), glbNMuonHits);
00672 
00673       glbMuME_->hNTrksEta_->Fill(glbTrack->eta());
00674       glbMuME_->hNTrksPt_->Fill(glbTrack->pt());
00675       
00676       commonME_->hTrkToGlbDiffNTrackerHitsEta_->Fill(glbTrack->eta(),trkNTrackerHits-glbNTrackerHits);
00677       commonME_->hStaToGlbDiffNMuonHitsEta_->Fill(glbTrack->eta(),staNMuonHits-glbNMuonHits);
00678       
00679       commonME_->hTrkToGlbDiffNTrackerHitsPt_->Fill(glbTrack->pt(),trkNTrackerHits-glbNTrackerHits);
00680       commonME_->hStaToGlbDiffNMuonHitsPt_->Fill(glbTrack->pt(),staNMuonHits-glbNMuonHits);
00681       
00682       commonME_->hTrkToGlbDiffNTrackerHits_->Fill(trkNTrackerHits-glbNTrackerHits);
00683       commonME_->hStaToGlbDiffNMuonHits_->Fill(staNMuonHits-glbNMuonHits);
00684 
00685     }
00686 
00687   }
00688 
00689   // Analyzer reco::Track
00690   for(TrackingParticleCollection::size_type i=0; i<nSim; i++) {
00691     TrackingParticleRef simRef(simHandle, i);
00692     const TrackingParticle* simTP = simRef.get();
00693     if ( ! tpSelector_(*simTP) ) continue;
00694 
00695     const double simP   = simRef->p();
00696     const double simPt  = simRef->pt();
00697     const double simEta = doAbsEta_ ? fabs(simRef->eta()) : simRef->eta();
00698     const double simPhi = simRef->phi();
00699 
00700     const unsigned int nSimHits = simRef->pSimHit_end() - simRef->pSimHit_begin();
00701 
00702     commonME_->hSimP_  ->Fill(simP  );
00703     commonME_->hSimPt_ ->Fill(simPt );
00704     commonME_->hSimEta_->Fill(simEta);
00705     commonME_->hSimPhi_->Fill(simPhi);
00706 
00707     commonME_->hNSimHits_->Fill(nSimHits);
00708 
00709     // Get sim-reco association for a simRef
00710     vector<pair<RefToBase<Track>, double> > trkMuRefV, staMuRefV, glbMuRefV;
00711     if ( simToTrkMuColl.find(simRef) != simToTrkMuColl.end() ) {
00712       trkMuRefV = simToTrkMuColl[simRef];
00713 
00714       trkMuME_->hNSimToReco_->Fill(trkMuRefV.size());
00715       if ( ! trkMuRefV.empty() ) {
00716         const Track* trkMuTrack = trkMuRefV.begin()->first.get();
00717 //        const double assocQuality = trkMuRefV.begin()->second;
00718 
00719         trkMuME_->fill(simTP, trkMuTrack);
00720       }
00721     }
00722 
00723     if ( simToStaMuColl.find(simRef) != simToStaMuColl.end() ) {
00724       staMuRefV = simToStaMuColl[simRef];
00725 
00726       staMuME_->hNSimToReco_->Fill(staMuRefV.size());
00727       if ( ! staMuRefV.empty() ) {
00728         const Track* staMuTrack = staMuRefV.begin()->first.get();
00729 //        const double assocQuality = staMuRefV.begin().second;
00730 
00731         staMuME_->fill(simTP, staMuTrack);
00732       }
00733     }
00734 
00735     if ( simToGlbMuColl.find(simRef) != simToGlbMuColl.end() ) {
00736       glbMuRefV = simToGlbMuColl[simRef];
00737 
00738       glbMuME_->hNSimToReco_->Fill(glbMuRefV.size());
00739       if ( ! glbMuRefV.empty() ) {
00740         const Track* glbMuTrack = glbMuRefV.begin()->first.get();
00741 //        const double assocQuality = glbMuRefV.begin().second;
00742 
00743         glbMuME_->fill(simTP, glbMuTrack);
00744       }
00745     }
00746   }
00747 }
00748 
00749 int
00750 RecoMuonValidator::countMuonHits(const reco::Track& track) const {
00751   TransientTrackingRecHit::ConstRecHitContainer result;
00752   
00753   int count = 0;
00754 
00755   for (trackingRecHit_iterator hit = track.recHitsBegin(); hit != track.recHitsEnd(); ++hit) {
00756     if((*hit)->isValid()) {
00757       DetId recoid = (*hit)->geographicalId();
00758       if ( recoid.det() == DetId::Muon ) count++;
00759     }
00760   }
00761   return count;
00762 }
00763 
00764 int
00765 RecoMuonValidator::countTrackerHits(const reco::Track& track) const {
00766   TransientTrackingRecHit::ConstRecHitContainer result;
00767   
00768   int count = 0;
00769 
00770   for (trackingRecHit_iterator hit = track.recHitsBegin(); hit != track.recHitsEnd(); ++hit) {
00771     if((*hit)->isValid()) {
00772       DetId recoid = (*hit)->geographicalId();
00773       if ( recoid.det() == DetId::Tracker ) count++;
00774     }
00775   }
00776   return count;
00777 }
00778 
00779 /* vim:set ts=2 sts=2 sw=2 expandtab: */