File indexing completed on 2024-04-06 12:09:41
0001
0002
0003
0004
0005
0006
0007
0008 #include "DQMOffline/Muon/interface/MuonPFAnalyzer.h"
0009
0010 #include "DataFormats/MuonReco/interface/MuonSelectors.h"
0011
0012 #include "DataFormats/GeometryVector/interface/Pi.h"
0013 #include "DataFormats/Math/interface/deltaR.h"
0014
0015
0016 #include <memory>
0017 #include <string>
0018 #include <typeinfo>
0019 #include <utility>
0020
0021
0022 #include "TH1.h"
0023 #include "TH2.h"
0024 #include "TProfile.h"
0025
0026
0027 #include "FWCore/Framework/interface/MakerMacros.h"
0028 #include "FWCore/Framework/interface/Event.h"
0029 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0030
0031 #include "FWCore/Utilities/interface/InputTag.h"
0032 #include "DQMServices/Core/interface/DQMStore.h"
0033 #include "FWCore/ServiceRegistry/interface/Service.h"
0034
0035 using namespace edm;
0036 using namespace std;
0037 using namespace reco;
0038
0039 MuonPFAnalyzer::MuonPFAnalyzer(const ParameterSet &pSet) {
0040 LogTrace("MuonPFAnalyzer") << "[MuonPFAnalyzer] Initializing configuration from parameterset.\n";
0041
0042 theGenLabel_ = consumes<GenParticleCollection>(pSet.getParameter<InputTag>("inputTagGenParticles"));
0043 theRecoLabel_ = consumes<MuonCollection>(pSet.getParameter<InputTag>("inputTagMuonReco"));
0044 theVertexLabel_ = consumes<VertexCollection>(pSet.getParameter<InputTag>("inputTagVertex"));
0045 theBeamSpotLabel_ = consumes<BeamSpot>(pSet.getParameter<InputTag>("inputTagBeamSpot"));
0046
0047 theHighPtTh = pSet.getParameter<double>("highPtThreshold");
0048 theRecoGenR = pSet.getParameter<double>("recoGenDeltaR");
0049 theIsoCut = pSet.getParameter<double>("relCombIsoCut");
0050 theRunOnMC = pSet.getParameter<bool>("runOnMC");
0051
0052 theFolder = pSet.getParameter<string>("folder");
0053
0054 theMuonKinds.push_back("");
0055 theMuonKinds.push_back("Tight");
0056 theMuonKinds.push_back("TightIso");
0057 }
0058
0059 MuonPFAnalyzer::~MuonPFAnalyzer() { LogTrace("MuonPFAnalyzer") << "[MuonPFAnalyzer] Destructor called.\n"; }
0060
0061
0062 void MuonPFAnalyzer::bookHistograms(DQMStore::IBooker &ibooker, edm::Run const &, edm::EventSetup const &) {
0063 if (theRunOnMC) {
0064 bookHistos(ibooker, "PF");
0065 bookHistos(ibooker, "PFTight");
0066 bookHistos(ibooker, "PFTightIso");
0067 bookHistos(ibooker, "TUNEP");
0068 bookHistos(ibooker, "TUNEPTight");
0069 bookHistos(ibooker, "TUNEPTightIso");
0070 }
0071
0072 bookHistos(ibooker, "PFvsTUNEP");
0073 bookHistos(ibooker, "PFvsTUNEPTight");
0074 bookHistos(ibooker, "PFvsTUNEPTightIso");
0075 }
0076
0077 void MuonPFAnalyzer::analyze(const Event &event, const EventSetup &context) {
0078 Handle<reco::MuonCollection> muons;
0079 event.getByToken(theRecoLabel_, muons);
0080
0081 Handle<GenParticleCollection> genMuons;
0082 event.getByToken(theGenLabel_, genMuons);
0083
0084 Handle<BeamSpot> beamSpot;
0085 event.getByToken(theBeamSpotLabel_, beamSpot);
0086
0087 Handle<VertexCollection> vertex;
0088 event.getByToken(theVertexLabel_, vertex);
0089
0090 const Vertex primaryVertex = getPrimaryVertex(vertex, beamSpot);
0091
0092 recoToGenMatch(muons, genMuons);
0093
0094 RecoGenCollection::const_iterator recoGenIt = theRecoGen.begin();
0095 RecoGenCollection::const_iterator recoGenEnd = theRecoGen.end();
0096
0097 for (; recoGenIt != recoGenEnd; ++recoGenIt) {
0098 const Muon *muon = recoGenIt->first;
0099 TrackRef tunePTrack = muon->tunePMuonBestTrack();
0100
0101 const GenParticle *genMuon = recoGenIt->second;
0102
0103 vector<string>::const_iterator kindIt = theMuonKinds.begin();
0104 vector<string>::const_iterator kindEnd = theMuonKinds.end();
0105
0106 for (; kindIt != kindEnd; ++kindIt) {
0107 const string &kind = (*kindIt);
0108
0109 if (kind.find("Tight") != string::npos && !muon::isTightMuon((*muon), primaryVertex))
0110 continue;
0111
0112 if (kind.find("Iso") != string::npos && combRelIso(muon) > theIsoCut)
0113 continue;
0114
0115 if (theRunOnMC && genMuon && !muon->innerTrack().isNull())
0116 {
0117 if (!tunePTrack.isNull()) {
0118 string group = "TUNEP" + kind;
0119
0120 float pt = tunePTrack->pt();
0121 float phi = tunePTrack->phi();
0122 float eta = tunePTrack->eta();
0123
0124 float genPt = genMuon->pt();
0125 float genPhi = genMuon->p4().phi();
0126 float genEta = genMuon->p4().eta();
0127
0128 float dPtOverPt = (pt / genPt) - 1;
0129
0130 if (pt < theHighPtTh) {
0131 fillInRange(getPlot(group, "code"), 1, muonTrackType(muon, false));
0132 fillInRange(getPlot(group, "deltaPtOverPt"), 1, dPtOverPt);
0133 } else {
0134 fillInRange(getPlot(group, "codeHighPt"), 1, muonTrackType(muon, false));
0135 fillInRange(getPlot(group, "deltaPtOverPtHighPt"), 1, dPtOverPt);
0136 }
0137
0138 fillInRange(getPlot(group, "deltaPt"), 1, (pt - genPt));
0139 fillInRange(getPlot(group, "deltaPhi"), 1, fDeltaPhi(genPhi, phi));
0140 fillInRange(getPlot(group, "deltaEta"), 1, genEta - eta);
0141 }
0142
0143 if (muon->isPFMuon()) {
0144 string group = "PF" + kind;
0145
0146
0147 float pt = muon->pt();
0148 float phi = muon->p4().phi();
0149 float eta = muon->p4().eta();
0150
0151 float genPt = genMuon->pt();
0152 float genPhi = genMuon->p4().phi();
0153 float genEta = genMuon->p4().eta();
0154
0155 float dPtOverPt = (pt / genPt) - 1;
0156
0157 if (pt < theHighPtTh) {
0158 fillInRange(getPlot(group, "code"), 1, muonTrackType(muon, true));
0159 fillInRange(getPlot(group, "deltaPtOverPt"), 1, dPtOverPt);
0160 } else {
0161 fillInRange(getPlot(group, "codeHighPt"), 1, muonTrackType(muon, true));
0162 fillInRange(getPlot(group, "deltaPtOverPtHighPt"), 1, dPtOverPt);
0163 }
0164
0165 fillInRange(getPlot(group, "deltaPt"), 1, pt - genPt);
0166 fillInRange(getPlot(group, "deltaPhi"), 1, fDeltaPhi(genPhi, phi));
0167 fillInRange(getPlot(group, "deltaEta"), 1, genEta - eta);
0168 }
0169 }
0170
0171 if (muon->isPFMuon() && !tunePTrack.isNull() && !muon->innerTrack().isNull())
0172 {
0173
0174 string group = "PFvsTUNEP" + kind;
0175
0176 float pt = tunePTrack->pt();
0177 float phi = tunePTrack->phi();
0178 float eta = tunePTrack->eta();
0179
0180
0181 float pfPt = muon->pt();
0182 float pfPhi = muon->p4().phi();
0183 float pfEta = muon->p4().eta();
0184 float dPtOverPt = (pfPt / pt) - 1;
0185
0186 if (pt < theHighPtTh) {
0187 fillInRange(getPlot(group, "code"), 2, muonTrackType(muon, false), muonTrackType(muon, true));
0188 fillInRange(getPlot(group, "deltaPtOverPt"), 1, dPtOverPt);
0189 } else {
0190 fillInRange(getPlot(group, "codeHighPt"), 2, muonTrackType(muon, false), muonTrackType(muon, true));
0191 fillInRange(getPlot(group, "deltaPtOverPtHighPt"), 1, dPtOverPt);
0192 }
0193
0194 fillInRange(getPlot(group, "deltaPt"), 1, pfPt - pt);
0195 fillInRange(getPlot(group, "deltaPhi"), 1, fDeltaPhi(pfPhi, phi));
0196 fillInRange(getPlot(group, "deltaEta"), 1, pfEta - eta);
0197
0198 if (theRunOnMC && genMuon)
0199
0200 {
0201 float genPt = genMuon->pt();
0202 float dPtOverPtGen = (pt / genPt) - 1;
0203 float dPtOverPtGenPF = (pfPt / genPt) - 1;
0204
0205 if (pt < theHighPtTh) {
0206 fillInRange(getPlot(group, "deltaPtOverPtPFvsTUNEP"), 2, dPtOverPtGen, dPtOverPtGenPF);
0207 } else {
0208 fillInRange(getPlot(group, "deltaPtOverPtHighPtPFvsTUNEP"), 2, dPtOverPtGen, dPtOverPtGenPF);
0209 }
0210 }
0211 }
0212 }
0213 }
0214 }
0215
0216 void MuonPFAnalyzer::bookHistos(DQMStore::IBooker &ibooker, const string &group) {
0217 LogTrace("MuonPFAnalyzer") << "[MuonPFAnalyzer] Booking histos for group :" << group << "\n";
0218
0219 ibooker.setCurrentFolder(string(theFolder) + group);
0220
0221 bool isPFvsTUNEP = group.find("PFvsTUNEP") != string::npos;
0222
0223 string hName;
0224
0225 hName = "deltaPtOverPt" + group;
0226 thePlots[group]["deltaPtOverPt"] = ibooker.book1D(hName.c_str(), hName.c_str(), 101, -1.01, 1.01);
0227
0228 hName = "deltaPtOverPtHighPt" + group;
0229 thePlots[group]["deltaPtOverPtHighPt"] = ibooker.book1D(hName.c_str(), hName.c_str(), 101, -1.01, 1.01);
0230
0231 hName = "deltaPt" + group;
0232 thePlots[group]["deltaPt"] = ibooker.book1D(hName.c_str(), hName.c_str(), 201., -10.25, 10.25);
0233
0234 hName = "deltaPhi" + group;
0235 thePlots[group]["deltaPhi"] = ibooker.book1D(hName.c_str(), hName.c_str(), 51., 0, .0102);
0236
0237 hName = "deltaEta" + group;
0238 thePlots[group]["deltaEta"] = ibooker.book1D(hName.c_str(), hName.c_str(), 101., -.00505, .00505);
0239
0240 if (isPFvsTUNEP) {
0241 hName = "code" + group;
0242 MonitorElement *plot = ibooker.book2D(hName.c_str(), hName.c_str(), 7, -.5, 6.5, 7, -.5, 6.5);
0243 thePlots[group]["code"] = plot;
0244 setCodeLabels(plot, 1);
0245 setCodeLabels(plot, 2);
0246
0247 hName = "codeHighPt" + group;
0248 plot = ibooker.book2D(hName.c_str(), hName.c_str(), 7, -.5, 6.5, 7, -.5, 6.5);
0249 thePlots[group]["codeHighPt"] = plot;
0250 setCodeLabels(plot, 1);
0251 setCodeLabels(plot, 2);
0252
0253 if (theRunOnMC) {
0254 hName = "deltaPtOverPtPFvsTUNEP" + group;
0255 thePlots[group]["deltaPtOverPtPFvsTUNEP"] =
0256 ibooker.book2D(hName.c_str(), hName.c_str(), 101, -1.01, 1.01, 101, -1.01, 1.01);
0257
0258 hName = "deltaPtOverPtHighPtPFvsTUNEP" + group;
0259 thePlots[group]["deltaPtOverPtHighPtPFvsTUNEP"] =
0260 ibooker.book2D(hName.c_str(), hName.c_str(), 101, -1.01, 1.01, 101, -1.01, 1.01);
0261 }
0262 } else {
0263 hName = "code" + group;
0264 MonitorElement *plot = ibooker.book1D(hName.c_str(), hName.c_str(), 7, -.5, 6.5);
0265 thePlots[group]["code"] = plot;
0266 setCodeLabels(plot, 1);
0267
0268 hName = "codeHighPt" + group;
0269 plot = ibooker.book1D(hName.c_str(), hName.c_str(), 7, -.5, 6.5);
0270 thePlots[group]["codeHighPt"] = plot;
0271 setCodeLabels(plot, 1);
0272 }
0273 }
0274
0275 MuonPFAnalyzer::MonitorElement *MuonPFAnalyzer::getPlot(const string &group, const string &type) {
0276 map<string, map<string, MonitorElement *> >::iterator groupIt = thePlots.find(group);
0277 if (groupIt == thePlots.end()) {
0278 LogTrace("MuonPFAnalyzer") << "[MuonPFAnalyzer] GROUP : " << group << " is not a valid plot group. Returning 0.\n";
0279 return nullptr;
0280 }
0281
0282 map<string, MonitorElement *>::iterator typeIt = groupIt->second.find(type);
0283 if (typeIt == groupIt->second.end()) {
0284 LogTrace("MuonPFAnalyzer") << "[MuonPFAnalyzer] TYPE : " << type << " is not a valid type for GROUP : " << group
0285 << ". Returning 0.\n";
0286 return nullptr;
0287 }
0288
0289 return typeIt->second;
0290 }
0291
0292 inline float MuonPFAnalyzer::combRelIso(const reco::Muon *muon) {
0293 MuonIsolation iso = muon->isolationR03();
0294 float combRelIso = (iso.emEt + iso.hadEt + iso.sumPt) / muon->pt();
0295
0296 return combRelIso;
0297 }
0298
0299 inline float MuonPFAnalyzer::fDeltaPhi(float phi1, float phi2) {
0300 float fPhiDiff = fabs(acos(cos(phi1 - phi2)));
0301 return fPhiDiff;
0302 }
0303
0304 void MuonPFAnalyzer::setCodeLabels(MonitorElement *plot, int nAxis) {
0305 TAxis *axis = nullptr;
0306
0307 TH1 *histo = plot->getTH1();
0308 if (!histo)
0309 return;
0310
0311 if (nAxis == 1)
0312 axis = histo->GetXaxis();
0313 else if (nAxis == 2)
0314 axis = histo->GetYaxis();
0315
0316 if (!axis)
0317 return;
0318
0319 axis->SetBinLabel(1, "Inner Track");
0320 axis->SetBinLabel(2, "Outer Track");
0321 axis->SetBinLabel(3, "Combined");
0322 axis->SetBinLabel(4, "TPFMS");
0323 axis->SetBinLabel(5, "Picky");
0324 axis->SetBinLabel(6, "DYT");
0325 axis->SetBinLabel(7, "None");
0326 }
0327
0328 void MuonPFAnalyzer::fillInRange(MonitorElement *plot, int nAxis, double x, double y) {
0329 TH1 *histo = plot->getTH1();
0330
0331 TAxis *axis[2] = {nullptr, nullptr};
0332 axis[0] = histo->GetXaxis();
0333 if (nAxis == 2)
0334 axis[1] = histo->GetYaxis();
0335
0336 double value[2] = {0, 0};
0337 value[0] = x;
0338 value[1] = y;
0339
0340 for (int i = 0; i < nAxis; ++i) {
0341 double min = axis[i]->GetXmin();
0342 double max = axis[i]->GetXmax();
0343
0344 if (value[i] <= min)
0345 value[i] = axis[i]->GetBinCenter(1);
0346
0347 if (value[i] >= max)
0348 value[i] = axis[i]->GetBinCenter(axis[i]->GetNbins());
0349 }
0350
0351 if (nAxis == 2)
0352 plot->Fill(value[0], value[1]);
0353 else
0354 plot->Fill(value[0]);
0355 }
0356
0357 int MuonPFAnalyzer::muonTrackType(const Muon *muon, bool usePF) {
0358 switch (usePF ? muon->muonBestTrackType() : muon->tunePMuonBestTrackType()) {
0359 case Muon::InnerTrack:
0360 return 0;
0361 case Muon::OuterTrack:
0362 return 1;
0363 case Muon::CombinedTrack:
0364 return 2;
0365 case Muon::TPFMS:
0366 return 3;
0367 case Muon::Picky:
0368 return 4;
0369 case Muon::DYT:
0370 return 5;
0371 case Muon::None:
0372 return 6;
0373 }
0374
0375 return 6;
0376 }
0377
0378 void MuonPFAnalyzer::recoToGenMatch(Handle<MuonCollection> &muons, Handle<GenParticleCollection> &gens) {
0379 theRecoGen.clear();
0380
0381 if (muons.isValid()) {
0382 MuonCollection::const_iterator muonIt = muons->begin();
0383 MuonCollection::const_iterator muonEnd = muons->end();
0384
0385 for (; muonIt != muonEnd; ++muonIt) {
0386 float bestDR = 999.;
0387 const GenParticle *bestGen = nullptr;
0388
0389 if (theRunOnMC && gens.isValid()) {
0390 GenParticleCollection::const_iterator genIt = gens->begin();
0391 GenParticleCollection::const_iterator genEnd = gens->end();
0392
0393 for (; genIt != genEnd; ++genIt) {
0394 if (abs(genIt->pdgId()) == 13) {
0395 float muonPhi = muonIt->phi();
0396 float muonEta = muonIt->eta();
0397
0398 float genPhi = genIt->phi();
0399 float genEta = genIt->eta();
0400
0401 float dR = deltaR(muonEta, muonPhi, genEta, genPhi);
0402
0403 if (dR < theRecoGenR && dR < bestDR) {
0404 bestDR = dR;
0405 bestGen = &(*genIt);
0406 }
0407 }
0408 }
0409 }
0410
0411 theRecoGen.push_back(RecoGenPair(&(*muonIt), bestGen));
0412 }
0413 }
0414 }
0415
0416 const reco::Vertex MuonPFAnalyzer::getPrimaryVertex(Handle<VertexCollection> &vertex, Handle<BeamSpot> &beamSpot) {
0417 Vertex::Point posVtx;
0418 Vertex::Error errVtx;
0419
0420 bool hasPrimaryVertex = false;
0421
0422 if (vertex.isValid()) {
0423 vector<Vertex>::const_iterator vertexIt = vertex->begin();
0424 vector<Vertex>::const_iterator vertexEnd = vertex->end();
0425
0426 for (; vertexIt != vertexEnd; ++vertexIt) {
0427 if (vertexIt->isValid() && !vertexIt->isFake()) {
0428 posVtx = vertexIt->position();
0429 errVtx = vertexIt->error();
0430 hasPrimaryVertex = true;
0431 break;
0432 }
0433 }
0434 }
0435
0436 if (!hasPrimaryVertex) {
0437 LogInfo("MuonPFAnalyzer") << "[MuonPFAnalyzer] PrimaryVertex not found, use BeamSpot position instead.\n";
0438
0439 posVtx = beamSpot->position();
0440 errVtx(0, 0) = beamSpot->BeamWidthX();
0441 errVtx(1, 1) = beamSpot->BeamWidthY();
0442 errVtx(2, 2) = beamSpot->sigmaZ();
0443 }
0444
0445 const Vertex primaryVertex(posVtx, errVtx);
0446
0447 return primaryVertex;
0448 }
0449
0450
0451 DEFINE_FWK_MODULE(MuonPFAnalyzer);