CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_6/src/Validation/RecoMuon/src/MuonTrackResidualAnalyzer.cc

Go to the documentation of this file.
00001 #include "Validation/RecoMuon/src/MuonTrackResidualAnalyzer.h"
00002 
00003 // Collaborating Class Header
00004 #include "FWCore/Framework/interface/Frameworkfwd.h"
00005 #include "FWCore/Framework/interface/Event.h"
00006 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00008 
00009 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
00010 
00011 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00012 #include "TrackingTools/KalmanUpdators/interface/KFUpdator.h"
00013 #include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimator.h"
00014 #include "TrackingTools/TrackFitters/interface/KFTrajectoryFitter.h"
00015 #include "TrackingTools/TrackFitters/interface/KFTrajectorySmoother.h"
00016 
00017 #include "DataFormats/TrajectorySeed/interface/TrajectorySeedCollection.h"
00018 #include "DataFormats/TrackReco/interface/Track.h"
00019 #include "DataFormats/MuonDetId/interface/DTLayerId.h"
00020 #include "DataFormats/MuonDetId/interface/MuonSubdetId.h"
00021 
00022 #include "RecoMuon/TrackingTools/interface/MuonPatternRecoDumper.h"
00023 #include "RecoMuon/TrackingTools/interface/MuonServiceProxy.h"
00024 #include "Validation/RecoMuon/src/Histograms.h"
00025 #include "RecoMuon/TransientTrackingRecHit/interface/MuonTransientTrackingRecHitBuilder.h"
00026 #include "RecoMuon/TransientTrackingRecHit/interface/MuonTransientTrackingRecHit.h"
00027 
00028 
00029 #include "TFile.h"
00030 #include "TH1F.h"
00031 #include "TH2F.h"
00032 #include "TDirectory.h"
00033 
00034 using namespace std;
00035 using namespace edm;
00036 
00038 MuonTrackResidualAnalyzer::MuonTrackResidualAnalyzer(const edm::ParameterSet& pset){
00039   
00040     // service parameters
00041   ParameterSet serviceParameters = pset.getParameter<ParameterSet>("ServiceParameters");
00042   // the services
00043   theService = new MuonServiceProxy(serviceParameters);
00044   
00045   theMuonTrackLabel = pset.getParameter<InputTag>("MuonTrack");
00046   theSeedCollectionLabel = pset.getParameter<InputTag>("MuonSeed");
00047 
00048   cscSimHitLabel = pset.getParameter<InputTag>("CSCSimHit");
00049   dtSimHitLabel = pset.getParameter<InputTag>("DTSimHit");
00050   rpcSimHitLabel = pset.getParameter<InputTag>("RPCSimHit");
00051 
00052   dbe_ = edm::Service<DQMStore>().operator->();
00053   out = pset.getUntrackedParameter<string>("rootFileName");
00054   dirName_ = pset.getUntrackedParameter<std::string>("dirName");
00055   
00056   // Sim or Real
00057   theDataType = pset.getParameter<InputTag>("DataType"); 
00058   if(theDataType.label() != "RealData" && theDataType.label() != "SimData")
00059     LogDebug("MuonTrackResidualAnalyzer")<<"Error in Data Type!!";
00060 
00061   theEtaRange = (EtaRange) pset.getParameter<int>("EtaRange");
00062 
00063   theUpdator = new KFUpdator();
00064   theEstimator = new Chi2MeasurementEstimator(100000.);
00065 
00066   theMuonSimHitNumberPerEvent = 0;
00067 }
00068 
00070 MuonTrackResidualAnalyzer::~MuonTrackResidualAnalyzer(){
00071   delete theUpdator;
00072   delete theEstimator;
00073   delete theService;
00074 }
00075 
00076 // Operations
00077 void MuonTrackResidualAnalyzer::beginJob(){
00078   LogDebug("MuonTrackResidualAnalyzer")<<"Begin Job";
00079   
00080   dbe_->showDirStructure();
00081   
00082   dbe_->cd();
00083   InputTag algo = theMuonTrackLabel;
00084   string dirName=dirName_;
00085   if (algo.process()!="")
00086     dirName+=algo.process()+"_";
00087   if(algo.label()!="")
00088     dirName+=algo.label()+"_";
00089   if(algo.instance()!="")
00090     dirName+=algo.instance()+"";
00091   if (dirName.find("Tracks")<dirName.length()){
00092     dirName.replace(dirName.find("Tracks"),6,"");
00093   }
00094   std::replace(dirName.begin(), dirName.end(), ':', '_');
00095   dbe_->setCurrentFolder(dirName.c_str());
00096   
00097   
00098   hDPtRef = dbe_->book1D("DeltaPtRef","P^{in}_{t}-P^{in ref}",10000,-20,20);
00099   
00100   // Resolution wrt the 1D Rec Hits
00101   //  h1DRecHitRes = new HResolution1DRecHit("TotalRec");
00102   
00103   // Resolution wrt the 1d Sim Hits
00104   //  h1DSimHitRes = new HResolution1DRecHit("TotalSim");
00105   
00106   hSimHitsPerTrack  = dbe_->book1D("SimHitsPerTrack","Number of sim hits per track",55,0,55);
00107   hSimHitsPerTrackVsEta  = dbe_->book2D("SimHitsPerTrackVsEta","Number of sim hits per track VS #eta",120,-3.,3.,55,0,55);
00108   hDeltaPtVsEtaSim = dbe_->book2D("DeltaPtVsEtaSim","#Delta P_{t} vs #eta gen, sim quantity",120,-3.,3.,500,-250.,250.);
00109   hDeltaPtVsEtaSim2 = dbe_->book2D("DeltaPtVsEtaSim2","#Delta P_{t} vs #eta gen, sim quantity",120,-3.,3.,500,-250.,250.);
00110 }
00111 
00112 void MuonTrackResidualAnalyzer::endJob(){
00113   if ( out.size() != 0 && dbe_ ) dbe_->save(out);
00114 }
00115  
00116 
00117 void MuonTrackResidualAnalyzer::analyze(const edm::Event & event, const edm::EventSetup& eventSetup){
00118   LogDebug("MuonTrackResidualAnalyzer")<<"Analyze";
00119 
00120   // Update the services
00121   theService->update(eventSetup);
00122   MuonPatternRecoDumper debug;
00123   theMuonSimHitNumberPerEvent = 0;
00124 
00125   // Get the SimHit collection from the event
00126   Handle<PSimHitContainer> dtSimHits;
00127   event.getByLabel(dtSimHitLabel.instance(),dtSimHitLabel.label(), dtSimHits);
00128 
00129   Handle<PSimHitContainer> cscSimHits;
00130   event.getByLabel(cscSimHitLabel.instance(),cscSimHitLabel.label(), cscSimHits);
00131 
00132   Handle<PSimHitContainer> rpcSimHits;
00133   event.getByLabel(rpcSimHitLabel.instance(),rpcSimHitLabel.label(), rpcSimHits);
00134 
00135   Handle<SimTrackContainer> simTracks;
00136 
00137   // FIXME Add the tracker one??
00138 
00139   // Map simhits per DetId
00140   map<DetId, const PSimHit* > muonSimHitsPerId =
00141     mapMuSimHitsPerId(dtSimHits,cscSimHits,rpcSimHits);
00142   
00143   hSimHitsPerTrack->Fill(theMuonSimHitNumberPerEvent);
00144   
00145   double etaSim=0;
00146 
00147   if(theDataType.label() == "SimData"){
00148     
00149     // Get the SimTrack collection from the event
00150     event.getByLabel(theDataType.instance(),simTracks);
00151     
00152     // Loop over the Sim tracks
00153     SimTrackContainer::const_iterator simTrack;
00154     
00155     for (simTrack = simTracks->begin(); simTrack != simTracks->end(); ++simTrack)
00156       if (abs((*simTrack).type()) == 13){
00157         hSimHitsPerTrackVsEta->Fill((*simTrack).momentum().eta(),theMuonSimHitNumberPerEvent);
00158         etaSim = (*simTrack).momentum().eta();
00159         theSimTkId = (*simTrack).trackId();
00160 
00161       }
00162   }
00163 
00164   
00165   // Get the RecTrack collection from the event
00166   Handle<reco::TrackCollection> muonTracks;
00167   event.getByLabel(theMuonTrackLabel, muonTracks);
00168 
00169   reco::TrackCollection::const_iterator muonTrack;
00170   
00171   // Loop over the Rec tracks
00172   for (muonTrack = muonTracks->begin(); muonTrack != muonTracks->end(); ++muonTrack) {
00173     
00174     reco::TransientTrack track(*muonTrack,&*theService->magneticField(),theService->trackingGeometry());   
00175 
00176     TrajectoryStateOnSurface outerTSOS = track.outermostMeasurementState();
00177     TrajectoryStateOnSurface innerTSOS = track.innermostMeasurementState();
00178 
00179     TransientTrackingRecHit::ConstRecHitContainer result;
00180     
00181     // SimHit Energy loss analysis  
00182     double momAtEntry = -150., momAtExit = -150.;
00183 
00184     if(theSimHitContainer.size()>1){
00185 
00186       const GeomDet *geomDetA = theService->trackingGeometry()->idToDet(DetId(theSimHitContainer.front()->detUnitId()));
00187       double distA = geomDetA->toGlobal(theSimHitContainer.front()->localPosition()).mag();
00188 
00189       const GeomDet *geomDetB = theService->trackingGeometry()->idToDet(DetId(theSimHitContainer.back()->detUnitId()));
00190       double distB = geomDetB->toGlobal(theSimHitContainer.back()->localPosition()).mag();
00191 
00192       LogTrace("MuonTrackResidualAnalyzer")<<"Inner SimHit: "<<theSimHitContainer.front()->particleType()
00193                                            <<" Pt: "<<theSimHitContainer.front()->momentumAtEntry().perp()
00194                                            <<" E: "<<theSimHitContainer.front()->momentumAtEntry().perp()
00195                                            <<" R: "<<distA<<endl;
00196       LogTrace("MuonTrackResidualAnalyzer")<<"Outer SimHit: "<<theSimHitContainer.back()->particleType()
00197                                            <<" Pt: "<<theSimHitContainer.back()->momentumAtEntry().perp()
00198                                            <<" E: "<<theSimHitContainer.front()->momentumAtEntry().perp()
00199                                            <<" R: "<<distB<<endl;
00200       
00201       momAtEntry = theSimHitContainer.front()->momentumAtEntry().perp();
00202       momAtExit =  theSimHitContainer.back()->momentumAtEntry().perp();
00203     }
00204     
00205     trackingRecHit_iterator rhFirst = track.recHitsBegin();
00206     trackingRecHit_iterator rhLast = track.recHitsEnd()-1;
00207     map<DetId,const PSimHit*>::const_iterator itFirst = muonSimHitsPerId.find((*rhFirst)->geographicalId());
00208     map<DetId,const PSimHit*>::const_iterator itLast = muonSimHitsPerId.find((*rhLast)->geographicalId());
00209     
00210     double momAtEntry2 = -150, momAtExit2 = -150.;
00211     if (itFirst != muonSimHitsPerId.end() )
00212       momAtEntry2 = itFirst->second->momentumAtEntry().perp();
00213     else {
00214       LogDebug("MuonTrackResidualAnalyzer")<<"No first sim hit found";
00215       ++rhFirst;
00216       itFirst = muonSimHitsPerId.find((*rhFirst)->geographicalId());
00217       if (itFirst != muonSimHitsPerId.end() )
00218         momAtEntry2 = itFirst->second->momentumAtEntry().perp();
00219       else{
00220         LogDebug("MuonTrackResidualAnalyzer")<<"No second sim hit found";
00221         // continue;
00222       }
00223     }
00224     
00225     if (itLast != muonSimHitsPerId.end() )
00226       momAtExit2 = itLast->second->momentumAtEntry().perp();
00227     else {
00228       LogDebug("MuonTrackResidualAnalyzer")<<"No last sim hit found";
00229       --rhLast;
00230       itLast = muonSimHitsPerId.find((*rhLast)->geographicalId());
00231       if (itLast != muonSimHitsPerId.end() )
00232         momAtExit2 = itLast->second->momentumAtEntry().perp();
00233       else{
00234         LogDebug("MuonTrackResidualAnalyzer")<<"No last but one sim hit found";
00235         // continue;
00236       }
00237     }
00238     
00239     if(etaSim){
00240       if(momAtEntry >=0 && momAtExit >= 0)
00241         hDeltaPtVsEtaSim->Fill(etaSim,momAtEntry-momAtExit);
00242       if(momAtEntry2 >=0 && momAtExit2 >= 0)
00243         hDeltaPtVsEtaSim2->Fill(etaSim,momAtEntry2-momAtExit2);
00244     }
00245     else
00246       LogDebug("MuonTrackResidualAnalyzer")<<"NO SimTrack'eta";
00247     //
00248 
00249     // computeResolution(trajectoryBW,muonSimHitsPerId,h1DSimHitRes);
00250     // computeResolution(smoothed,muonSimHitsPerId,h1DSimHitRes);
00251     
00252   }
00253 }
00254 
00255 bool MuonTrackResidualAnalyzer::isInTheAcceptance(double eta){
00256   switch(theEtaRange){
00257   case all:
00258     return ( abs(eta) <= 2.4 ) ? true : false;
00259   case barrel:
00260     return ( abs(eta) < 1.1 ) ? true : false;
00261   case endcap:
00262     return ( abs(eta) >= 1.1 && abs(eta) <= 2.4 ) ? true : false;  
00263   default:
00264     {LogDebug("MuonTrackResidualAnalyzer")<<"No correct Eta range selected!! "; return false;}
00265   }
00266 }
00267 
00268 // map the muon simhits by id
00269 map<DetId,const PSimHit*>
00270 MuonTrackResidualAnalyzer::mapMuSimHitsPerId(Handle<PSimHitContainer> dtSimhits,
00271                                              Handle<PSimHitContainer> cscSimhits,
00272                                              Handle<PSimHitContainer> rpcSimhits) {
00273   
00274   MuonPatternRecoDumper debug;
00275   
00276   map<DetId,const PSimHit*> hitIdMap;
00277   theSimHitContainer.clear();
00278 
00279   mapMuSimHitsPerId(dtSimhits,hitIdMap);
00280   mapMuSimHitsPerId(cscSimhits,hitIdMap);
00281   mapMuSimHitsPerId(rpcSimhits,hitIdMap);
00282 
00283   if(theSimHitContainer.size() >1)
00284     stable_sort(theSimHitContainer.begin(),theSimHitContainer.end(),RadiusComparatorInOut(theService->trackingGeometry()));
00285 
00286   LogDebug("MuonTrackResidualAnalyzer")<<"Sim Hit list";
00287   int count=1;
00288   for(vector<const PSimHit*>::const_iterator it = theSimHitContainer.begin(); 
00289       it != theSimHitContainer.end(); ++it){
00290     LogTrace("MuonTrackResidualAnalyzer")<<count 
00291         << " " 
00292         << " Process Type: " << (*it)->processType()
00293         << " " 
00294         << debug.dumpMuonId(DetId( (*it)->detUnitId() ))<<endl;
00295   }  
00296 
00297   return hitIdMap;
00298 }
00299 
00300 
00301 void MuonTrackResidualAnalyzer::mapMuSimHitsPerId(Handle<PSimHitContainer> simhits, 
00302                                                   map<DetId,const PSimHit*> &hitIdMap){
00303   
00304   for(PSimHitContainer::const_iterator simhit = simhits->begin();
00305       simhit != simhits->end(); ++simhit) {
00306     
00307     if ( abs(simhit->particleType()) != 13 && theSimTkId != simhit->trackId()) continue; 
00308     
00309     theSimHitContainer.push_back(&*simhit);
00310     DetId id = DetId(simhit->detUnitId());
00311     
00312     if(id.subdetId() == MuonSubdetId::DT){
00313       DTLayerId lId(id.rawId());
00314       id = DetId(lId.rawId());
00315     }
00316 
00317     map<DetId,const PSimHit*>::const_iterator it = hitIdMap.find(id);
00318     
00319     if (it == hitIdMap.end() )
00320       hitIdMap[id] = &*simhit;
00321     else
00322       LogDebug("MuonTrackResidualAnalyzer")<<"TWO muons in the same sensible volume!!";
00323     
00324     ++theMuonSimHitNumberPerEvent;
00325   }
00326 }
00327 
00328 
00329 void MuonTrackResidualAnalyzer::computeResolution(Trajectory &trajectory, 
00330                                                   map<DetId,const PSimHit*> &hitIdMap,
00331                                                   HResolution1DRecHit *histos){
00332   
00333   Trajectory::DataContainer data = trajectory.measurements();
00334 
00335   for(Trajectory::DataContainer::const_iterator datum = data.begin();
00336       datum != data.end(); ++datum){
00337     
00338     GlobalPoint fitPoint = datum->updatedState().globalPosition();
00339 
00340     // FIXME!
00341     //     double errX = datum->updatedState().cartesianError().matrix()[0][0];
00342     //     double errY = datum->updatedState().cartesianError().matrix()[1][1];
00343     //     double errZ = datum->updatedState().cartesianError().matrix()[2][2];
00344     //
00345     double errX = datum->updatedState().localError().matrix()(3,3);
00346     double errY = datum->updatedState().localError().matrix()(4,4);
00347     double errZ = 1.;
00348 
00349     map<DetId,const PSimHit*>::const_iterator it = hitIdMap.find(datum->recHit()->geographicalId());
00350  
00351     
00352     if (it == hitIdMap.end() ) continue; // FIXME! Put a counter
00353     
00354     const PSimHit* simhit = it->second;
00355     
00356     LocalPoint simHitPoint = simhit->localPosition();
00357 
00358     const GeomDet* geomDet = theService->trackingGeometry()->idToDet(DetId(simhit->detUnitId()));
00359 
00360     LocalPoint fitLocalPoint = geomDet->toLocal(fitPoint);
00361     
00362     LocalVector diff = fitLocalPoint-simHitPoint;
00363 
00364     
00365     cout << "SimHit position "<< simHitPoint << endl;
00366     cout << "Fit position "<<  fitLocalPoint << endl;
00367     cout << "Fit position2 "<< datum->updatedState().localPosition() << endl;
00368     cout << "Errors on the fit position: (" << errX << "," << errY << "," << errZ << ")"<<endl;
00369     cout << "Resolution on x: " << diff.x()/abs(simHitPoint.x()) << endl;
00370     cout << "Resolution on y: " << diff.y()/abs(simHitPoint.y()) << endl;
00371     cout << "Resolution on z: " << diff.z()/abs(simHitPoint.z()) << endl;
00372 
00373     cout << "Eta direction: "<< simhit->momentumAtEntry().eta() <<" eta position: " << simHitPoint.eta() << endl;
00374     cout << "Phi direction: "<< simhit->momentumAtEntry().phi() <<" phi position: " << simHitPoint.phi() << endl;
00375 
00376     
00377     histos->Fill( simHitPoint.x(), simHitPoint.y(), simHitPoint.z(), 
00378                   diff.x(), diff.y(), diff.z(),
00379                   errX,  errY, errZ,
00380                   simhit->momentumAtEntry().eta(), simhit->momentumAtEntry().phi());
00381                   // simHitPoint.eta(), simHitPoint.phi() ); // FIXME!
00382   }
00383 
00384 
00385 }