File indexing completed on 2024-04-06 12:33:10
0001 #include "Validation/RecoMuon/src/MuonTrackResidualAnalyzer.h"
0002
0003
0004 #include "FWCore/Framework/interface/ConsumesCollector.h"
0005 #include "FWCore/Framework/interface/Frameworkfwd.h"
0006 #include "FWCore/Framework/interface/Event.h"
0007 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0009
0010 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
0011
0012 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
0013 #include "TrackingTools/KalmanUpdators/interface/KFUpdator.h"
0014 #include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimator.h"
0015 #include "TrackingTools/TrackFitters/interface/KFTrajectoryFitter.h"
0016 #include "TrackingTools/TrackFitters/interface/KFTrajectorySmoother.h"
0017
0018 #include "DataFormats/TrajectorySeed/interface/TrajectorySeedCollection.h"
0019 #include "DataFormats/MuonDetId/interface/DTLayerId.h"
0020 #include "DataFormats/MuonDetId/interface/MuonSubdetId.h"
0021
0022 #include "RecoMuon/TrackingTools/interface/MuonPatternRecoDumper.h"
0023 #include "RecoMuon/TrackingTools/interface/MuonServiceProxy.h"
0024 #include "Validation/RecoMuon/src/Histograms.h"
0025 #include "RecoMuon/TransientTrackingRecHit/interface/MuonTransientTrackingRecHitBuilder.h"
0026 #include "RecoMuon/TransientTrackingRecHit/interface/MuonTransientTrackingRecHit.h"
0027
0028 #include "TFile.h"
0029 #include "TH1F.h"
0030 #include "TH2F.h"
0031 #include "TDirectory.h"
0032
0033 using namespace std;
0034 using namespace edm;
0035
0036
0037
0038 MuonTrackResidualAnalyzer::MuonTrackResidualAnalyzer(const edm::ParameterSet &ps) {
0039 pset = ps;
0040
0041 ParameterSet serviceParameters = pset.getParameter<ParameterSet>("ServiceParameters");
0042
0043 theService = new MuonServiceProxy(serviceParameters, consumesCollector());
0044
0045 theMuonTrackLabel = pset.getParameter<InputTag>("MuonTrack");
0046 theMuonTrackToken = consumes<reco::TrackCollection>(theMuonTrackLabel);
0047
0048 cscSimHitLabel = pset.getParameter<InputTag>("CSCSimHit");
0049 dtSimHitLabel = pset.getParameter<InputTag>("DTSimHit");
0050 rpcSimHitLabel = pset.getParameter<InputTag>("RPCSimHit");
0051 theCSCSimHitToken = consumes<std::vector<PSimHit> >(cscSimHitLabel);
0052 theDTSimHitToken = consumes<std::vector<PSimHit> >(dtSimHitLabel);
0053 theRPCSimHitToken = consumes<std::vector<PSimHit> >(rpcSimHitLabel);
0054
0055 dbe_ = edm::Service<DQMStore>().operator->();
0056 out = pset.getUntrackedParameter<string>("rootFileName");
0057 dirName_ = pset.getUntrackedParameter<std::string>("dirName");
0058 subsystemname_ = pset.getUntrackedParameter<std::string>("subSystemFolder", "YourSubsystem");
0059
0060
0061 theDataType = pset.getParameter<InputTag>("DataType");
0062 if (theDataType.label() != "RealData" && theDataType.label() != "SimData")
0063 LogDebug("MuonTrackResidualAnalyzer") << "Error in Data Type!!";
0064 theDataTypeToken = consumes<edm::SimTrackContainer>(theDataType);
0065
0066 theEtaRange = (EtaRange)pset.getParameter<int>("EtaRange");
0067
0068 theUpdator = new KFUpdator();
0069 theEstimator = new Chi2MeasurementEstimator(100000.);
0070
0071 theMuonSimHitNumberPerEvent = 0;
0072 }
0073
0074
0075 MuonTrackResidualAnalyzer::~MuonTrackResidualAnalyzer() {
0076 delete theUpdator;
0077 delete theEstimator;
0078 delete theService;
0079 }
0080
0081 void MuonTrackResidualAnalyzer::bookHistograms(DQMStore::IBooker &ibooker,
0082 edm::Run const &iRun,
0083 edm::EventSetup const & ) {
0084 LogDebug("MuonTrackResidualAnalyzer") << "Begin Run";
0085
0086 ibooker.cd();
0087 InputTag algo = theMuonTrackLabel;
0088 string dirName = dirName_;
0089 if (!algo.process().empty())
0090 dirName += algo.process() + "_";
0091 if (!algo.label().empty())
0092 dirName += algo.label() + "_";
0093 if (!algo.instance().empty())
0094 dirName += algo.instance() + "";
0095 if (dirName.find("Tracks") < dirName.length()) {
0096 dirName.replace(dirName.find("Tracks"), 6, "");
0097 }
0098 std::replace(dirName.begin(), dirName.end(), ':', '_');
0099 ibooker.setCurrentFolder(dirName);
0100
0101 hDPtRef = ibooker.book1D("DeltaPtRef", "P^{in}_{t}-P^{in ref}", 10000, -20, 20);
0102
0103
0104
0105
0106
0107
0108
0109 hSimHitsPerTrack = ibooker.book1D("SimHitsPerTrack", "Number of sim hits per track", 55, 0, 55);
0110 hSimHitsPerTrackVsEta =
0111 ibooker.book2D("SimHitsPerTrackVsEta", "Number of sim hits per track VS #eta", 120, -3., 3., 55, 0, 55);
0112 hDeltaPtVsEtaSim =
0113 ibooker.book2D("DeltaPtVsEtaSim", "#Delta P_{t} vs #eta gen, sim quantity", 120, -3., 3., 500, -250., 250.);
0114 hDeltaPtVsEtaSim2 =
0115 ibooker.book2D("DeltaPtVsEtaSim2", "#Delta P_{t} vs #eta gen, sim quantity", 120, -3., 3., 500, -250., 250.);
0116 }
0117
0118 void MuonTrackResidualAnalyzer::dqmEndRun(edm::Run const &, edm::EventSetup const &) {
0119 if (!out.empty() && dbe_)
0120 dbe_->save(out);
0121 }
0122 void MuonTrackResidualAnalyzer::analyze(const edm::Event &event, const edm::EventSetup &eventSetup) {
0123 LogDebug("MuonTrackResidualAnalyzer") << "Analyze";
0124
0125
0126 theService->update(eventSetup);
0127 MuonPatternRecoDumper debug;
0128 theMuonSimHitNumberPerEvent = 0;
0129
0130
0131 Handle<PSimHitContainer> dtSimHits;
0132 event.getByToken(theDTSimHitToken, dtSimHits);
0133
0134 Handle<PSimHitContainer> cscSimHits;
0135 event.getByToken(theCSCSimHitToken, cscSimHits);
0136
0137 Handle<PSimHitContainer> rpcSimHits;
0138 event.getByToken(theRPCSimHitToken, rpcSimHits);
0139
0140 Handle<SimTrackContainer> simTracks;
0141
0142
0143
0144
0145 map<DetId, const PSimHit *> muonSimHitsPerId = mapMuSimHitsPerId(dtSimHits, cscSimHits, rpcSimHits);
0146
0147 hSimHitsPerTrack->Fill(theMuonSimHitNumberPerEvent);
0148
0149 double etaSim = 0;
0150
0151 if (theDataType.label() == "SimData") {
0152
0153 event.getByToken(theDataTypeToken, simTracks);
0154
0155
0156 SimTrackContainer::const_iterator simTrack;
0157
0158 for (simTrack = simTracks->begin(); simTrack != simTracks->end(); ++simTrack)
0159 if (abs((*simTrack).type()) == 13) {
0160 hSimHitsPerTrackVsEta->Fill((*simTrack).momentum().eta(), theMuonSimHitNumberPerEvent);
0161 etaSim = (*simTrack).momentum().eta();
0162 theSimTkId = (*simTrack).trackId();
0163 }
0164 }
0165
0166
0167 Handle<reco::TrackCollection> muonTracks;
0168 event.getByToken(theMuonTrackToken, muonTracks);
0169
0170 reco::TrackCollection::const_iterator muonTrack;
0171
0172
0173 for (muonTrack = muonTracks->begin(); muonTrack != muonTracks->end(); ++muonTrack) {
0174 reco::TransientTrack track(*muonTrack, &*theService->magneticField(), theService->trackingGeometry());
0175
0176 TrajectoryStateOnSurface outerTSOS = track.outermostMeasurementState();
0177 TrajectoryStateOnSurface innerTSOS = track.innermostMeasurementState();
0178
0179 TransientTrackingRecHit::ConstRecHitContainer result;
0180
0181
0182 double momAtEntry = -150., momAtExit = -150.;
0183
0184 if (theSimHitContainer.size() > 1) {
0185 const GeomDet *geomDetA = theService->trackingGeometry()->idToDet(DetId(theSimHitContainer.front()->detUnitId()));
0186 double distA = geomDetA->toGlobal(theSimHitContainer.front()->localPosition()).mag();
0187
0188 const GeomDet *geomDetB = theService->trackingGeometry()->idToDet(DetId(theSimHitContainer.back()->detUnitId()));
0189 double distB = geomDetB->toGlobal(theSimHitContainer.back()->localPosition()).mag();
0190
0191 LogTrace("MuonTrackResidualAnalyzer")
0192 << "Inner SimHit: " << theSimHitContainer.front()->particleType()
0193 << " Pt: " << theSimHitContainer.front()->momentumAtEntry().perp()
0194 << " E: " << theSimHitContainer.front()->momentumAtEntry().perp() << " R: " << distA << endl;
0195 LogTrace("MuonTrackResidualAnalyzer")
0196 << "Outer SimHit: " << theSimHitContainer.back()->particleType()
0197 << " Pt: " << theSimHitContainer.back()->momentumAtEntry().perp()
0198 << " E: " << theSimHitContainer.front()->momentumAtEntry().perp() << " R: " << distB << endl;
0199
0200 momAtEntry = theSimHitContainer.front()->momentumAtEntry().perp();
0201 momAtExit = theSimHitContainer.back()->momentumAtEntry().perp();
0202 }
0203
0204 trackingRecHit_iterator rhFirst = track.recHitsBegin();
0205 trackingRecHit_iterator rhLast = track.recHitsEnd() - 1;
0206 map<DetId, const PSimHit *>::const_iterator itFirst = muonSimHitsPerId.find((*rhFirst)->geographicalId());
0207 map<DetId, const PSimHit *>::const_iterator itLast = muonSimHitsPerId.find((*rhLast)->geographicalId());
0208
0209 double momAtEntry2 = -150, momAtExit2 = -150.;
0210 if (itFirst != muonSimHitsPerId.end())
0211 momAtEntry2 = itFirst->second->momentumAtEntry().perp();
0212 else {
0213 LogDebug("MuonTrackResidualAnalyzer") << "No first sim hit found";
0214 ++rhFirst;
0215 itFirst = muonSimHitsPerId.find((*rhFirst)->geographicalId());
0216 if (itFirst != muonSimHitsPerId.end())
0217 momAtEntry2 = itFirst->second->momentumAtEntry().perp();
0218 else {
0219 LogDebug("MuonTrackResidualAnalyzer") << "No second sim hit found";
0220
0221 }
0222 }
0223
0224 if (itLast != muonSimHitsPerId.end())
0225 momAtExit2 = itLast->second->momentumAtEntry().perp();
0226 else {
0227 LogDebug("MuonTrackResidualAnalyzer") << "No last sim hit found";
0228 --rhLast;
0229 itLast = muonSimHitsPerId.find((*rhLast)->geographicalId());
0230 if (itLast != muonSimHitsPerId.end())
0231 momAtExit2 = itLast->second->momentumAtEntry().perp();
0232 else {
0233 LogDebug("MuonTrackResidualAnalyzer") << "No last but one sim hit found";
0234
0235 }
0236 }
0237
0238 if (etaSim) {
0239 if (momAtEntry >= 0 && momAtExit >= 0)
0240 hDeltaPtVsEtaSim->Fill(etaSim, momAtEntry - momAtExit);
0241 if (momAtEntry2 >= 0 && momAtExit2 >= 0)
0242 hDeltaPtVsEtaSim2->Fill(etaSim, momAtEntry2 - momAtExit2);
0243 } else
0244 LogDebug("MuonTrackResidualAnalyzer") << "NO SimTrack'eta";
0245
0246
0247
0248
0249 }
0250 }
0251
0252 bool MuonTrackResidualAnalyzer::isInTheAcceptance(double eta) {
0253 switch (theEtaRange) {
0254 case all:
0255 return (abs(eta) <= 2.4) ? true : false;
0256 case barrel:
0257 return (abs(eta) < 1.1) ? true : false;
0258 case endcap:
0259 return (abs(eta) >= 1.1 && abs(eta) <= 2.4) ? true : false;
0260 default: {
0261 LogDebug("MuonTrackResidualAnalyzer") << "No correct Eta range selected!! ";
0262 return false;
0263 }
0264 }
0265 }
0266
0267
0268 map<DetId, const PSimHit *> MuonTrackResidualAnalyzer::mapMuSimHitsPerId(Handle<PSimHitContainer> dtSimhits,
0269 Handle<PSimHitContainer> cscSimhits,
0270 Handle<PSimHitContainer> rpcSimhits) {
0271 MuonPatternRecoDumper debug;
0272
0273 map<DetId, const PSimHit *> hitIdMap;
0274 theSimHitContainer.clear();
0275
0276 mapMuSimHitsPerId(dtSimhits, hitIdMap);
0277 mapMuSimHitsPerId(cscSimhits, hitIdMap);
0278 mapMuSimHitsPerId(rpcSimhits, hitIdMap);
0279
0280 if (theSimHitContainer.size() > 1)
0281 stable_sort(
0282 theSimHitContainer.begin(), theSimHitContainer.end(), RadiusComparatorInOut(theService->trackingGeometry()));
0283
0284 LogDebug("MuonTrackResidualAnalyzer") << "Sim Hit list";
0285 int count = 1;
0286 for (vector<const PSimHit *>::const_iterator it = theSimHitContainer.begin(); it != theSimHitContainer.end(); ++it) {
0287 LogTrace("MuonTrackResidualAnalyzer")
0288 << count << " "
0289 << " Process Type: " << (*it)->processType() << " " << debug.dumpMuonId(DetId((*it)->detUnitId())) << endl;
0290 }
0291
0292 return hitIdMap;
0293 }
0294
0295 void MuonTrackResidualAnalyzer::mapMuSimHitsPerId(Handle<PSimHitContainer> simhits,
0296 map<DetId, const PSimHit *> &hitIdMap) {
0297 for (PSimHitContainer::const_iterator simhit = simhits->begin(); simhit != simhits->end(); ++simhit) {
0298 if (abs(simhit->particleType()) != 13 && theSimTkId != simhit->trackId())
0299 continue;
0300
0301 theSimHitContainer.push_back(&*simhit);
0302 DetId id = DetId(simhit->detUnitId());
0303
0304 if (id.subdetId() == MuonSubdetId::DT) {
0305 DTLayerId lId(id.rawId());
0306 id = DetId(lId.rawId());
0307 }
0308
0309 map<DetId, const PSimHit *>::const_iterator it = hitIdMap.find(id);
0310
0311 if (it == hitIdMap.end())
0312 hitIdMap[id] = &*simhit;
0313 else
0314 LogDebug("MuonTrackResidualAnalyzer") << "TWO muons in the same sensible volume!!";
0315
0316 ++theMuonSimHitNumberPerEvent;
0317 }
0318 }
0319
0320 void MuonTrackResidualAnalyzer::computeResolution(Trajectory &trajectory,
0321 map<DetId, const PSimHit *> &hitIdMap,
0322 HResolution1DRecHit *histos) {
0323 Trajectory::DataContainer data = trajectory.measurements();
0324
0325 for (Trajectory::DataContainer::const_iterator datum = data.begin(); datum != data.end(); ++datum) {
0326 GlobalPoint fitPoint = datum->updatedState().globalPosition();
0327
0328
0329
0330
0331
0332
0333 double errX = datum->updatedState().localError().matrix()(3, 3);
0334 double errY = datum->updatedState().localError().matrix()(4, 4);
0335 double errZ = 1.;
0336
0337 map<DetId, const PSimHit *>::const_iterator it = hitIdMap.find(datum->recHit()->geographicalId());
0338
0339 if (it == hitIdMap.end())
0340 continue;
0341
0342 const PSimHit *simhit = it->second;
0343
0344 LocalPoint simHitPoint = simhit->localPosition();
0345
0346 const GeomDet *geomDet = theService->trackingGeometry()->idToDet(DetId(simhit->detUnitId()));
0347
0348 LocalPoint fitLocalPoint = geomDet->toLocal(fitPoint);
0349
0350 LocalVector diff = fitLocalPoint - simHitPoint;
0351
0352 cout << "SimHit position " << simHitPoint << endl;
0353 cout << "Fit position " << fitLocalPoint << endl;
0354 cout << "Fit position2 " << datum->updatedState().localPosition() << endl;
0355 cout << "Errors on the fit position: (" << errX << "," << errY << "," << errZ << ")" << endl;
0356 cout << "Resolution on x: " << diff.x() / abs(simHitPoint.x()) << endl;
0357 cout << "Resolution on y: " << diff.y() / abs(simHitPoint.y()) << endl;
0358 cout << "Resolution on z: " << diff.z() / abs(simHitPoint.z()) << endl;
0359
0360 cout << "Eta direction: " << simhit->momentumAtEntry().eta() << " eta position: " << simHitPoint.eta() << endl;
0361 cout << "Phi direction: " << simhit->momentumAtEntry().phi() << " phi position: " << simHitPoint.phi() << endl;
0362
0363 histos->Fill(simHitPoint.x(),
0364 simHitPoint.y(),
0365 simHitPoint.z(),
0366 diff.x(),
0367 diff.y(),
0368 diff.z(),
0369 errX,
0370 errY,
0371 errZ,
0372 simhit->momentumAtEntry().eta(),
0373 simhit->momentumAtEntry().phi());
0374
0375 }
0376 }