CMS 3D CMS Logo

HLTMuonMatchAndPlot.cc
Go to the documentation of this file.
1 
7 
16 #include <boost/algorithm/string/replace.hpp>
17 
18 #include <iostream>
19 #include <string>
20 #include <utility>
21 #include <utility>
22 
25 
26 using namespace std;
27 using namespace edm;
28 using namespace reco;
29 using namespace trigger;
30 using namespace l1extra;
31 
32 using vstring = std::vector<std::string>;
33 
34 
37 
40  string hltPath,
41  string moduleLabel, bool islastfilter) :
42  hltProcessName_(pset.getParameter<string>("hltProcessName")),
43  destination_(pset.getUntrackedParameter<string>("destination")),
44  requiredTriggers_(pset.getUntrackedParameter<vstring>("requiredTriggers")),
45  targetParams_(pset.getParameterSet("targetParams")),
46  probeParams_(pset.getParameterSet("probeParams")),
47  hltPath_(std::move(hltPath)),
48  moduleLabel_(std::move(moduleLabel)),
49  isLastFilter_(islastfilter),
50  hasTargetRecoCuts(targetParams_.exists("recoCuts")),
51  hasProbeRecoCuts(probeParams_.exists("recoCuts")),
52  targetMuonSelector_(targetParams_.getUntrackedParameter<string>("recoCuts", "")),
53  targetZ0Cut_(targetParams_.getUntrackedParameter<double>("z0Cut",0.)),
54  targetD0Cut_(targetParams_.getUntrackedParameter<double>("d0Cut",0.)),
55  targetptCutZ_(targetParams_.getUntrackedParameter<double>("ptCut_Z",20.)),
56  targetptCutJpsi_(targetParams_.getUntrackedParameter<double>("ptCut_Jpsi",20.)),
57  probeMuonSelector_(probeParams_.getUntrackedParameter<string>("recoCuts", "")),
58  probeZ0Cut_(probeParams_.getUntrackedParameter<double>("z0Cut",0.)),
59  probeD0Cut_(probeParams_.getUntrackedParameter<double>("d0Cut",0.)),
60  triggerSelector_(targetParams_.getUntrackedParameter<string>("hltCuts","")),
61  hasTriggerCuts_(targetParams_.exists("hltCuts"))
62 {
63  // Create std::map<string, T> from ParameterSets.
64  fillMapFromPSet(binParams_, pset, "binParams");
65  fillMapFromPSet(plotCuts_, pset, "plotCuts");
66 
67  // Get the trigger level.
68  triggerLevel_ = "L3";
69  TPRegexp levelRegexp("L[1-3]");
70  // size_t nModules = moduleLabels_.size();
71  // cout << moduleLabel_ << " " << hltPath_ << endl;
72  TObjArray * levelArray = levelRegexp.MatchS(moduleLabel_);
73  if (levelArray->GetEntriesFast() > 0) {
74  triggerLevel_ = static_cast<const char *>(((TObjString *)levelArray->At(0))->GetString());
75  }
76  delete levelArray;
77 
78  // Get the pT cut by parsing the name of the HLT path.
79  cutMinPt_ = 3;
80  TPRegexp ptRegexp("Mu([0-9]*)");
81  TObjArray * objArray = ptRegexp.MatchS(hltPath_);
82  if (objArray->GetEntriesFast() >= 2) {
83  auto * ptCutString = (TObjString *)objArray->At(1);
84  cutMinPt_ = atoi(ptCutString->GetString());
85  cutMinPt_ = ceil(cutMinPt_ * plotCuts_["minPtFactor"]);
86  }
87  delete objArray;
88 
89 }
90 
92  const edm::Run& iRun,
93  const edm::EventSetup& iSetup)
94 {
95 
96  TPRegexp suffixPtCut("Mu[0-9]+$");
97 
98  string baseDir = destination_;
99  if (baseDir[baseDir.size() - 1] != '/') baseDir += '/';
100  string pathSansSuffix = hltPath_;
101  if (hltPath_.rfind("_v") < hltPath_.length())
102  pathSansSuffix = hltPath_.substr(0, hltPath_.rfind("_v"));
103 
104  if (isLastFilter_)
105  iBooker.setCurrentFolder(baseDir + pathSansSuffix);
106  else
107  iBooker.setCurrentFolder(baseDir + pathSansSuffix + "/" + moduleLabel_);
108 
109  // Form is book1D(name, binningType, title) where 'binningType' is used
110  // to fetch the bin settings from binParams_.
111  if (isLastFilter_){
112  book1D(iBooker, "hltPt", "pt", ";p_{T} of HLT object");
113  book1D(iBooker, "hltEta", "eta", ";#eta of HLT object");
114  book1D(iBooker, "hltPhi", "phi", ";#phi of HLT object");
115  book1D(iBooker, "resolutionEta", "resolutionEta", ";#eta^{reco}-#eta^{HLT};");
116  book1D(iBooker, "resolutionPhi", "resolutionPhi", ";#phi^{reco}-#phi^{HLT};");
117  }
118  book1D(iBooker, "deltaR", "deltaR", ";#Deltar(reco, HLT);");
119 
120  book1D(iBooker, "resolutionPt", "resolutionRel",
121  ";(p_{T}^{reco}-p_{T}^{HLT})/|p_{T}^{reco}|;");
122 
123  for (auto suffix : EFFICIENCY_SUFFIXES) {
124 
125  if (isLastFilter_)
126  iBooker.setCurrentFolder(baseDir + pathSansSuffix);
127  else
128  iBooker.setCurrentFolder(baseDir + pathSansSuffix + "/" + moduleLabel_);
129 
130 
131  book1D(iBooker, "efficiencyEta_" + suffix, "eta", ";#eta;");
132  book1D(iBooker, "efficiencyPhi_" + suffix, "phi", ";#phi;");
133  book1D(iBooker, "efficiencyTurnOn_" + suffix, "pt", ";p_{T};");
134  book1D(iBooker, "efficiencyVertex_" + suffix, "NVertex", ";NVertex;");
135  book1D(iBooker, "efficiencyDeltaR_" + suffix, "deltaR2", ";#Delta R;");
136 
137  book2D(iBooker, "efficiencyPhiVsEta_" + suffix, "etaCoarse",
138  "phiCoarse", ";#eta;#phi");
139 
140  auto MRbaseDir = boost::replace_all_copy<string>(baseDir, "HLT/Muon","HLT/Muon/MR");
141  if (isLastFilter_)
142  iBooker.setCurrentFolder(MRbaseDir + pathSansSuffix);
143  else
144  iBooker.setCurrentFolder(MRbaseDir + pathSansSuffix + "/" + moduleLabel_);
145 
146  book2D(iBooker, "MR_efficiencyPhiVsEta_" + suffix, "etaCoarse",
147  "phiHEP17", ";#eta;#phi");
148 
149  if (isLastFilter_)
150  iBooker.setCurrentFolder(baseDir + pathSansSuffix);
151  else
152  iBooker.setCurrentFolder(baseDir + pathSansSuffix + "/" + moduleLabel_);
153 
154 
155  if (!isLastFilter_) continue; //this will be plotted only for the last filter
156 
157  book1D(iBooker, "efficiencyD0_" + suffix, "d0", ";d0;");
158  book1D(iBooker, "efficiencyZ0_" + suffix, "z0", ";z0;");
159  book1D(iBooker, "efficiencyCharge_" + suffix, "charge", ";charge;");
160 
161  book1D(iBooker, "fakerateEta_" + suffix, "eta", ";#eta;");
162  book1D(iBooker, "fakerateVertex_" + suffix, "NVertex", ";NVertex;");
163  book1D(iBooker, "fakeratePhi_" + suffix, "phi", ";#phi;");
164  book1D(iBooker, "fakerateTurnOn_" + suffix, "pt", ";p_{T};");
165 
166  book1D(iBooker, "massVsEtaZ_" + suffix, "etaCoarse", ";#eta");
167  book1D(iBooker, "massVsEtaJpsi_" + suffix, "etaCoarse", ";#eta");
168  book1D(iBooker, "massVsPtZ_" + suffix, "ptCoarse", ";p_{T}");
169  book1D(iBooker, "massVsPtJpsi_" + suffix, "ptCoarse", ";p_{T}");
170  book1D(iBooker, "massVsVertexZ_" + suffix, "NVertex", ";NVertex");
171  book1D(iBooker, "massVsVertexJpsi_" + suffix, "NVertex", ";NVertex");
172  book1D(iBooker, "massVsDZZ_" + suffix, "z0", ";z0;");
173 
174 
175  if (requiredTriggers_.size() > 0){
176  book1D(iBooker, "Refefficiency_Eta_Mu1_" + suffix, "etaCoarse", ";#eta;");
177  book1D(iBooker, "Refefficiency_Eta_Mu2_" + suffix, "etaCoarse", ";#eta;");
178  book1D(iBooker, "Refefficiency_TurnOn_Mu1_" + suffix, "ptCoarse", ";p_{T};");
179  book1D(iBooker, "Refefficiency_TurnOn_Mu2_" + suffix, "ptCoarse", ";p_{T};");
180  book1D(iBooker, "Refefficiency_Vertex_" + suffix, "NVertex", ";NVertex;");
181  book1D(iBooker, "Refefficiency_DZ_Mu_" + suffix, "z0", ";z0;");
182 
183  book2D(iBooker, "Refefficiency_Eta_"+suffix, "etaCoarse", "etaCoarse", ";#eta;#eta");
184  book2D(iBooker, "Refefficiency_Pt_"+suffix, "ptCoarse", "ptCoarse", ";p_{T};p_{T}");
185  book1D(iBooker, "Refefficiency_DZ_Vertex_" + suffix, "NVertex", ";NVertex;");
186  // book1D(iBooker, "Refefficiency_DZ_Mu2_" + suffix, "z0", ";z0;");
187  }
188  // string MRbaseDir = boost::replace_all_copy<string>(baseDir, "HLT/Muon","HLT/Muon/MR");
189  iBooker.setCurrentFolder(MRbaseDir + pathSansSuffix + "/");
190 
191  if (requiredTriggers_.size() > 0){
192  book1D(iBooker, "MR_Refefficiency_TurnOn_Mu1_" + suffix, "pt", ";p_{T};");
193  book1D(iBooker, "MR_Refefficiency_TurnOn_Mu2_" + suffix, "pt", ";p_{T};");
194  book1D(iBooker, "MR_Refefficiency_Vertex_" + suffix, "NVertexFine", ";NVertex;");
195  book1D(iBooker, "MR_Refefficiency_DZ_Mu_" + suffix, "z0Fine", ";z0;");
196  // book1D(iBooker, "MR_Refefficiency_DZ_Mu2_" + suffix, "z0Fine", ";z0;");
197  book2D(iBooker, "MR_Refefficiency_Pt_"+suffix, "pt", "pt", ";p_{T};p_{T}");
198  book1D(iBooker, "MR_Refefficiency_DZ_Vertex_" + suffix, "NVertexFine",";NVertex;");
199  }
200  book1D(iBooker, "MR_massVsPtZ_" + suffix, "pt", ";p_{T}");
201  book1D(iBooker, "MR_massVsPtJpsi_" + suffix, "pt", ";p_{T}");
202  book1D(iBooker, "MR_massVsVertexZ_" + suffix, "NVertex", ";NVertex");
203  book1D(iBooker, "MR_massVsVertexJpsi_" + suffix, "NVertexFine", ";NVertex");
204  book1D(iBooker, "MR_massVsDZZ_" + suffix, "z0Fine", ";z0;");
205  book1D(iBooker, "MR_massVsEtaZ_" + suffix, "etaFine", ";#eta");
206  book1D(iBooker, "MR_massVsEtaJpsi_" + suffix, "etaFine", ";#eta");
207  book1D(iBooker, "MR_massVsPhiZ_" + suffix, "phiFine", ";#phi");
208  book1D(iBooker, "MR_massVsPhiJpsi_" + suffix, "phiFine", ";#phi");
209 
210  }
211 
212 }
213 
214 
215 
217  const edm::EventSetup& iSetup)
218 {
219 
220 }
221 
222 
223 
227  Handle<TriggerEvent> & triggerSummary,
230 {
231  /*
232  if(gen != 0) {
233  for(g_part = gen->begin(); g_part != gen->end(); g_part++){
234  if( abs(g_part->pdgId()) == 13) {
235  if(!( g_part->status() ==1 || (g_part->status() ==2 && abs(g_part->pdgId())==5))) continue;
236  bool GenMomExists (true);
237  bool GenGrMomExists(true);
238  if( g_part->pt() < 10.0 ) continue;
239  if( fabs(g_part->eta()) > 2.4 ) continue;
240  int gen_id= g_part->pdgId();
241  const GenParticle* gen_lept = &(*g_part);
242  // get mother of gen_lept
243  const GenParticle* gen_mom = static_cast<const GenParticle*> (gen_lept->mother());
244  if(gen_mom==NULL) GenMomExists=false;
245  int m_id=-999;
246  if(GenMomExists) m_id = gen_mom->pdgId();
247  if(m_id != gen_id || !GenMomExists);
248  else{
249  int id= m_id;
250  while(id == gen_id && GenMomExists){
251  gen_mom = static_cast<const GenParticle*> (gen_mom->mother());
252  if(gen_mom==NULL){
253  GenMomExists=false;
254  }
255  if(GenMomExists) id=gen_mom->pdgId();
256  }
257  }
258  if(GenMomExists) m_id = gen_mom->pdgId();
259  gen_leptsp.push_back(gen_lept);
260  gen_momsp.push_back(gen_mom);
261  }
262  }
263  }
264 
265 
266  std::vector<GenParticle> gen_lepts;
267  for(size_t i = 0; i < gen_leptsp.size(); i++) {
268  gen_lepts.push_back(*gen_leptsp[i]);
269  }
270 
271 
272  */
273 
274 
275 
276  // Select objects based on the configuration.
279  TriggerObjectCollection allTriggerObjects = triggerSummary->getObjects();
280  TriggerObjectCollection hltMuons =
281  selectedTriggerObjects(allTriggerObjects, * triggerSummary, hasTriggerCuts_,triggerSelector_);
282  // Fill plots for HLT muons.
283  if (isLastFilter_){
284  for (auto & hltMuon : hltMuons) {
285  hists_["hltPt"]->Fill(hltMuon.pt());
286  hists_["hltEta"]->Fill(hltMuon.eta());
287  hists_["hltPhi"]->Fill(hltMuon.phi());
288  }
289  }
290  // Find the best trigger object matches for the targetMuons.
291  vector<size_t> matches = matchByDeltaR(targetMuons, hltMuons,
292  plotCuts_[triggerLevel_ + "DeltaR"]);
293 
294  // Fill plots for matched muons.
295  bool pairalreadyconsidered = false;
296  for (size_t i = 0; i < targetMuons.size(); i++) {
297  Muon & muon = targetMuons[i];
298 
299  // Fill plots which are not efficiencies.
300  if (matches[i] < targetMuons.size()) {
301  TriggerObject & hltMuon = hltMuons[matches[i]];
302  double ptRes = (muon.pt() - hltMuon.pt()) / muon.pt();
303  hists_["resolutionPt"]->Fill(ptRes);
304  hists_["deltaR"]->Fill(deltaR(muon, hltMuon));
305 
306  if (isLastFilter_){
307  double etaRes = muon.eta() - hltMuon.eta();
308  double phiRes = muon.phi() - hltMuon.phi();
309  hists_["resolutionEta"]->Fill(etaRes);
310  hists_["resolutionPhi"]->Fill(phiRes);
311  }
312  }
313 
314  // Fill numerators and denominators for efficiency plots.
315  for (auto suffix : EFFICIENCY_SUFFIXES) {
316 
317  // If no match was found, then the numerator plots don't get filled.
318  if (suffix == "numer" && matches[i] >= targetMuons.size()) continue;
319 
320  if (muon.pt() > cutMinPt_) {
321  hists_["efficiencyEta_" + suffix]->Fill(muon.eta());
322  hists_["efficiencyPhiVsEta_" + suffix]->Fill(muon.eta(), muon.phi());
323  hists_["MR_efficiencyPhiVsEta_"+suffix]->Fill(muon.eta(), muon.phi());
324  }
325 
326  if (fabs(muon.eta()) < plotCuts_["maxEta"]) {
327  hists_["efficiencyTurnOn_" + suffix]->Fill(muon.pt());
328  }
329 
330 
331  if (muon.pt() > cutMinPt_ && fabs(muon.eta()) < plotCuts_["maxEta"]) {
332  const Track * track = nullptr;
333  if (muon.isTrackerMuon()) track = & * muon.innerTrack();
334  else if (muon.isStandAloneMuon()) track = & * muon.outerTrack();
335  if (track) {
336  hists_["efficiencyVertex_" + suffix]->Fill(vertices->size());
337  hists_["efficiencyPhi_" + suffix]->Fill(muon.phi());
338 
339  if (isLastFilter_){
340  double d0 = track->dxy(beamSpot->position());
341  double z0 = track->dz(beamSpot->position());
342  hists_["efficiencyD0_" + suffix]->Fill(d0);
343  hists_["efficiencyZ0_" + suffix]->Fill(z0);
344  hists_["efficiencyCharge_" + suffix]->Fill(muon.charge());
345  }
346  }
347  }
348  } // finish loop numerator / denominator...
349 
350  if (!isLastFilter_) continue;
351  // Fill plots for tag and probe
352  // Muon cannot be a tag because doesn't match an hlt muon
353  if(matches[i] >= targetMuons.size()) continue;
354  for (size_t k = 0; k < targetMuons.size(); k++) {
355  if(k == i) continue;
356  Muon & theProbe = targetMuons[k];
357  if (muon.charge() != theProbe.charge() && !pairalreadyconsidered) {
358  double mass = (muon.p4() + theProbe.p4()).M();
359 
360  if(mass > 60 && mass < 120) {
361  if(muon.pt() < targetptCutZ_) continue;
362  hists_["massVsEtaZ_denom"]->Fill(theProbe.eta());
363  hists_["MR_massVsEtaZ_denom"]->Fill(theProbe.eta());
364  hists_["MR_massVsPhiZ_denom"]->Fill(theProbe.phi());
365  hists_["massVsPtZ_denom"]->Fill(theProbe.pt());
366  hists_["MR_massVsPtZ_denom"]->Fill(theProbe.pt());
367  hists_["massVsVertexZ_denom"]->Fill(vertices->size());
368  hists_["MR_massVsVertexZ_denom"]->Fill(vertices->size());
369  const Track * track = nullptr;
370  if (theProbe.isTrackerMuon()) track = & * theProbe.innerTrack();
371  else if (theProbe.isStandAloneMuon()) track = & * theProbe.outerTrack();
372  if (track){
373  hists_["massVsDZZ_denom"]->Fill(track->dz(beamSpot->position()));
374  hists_["MR_massVsDZZ_denom"]->Fill(track->dz(beamSpot->position()));
375  }
376  hists_["efficiencyDeltaR_denom" ]->Fill(deltaR(theProbe, muon));
377  if(matches[k] < targetMuons.size()) {
378  hists_["massVsEtaZ_numer"]->Fill(theProbe.eta());
379  hists_["MR_massVsEtaZ_numer"]->Fill(theProbe.eta());
380  hists_["MR_massVsPhiZ_numer"]->Fill(theProbe.phi());
381  hists_["massVsPtZ_numer"]->Fill(theProbe.pt());
382  hists_["MR_massVsPtZ_numer"]->Fill(theProbe.pt());
383  hists_["massVsVertexZ_numer"]->Fill(vertices->size());
384  hists_["MR_massVsVertexZ_numer"]->Fill(vertices->size());
385  hists_["efficiencyDeltaR_numer" ]->Fill(deltaR(theProbe, muon));
386  if (track){
387  hists_["massVsDZZ_numer"]->Fill(track->dz(beamSpot->position()));
388  hists_["MR_massVsDZZ_numer"]->Fill(track->dz(beamSpot->position()));
389  }
390  }
391  pairalreadyconsidered = true;
392  }
393  if(mass > 1 && mass < 4) {
394  if(muon.pt() < targetptCutJpsi_) continue;
395  hists_["massVsEtaJpsi_denom"]->Fill(theProbe.eta());
396  hists_["MR_massVsEtaJpsi_denom"]->Fill(theProbe.eta());
397  hists_["massVsPtJpsi_denom"]->Fill(theProbe.pt());
398  hists_["MR_massVsPtJpsi_denom"]->Fill(theProbe.pt());
399  hists_["massVsVertexJpsi_denom"]->Fill(vertices->size());
400  hists_["MR_massVsVertexJpsi_denom"]->Fill(vertices->size());
401  if(matches[k] < targetMuons.size()) {
402  hists_["massVsEtaJpsi_numer"]->Fill(theProbe.eta());
403  hists_["MR_massVsEtaJpsi_numer"]->Fill(theProbe.eta());
404  hists_["massVsPtJpsi_numer"]->Fill(theProbe.pt());
405  hists_["MR_massVsPtJpsi_numer"]->Fill(theProbe.pt());
406  hists_["massVsVertexJpsi_numer"]->Fill(vertices->size());
407  hists_["MR_massVsVertexJpsi_numer"]->Fill(vertices->size());
408  }
409  pairalreadyconsidered = true;
410  }
411  }
412  } // End loop over denominator and numerator.
413  } // End loop over targetMuons.
414 
415  // fill eff histograms for reference trigger method
416  // Denominator: events passing reference trigger and two target muons
417  // Numerator: events in the denominator with two target muons
418  // matched to hlt muons
419  if (!isLastFilter_) return;
420  unsigned int numTriggers = trigNames.size();
421  bool passTrigger = false;
422  if (requiredTriggers_.size() == 0) passTrigger = true;
423  for (auto const & requiredTrigger : requiredTriggers_) {
424  for ( unsigned int hltIndex = 0; hltIndex < numTriggers; ++hltIndex){
425  passTrigger = (trigNames.triggerName(hltIndex).find(requiredTrigger) != std::string::npos && triggerResults->wasrun(hltIndex) && triggerResults->accept(hltIndex));
426  if (passTrigger) break;
427  }
428  }
429 
430  int nMatched = 0;
431  for (unsigned long matche : matches){
432  if (matche < targetMuons.size()) nMatched++;
433  }
434  if (requiredTriggers_.size() > 0 && targetMuons.size() > 1 && passTrigger){
435  // denominator:
436  hists_["Refefficiency_Eta_Mu1_denom"]->Fill( targetMuons.at(0).eta());
437  hists_["Refefficiency_Eta_Mu2_denom"]->Fill( targetMuons.at(1).eta());
438  hists_["Refefficiency_TurnOn_Mu1_denom"]->Fill( targetMuons.at(0).pt() );
439  hists_["MR_Refefficiency_TurnOn_Mu1_denom"]->Fill( targetMuons.at(0).pt() );
440  hists_["Refefficiency_TurnOn_Mu2_denom"]->Fill( targetMuons.at(1).pt() );
441  hists_["MR_Refefficiency_TurnOn_Mu2_denom"]->Fill( targetMuons.at(1).pt() );
442  hists_["Refefficiency_Vertex_denom"]->Fill( vertices->size() );
443  hists_["MR_Refefficiency_Vertex_denom"]->Fill( vertices->size() );
444  hists_["MR_Refefficiency_Pt_denom"]->Fill(targetMuons.at(0).pt(),targetMuons.at(1).pt());
445  hists_["Refefficiency_Pt_denom"]->Fill(targetMuons.at(0).pt(),targetMuons.at(1).pt());
446  hists_["Refefficiency_Eta_denom" ]->Fill(targetMuons.at(0).eta(),targetMuons.at(1).eta());
447 
448 
449 
450 
451  // if (track0){
452  // hists_["Refefficiency_DZ_Mu1_denom"]->Fill(track0->dz(beamSpot->position()));
453  // hists_["MR_Refefficiency_DZ_Mu1_denom"]->Fill(track0->dz(beamSpot->position()));
454  // }
455 
456  // if (track1){
457  // hists_["Refefficiency_DZ_Mu2_denom"]->Fill(track1->dz(beamSpot->position()));
458  // hists_["MR_Refefficiency_DZ_Mu2_denom"]->Fill(track1->dz(beamSpot->position()));
459  // }
460 
461  // numerator:
462  if (nMatched > 1){
463  hists_["Refefficiency_Eta_Mu1_numer" ]->Fill( targetMuons.at(0).eta());
464  hists_["Refefficiency_Eta_Mu2_numer" ]->Fill( targetMuons.at(1).eta());
465  hists_["Refefficiency_TurnOn_Mu1_numer"]->Fill( targetMuons.at(0).pt() );
466  hists_["MR_Refefficiency_TurnOn_Mu1_numer"]->Fill( targetMuons.at(0).pt() );
467  hists_["Refefficiency_TurnOn_Mu2_numer"]->Fill( targetMuons.at(1).pt() );
468  hists_["MR_Refefficiency_TurnOn_Mu2_numer"]->Fill( targetMuons.at(1).pt() );
469  hists_["Refefficiency_Vertex_numer" ]->Fill( vertices->size() );
470  hists_["MR_Refefficiency_Vertex_numer" ]->Fill( vertices->size() );
471  hists_["MR_Refefficiency_Pt_numer"]->Fill(targetMuons.at(0).pt(),targetMuons.at(1).pt());
472  hists_["Refefficiency_Pt_numer"]->Fill(targetMuons.at(0).pt(),targetMuons.at(1).pt());
473  hists_["Refefficiency_Eta_numer" ]->Fill(targetMuons.at(0).eta(),targetMuons.at(1).eta());
474 
475  // if (track0){
476  // hists_["Refefficiency_DZ_Mu1_numer"]->Fill(track0->dz(beamSpot->position()));
477  // hists_["MR_Refefficiency_DZ_Mu1_numer"]->Fill(track0->dz(beamSpot->position()));
478  // }
479  // if (track1){
480  // hists_["Refefficiency_DZ_Mu2_numer"]->Fill(track1->dz(beamSpot->position()));
481  // hists_["MR_Refefficiency_DZ_Mu2_numer"]->Fill(track1->dz(beamSpot->position()));
482  // }
483 
484  }
485  }
486 
487  string nonDZPath = hltPath_;
488  bool dzPath = false;
489  if ( nonDZPath.rfind("_DZ") < nonDZPath.length()){
490  dzPath = true;
491  nonDZPath = boost::replace_all_copy<string>(nonDZPath, "_DZ","");
492  nonDZPath = nonDZPath.substr(0, nonDZPath.rfind("_v")+2);
493  }
494  bool passTriggerDZ = false;
495  if (dzPath){
496  for ( unsigned int hltIndex = 0; hltIndex < numTriggers; ++hltIndex){
497  passTriggerDZ = passTriggerDZ || (trigNames.triggerName(hltIndex).find(nonDZPath) != std::string::npos && triggerResults->wasrun(hltIndex) && triggerResults->accept(hltIndex));
498 
499  }
500  }
501 
502  if (dzPath && targetMuons.size() > 1 && passTriggerDZ){
503  const Track * track0 = nullptr; const Track * track1 = nullptr;
504  if (targetMuons.at(0).isTrackerMuon()) track0 = & * targetMuons.at(0).innerTrack();
505  else if (targetMuons.at(0).isTrackerMuon()) track0 = & * targetMuons.at(0).outerTrack();
506  if (targetMuons.at(1).isTrackerMuon()) track1 = & * targetMuons.at(1).innerTrack();
507  else if (targetMuons.at(1).isTrackerMuon()) track1 = & * targetMuons.at(1).outerTrack();
508 
509  if (track0 && track1){
510  hists_["Refefficiency_DZ_Mu_denom"]->Fill(track0->dz(beamSpot->position()) - track1->dz(beamSpot->position()));
511  hists_["MR_Refefficiency_DZ_Mu_denom"]->Fill(track0->dz(beamSpot->position()) - track1->dz(beamSpot->position()));
512  }
513  hists_["Refefficiency_DZ_Vertex_denom"]->Fill( vertices->size() );
514  hists_["MR_Refefficiency_DZ_Vertex_denom"]->Fill( vertices->size() );
515  if (nMatched > 1){
516  if (track0 && track1){
517  hists_["Refefficiency_DZ_Mu_numer"]->Fill(track0->dz(beamSpot->position()) - track1->dz(beamSpot->position()));
518  hists_["MR_Refefficiency_DZ_Mu_numer"]->Fill(track0->dz(beamSpot->position()) - track1->dz(beamSpot->position()));
519  hists_["Refefficiency_DZ_Vertex_numer"] ->Fill( vertices->size() );
520  hists_["MR_Refefficiency_DZ_Vertex_numer"]->Fill( vertices->size() );
521  }
522  }
523  }
524 
525 
526  // Plot fake rates (efficiency for HLT objects to not get matched to RECO).
527  vector<size_t> hltMatches = matchByDeltaR(hltMuons, targetMuons,
528  plotCuts_[triggerLevel_ + "DeltaR"]);
529  for (size_t i = 0; i < hltMuons.size(); i++) {
530  TriggerObject & hltMuon = hltMuons[i];
531  bool isFake = hltMatches[i] > hltMuons.size();
532  for (auto suffix : EFFICIENCY_SUFFIXES) {
533  // If match is found, then numerator plots should not get filled
534  if (suffix == "numer" && ! isFake) continue;
535  hists_["fakerateVertex_" + suffix]->Fill(vertices->size());
536  hists_["fakerateEta_" + suffix]->Fill(hltMuon.eta());
537  hists_["fakeratePhi_" + suffix]->Fill(hltMuon.phi());
538  hists_["fakerateTurnOn_" + suffix]->Fill(hltMuon.pt());
539  } // End loop over numerator and denominator.
540  } // End loop over hltMuons.
541 
542 
543 
544 
545 } // End analyze() method.
546 
547 
548 
549 // Method to fill binning parameters from a vector of doubles.
550 void
551 HLTMuonMatchAndPlot::fillEdges(size_t & nBins, float * & edges,
552  const vector<double>& binning)
553 {
554 
555  if (binning.size() < 3) {
556  LogWarning("HLTMuonVal") << "Invalid binning parameters!";
557  return;
558  }
559 
560  // Fixed-width binning.
561  if (binning.size() == 3) {
562  nBins = binning[0];
563  edges = new float[nBins + 1];
564  const double min = binning[1];
565  const double binwidth = (binning[2] - binning[1]) / nBins;
566  for (size_t i = 0; i <= nBins; i++) edges[i] = min + (binwidth * i);
567  }
568 
569  // Variable-width binning.
570  else {
571  nBins = binning.size() - 1;
572  edges = new float[nBins + 1];
573  for (size_t i = 0; i <= nBins; i++) edges[i] = binning[i];
574  }
575 
576 }
577 
578 
579 
580 // This is an unorthodox method of getting parameters, but cleaner in my mind
581 // It looks for parameter 'target' in the pset, and assumes that all entries
582 // have the same class (T), filling the values into a std::map.
583 template <class T>
584 void
586  const ParameterSet& pset, const string& target)
587 {
588 
589  // Get the ParameterSet with name 'target' from 'pset'
590  ParameterSet targetPset;
591  if (pset.existsAs<ParameterSet>(target, true)) // target is tracked
592  targetPset = pset.getParameterSet(target);
593  else if (pset.existsAs<ParameterSet>(target, false)) // target is untracked
594  targetPset = pset.getUntrackedParameterSet(target);
595 
596  // Get the parameter names from targetPset
597  vector<string> names = targetPset.getParameterNames();
598  vector<string>::const_iterator iter;
599 
600  for (iter = names.begin(); iter != names.end(); ++iter) {
601  if (targetPset.existsAs<T>(* iter, true)) // target is tracked
602  m[* iter] = targetPset.getParameter<T>(* iter);
603  else if (targetPset.existsAs<T>(* iter, false)) // target is untracked
604  m[* iter] = targetPset.getUntrackedParameter<T>(* iter);
605  }
606 
607 }
608 
609 
610 
611 // A generic method to find the best deltaR matches from 2 collections.
612 template <class T1, class T2>
613 vector<size_t>
614 HLTMuonMatchAndPlot::matchByDeltaR(const vector<T1> & collection1,
615  const vector<T2> & collection2,
616  const double maxDeltaR)
617 {
618 
619  const size_t n1 = collection1.size();
620  const size_t n2 = collection2.size();
621 
622  vector<size_t> result(n1, -1);
623  vector<vector<double> > deltaRMatrix(n1, vector<double>(n2, NOMATCH));
624 
625  for (size_t i = 0; i < n1; i++)
626  for (size_t j = 0; j < n2; j++) {
627  deltaRMatrix[i][j] = deltaR(collection1[i], collection2[j]);
628  }
629 
630  // Run through the matrix n1 times to make sure we've found all matches.
631  for (size_t k = 0; k < n1; k++) {
632  size_t i_min = -1;
633  size_t j_min = -1;
634  double minDeltaR = maxDeltaR;
635  // find the smallest deltaR
636  for (size_t i = 0; i < n1; i++)
637  for (size_t j = 0; j < n2; j++)
638  if (deltaRMatrix[i][j] < minDeltaR) {
639  i_min = i;
640  j_min = j;
641  minDeltaR = deltaRMatrix[i][j];
642  }
643  // If a match has been made, save it and make those candidates unavailable.
644  if (minDeltaR < maxDeltaR) {
645  result[i_min] = j_min;
646  deltaRMatrix[i_min] = vector<double>(n2, NOMATCH);
647  for (size_t i = 0; i < n1; i++)
648  deltaRMatrix[i][j_min] = NOMATCH;
649  }
650  }
651 
652  return result;
653 
654 }
655 
656 
657 
660  const BeamSpot & beamSpot,
661  bool hasRecoCuts,
662  const StringCutObjectSelector<reco::Muon> &selector,
663  double d0Cut, double z0Cut)
664 {
665 
666  // If there is no selector (recoCuts does not exists), return an empty collection.
667  if (!hasRecoCuts)
668  return MuonCollection();
669 
670  MuonCollection reducedMuons;
671  for (auto const& mu : allMuons){
672  const Track * track = nullptr;
673  if (mu.isTrackerMuon()) track = & * mu.innerTrack();
674  else if (mu.isStandAloneMuon()) track = & * mu.outerTrack();
675  if (track && selector(mu) &&
676  fabs(track->dxy(beamSpot.position())) < d0Cut &&
677  fabs(track->dz(beamSpot.position())) < z0Cut)
678  reducedMuons.push_back(mu);
679  }
680 
681  return reducedMuons;
682 
683 }
684 
685 
686 
690  const TriggerEvent & triggerSummary,
691  bool hasTriggerCuts,
692  const StringCutObjectSelector<TriggerObject>& triggerSelector)
693 {
694  if ( !hasTriggerCuts) return TriggerObjectCollection();
695 
696  InputTag filterTag(moduleLabel_, "", hltProcessName_);
697  size_t filterIndex = triggerSummary.filterIndex(filterTag);
698 
699  TriggerObjectCollection selectedObjects;
700 
701  if (filterIndex < triggerSummary.sizeFilters()) {
702  const Keys &keys = triggerSummary.filterKeys(filterIndex);
703  for (unsigned short key : keys){
704  TriggerObject foundObject = triggerObjects[key];
705  if (triggerSelector(foundObject))
706  selectedObjects.push_back(foundObject);
707  }
708  }
709 
710  return selectedObjects;
711 
712 }
713 
714 
715 
717  const string& binningType, string title)
718 {
719 
720  /* Properly delete the array of floats that has been allocated on
721  * the heap by fillEdges. Avoid multiple copies and internal ROOT
722  * clones by simply creating the histograms directly in the DQMStore
723  * using the appropriate book1D method to handle the variable bins
724  * case. */
725 
726  size_t nBins;
727  float * edges = nullptr;
728  fillEdges(nBins, edges, binParams_[binningType]);
729  hists_[name] = iBooker.book1D(name, title, nBins, edges);
730  if (hists_[name])
731  if (hists_[name]->getTH1F()->GetSumw2N())
732  hists_[name]->getTH1F()->Sumw2();
733 
734  if (edges)
735  delete [] edges;
736 
737 }
738 
739 
740 
741 void
743  const string& binningTypeX, const string& binningTypeY,
744  const string& title)
745 {
746 
747  /* Properly delete the arrays of floats that have been allocated on
748  * the heap by fillEdges. Avoid multiple copies and internal ROOT
749  * clones by simply creating the histograms directly in the DQMStore
750  * using the appropriate book2D method to handle the variable bins
751  * case. */
752 
753  size_t nBinsX;
754  float * edgesX = nullptr;
755  fillEdges(nBinsX, edgesX, binParams_[binningTypeX]);
756 
757  size_t nBinsY;
758  float * edgesY = nullptr;
759  fillEdges(nBinsY, edgesY, binParams_[binningTypeY]);
760 
761  hists_[name] = iBooker.book2D(name.c_str(), title.c_str(),
762  nBinsX, edgesX, nBinsY, edgesY);
763  if (hists_[name])
764  if (hists_[name]->getTH2F()->GetSumw2N())
765  hists_[name]->getTH2F()->Sumw2();
766 
767  if (edgesX)
768  delete [] edgesX;
769  if (edgesY)
770  delete [] edgesY;
771 
772 }
773 
774 
T getParameter(std::string const &) const
virtual double pt() const final
transverse momentum
T getUntrackedParameter(std::string const &, T const &) const
reco::MuonCollection selectedMuons(const reco::MuonCollection &, const reco::BeamSpot &, bool, const StringCutObjectSelector< reco::Muon > &, double, double)
bool wasrun() const
Was at least one path run?
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:186
StringCutObjectSelector< reco::Muon > probeMuonSelector_
The single EDProduct to be saved for each event (AOD case)
Definition: TriggerEvent.h:25
trigger::size_type sizeFilters() const
Definition: TriggerEvent.h:135
static const HistoName names[]
const std::string EFFICIENCY_SUFFIXES[2]
vector< string > vstring
Definition: ExoticaDQM.cc:8
virtual double eta() const final
momentum pseudorapidity
virtual TrackRef innerTrack() const
Definition: Muon.h:48
float phi() const
Definition: TriggerObject.h:58
bool isTrackerMuon() const
Definition: Muon.h:226
ParameterSet const & getParameterSet(ParameterSetID const &id)
bool accept() const
Has at least one path accepted the event?
const Keys & filterKeys(trigger::size_type index) const
Definition: TriggerEvent.h:111
trigger::size_type filterIndex(const edm::InputTag &filterTag) const
find index of filter in data-member vector from filter tag
Definition: TriggerEvent.h:123
std::map< std::string, std::vector< double > > binParams_
ParameterSet getUntrackedParameterSet(std::string const &name, ParameterSet const &defaultValue) const
Strings::size_type size() const
Definition: TriggerNames.cc:39
std::map< std::string, MonitorElement * > hists_
float eta() const
Definition: TriggerObject.h:57
bool isStandAloneMuon() const
Definition: Muon.h:227
std::vector< Muon > MuonCollection
collection of Muon objects
Definition: MuonFwd.h:9
HLTMuonMatchAndPlot(const edm::ParameterSet &, std::string, std::string, bool)
Constructor.
std::vector< std::string > requiredTriggers_
virtual double phi() const final
momentum azimuthal angle
virtual int charge() const final
electric charge
Definition: LeafCandidate.h:91
const double NOMATCH
void book2D(DQMStore::IBooker &, const std::string &, const std::string &, const std::string &, const std::string &)
std::vector< size_t > matchByDeltaR(const std::vector< T1 > &, const std::vector< T2 > &, const double maxDeltaR=NOMATCH)
Definition: Muon.py:1
const TriggerObjectCollection & getObjects() const
Definition: TriggerEvent.h:98
void fillMapFromPSet(std::map< std::string, T > &, const edm::ParameterSet &, const std::string &)
trigger::TriggerObjectCollection selectedTriggerObjects(const trigger::TriggerObjectCollection &, const trigger::TriggerEvent &, bool hasTriggerCuts, const StringCutObjectSelector< trigger::TriggerObject > &triggerSelector)
MonitorElement * book1D(Args &&...args)
Definition: DQMStore.h:115
const int mu
Definition: Constants.h:22
T min(T a, T b)
Definition: MathUtil.h:58
static std::string const triggerResults
Definition: EdmProvDump.cc:41
std::vector< std::string > getParameterNames() const
virtual TrackRef outerTrack() const
reference to Track reconstructed in the muon detector only
Definition: Muon.h:51
int k[5][pyjets_maxn]
double dz() const
dz parameter (= dsz/cos(lambda)). This is the track z0 w.r.t (0,0,0) only if the refPoint is close to...
Definition: TrackBase.h:609
double deltaR(double eta1, double eta2, double phi1, double phi2)
Definition: TreeUtility.cc:17
void book1D(DQMStore::IBooker &, std::string, const std::string &, std::string)
std::vector< TriggerObject > TriggerObjectCollection
collection of trigger physics objects (e.g., all isolated muons)
Definition: TriggerObject.h:81
static const char *const trigNames[]
Definition: EcalDumpRaw.cc:74
void analyze(edm::Handle< reco::MuonCollection > &, edm::Handle< reco::BeamSpot > &, edm::Handle< reco::VertexCollection > &, edm::Handle< trigger::TriggerEvent > &, edm::Handle< edm::TriggerResults > &, const edm::TriggerNames &)
void setCurrentFolder(const std::string &fullpath)
Definition: DQMStore.cc:277
StringCutObjectSelector< reco::Muon > targetMuonSelector_
MonitorElement * book2D(Args &&...args)
Definition: DQMStore.h:133
ParameterSet const & getParameterSet(std::string const &) const
std::string const & triggerName(unsigned int index) const
Definition: TriggerNames.cc:27
std::vector< size_type > Keys
fixed size matrix
HLT enums.
StringCutObjectSelector< trigger::TriggerObject > triggerSelector_
void endRun(const edm::Run &, const edm::EventSetup &)
const Point & position() const
position
Definition: BeamSpot.h:62
virtual const LorentzVector & p4() const final
four-momentum Lorentz vector
Definition: LeafCandidate.h:99
double dxy() const
dxy parameter. (This is the transverse impact parameter w.r.t. to (0,0,0) ONLY if refPoint is close t...
Definition: TrackBase.h:591
long double T
std::map< std::string, double > plotCuts_
void fillEdges(size_t &nBins, float *&edges, const std::vector< double > &binning)
def move(src, dest)
Definition: eostools.py:510
Definition: Run.h:42
void beginRun(DQMStore::IBooker &, const edm::Run &, const edm::EventSetup &)