CMS 3D CMS Logo

MuonPFAnalyzer.cc
Go to the documentation of this file.
1 
7 //Base class
9 
11 
14 
15 //System included files
16 #include <memory>
17 #include <string>
18 #include <typeinfo>
19 #include <utility>
20 
21 //Root included files
22 #include "TH1.h"
23 #include "TH2.h"
24 #include "TProfile.h"
25 
26 //Event framework included files
30 
34 
35 using namespace edm;
36 using namespace std;
37 using namespace reco;
38 
40  LogTrace("MuonPFAnalyzer") << "[MuonPFAnalyzer] Initializing configuration from parameterset.\n";
41 
42  theGenLabel_ = consumes<GenParticleCollection>(pSet.getParameter<InputTag>("inputTagGenParticles"));
43  theRecoLabel_ = consumes<MuonCollection>(pSet.getParameter<InputTag>("inputTagMuonReco"));
44  theVertexLabel_ = consumes<VertexCollection>(pSet.getParameter<InputTag>("inputTagVertex"));
45  theBeamSpotLabel_ = consumes<BeamSpot>(pSet.getParameter<InputTag>("inputTagBeamSpot"));
46 
47  theHighPtTh = pSet.getParameter<double>("highPtThreshold");
48  theRecoGenR = pSet.getParameter<double>("recoGenDeltaR");
49  theIsoCut = pSet.getParameter<double>("relCombIsoCut");
50  theRunOnMC = pSet.getParameter<bool>("runOnMC");
51 
52  theFolder = pSet.getParameter<string>("folder");
53 
54  theMuonKinds.push_back(""); // all TUNEP/PF muons
55  theMuonKinds.push_back("Tight"); // tight TUNEP/PF muons
56  theMuonKinds.push_back("TightIso"); // tight/iso TUNEP/PF muons
57 }
58 
59 MuonPFAnalyzer::~MuonPFAnalyzer() { LogTrace("MuonPFAnalyzer") << "[MuonPFAnalyzer] Destructor called.\n"; }
60 
61 // ------------ method called when starting to processes a run ------------
63  if (theRunOnMC) {
64  bookHistos(ibooker, "PF");
65  bookHistos(ibooker, "PFTight");
66  bookHistos(ibooker, "PFTightIso");
67  bookHistos(ibooker, "TUNEP");
68  bookHistos(ibooker, "TUNEPTight");
69  bookHistos(ibooker, "TUNEPTightIso");
70  }
71 
72  bookHistos(ibooker, "PFvsTUNEP");
73  bookHistos(ibooker, "PFvsTUNEPTight");
74  bookHistos(ibooker, "PFvsTUNEPTightIso");
75 }
76 
79  event.getByToken(theRecoLabel_, muons);
80 
82  event.getByToken(theGenLabel_, genMuons);
83 
85  event.getByToken(theBeamSpotLabel_, beamSpot);
86 
88  event.getByToken(theVertexLabel_, vertex);
89 
91 
92  recoToGenMatch(muons, genMuons);
93 
94  RecoGenCollection::const_iterator recoGenIt = theRecoGen.begin();
95  RecoGenCollection::const_iterator recoGenEnd = theRecoGen.end();
96 
97  for (; recoGenIt != recoGenEnd; ++recoGenIt) {
98  const Muon *muon = recoGenIt->first;
99  TrackRef tunePTrack = muon->tunePMuonBestTrack();
100 
101  const GenParticle *genMuon = recoGenIt->second;
102 
103  vector<string>::const_iterator kindIt = theMuonKinds.begin();
104  vector<string>::const_iterator kindEnd = theMuonKinds.end();
105 
106  for (; kindIt != kindEnd; ++kindIt) {
107  const string &kind = (*kindIt);
108 
109  if (kind.find("Tight") != string::npos && !muon::isTightMuon((*muon), primaryVertex))
110  continue;
111 
112  if (kind.find("Iso") != string::npos && combRelIso(muon) > theIsoCut)
113  continue;
114 
115  if (theRunOnMC && genMuon && !muon->innerTrack().isNull()) // has matched gen muon
116  {
117  if (!tunePTrack.isNull()) {
118  string group = "TUNEP" + kind;
119 
120  float pt = tunePTrack->pt();
121  float phi = tunePTrack->phi();
122  float eta = tunePTrack->eta();
123 
124  float genPt = genMuon->pt();
125  float genPhi = genMuon->p4().phi();
126  float genEta = genMuon->p4().eta();
127 
128  float dPtOverPt = (pt / genPt) - 1;
129 
130  if (pt < theHighPtTh) {
131  fillInRange(getPlot(group, "code"), 1, muonTrackType(muon, false));
132  fillInRange(getPlot(group, "deltaPtOverPt"), 1, dPtOverPt);
133  } else {
134  fillInRange(getPlot(group, "codeHighPt"), 1, muonTrackType(muon, false));
135  fillInRange(getPlot(group, "deltaPtOverPtHighPt"), 1, dPtOverPt);
136  }
137 
138  fillInRange(getPlot(group, "deltaPt"), 1, (pt - genPt));
139  fillInRange(getPlot(group, "deltaPhi"), 1, fDeltaPhi(genPhi, phi));
140  fillInRange(getPlot(group, "deltaEta"), 1, genEta - eta);
141  }
142 
143  if (muon->isPFMuon()) {
144  string group = "PF" + kind;
145 
146  // Assumes that default in muon is PF
147  float pt = muon->pt();
148  float phi = muon->p4().phi();
149  float eta = muon->p4().eta();
150 
151  float genPt = genMuon->pt();
152  float genPhi = genMuon->p4().phi();
153  float genEta = genMuon->p4().eta();
154 
155  float dPtOverPt = (pt / genPt) - 1;
156 
157  if (pt < theHighPtTh) {
158  fillInRange(getPlot(group, "code"), 1, muonTrackType(muon, true));
159  fillInRange(getPlot(group, "deltaPtOverPt"), 1, dPtOverPt);
160  } else {
161  fillInRange(getPlot(group, "codeHighPt"), 1, muonTrackType(muon, true));
162  fillInRange(getPlot(group, "deltaPtOverPtHighPt"), 1, dPtOverPt);
163  }
164 
165  fillInRange(getPlot(group, "deltaPt"), 1, pt - genPt);
166  fillInRange(getPlot(group, "deltaPhi"), 1, fDeltaPhi(genPhi, phi));
167  fillInRange(getPlot(group, "deltaEta"), 1, genEta - eta);
168  }
169  }
170 
171  if (muon->isPFMuon() && !tunePTrack.isNull() && !muon->innerTrack().isNull()) // Compare PF with TuneP + Tracker
172  { // No gen matching needed
173 
174  string group = "PFvsTUNEP" + kind;
175 
176  float pt = tunePTrack->pt();
177  float phi = tunePTrack->phi();
178  float eta = tunePTrack->eta();
179 
180  // Assumes that default in muon is PF
181  float pfPt = muon->pt();
182  float pfPhi = muon->p4().phi();
183  float pfEta = muon->p4().eta();
184  float dPtOverPt = (pfPt / pt) - 1; // TUNEP vs PF pt used as denum.
185 
186  if (pt < theHighPtTh) {
187  fillInRange(getPlot(group, "code"), 2, muonTrackType(muon, false), muonTrackType(muon, true));
188  fillInRange(getPlot(group, "deltaPtOverPt"), 1, dPtOverPt);
189  } else {
190  fillInRange(getPlot(group, "codeHighPt"), 2, muonTrackType(muon, false), muonTrackType(muon, true));
191  fillInRange(getPlot(group, "deltaPtOverPtHighPt"), 1, dPtOverPt);
192  }
193 
194  fillInRange(getPlot(group, "deltaPt"), 1, pfPt - pt);
195  fillInRange(getPlot(group, "deltaPhi"), 1, fDeltaPhi(pfPhi, phi));
196  fillInRange(getPlot(group, "deltaEta"), 1, pfEta - eta);
197 
198  if (theRunOnMC && genMuon) // has a matched gen muon
199 
200  {
201  float genPt = genMuon->pt();
202  float dPtOverPtGen = (pt / genPt) - 1;
203  float dPtOverPtGenPF = (pfPt / genPt) - 1;
204 
205  if (pt < theHighPtTh) {
206  fillInRange(getPlot(group, "deltaPtOverPtPFvsTUNEP"), 2, dPtOverPtGen, dPtOverPtGenPF);
207  } else {
208  fillInRange(getPlot(group, "deltaPtOverPtHighPtPFvsTUNEP"), 2, dPtOverPtGen, dPtOverPtGenPF);
209  }
210  }
211  }
212  }
213  }
214 }
215 
216 void MuonPFAnalyzer::bookHistos(DQMStore::IBooker &ibooker, const string &group) {
217  LogTrace("MuonPFAnalyzer") << "[MuonPFAnalyzer] Booking histos for group :" << group << "\n";
218 
219  ibooker.setCurrentFolder(string(theFolder) + group);
220 
221  bool isPFvsTUNEP = group.find("PFvsTUNEP") != string::npos;
222 
223  string hName;
224 
225  hName = "deltaPtOverPt" + group;
226  thePlots[group]["deltaPtOverPt"] = ibooker.book1D(hName.c_str(), hName.c_str(), 101, -1.01, 1.01);
227 
228  hName = "deltaPtOverPtHighPt" + group;
229  thePlots[group]["deltaPtOverPtHighPt"] = ibooker.book1D(hName.c_str(), hName.c_str(), 101, -1.01, 1.01);
230 
231  hName = "deltaPt" + group;
232  thePlots[group]["deltaPt"] = ibooker.book1D(hName.c_str(), hName.c_str(), 201., -10.25, 10.25);
233 
234  hName = "deltaPhi" + group;
235  thePlots[group]["deltaPhi"] = ibooker.book1D(hName.c_str(), hName.c_str(), 51., 0, .0102);
236 
237  hName = "deltaEta" + group;
238  thePlots[group]["deltaEta"] = ibooker.book1D(hName.c_str(), hName.c_str(), 101., -.00505, .00505);
239 
240  if (isPFvsTUNEP) {
241  hName = "code" + group;
242  MonitorElement *plot = ibooker.book2D(hName.c_str(), hName.c_str(), 7, -.5, 6.5, 7, -.5, 6.5);
243  thePlots[group]["code"] = plot;
244  setCodeLabels(plot, 1);
245  setCodeLabels(plot, 2);
246 
247  hName = "codeHighPt" + group;
248  plot = ibooker.book2D(hName.c_str(), hName.c_str(), 7, -.5, 6.5, 7, -.5, 6.5);
249  thePlots[group]["codeHighPt"] = plot;
250  setCodeLabels(plot, 1);
251  setCodeLabels(plot, 2);
252 
253  if (theRunOnMC) {
254  hName = "deltaPtOverPtPFvsTUNEP" + group;
255  thePlots[group]["deltaPtOverPtPFvsTUNEP"] =
256  ibooker.book2D(hName.c_str(), hName.c_str(), 101, -1.01, 1.01, 101, -1.01, 1.01);
257 
258  hName = "deltaPtOverPtHighPtPFvsTUNEP" + group;
259  thePlots[group]["deltaPtOverPtHighPtPFvsTUNEP"] =
260  ibooker.book2D(hName.c_str(), hName.c_str(), 101, -1.01, 1.01, 101, -1.01, 1.01);
261  }
262  } else {
263  hName = "code" + group;
264  MonitorElement *plot = ibooker.book1D(hName.c_str(), hName.c_str(), 7, -.5, 6.5);
265  thePlots[group]["code"] = plot;
266  setCodeLabels(plot, 1);
267 
268  hName = "codeHighPt" + group;
269  plot = ibooker.book1D(hName.c_str(), hName.c_str(), 7, -.5, 6.5);
270  thePlots[group]["codeHighPt"] = plot;
271  setCodeLabels(plot, 1);
272  }
273 }
274 
276  map<string, map<string, MonitorElement *> >::iterator groupIt = thePlots.find(group);
277  if (groupIt == thePlots.end()) {
278  LogTrace("MuonPFAnalyzer") << "[MuonPFAnalyzer] GROUP : " << group << " is not a valid plot group. Returning 0.\n";
279  return nullptr;
280  }
281 
282  map<string, MonitorElement *>::iterator typeIt = groupIt->second.find(type);
283  if (typeIt == groupIt->second.end()) {
284  LogTrace("MuonPFAnalyzer") << "[MuonPFAnalyzer] TYPE : " << type << " is not a valid type for GROUP : " << group
285  << ". Returning 0.\n";
286  return nullptr;
287  }
288 
289  return typeIt->second;
290 }
291 
293  MuonIsolation iso = muon->isolationR03();
294  float combRelIso = (iso.emEt + iso.hadEt + iso.sumPt) / muon->pt();
295 
296  return combRelIso;
297 }
298 
299 inline float MuonPFAnalyzer::fDeltaPhi(float phi1, float phi2) {
300  float fPhiDiff = fabs(acos(cos(phi1 - phi2)));
301  return fPhiDiff;
302 }
303 
305  TAxis *axis = nullptr;
306 
307  TH1 *histo = plot->getTH1();
308  if (!histo)
309  return;
310 
311  if (nAxis == 1)
312  axis = histo->GetXaxis();
313  else if (nAxis == 2)
314  axis = histo->GetYaxis();
315 
316  if (!axis)
317  return;
318 
319  axis->SetBinLabel(1, "Inner Track");
320  axis->SetBinLabel(2, "Outer Track");
321  axis->SetBinLabel(3, "Combined");
322  axis->SetBinLabel(4, "TPFMS");
323  axis->SetBinLabel(5, "Picky");
324  axis->SetBinLabel(6, "DYT");
325  axis->SetBinLabel(7, "None");
326 }
327 
328 void MuonPFAnalyzer::fillInRange(MonitorElement *plot, int nAxis, double x, double y) {
329  TH1 *histo = plot->getTH1();
330 
331  TAxis *axis[2] = {nullptr, nullptr};
332  axis[0] = histo->GetXaxis();
333  if (nAxis == 2)
334  axis[1] = histo->GetYaxis();
335 
336  double value[2] = {0, 0};
337  value[0] = x;
338  value[1] = y;
339 
340  for (int i = 0; i < nAxis; ++i) {
341  double min = axis[i]->GetXmin();
342  double max = axis[i]->GetXmax();
343 
344  if (value[i] <= min)
345  value[i] = axis[i]->GetBinCenter(1);
346 
347  if (value[i] >= max)
348  value[i] = axis[i]->GetBinCenter(axis[i]->GetNbins());
349  }
350 
351  if (nAxis == 2)
352  plot->Fill(value[0], value[1]);
353  else
354  plot->Fill(value[0]);
355 }
356 
357 int MuonPFAnalyzer::muonTrackType(const Muon *muon, bool usePF) {
358  switch (usePF ? muon->muonBestTrackType() : muon->tunePMuonBestTrackType()) {
359  case Muon::InnerTrack:
360  return 0;
361  case Muon::OuterTrack:
362  return 1;
363  case Muon::CombinedTrack:
364  return 2;
365  case Muon::TPFMS:
366  return 3;
367  case Muon::Picky:
368  return 4;
369  case Muon::DYT:
370  return 5;
371  case Muon::None:
372  return 6;
373  }
374 
375  return 6;
376 }
377 
379  theRecoGen.clear();
380 
381  if (muons.isValid()) {
382  MuonCollection::const_iterator muonIt = muons->begin();
383  MuonCollection::const_iterator muonEnd = muons->end();
384 
385  for (; muonIt != muonEnd; ++muonIt) {
386  float bestDR = 999.;
387  const GenParticle *bestGen = nullptr;
388 
389  if (theRunOnMC && gens.isValid()) {
390  GenParticleCollection::const_iterator genIt = gens->begin();
391  GenParticleCollection::const_iterator genEnd = gens->end();
392 
393  for (; genIt != genEnd; ++genIt) {
394  if (abs(genIt->pdgId()) == 13) {
395  float muonPhi = muonIt->phi();
396  float muonEta = muonIt->eta();
397 
398  float genPhi = genIt->phi();
399  float genEta = genIt->eta();
400 
401  float dR = deltaR(muonEta, muonPhi, genEta, genPhi);
402 
403  if (dR < theRecoGenR && dR < bestDR) {
404  bestDR = dR;
405  bestGen = &(*genIt);
406  }
407  }
408  }
409  }
410 
411  theRecoGen.push_back(RecoGenPair(&(*muonIt), bestGen));
412  }
413  }
414 }
415 
417  Vertex::Point posVtx;
418  Vertex::Error errVtx;
419 
420  bool hasPrimaryVertex = false;
421 
422  if (vertex.isValid()) {
423  vector<Vertex>::const_iterator vertexIt = vertex->begin();
424  vector<Vertex>::const_iterator vertexEnd = vertex->end();
425 
426  for (; vertexIt != vertexEnd; ++vertexIt) {
427  if (vertexIt->isValid() && !vertexIt->isFake()) {
428  posVtx = vertexIt->position();
429  errVtx = vertexIt->error();
430  hasPrimaryVertex = true;
431  break;
432  }
433  }
434  }
435 
436  if (!hasPrimaryVertex) {
437  LogInfo("MuonPFAnalyzer") << "[MuonPFAnalyzer] PrimaryVertex not found, use BeamSpot position instead.\n";
438 
439  posVtx = beamSpot->position();
440  errVtx(0, 0) = beamSpot->BeamWidthX();
441  errVtx(1, 1) = beamSpot->BeamWidthY();
442  errVtx(2, 2) = beamSpot->sigmaZ();
443  }
444 
445  const Vertex primaryVertex(posVtx, errVtx);
446 
447  return primaryVertex;
448 }
449 
450 //define this as a plug-in
int muonTrackType(const reco::Muon *muon, bool usePF)
float hadEt
hcal sum-Et
Definition: MuonIsolation.h:8
~MuonPFAnalyzer() override
Destructor.
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
const reco::Vertex getPrimaryVertex(edm::Handle< reco::VertexCollection > &vertex, edm::Handle< reco::BeamSpot > &beamSpot)
float sumPt
sum-pt of tracks
Definition: MuonIsolation.h:6
double pt() const final
transverse momentum
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:36
void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override
math::Error< dimension >::type Error
covariance error matrix (3x3)
Definition: Vertex.h:45
MonitorElement * getPlot(const std::string &group, const std::string &type)
const l1t::Vertex & getPrimaryVertex(const std::vector< l1t::Vertex > &aVertexCollection)
Returns primary vertex based on default criterion (max sum pT from all constituent tracks); throws if...
Definition: selection.cc:9
void bookHistos(DQMStore::IBooker &, const std::string &)
muons
the two sets of parameters below are mutually exclusive, depending if RECO or ALCARECO is used the us...
Definition: DiMuonV_cfg.py:212
const LorentzVector & p4() const final
four-momentum Lorentz vector
void setCodeLabels(MonitorElement *plot, int nAxis)
#define LogTrace(id)
void fillInRange(MonitorElement *plot, int nAxis, double x, double y=0)
Definition: Muon.py:1
void bookHistos()
Definition: Histogram.h:33
void analyze(const edm::Event &, const edm::EventSetup &) override
float combRelIso(const reco::Muon *muon)
float emEt
ecal sum-Et
Definition: MuonIsolation.h:7
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
math::XYZPoint Point
point in the space
Definition: Vertex.h:40
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
EventID const & min(EventID const &lh, EventID const &rh)
Definition: EventID.h:116
Definition: value.py:1
bool isNull() const
Checks for null.
Definition: Ref.h:235
Log< level::Info, false > LogInfo
float fDeltaPhi(float phi1, float phi2)
MonitorElement * book2D(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, FUNC onbooking=NOOP())
Definition: DQMStore.h:212
bool isValid() const
Definition: HandleBase.h:70
fixed size matrix
HLT enums.
void recoToGenMatch(edm::Handle< reco::MuonCollection > &reco, edm::Handle< reco::GenParticleCollection > &gen)
float x
bool isTightMuon(const reco::Muon &, const reco::Vertex &)
std::pair< const reco::Muon *, const reco::GenParticle * > RecoGenPair
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
primaryVertex
hltOfflineBeamSpot for HLTMON
MuonPFAnalyzer(const edm::ParameterSet &)
Constructor.
Definition: event.py:1
Definition: Run.h:45
EventID const & max(EventID const &lh, EventID const &rh)
Definition: EventID.h:118