CMS 3D CMS Logo

HeavyFlavorValidation.cc
Go to the documentation of this file.
1 
8 // Original Author: Zoltan Gecse
9 
10 #include <memory>
11 #include <initializer_list>
19 
35 
37 
40 
42 
43 #include "TLorentzVector.h"
44 
45 using namespace std;
46 using namespace edm;
47 using namespace reco;
48 using namespace l1extra;
49 using namespace trigger;
50 
52 public:
53  explicit HeavyFlavorValidation(const edm::ParameterSet &);
54  ~HeavyFlavorValidation() override;
55 
56 protected:
57  void dqmBeginRun(const edm::Run &, const edm::EventSetup &) override;
58  void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override;
59  void analyze(const edm::Event &, const edm::EventSetup &) override;
60 
61 private:
62  int getMotherId(const Candidate *p);
63  void match(MonitorElement *me,
64  vector<LeafCandidate> &from,
65  vector<LeafCandidate> &to,
66  double deltaRMatchingCut,
67  vector<int> &map);
68  void myBook2D(DQMStore::IBooker &ibooker,
69  TString name,
70  vector<double> &xBins,
71  TString xLabel,
72  vector<double> &yBins,
73  TString yLabel,
74  TString title);
75  void myBook2D(DQMStore::IBooker &ibooker,
76  TString name,
77  vector<double> &xBins,
78  TString xLabel,
79  vector<double> &yBins,
80  TString yLabel) {
81  myBook2D(ibooker, name, xBins, xLabel, yBins, yLabel, name);
82  }
83  void myBookProfile2D(DQMStore::IBooker &ibooker,
84  TString name,
85  vector<double> &xBins,
86  TString xLabel,
87  vector<double> &yBins,
88  TString yLabel,
89  TString title);
91  TString name,
92  vector<double> &xBins,
93  TString xLabel,
94  vector<double> &yBins,
95  TString yLabel) {
96  myBookProfile2D(ibooker, name, xBins, xLabel, yBins, yLabel, name);
97  }
98  void myBook1D(DQMStore::IBooker &ibooker, TString name, vector<double> &xBins, TString label, TString title);
99  void myBook1D(DQMStore::IBooker &ibooker, TString name, vector<double> &xBins, TString label) {
100  myBook1D(ibooker, name, xBins, label, name);
101  }
102 
112  int getFilterLevel(const std::string &moduleName, const HLTConfigProvider &hltConfig);
113 
114  string dqmFolder;
117 
126 
127  vector<int> motherIDs;
132  vector<double> deltaEtaBins;
133  vector<double> deltaPhiBins;
134  vector<double> muonPtBins;
135  vector<double> muonEtaBins;
136  vector<double> muonPhiBins;
137  vector<double> dimuonPtBins;
138  vector<double> dimuonEtaBins;
139  vector<double> dimuonDRBins;
140  map<TString, MonitorElement *> ME;
141  vector<pair<string, int> > filterNamesLevels;
142  const double muonMass;
143 };
144 
146  : //get parameters
147  dqmFolder(pset.getUntrackedParameter<string>("DQMFolder")),
148  triggerProcessName(pset.getUntrackedParameter<string>("TriggerProcessName")),
149  triggerPathName(pset.getUntrackedParameter<string>("TriggerPathName")),
150  motherIDs(pset.getUntrackedParameter<vector<int> >("MotherIDs")),
151  genGlobDeltaRMatchingCut(pset.getUntrackedParameter<double>("GenGlobDeltaRMatchingCut")),
152  globL1DeltaRMatchingCut(pset.getUntrackedParameter<double>("GlobL1DeltaRMatchingCut")),
153  globL2DeltaRMatchingCut(pset.getUntrackedParameter<double>("GlobL2DeltaRMatchingCut")),
154  globL3DeltaRMatchingCut(pset.getUntrackedParameter<double>("GlobL3DeltaRMatchingCut")),
155  deltaEtaBins(pset.getUntrackedParameter<vector<double> >("DeltaEtaBins")),
156  deltaPhiBins(pset.getUntrackedParameter<vector<double> >("DeltaPhiBins")),
157  muonPtBins(pset.getUntrackedParameter<vector<double> >("MuonPtBins")),
158  muonEtaBins(pset.getUntrackedParameter<vector<double> >("MuonEtaBins")),
159  muonPhiBins(pset.getUntrackedParameter<vector<double> >("MuonPhiBins")),
160  dimuonPtBins(pset.getUntrackedParameter<vector<double> >("DimuonPtBins")),
161  dimuonEtaBins(pset.getUntrackedParameter<vector<double> >("DimuonEtaBins")),
162  dimuonDRBins(pset.getUntrackedParameter<vector<double> >("DimuonDRBins")),
163  muonMass(0.106) {
164  triggerSummaryRAWTag = consumes<TriggerEventWithRefs>(
165  InputTag(pset.getUntrackedParameter<string>("TriggerSummaryRAW"), "", triggerProcessName));
167  consumes<TriggerEvent>(InputTag(pset.getUntrackedParameter<string>("TriggerSummaryAOD"), "", triggerProcessName));
168  triggerResultsTag = InputTag(pset.getUntrackedParameter<string>("TriggerResults"), "", triggerProcessName);
169  triggerResultsToken = consumes<TriggerResults>(triggerResultsTag);
170  recoMuonsTag = pset.getParameter<InputTag>("RecoMuons");
171  recoMuonsToken = consumes<MuonCollection>(recoMuonsTag);
172  genParticlesTag = pset.getParameter<InputTag>("GenParticles");
173  genParticlesToken = consumes<GenParticleCollection>(genParticlesTag);
174 }
175 
177  //discover HLT configuration
179  bool isChanged;
180  if (hltConfig.init(iRun, iSetup, triggerProcessName, isChanged)) {
181  LogDebug("HLTriggerOfflineHeavyFlavor")
182  << "Successfully initialized HLTConfigProvider with process name: " << triggerProcessName << endl;
183  } else {
184  LogWarning("HLTriggerOfflineHeavyFlavor")
185  << "Could not initialize HLTConfigProvider with process name: " << triggerProcessName << endl;
186  return;
187  }
188  vector<string> triggerNames = hltConfig.triggerNames();
189  for (const auto &trigName : triggerNames) {
190  // TString triggerName = trigName;
191  if (trigName.find(triggerPathName) != std::string::npos) {
192  vector<string> moduleNames = hltConfig.moduleLabels(trigName);
193  for (const auto &moduleName : moduleNames) {
195  if (level > 0) {
196  filterNamesLevels.push_back({moduleName, level});
197  }
198  }
199  break;
200  }
201  }
202 
203  if (filterNamesLevels.empty()) {
204  LogDebug("HLTriggerOfflineHeavyFlavor") << "Bad Trigger Path: " << triggerPathName << endl;
205  return;
206  } else {
208  str.reserve(
209  512); // avoid too many realloctions in the following loop (allows for filter names with roughly 100 chars each)
210  for (const auto &filters : filterNamesLevels)
211  str = str + " " + filters.first;
212  LogDebug("HLTriggerOfflineHeavyFlavor") << "Trigger Path: " << triggerPathName << " has filters:" << str;
213  }
214 }
215 
217  edm::Run const &iRun,
218  edm::EventSetup const &iSetup) {
219  ibooker.cd();
221 
222  // create Monitor Elements
223  // Eta Pt Single
224  myBook2D(ibooker, "genMuon_genEtaPt", muonEtaBins, "#mu eta", muonPtBins, " #mu pT (GeV)");
225  myBook2D(ibooker, "globMuon_genEtaPt", muonEtaBins, "#mu eta", muonPtBins, " #mu pT (GeV)");
226  myBook2D(ibooker, "globMuon_recoEtaPt", muonEtaBins, "#mu eta", muonPtBins, " #mu pT (GeV)");
227 
228  for (size_t i = 0; i < filterNamesLevels.size(); i++) {
229  myBook2D(ibooker,
230  TString::Format("filt%dMuon_recoEtaPt", int(i + 1)),
231  muonEtaBins,
232  "#mu eta",
233  muonPtBins,
234  " #mu pT (GeV)",
236  }
237  myBook2D(ibooker, "pathMuon_recoEtaPt", muonEtaBins, "#mu eta", muonPtBins, " #mu pT (GeV)", triggerPathName);
238  myBook2D(ibooker, "resultMuon_recoEtaPt", muonEtaBins, "#mu eta", muonPtBins, " #mu pT (GeV)");
239  // Eta Pt Single Resolution
240  myBookProfile2D(ibooker, "resGlobGen_genEtaPt", muonEtaBins, "#mu eta", muonPtBins, " #mu pT (GeV)");
241  for (size_t i = 0; i < filterNamesLevels.size(); i++) {
242  myBookProfile2D(ibooker,
243  TString::Format("resFilt%dGlob_recoEtaPt", int(i + 1)),
244  muonEtaBins,
245  "#mu eta",
246  muonPtBins,
247  " #mu pT (GeV)",
249  }
251  ibooker, "resPathGlob_recoEtaPt", muonEtaBins, "#mu eta", muonPtBins, " #mu pT (GeV)", triggerPathName);
252  // Eta Pt Double
253  myBook2D(ibooker, "genDimuon_genEtaPt", dimuonEtaBins, "#mu#mu eta", dimuonPtBins, " #mu#mu pT (GeV)");
254  myBook2D(ibooker, "globDimuon_genEtaPt", dimuonEtaBins, "#mu#mu eta", dimuonPtBins, " #mu#mu pT (GeV)");
255  myBook2D(ibooker, "globDimuon_recoEtaPt", dimuonEtaBins, "#mu#mu eta", dimuonPtBins, " #mu#mu pT (GeV)");
256  for (size_t i = 0; i < filterNamesLevels.size(); i++) {
257  myBook2D(ibooker,
258  TString::Format("filt%dDimuon_recoEtaPt", int(i + 1)),
260  "#mu#mu eta",
261  dimuonPtBins,
262  " #mu#mu pT (GeV)",
264  }
265  myBook2D(
266  ibooker, "pathDimuon_recoEtaPt", dimuonEtaBins, "#mu#mu eta", dimuonPtBins, " #mu#mu pT (GeV)", triggerPathName);
267  myBook2D(ibooker, "resultDimuon_recoEtaPt", dimuonEtaBins, "#mu#mu eta", dimuonPtBins, " #mu#mu pT (GeV)");
268  for (size_t i = 0; i < filterNamesLevels.size(); i++) {
269  myBook2D(ibooker,
270  TString::Format("diFilt%dDimuon_recoEtaPt", int(i + 1)),
272  "#mu#mu eta",
273  dimuonPtBins,
274  " #mu#mu pT (GeV)",
276  }
277  myBook2D(
278  ibooker, "diPathDimuon_recoEtaPt", dimuonEtaBins, "#mu#mu eta", dimuonPtBins, " #mu#mu pT (GeV)", triggerPathName);
279  // Eta Phi Single
280  myBook2D(ibooker, "genMuon_genEtaPhi", muonEtaBins, "#mu eta", muonPhiBins, "#mu phi");
281  myBook2D(ibooker, "globMuon_genEtaPhi", muonEtaBins, "#mu eta", muonPhiBins, "#mu phi");
282  myBook2D(ibooker, "globMuon_recoEtaPhi", muonEtaBins, "#mu eta", muonPhiBins, "#mu phi");
283  for (size_t i = 0; i < filterNamesLevels.size(); i++) {
284  myBook2D(ibooker,
285  TString::Format("filt%dMuon_recoEtaPhi", int(i + 1)),
286  muonEtaBins,
287  "#mu eta",
288  muonPhiBins,
289  "#mu phi",
291  }
292  myBook2D(ibooker, "pathMuon_recoEtaPhi", muonEtaBins, "#mu eta", muonPhiBins, "#mu phi", triggerPathName);
293  myBook2D(ibooker, "resultMuon_recoEtaPhi", muonEtaBins, "#mu eta", muonPhiBins, "#mu phi");
294  // Rap Pt Double
295  myBook2D(ibooker, "genDimuon_genRapPt", dimuonEtaBins, "#mu#mu rapidity", dimuonPtBins, " #mu#mu pT (GeV)");
296  myBook2D(ibooker, "globDimuon_genRapPt", dimuonEtaBins, "#mu#mu rapidity", dimuonPtBins, " #mu#mu pT (GeV)");
297  myBook2D(ibooker, "globDimuon_recoRapPt", dimuonEtaBins, "#mu#mu rapidity", dimuonPtBins, " #mu#mu pT (GeV)");
298  for (size_t i = 0; i < filterNamesLevels.size(); i++) {
299  myBook2D(ibooker,
300  TString::Format("filt%dDimuon_recoRapPt", int(i + 1)),
302  "#mu#mu rapidity",
303  dimuonPtBins,
304  " #mu#mu pT (GeV)",
306  }
307  myBook2D(ibooker,
308  "pathDimuon_recoRapPt",
310  "#mu#mu rapidity",
311  dimuonPtBins,
312  " #mu#mu pT (GeV)",
314  myBook2D(ibooker, "resultDimuon_recoRapPt", dimuonEtaBins, "#mu#mu rapidity", dimuonPtBins, " #mu#mu pT (GeV)");
315  for (size_t i = 0; i < filterNamesLevels.size(); i++) {
316  myBook2D(ibooker,
317  TString::Format("diFilt%dDimuon_recoRapPt", int(i + 1)),
319  "#mu#mu rapidity",
320  dimuonPtBins,
321  " #mu#mu pT (GeV)",
323  }
324  myBook2D(ibooker,
325  "diPathDimuon_recoRapPt",
327  "#mu#mu rapidity",
328  dimuonPtBins,
329  " #mu#mu pT (GeV)",
331  // Pt DR Double
332  myBook2D(ibooker, "genDimuon_genPtDR", dimuonPtBins, " #mu#mu pT (GeV)", dimuonDRBins, "#mu#mu #Delta R at IP");
333  myBook2D(ibooker, "globDimuon_genPtDR", dimuonPtBins, " #mu#mu pT (GeV)", dimuonDRBins, "#mu#mu #Delta R at IP");
334  myBook2D(ibooker, "globDimuon_recoPtDR", dimuonPtBins, " #mu#mu pT (GeV)", dimuonDRBins, "#mu#mu #Delta R at IP");
335  for (size_t i = 0; i < filterNamesLevels.size(); i++) {
336  myBook2D(ibooker,
337  TString::Format("filt%dDimuon_recoPtDR", int(i + 1)),
338  dimuonPtBins,
339  " #mu#mu pT (GeV)",
340  dimuonDRBins,
341  "#mu#mu #Delta R at IP",
343  }
344  myBook2D(ibooker,
345  "pathDimuon_recoPtDR",
346  dimuonPtBins,
347  " #mu#mu pT (GeV)",
348  dimuonDRBins,
349  "#mu#mu #Delta R at IP",
351  for (size_t i = 0; i < filterNamesLevels.size(); i++) {
352  myBook2D(ibooker,
353  TString::Format("diFilt%dDimuon_recoPtDR", int(i + 1)),
354  dimuonPtBins,
355  " #mu#mu pT (GeV)",
356  dimuonDRBins,
357  "#mu#mu #Delta R at IP",
359  }
360  myBook2D(ibooker,
361  "diPathDimuon_recoPtDR",
362  dimuonPtBins,
363  " #mu#mu pT (GeV)",
364  dimuonDRBins,
365  "#mu#mu #Delta R at IP",
367  myBook2D(ibooker, "resultDimuon_recoPtDR", dimuonPtBins, " #mu#mu pT (GeV)", dimuonDRBins, "#mu#mu #Delta R at IP");
368  // Pt DRpos Double
369  myBook2D(ibooker, "globDimuon_recoPtDRpos", dimuonPtBins, " #mu#mu pT (GeV)", dimuonDRBins, "#mu#mu #Delta R in MS");
370  for (size_t i = 0; i < filterNamesLevels.size(); i++) {
371  myBook2D(ibooker,
372  TString::Format("filt%dDimuon_recoPtDRpos", int(i + 1)),
373  dimuonPtBins,
374  " #mu#mu pT (GeV)",
375  dimuonDRBins,
376  "#mu#mu #Delta R in MS",
378  }
379  myBook2D(ibooker,
380  "pathDimuon_recoPtDRpos",
381  dimuonPtBins,
382  " #mu#mu pT (GeV)",
383  dimuonDRBins,
384  "#mu#mu #Delta R in MS",
386  for (size_t i = 0; i < filterNamesLevels.size(); i++) {
387  myBook2D(ibooker,
388  TString::Format("diFilt%dDimuon_recoPtDRpos", int(i + 1)),
389  dimuonPtBins,
390  " #mu#mu pT (GeV)",
391  dimuonDRBins,
392  "#mu#mu #Delta R in MS",
394  }
395  myBook2D(ibooker,
396  "diPathDimuon_recoPtDRpos",
397  dimuonPtBins,
398  " #mu#mu pT (GeV)",
399  dimuonDRBins,
400  "#mu#mu #Delta R in MS",
402  myBook2D(
403  ibooker, "resultDimuon_recoPtDRpos", dimuonPtBins, " #mu#mu pT (GeV)", dimuonDRBins, "#mu#mu #Delta R in MS");
404 
405  // Matching
406  myBook2D(ibooker, "globGen_deltaEtaDeltaPhi", deltaEtaBins, "#Delta eta", deltaPhiBins, "#Delta phi");
407  for (size_t i = 0; i < filterNamesLevels.size(); i++) {
408  myBook2D(ibooker,
409  TString::Format("filt%dGlob_deltaEtaDeltaPhi", int(i + 1)),
410  deltaEtaBins,
411  "#Delta eta",
412  deltaPhiBins,
413  "#Delta phi",
415  }
416  myBook2D(
417  ibooker, "pathGlob_deltaEtaDeltaPhi", deltaEtaBins, "#Delta eta", deltaPhiBins, "#Delta phi", triggerPathName);
418  // Size of containers
419  vector<double> sizeBins;
420  sizeBins.push_back(10);
421  sizeBins.push_back(0);
422  sizeBins.push_back(10);
423  myBook1D(ibooker, "genMuon_size", sizeBins, "container size");
424  myBook1D(ibooker, "globMuon_size", sizeBins, "container size");
425  for (size_t i = 0; i < filterNamesLevels.size(); i++) {
426  myBook1D(
427  ibooker, TString::Format("filt%dMuon_size", int(i + 1)), sizeBins, "container size", filterNamesLevels[i].first);
428  }
429  myBook1D(ibooker, "pathMuon_size", sizeBins, "container size", triggerPathName);
430 }
431 
433  if (filterNamesLevels.empty()) {
434  return;
435  }
436  //access the containers and create LeafCandidate copies
437  vector<LeafCandidate> genMuons;
440  if (genParticles.isValid()) {
441  for (GenParticleCollection::const_iterator p = genParticles->begin(); p != genParticles->end(); ++p) {
442  if (p->status() == 1 && std::abs(p->pdgId()) == 13 &&
443  (find(motherIDs.begin(), motherIDs.end(), -1) != motherIDs.end() ||
444  find(motherIDs.begin(), motherIDs.end(), getMotherId(&(*p))) != motherIDs.end())) {
445  genMuons.push_back(*p);
446  }
447  }
448  } else {
449  LogDebug("HLTriggerOfflineHeavyFlavor") << "Could not access GenParticleCollection" << endl;
450  }
452  ME["genMuon_size"]->Fill(genMuons.size());
453  LogDebug("HLTriggerOfflineHeavyFlavor")
454  << "GenParticleCollection from " << genParticlesTag << " has size: " << genMuons.size() << endl;
455 
456  vector<LeafCandidate> globMuons;
457  vector<LeafCandidate> globMuons_position;
458  Handle<MuonCollection> recoMuonsHandle;
459  iEvent.getByToken(recoMuonsToken, recoMuonsHandle);
460  if (recoMuonsHandle.isValid()) {
461  for (MuonCollection::const_iterator p = recoMuonsHandle->begin(); p != recoMuonsHandle->end(); ++p) {
462  if (p->isGlobalMuon()) {
463  globMuons.push_back(*p);
464  globMuons_position.push_back(LeafCandidate(p->charge(),
465  math::XYZTLorentzVector(p->outerTrack()->innerPosition().x(),
466  p->outerTrack()->innerPosition().y(),
467  p->outerTrack()->innerPosition().z(),
468  0.)));
469  }
470  }
471  } else {
472  LogDebug("HLTriggerOfflineHeavyFlavor") << "Could not access reco Muons" << endl;
473  }
474  ME["globMuon_size"]->Fill(globMuons.size());
475  LogDebug("HLTriggerOfflineHeavyFlavor")
476  << "Global Muons from " << recoMuonsTag << " has size: " << globMuons.size() << endl;
477 
478  // access RAW trigger event
479  vector<vector<LeafCandidate> > muonsAtFilter;
480  vector<vector<LeafCandidate> > muonPositionsAtFilter;
481  for (size_t i = 0; i < filterNamesLevels.size(); i++) {
482  muonsAtFilter.push_back(vector<LeafCandidate>());
483  muonPositionsAtFilter.push_back(vector<LeafCandidate>());
484  }
485  Handle<TriggerEventWithRefs> rawTriggerEvent;
486  iEvent.getByToken(triggerSummaryRAWTag, rawTriggerEvent);
487  if (rawTriggerEvent.isValid()) {
488  for (size_t i = 0; i < filterNamesLevels.size(); i++) {
489  size_t index = rawTriggerEvent->filterIndex(InputTag(filterNamesLevels[i].first, "", triggerProcessName));
490  if (index < rawTriggerEvent->size()) {
491  if (filterNamesLevels[i].second == 1) {
492  vector<L1MuonParticleRef> l1Cands;
493  rawTriggerEvent->getObjects(index, TriggerL1Mu, l1Cands);
494  for (size_t j = 0; j < l1Cands.size(); j++) {
495  muonsAtFilter[i].push_back(*l1Cands[j]);
496  }
497  } else {
498  vector<RecoChargedCandidateRef> hltCands;
499  rawTriggerEvent->getObjects(index, TriggerMuon, hltCands);
500  for (size_t j = 0; j < hltCands.size(); j++) {
501  muonsAtFilter[i].push_back(*hltCands[j]);
502  if (filterNamesLevels[i].second == 2) {
503  muonPositionsAtFilter[i].push_back(
504  LeafCandidate(hltCands[j]->charge(),
505  math::XYZTLorentzVector(hltCands[j]->track()->innerPosition().x(),
506  hltCands[j]->track()->innerPosition().y(),
507  hltCands[j]->track()->innerPosition().z(),
508  0.)));
509  }
510  }
511  }
512  }
513  ME[TString::Format("filt%dMuon_size", int(i + 1))]->Fill(muonsAtFilter[i].size());
514  LogDebug("HLTriggerOfflineHeavyFlavor")
515  << "Filter \"" << filterNamesLevels[i].first << "\" has " << muonsAtFilter[i].size() << " muons" << endl;
516  }
517  } else {
518  LogDebug("HLTriggerOfflineHeavyFlavor") << "Could not access RAWTriggerEvent" << endl;
519  }
520 
521  // access AOD trigger event
522  vector<LeafCandidate> pathMuons;
523  Handle<TriggerEvent> aodTriggerEvent;
524  iEvent.getByToken(triggerSummaryAODTag, aodTriggerEvent);
525  if (aodTriggerEvent.isValid()) {
526  TriggerObjectCollection allObjects = aodTriggerEvent->getObjects();
527  for (int i = 0; i < aodTriggerEvent->sizeFilters(); i++) {
528  if (aodTriggerEvent->filterTag(i) == InputTag((filterNamesLevels.end() - 1)->first, "", triggerProcessName)) {
529  Keys keys = aodTriggerEvent->filterKeys(i);
530  for (size_t j = 0; j < keys.size(); j++) {
531  pathMuons.push_back(LeafCandidate(
532  allObjects[keys[j]].id() > 0 ? 1 : -1,
534  allObjects[keys[j]].pt(), allObjects[keys[j]].eta(), allObjects[keys[j]].phi(), muonMass)));
535  }
536  }
537  }
538  ME["pathMuon_size"]->Fill(pathMuons.size());
539  LogDebug("HLTriggerOfflineHeavyFlavor")
540  << "Path \"" << triggerPathName << "\" has " << pathMuons.size() << " muons at last filter \""
541  << (filterNamesLevels.end() - 1)->first << "\"" << endl;
542  } else {
543  LogDebug("HLTriggerOfflineHeavyFlavor") << "Could not access AODTriggerEvent" << endl;
544  }
545 
546  // access Trigger Results
547  bool triggerFired = false;
550  if (triggerResults.isValid()) {
551  LogDebug("HLTriggerOfflineHeavyFlavor") << "Successfully initialized " << triggerResultsTag << endl;
552  const edm::TriggerNames &triggerNames = iEvent.triggerNames(*triggerResults);
553  bool hlt_exists = false;
554  for (unsigned int i = 0; i != triggerNames.size(); i++) {
555  TString hlt_name = triggerNames.triggerName(i);
556  if (hlt_name.Contains(triggerPathName)) {
557  triggerFired = triggerResults->accept(i);
558  hlt_exists = true;
559  break;
560  }
561  }
562  if (!hlt_exists) {
563  LogDebug("HLTriggerOfflineHeavyFlavor") << triggerResultsTag << " has no trigger: " << triggerPathName << endl;
564  }
565  } else {
566  LogDebug("HLTriggerOfflineHeavyFlavor") << "Could not initialize " << triggerResultsTag << endl;
567  }
568 
569  //create matching maps
570  vector<int> glob_gen(genMuons.size(), -1);
571  match(ME["globGen_deltaEtaDeltaPhi"], genMuons, globMuons, genGlobDeltaRMatchingCut, glob_gen);
572  vector<vector<int> > filt_glob;
573  for (size_t i = 0; i < filterNamesLevels.size(); i++) {
574  filt_glob.push_back(vector<int>(globMuons.size(), -1));
575  if (filterNamesLevels[i].second == 1) {
576  match(ME[TString::Format("filt%dGlob_deltaEtaDeltaPhi", int(i + 1))],
577  globMuons_position,
578  muonsAtFilter[i],
580  filt_glob[i]);
581  } else if (filterNamesLevels[i].second == 2) {
582  match(ME[TString::Format("filt%dGlob_deltaEtaDeltaPhi", int(i + 1))],
583  globMuons_position,
584  muonPositionsAtFilter[i],
586  filt_glob[i]);
587  } else if (filterNamesLevels[i].second > 2) {
588  match(ME[TString::Format("filt%dGlob_deltaEtaDeltaPhi", int(i + 1))],
589  globMuons,
590  muonsAtFilter[i],
592  filt_glob[i]);
593  }
594  }
595  vector<int> path_glob(globMuons.size(), -1);
596  if ((filterNamesLevels.end() - 1)->second == 1) {
597  match(ME["pathGlob_deltaEtaDeltaPhi"], globMuons_position, pathMuons, globL1DeltaRMatchingCut, path_glob);
598  } else if ((filterNamesLevels.end() - 1)->second == 2) {
599  match(ME["pathGlob_deltaEtaDeltaPhi"], globMuons, pathMuons, globL2DeltaRMatchingCut, path_glob);
600  } else if ((filterNamesLevels.end() - 1)->second > 2) {
601  match(ME["pathGlob_deltaEtaDeltaPhi"], globMuons, pathMuons, globL3DeltaRMatchingCut, path_glob);
602  }
603 
604  //fill histos
605  bool first = true;
606  for (size_t i = 0; i < genMuons.size(); i++) {
607  ME["genMuon_genEtaPt"]->Fill(genMuons[i].eta(), genMuons[i].pt());
608  ME["genMuon_genEtaPhi"]->Fill(genMuons[i].eta(), genMuons[i].phi());
609  if (glob_gen[i] != -1) {
610  ME["resGlobGen_genEtaPt"]->Fill(
611  genMuons[i].eta(), genMuons[i].pt(), (globMuons[glob_gen[i]].pt() - genMuons[i].pt()) / genMuons[i].pt());
612  ME["globMuon_genEtaPt"]->Fill(genMuons[i].eta(), genMuons[i].pt());
613  ME["globMuon_genEtaPhi"]->Fill(genMuons[i].eta(), genMuons[i].phi());
614  ME["globMuon_recoEtaPt"]->Fill(globMuons[glob_gen[i]].eta(), globMuons[glob_gen[i]].pt());
615  ME["globMuon_recoEtaPhi"]->Fill(globMuons[glob_gen[i]].eta(), globMuons[glob_gen[i]].phi());
616  for (size_t f = 0; f < filterNamesLevels.size(); f++) {
617  if (filt_glob[f][glob_gen[i]] != -1) {
618  ME[TString::Format("resFilt%dGlob_recoEtaPt", int(f + 1))]->Fill(
619  globMuons[glob_gen[i]].eta(),
620  globMuons[glob_gen[i]].pt(),
621  (muonsAtFilter[f][filt_glob[f][glob_gen[i]]].pt() - globMuons[glob_gen[i]].pt()) /
622  globMuons[glob_gen[i]].pt());
623  ME[TString::Format("filt%dMuon_recoEtaPt", int(f + 1))]->Fill(globMuons[glob_gen[i]].eta(),
624  globMuons[glob_gen[i]].pt());
625  ME[TString::Format("filt%dMuon_recoEtaPhi", int(f + 1))]->Fill(globMuons[glob_gen[i]].eta(),
626  globMuons[glob_gen[i]].phi());
627  } else {
628  break;
629  }
630  }
631  if (path_glob[glob_gen[i]] != -1) {
632  ME["resPathGlob_recoEtaPt"]->Fill(
633  globMuons[glob_gen[i]].eta(),
634  globMuons[glob_gen[i]].pt(),
635  (pathMuons[path_glob[glob_gen[i]]].pt() - globMuons[glob_gen[i]].pt()) / globMuons[glob_gen[i]].pt());
636  ME["pathMuon_recoEtaPt"]->Fill(globMuons[glob_gen[i]].eta(), globMuons[glob_gen[i]].pt());
637  ME["pathMuon_recoEtaPhi"]->Fill(globMuons[glob_gen[i]].eta(), globMuons[glob_gen[i]].phi());
638  }
639  //highest pt muon
640  if (first) {
641  first = false;
642  if (triggerFired) {
643  ME["resultMuon_recoEtaPt"]->Fill(globMuons[glob_gen[i]].eta(), globMuons[glob_gen[i]].pt());
644  ME["resultMuon_recoEtaPhi"]->Fill(globMuons[glob_gen[i]].eta(), globMuons[glob_gen[i]].phi());
645  }
646  }
647  }
648  }
649 
650  //fill dimuon histograms (highest pT, opposite charge)
651  int secondMuon = 0;
652  for (size_t j = 1; j < genMuons.size(); j++) {
653  if (genMuons[0].charge() * genMuons[j].charge() == -1) {
654  secondMuon = j;
655  break;
656  }
657  }
658  if (secondMuon > 0) {
659  //two generated
660  double genDimuonPt = (genMuons[0].p4() + genMuons[secondMuon].p4()).pt();
661  double genDimuonEta = (genMuons[0].p4() + genMuons[secondMuon].p4()).eta();
662  double genDimuonRap = (genMuons[0].p4() + genMuons[secondMuon].p4()).Rapidity();
663  double genDimuonDR = deltaR<LeafCandidate, LeafCandidate>(genMuons[0], genMuons[secondMuon]);
664  bool highPt = genMuons[0].pt() > 7. && genMuons[secondMuon].pt() > 7;
665  ME["genDimuon_genEtaPt"]->Fill(genDimuonEta, genDimuonPt);
666  ME["genDimuon_genRapPt"]->Fill(genDimuonRap, genDimuonPt);
667  if (highPt)
668  ME["genDimuon_genPtDR"]->Fill(genDimuonPt, genDimuonDR);
669  //two global
670  if (glob_gen[0] != -1 && glob_gen[secondMuon] != -1) {
671  ME["globDimuon_genEtaPt"]->Fill(genDimuonEta, genDimuonPt);
672  ME["globDimuon_genRapPt"]->Fill(genDimuonRap, genDimuonPt);
673  if (highPt)
674  ME["globDimuon_genPtDR"]->Fill(genDimuonPt, genDimuonDR);
675  double globDimuonPt = (globMuons[glob_gen[0]].p4() + globMuons[glob_gen[secondMuon]].p4()).pt();
676  double globDimuonEta = (globMuons[glob_gen[0]].p4() + globMuons[glob_gen[secondMuon]].p4()).eta();
677  double globDimuonRap = (globMuons[glob_gen[0]].p4() + globMuons[glob_gen[secondMuon]].p4()).Rapidity();
678  double globDimuonDR =
679  deltaR<LeafCandidate, LeafCandidate>(globMuons[glob_gen[0]], globMuons[glob_gen[secondMuon]]);
680  double globDimuonDRpos = deltaR<LeafCandidate, LeafCandidate>(globMuons_position[glob_gen[0]],
681  globMuons_position[glob_gen[secondMuon]]);
682  ME["globDimuon_recoEtaPt"]->Fill(globDimuonEta, globDimuonPt);
683  ME["globDimuon_recoRapPt"]->Fill(globDimuonRap, globDimuonPt);
684  if (highPt)
685  ME["globDimuon_recoPtDR"]->Fill(globDimuonPt, globDimuonDR);
686  if (highPt)
687  ME["globDimuon_recoPtDRpos"]->Fill(globDimuonPt, globDimuonDRpos);
688  //two filter objects
689  for (size_t f = 0; f < filterNamesLevels.size(); f++) {
690  if (filt_glob[f][glob_gen[0]] != -1 && filt_glob[f][glob_gen[secondMuon]] != -1) {
691  ME[TString::Format("diFilt%dDimuon_recoEtaPt", int(f + 1))]->Fill(globDimuonEta, globDimuonPt);
692  ME[TString::Format("diFilt%dDimuon_recoRapPt", int(f + 1))]->Fill(globDimuonRap, globDimuonPt);
693  if (highPt)
694  ME[TString::Format("diFilt%dDimuon_recoPtDR", int(f + 1))]->Fill(globDimuonPt, globDimuonDR);
695  if (highPt)
696  ME[TString::Format("diFilt%dDimuon_recoPtDRpos", int(f + 1))]->Fill(globDimuonPt, globDimuonDRpos);
697  } else {
698  break;
699  }
700  }
701  //one filter object
702  for (size_t f = 0; f < filterNamesLevels.size(); f++) {
703  if (filt_glob[f][glob_gen[0]] != -1 || filt_glob[f][glob_gen[secondMuon]] != -1) {
704  ME[TString::Format("filt%dDimuon_recoEtaPt", int(f + 1))]->Fill(globDimuonEta, globDimuonPt);
705  ME[TString::Format("filt%dDimuon_recoRapPt", int(f + 1))]->Fill(globDimuonRap, globDimuonPt);
706  if (highPt)
707  ME[TString::Format("filt%dDimuon_recoPtDR", int(f + 1))]->Fill(globDimuonPt, globDimuonDR);
708  if (highPt)
709  ME[TString::Format("filt%dDimuon_recoPtDRpos", int(f + 1))]->Fill(globDimuonPt, globDimuonDRpos);
710  } else {
711  break;
712  }
713  }
714  //two path objects
715  if (path_glob[glob_gen[0]] != -1 && path_glob[glob_gen[secondMuon]] != -1) {
716  ME["diPathDimuon_recoEtaPt"]->Fill(globDimuonEta, globDimuonPt);
717  ME["diPathDimuon_recoRapPt"]->Fill(globDimuonRap, globDimuonPt);
718  if (highPt)
719  ME["diPathDimuon_recoPtDR"]->Fill(globDimuonPt, globDimuonDR);
720  if (highPt)
721  ME["diPathDimuon_recoPtDRpos"]->Fill(globDimuonPt, globDimuonDRpos);
722  }
723  //one path object
724  if (path_glob[glob_gen[0]] != -1 || path_glob[glob_gen[secondMuon]] != -1) {
725  ME["pathDimuon_recoEtaPt"]->Fill(globDimuonEta, globDimuonPt);
726  ME["pathDimuon_recoRapPt"]->Fill(globDimuonRap, globDimuonPt);
727  if (highPt)
728  ME["pathDimuon_recoPtDR"]->Fill(globDimuonPt, globDimuonDR);
729  if (highPt)
730  ME["pathDimuon_recoPtDRpos"]->Fill(globDimuonPt, globDimuonDRpos);
731  }
732  //trigger result
733  if (triggerFired) {
734  ME["resultDimuon_recoEtaPt"]->Fill(globDimuonEta, globDimuonPt);
735  ME["resultDimuon_recoRapPt"]->Fill(globDimuonRap, globDimuonPt);
736  if (highPt)
737  ME["resultDimuon_recoPtDR"]->Fill(globDimuonPt, globDimuonDR);
738  if (highPt)
739  ME["resultDimuon_recoPtDRpos"]->Fill(globDimuonPt, globDimuonDRpos);
740  }
741  }
742  }
743 }
744 
746  const Candidate *mother = p->mother();
747  if (mother) {
748  if (mother->pdgId() == p->pdgId()) {
749  return getMotherId(mother);
750  } else {
751  return mother->pdgId();
752  }
753  } else {
754  return 0;
755  }
756 }
757 
759  vector<LeafCandidate> &from,
760  vector<LeafCandidate> &to,
761  double dRMatchingCut,
762  vector<int> &map) {
763  vector<double> dR(from.size());
764  for (size_t i = 0; i < from.size(); i++) {
765  map[i] = -1;
766  dR[i] = 10.;
767  //find closest
768  for (size_t j = 0; j < to.size(); j++) {
769  double dRtmp = deltaR<double>(from[i].eta(), from[i].phi(), to[j].eta(), to[j].phi());
770  if (dRtmp < dR[i]) {
771  dR[i] = dRtmp;
772  map[i] = j;
773  }
774  }
775  //fill matching histo
776  if (map[i] != -1) {
777  me->Fill(to[map[i]].eta() - from[i].eta(), deltaPhi<double>(to[map[i]].phi(), from[i].phi()));
778  }
779  //apply matching cut
780  if (dR[i] > dRMatchingCut) {
781  map[i] = -1;
782  }
783  //remove duplication
784  if (map[i] != -1) {
785  for (size_t k = 0; k < i; k++) {
786  if (map[k] != -1 && map[i] == map[k]) {
787  if (dR[i] < dR[k]) {
788  map[k] = -1;
789  } else {
790  map[i] = -1;
791  }
792  break;
793  }
794  }
795  }
796  }
797 }
798 
800  TString name,
801  vector<double> &ptBins,
802  TString ptLabel,
803  vector<double> &etaBins,
804  TString etaLabel,
805  TString title) {
806  // dqmStore->setCurrentFolder(dqmFolder+"/"+folder);
807  int ptN = ptBins.size() == 3 ? (int)ptBins[0] + 1 : ptBins.size();
808  Double_t *pt = new Double_t[ptN];
809  for (int i = 0; i < ptN; i++) {
810  pt[i] = ptBins.size() == 3 ? ptBins[1] + i * (ptBins[2] - ptBins[1]) / ptBins[0] : ptBins[i];
811  }
812  int etaN = etaBins.size() == 3 ? (int)etaBins[0] + 1 : etaBins.size();
813  Double_t *eta = new Double_t[etaN];
814  for (int i = 0; i < etaN; i++) {
815  eta[i] = etaBins.size() == 3 ? etaBins[1] + i * (etaBins[2] - etaBins[1]) / etaBins[0] : etaBins[i];
816  }
817  TH2F *h = new TH2F(name, name, ptN - 1, pt, etaN - 1, eta);
818  h->SetXTitle(ptLabel);
819  h->SetYTitle(etaLabel);
820  h->SetTitle(title);
821  ME[name] = ibooker.book2D(name.Data(), h);
822  delete h;
823 }
824 
826  TString name,
827  vector<double> &ptBins,
828  TString ptLabel,
829  vector<double> &etaBins,
830  TString etaLabel,
831  TString title) {
832  // dqmStore->setCurrentFolder(dqmFolder+"/"+folder);
833  int ptN = ptBins.size() == 3 ? (int)ptBins[0] + 1 : ptBins.size();
834  Double_t *pt = new Double_t[ptN];
835  for (int i = 0; i < ptN; i++) {
836  pt[i] = ptBins.size() == 3 ? ptBins[1] + i * (ptBins[2] - ptBins[1]) / ptBins[0] : ptBins[i];
837  }
838  int etaN = etaBins.size() == 3 ? (int)etaBins[0] + 1 : etaBins.size();
839  Double_t *eta = new Double_t[etaN];
840  for (int i = 0; i < etaN; i++) {
841  eta[i] = etaBins.size() == 3 ? etaBins[1] + i * (etaBins[2] - etaBins[1]) / etaBins[0] : etaBins[i];
842  }
843  TProfile2D *h = new TProfile2D(name, name, ptN - 1, pt, etaN - 1, eta);
844  h->SetXTitle(ptLabel);
845  h->SetYTitle(etaLabel);
846  h->SetTitle(title);
847  ME[name] = ibooker.bookProfile2D(name.Data(), h);
848  delete h;
849 }
850 
852  DQMStore::IBooker &ibooker, TString name, vector<double> &bins, TString label, TString title) {
853  // dqmStore->setCurrentFolder(dqmFolder+"/"+folder);
854  int binsN = bins.size() == 3 ? (int)bins[0] + 1 : bins.size();
855  Double_t *myBins = new Double_t[binsN];
856  for (int i = 0; i < binsN; i++) {
857  myBins[i] = bins.size() == 3 ? bins[1] + i * (bins[2] - bins[1]) / bins[0] : bins[i];
858  }
859  TH1F *h = new TH1F(name, name, binsN - 1, myBins);
860  h->SetXTitle(label);
861  h->SetTitle(title);
862  ME[name] = ibooker.book1D(name.Data(), h);
863  delete h;
864 }
865 
867  // helper lambda to check if a string contains a substring
868  const auto contains = [](const std::string &s, const std::string &sub) -> bool {
869  return s.find(sub) != std::string::npos;
870  };
871 
872  // helper lambda to check if a string contains any of a list of substrings
873  const auto containsAny = [](const std::string &s, const std::vector<std::string> &subs) -> bool {
874  for (const auto &sub : subs) {
875  if (s.find(sub) != std::string::npos)
876  return true;
877  }
878  return false;
879  };
880 
881  // helper lambda to check if string s is any of the strings in vector ms
882  const auto isAnyOf = [](const std::string &s, const std::vector<std::string> &ms) -> bool {
883  for (const auto &m : ms) {
884  if (s == m)
885  return true;
886  }
887  return false;
888  };
889 
890  // tmadlener, 20.08.2017:
891  // define the valid module names for the different "levels", to add a little bit more stability
892  // to the checking compared to just doing some name matching.
893  // Note, that the name matching is not completely remved, since at level 4 and 5 some of the
894  // valid modules are the same, so that the name matching is still needed.
895  // With the current definition this yields the exact same levels as before, but weeds out some
896  // of the "false" positives at level 3 (naming matches also to some HLTMuonL1TFilter modules due to
897  // the 'forIterL3' in the name)
898  const std::string l1Filter = "HLTMuonL1TFilter";
899  const std::string l2Filter = "HLTMuonL2FromL1TPreFilter";
900  const std::vector<std::string> l3Filters = {"HLTMuonDimuonL3Filter", "HLTMuonL3PreFilter"};
901  const std::vector<std::string> l4Filters = {
902  "HLTDisplacedmumuFilter", "HLTDiMuonGlbTrkFilter", "HLTMuonTrackMassFilter"};
903  const std::vector<std::string> l5Filters = {"HLTmumutkFilter", "HLT2MuonMuonDZ", "HLTDisplacedmumuFilter"};
904 
905  if (contains(moduleName, "Filter") && hltConfig.moduleEDMType(moduleName) == "EDFilter") {
906  if (contains(moduleName, "L1") && !contains(moduleName, "ForIterL3") &&
907  hltConfig.moduleType(moduleName) == l1Filter) {
908  return 1;
909  }
910  if (contains(moduleName, "L2") && hltConfig.moduleType(moduleName) == l2Filter) {
911  return 2;
912  }
913  if (contains(moduleName, "L3") && isAnyOf(hltConfig.moduleType(moduleName), l3Filters)) {
914  return 3;
915  }
916  if (containsAny(moduleName, {"DisplacedmumuFilter", "DiMuon", "MuonL3Filtered", "TrackMassFiltered"}) &&
917  isAnyOf(hltConfig.moduleType(moduleName), l4Filters)) {
918  return 4;
919  }
920  if (containsAny(moduleName, {"Vertex", "Dz"}) && isAnyOf(hltConfig.moduleType(moduleName), l5Filters)) {
921  return 5;
922  }
923  }
924 
925  return -1;
926 }
927 
929 
930 //define this as a plug-in
size
Write out results.
const Keys & filterKeys(trigger::size_type index) const
Definition: TriggerEvent.h:118
MonitorElement * bookProfile2D(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, double lowZ, double highZ, char const *option="s", FUNC onbooking=NOOP())
Definition: DQMStore.h:476
bool contains(EventRange const &lh, EventID const &rh)
Definition: EventRange.cc:37
void myBook2D(DQMStore::IBooker &ibooker, TString name, vector< double > &xBins, TString xLabel, vector< double > &yBins, TString yLabel, TString title)
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:32
void analyze(const edm::Event &, const edm::EventSetup &) override
enum start value shifted to 81 so as to avoid clashes with PDG codes
void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
trigger::size_type sizeFilters() const
Definition: TriggerEvent.h:146
void dqmBeginRun(const edm::Run &, const edm::EventSetup &) override
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
const edm::InputTag filterTag(trigger::size_type index) const
Definition: TriggerEvent.h:108
std::vector< TPRegexp > filters
Definition: eve_filter.cc:22
int getFilterLevel(const std::string &moduleName, const HLTConfigProvider &hltConfig)
example_stream void analyze(const edm::Event &, const edm::EventSetup &) override
EDGetTokenT< TriggerEvent > triggerSummaryAODTag
example_stream void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override
U second(std::pair< T, U > const &p)
PtEtaPhiMLorentzVectorD PtEtaPhiMLorentzVector
Lorentz vector with cartesian internal representation.
Definition: LorentzVector.h:25
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
Definition: ME.h:11
void myBookProfile2D(DQMStore::IBooker &ibooker, TString name, vector< double > &xBins, TString xLabel, vector< double > &yBins, TString yLabel, TString title)
char const * label
int getMotherId(const Candidate *p)
int iEvent
Definition: GenABIO.cc:224
size_type filterIndex(const edm::InputTag &filterTag) const
index from tag
void match(MonitorElement *me, vector< LeafCandidate > &from, vector< LeafCandidate > &to, double deltaRMatchingCut, vector< int > &map)
EDGetTokenT< TriggerEventWithRefs > triggerSummaryRAWTag
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
const TriggerObjectCollection & getObjects() const
Definition: TriggerEvent.h:101
double f[11][100]
void myBook1D(DQMStore::IBooker &ibooker, TString name, vector< double > &xBins, TString label, TString title)
static std::string const triggerResults
Definition: EdmProvDump.cc:44
HeavyFlavorValidation(const edm::ParameterSet &)
virtual int pdgId() const =0
PDG identifier.
std::vector< TriggerObject > TriggerObjectCollection
collection of trigger physics objects (e.g., all isolated muons)
Definition: TriggerObject.h:75
void myBook2D(DQMStore::IBooker &ibooker, TString name, vector< double > &xBins, TString xLabel, vector< double > &yBins, TString yLabel)
EDGetTokenT< MuonCollection > recoMuonsToken
std::vector< size_type > Keys
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
EDGetTokenT< GenParticleCollection > genParticlesToken
fixed size matrix
HLT enums.
void myBookProfile2D(DQMStore::IBooker &ibooker, TString name, vector< double > &xBins, TString xLabel, vector< double > &yBins, TString yLabel)
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
void myBook1D(DQMStore::IBooker &ibooker, TString name, vector< double > &xBins, TString label)
EDGetTokenT< TriggerResults > triggerResultsToken
Log< level::Warning, false > LogWarning
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
map< TString, MonitorElement * > ME
vector< pair< string, int > > filterNamesLevels
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
#define str(s)
Definition: Run.h:45
void getObjects(size_type filter, Vids &ids, VRphoton &photons) const
extract Ref<C>s for a specific filter and of specific physics type
#define LogDebug(id)