00001 #include "Validation/RecoMuon/src/MuonTrackResidualAnalyzer.h"
00002
00003
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
00041 ParameterSet serviceParameters = pset.getParameter<ParameterSet>("ServiceParameters");
00042
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
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
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
00101
00102
00103
00104
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
00121 theService->update(eventSetup);
00122 MuonPatternRecoDumper debug;
00123 theMuonSimHitNumberPerEvent = 0;
00124
00125
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
00138
00139
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
00150 event.getByLabel(theDataType.instance(),simTracks);
00151
00152
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
00166 Handle<reco::TrackCollection> muonTracks;
00167 event.getByLabel(theMuonTrackLabel, muonTracks);
00168
00169 reco::TrackCollection::const_iterator muonTrack;
00170
00171
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
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
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
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
00250
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
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
00341
00342
00343
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;
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
00382 }
00383
00384
00385 }