ATLAS Offline Software
Calculator.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // contact: jmaurer@cern.ch
6 
8 
9 #include <iterator>
10 #include <random>
11 
15 
16 using namespace TrigGlobEffCorr;
17 using std::placeholders::_1;
18 using std::placeholders::_2;
19 using std::placeholders::_3;
20 using std::placeholders::_4;
21 
23  unsigned nPeriodsToReserve)
24  : asg::AsgMessaging(&parent), m_parent(&parent) {
25  msg().setLevel(parent.msg().level());
26  m_periods.reserve(nPeriodsToReserve);
27 }
28 
30  const std::pair<unsigned, unsigned>& boundaries,
31  const std::string& combination, bool useToys,
32  std::size_t& uniqueElectronLeg,
33  std::size_t& uniquePhotonLeg) {
34  bool success = true;
35  m_parent = data.getParent();
36 
37  auto triggers = data.parseTriggerString(combination, success);
38  if (!success)
39  return false;
40  if (!triggers.size()) {
41  ATH_MSG_ERROR("The trigger combination is empty!");
42  return false;
43  }
44 
45  if (!findUniqueLeg(xAOD::Type::Electron, uniqueElectronLeg, triggers))
46  return false;
47  if (!findUniqueLeg(xAOD::Type::Photon, uniquePhotonLeg, triggers))
48  return false;
49 
53  if (helper.duplicates()) {
54  ATH_MSG_ERROR("The following combination of triggers contains duplicates: "
55  << combination);
56  return false;
57  }
58  if (!useToys) {
59  success = helper.findAndBindFunction();
60  if (!helper.m_formula) {
62  "This trigger combination is currently not supported with an "
63  "explicit formula (you may use toys instead, slower): "
64  << combination);
65  return false;
66  }
67  } else {
68  helper.m_formula = std::bind(&Calculator::globalEfficiency_Toys, ::_1, ::_2,
69  ::_3, triggers, ::_4);
70  }
71  if (success) {
72  if (data.adaptTriggerListForTriggerMatching(triggers)) {
73  m_periods.emplace_back(boundaries, std::move(helper.m_formula),
74  std::move(triggers));
75  } else {
77  return false;
78  m_periods.emplace_back(boundaries, std::move(helper.m_formula));
79  }
80  } else {
82  "Unspecified error occurred while trying to find the formula for the "
83  "trigger combination "
84  << combination);
85  }
86  return success;
87 }
88 
90  std::size_t& uniqueLeg,
91  const std::vector<TrigDef>& defs) {
92  if (uniqueLeg)
93  return true;
94  for (auto& def : defs) {
96  TriggerProperties tp(def);
97  for (auto itr = tp.cbegin(obj); itr != tp.cend(obj); ++itr) {
98  if (uniqueLeg && uniqueLeg != *itr) {
100  "The property 'ListOfLegsPerTool' needs to be filled as the "
101  "specified trigger combination involves several electron (or "
102  "photon) trigger legs");
103  return false;
104  }
105  uniqueLeg = *itr;
106  }
107  }
108  return true;
109 }
110 
112  auto period =
113  std::find_if(m_periods.cbegin(), m_periods.cend(), [=](const Period& p) {
114  return runNumber >= p.m_boundaries.first &&
115  runNumber <= p.m_boundaries.second;
116  });
117  if (period == m_periods.end()) {
118  ATH_MSG_ERROR("No trigger combination has been specified for run "
119  << runNumber);
120  return nullptr;
121  }
122  return &*period;
123 }
124 
126  const LeptonList& leptons, unsigned runNumber,
128  m_parent = &parent;
129  m_forceUnitSF = false;
130  auto period = getPeriod(runNumber);
131  if (!period)
132  return false;
133  m_cachedEfficiencies.clear();
134  bool success = period->m_formula &&
135  period->m_formula(this, leptons, runNumber, efficiencies);
136  if (m_forceUnitSF) {
137  efficiencies.data() = 1.;
138  efficiencies.mc() = 1.;
139  success = true;
140  }
141  return success;
142 }
143 
146  std::unordered_map<std::string, bool>* matched_per_trigger,
147  const LeptonList& leptons, unsigned runNumber) {
148  matched = false;
149  if(matched_per_trigger) {
150  for(auto& [key, flag] : *matched_per_trigger) flag = false;
151  }
152 
153  m_parent = &parent;
154  auto period = getPeriod(runNumber);
155  if (!period)
156  return false;
157  if (!period->m_triggers.size()) {
158  ATH_MSG_ERROR("Empty list of triggers for run number " << runNumber);
159  return false;
160  }
161  auto& trigMatchTool = m_parent->m_trigMatchTool;
162 
165  const unsigned nLep = leptons.size();
166  std::vector<flat_set<std::size_t>> validLegs(leptons.size());
167  for (unsigned i = 0; i < nLep; ++i) {
168  if (!fillListOfLegsFor(leptons[i], period->m_triggers, validLegs[i]))
169  return false;
170  }
171 
174  std::vector<flat_set<std::size_t>> firedLegs;
175  std::vector<const xAOD::IParticle*> trigLeptons;
176  const std::size_t magicWordHLT = 0xf7b8b87ef2917d66;
177 
178  for (auto& trig : period->m_triggers) {
180  auto itr = m_parent->m_dictionary.find(trig.name ^ magicWordHLT);
181  if (itr == m_parent->m_dictionary.end()) {
182  itr = m_parent->m_dictionary
183  .emplace(trig.name ^ magicWordHLT,
184  "HLT_" + m_parent->m_dictionary.at(trig.name))
185  .first;
186  }
187  const std::string& chain = itr->second;
188 
189  unsigned nLegs = 0;
190  if (trig.type & TT_SINGLELEPTON_FLAG)
191  nLegs = 1;
192  else if (trig.type & TT_DILEPTON_FLAG)
193  nLegs = 2;
194  else if (trig.type & TT_TRILEPTON_FLAG)
195  nLegs = 3;
196  else {
197  ATH_MSG_ERROR("Unsupported trigger (type = "
198  << std::hex << trig.type << std::dec << ") " << chain);
199  return false;
200  }
201  firedLegs.resize(nLegs);
202  trigLeptons.resize(nLegs);
203  for (unsigned i0 = 0; i0 < nLep; ++i0) {
204  firedLegs[0].swap(validLegs[i0]);
205  trigLeptons[0] = leptons[i0].particle();
207  if (nLegs == 1) {
208  // Check we have enough lepton(s) on trigger plateau and test the trigger matching
209  if(canTriggerBeFired(trig, firedLegs) && trigMatchTool->match(trigLeptons, chain)) {
210  matched = true;
211  if(!matched_per_trigger) return true;
212  if(matched_per_trigger->count(chain)) matched_per_trigger->at(chain) = true;
213  }
214  } else
215  for (unsigned i1 = i0 + 1; i1 < nLep; ++i1) {
216  firedLegs[1].swap(validLegs[i1]);
217  trigLeptons[1] = leptons[i1].particle();
218  if (nLegs == 2) {
219  if(canTriggerBeFired(trig, firedLegs) && trigMatchTool->match(trigLeptons, chain)) {
220  matched = true;
221  if(!matched_per_trigger) return true;
222  if(matched_per_trigger->count(chain)) matched_per_trigger->at(chain) = true;
223  }
224  } else
225  for (unsigned i2 = i1 + 1; i2 < nLep; ++i2) {
226  firedLegs[2].swap(validLegs[i2]);
227  trigLeptons[2] = leptons[i2].particle();
228  if(canTriggerBeFired(trig, firedLegs) && trigMatchTool->match(trigLeptons, chain)) {
229  matched = true;
230  if(!matched_per_trigger) return true;
231  if(matched_per_trigger->count(chain)) matched_per_trigger->at(chain) = true;
232  }
233  firedLegs[2].swap(validLegs[i2]);
234  }
235  firedLegs[1].swap(validLegs[i1]);
236  }
237  firedLegs[0].swap(
238  validLegs[i0]);
239  }
240  }
241  return true;
242 }
243 
246  std::vector<std::string>& triggers, unsigned runNumber) {
247  triggers.clear();
248  m_parent = &parent;
249  auto period = getPeriod(runNumber);
250  if (!period)
251  return false;
252  if (!period->m_triggers.size()) {
253  ATH_MSG_ERROR("Empty list of triggers for run number "
254  << runNumber
255  << " (was there a configuration issue? please check for "
256  "warnings during initialization)");
257  return false;
258  }
259  bool success = true;
260  auto notfound = parent.m_dictionary.end();
261  for (auto& trig : period->m_triggers) {
262  auto itr = parent.m_dictionary.find(trig.name);
263  if (itr == notfound) {
264  ATH_MSG_ERROR("can't retrieve name of trigger with hash "
265  << trig.name
266  << " (shouldn't happen; contact tool developers!)");
267  success = false;
268  } else
269  triggers.push_back(itr->second);
270  }
271  if (!success)
272  triggers.clear();
273  return success;
274 }
275 
277  unsigned runNumber,
278  std::size_t leg,
279  bool& success) {
280  auto insertion = m_cachedEfficiencies.emplace(std::make_pair(&lepton, leg),
281  Efficiencies());
282  Efficiencies& efficiencies = insertion.first->second;
283  if (insertion.second) {
285  switch (lepton.type()) {
288  lepton.electron(), runNumber, leg, lepton.tag(), efficiencies);
289  break;
290  case xAOD::Type::Muon:
292  lepton.tag(), efficiencies);
293  break;
294  case xAOD::Type::Photon:
296  lepton.photon(), runNumber, leg, lepton.tag(), efficiencies);
297  break;
298  default:
299  ATH_MSG_ERROR("Unsupported particle type");
300  }
301  switch (res) {
303  break;
305  m_forceUnitSF = true;
306  break;
308  [[fallthrough]];
309  default:
310  success = false;
311  efficiencies.data() = -777.;
312  efficiencies.mc() = -777.;
313  }
314  }
315  if (efficiencies.mc() == -777. && !m_forceUnitSF)
316  success = false;
317  return efficiencies;
318 }
319 
323 template <typename Trig1L>
324 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
325  const Trig1L trig,
326  Efficiencies& globalEfficiencies)
327  -> std::enable_if_t<Trig1L::is1L(), bool> {
328  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_One1L() at line "
329  << __LINE__);
330  if (!trig) {
331  globalEfficiencies = {0.};
332  return true;
333  }
334  globalEfficiencies = {1.};
335  bool success = true;
336  for (auto& lepton : leptons) {
337  if (trig.irrelevantFor(lepton) || !aboveThreshold(lepton, trig()))
338  continue;
339  auto efficiencies =
340  getCachedTriggerLegEfficiencies(lepton, runNumber, trig(), success);
341  globalEfficiencies *= ~efficiencies;
342  }
343  globalEfficiencies = ~globalEfficiencies;
344  return success;
345 }
346 
350 template <typename Trig1L_obj1, typename Trig1L_obj2>
351 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
352  const Trig1L_obj1 trig1,
353  const Trig1L_obj2 trig2,
354  Efficiencies& globalEfficiencies)
355  -> std::enable_if_t<Trig1L_obj1::is1L() && Trig1L_obj2::is1L() &&
357  bool> {
358  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_Two1L() at line "
359  << __LINE__);
360  if (!trig1)
361  return globalEfficiency(leptons, runNumber, trig2, globalEfficiencies);
362  if (!trig2)
363  return globalEfficiency(leptons, runNumber, trig1, globalEfficiencies);
364  globalEfficiencies = {1.};
365  bool success = true;
366  for (auto& lepton : leptons) {
367  std::size_t leg;
368  if (trig1.relevantFor(lepton))
369  leg = trig1();
370  else if (trig2.relevantFor(lepton))
371  leg = trig2();
372  else
373  continue;
374  if (!aboveThreshold(lepton, leg))
375  continue;
376  auto efficiencies =
377  getCachedTriggerLegEfficiencies(lepton, runNumber, leg, success);
378  globalEfficiencies *= ~efficiencies;
379  }
380  globalEfficiencies = ~globalEfficiencies;
381  return success;
382 }
383 
387 template <typename Trig1L>
388 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
389  const flat_set<Trig1L>& trigs,
390  Efficiencies& globalEfficiencies)
391  -> std::enable_if_t<Trig1L::is1L(), bool> {
392  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_Several1L() at line "
393  << __LINE__);
394  if (trigs.size() == 1)
395  return globalEfficiency(leptons, runNumber, *trigs.cbegin(),
396  globalEfficiencies);
397  if (!trigs.size()) {
398  globalEfficiencies = {0.};
399  return true;
400  }
401  globalEfficiencies = {1.};
402  bool success = true;
403  for (auto& lepton : leptons) {
404  if (Trig1L::irrelevantFor(lepton))
405  continue;
406  std::size_t loosestLeg =
407  getLoosestLegAboveThreshold(lepton, trigs, success);
408  if (loosestLeg && success) {
409  auto efficiencies = getCachedTriggerLegEfficiencies(lepton, runNumber,
410  loosestLeg, success);
411  globalEfficiencies *= ~efficiencies;
412  }
413  }
414  globalEfficiencies = ~globalEfficiencies;
415  return success;
416 }
417 
421 template <typename Trig1L_obj1, typename Trig1L_obj2>
422 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
423  const flat_set<Trig1L_obj1>& trigs1,
424  const flat_set<Trig1L_obj2>& trigs2,
425  Efficiencies& globalEfficiencies)
426  -> std::enable_if_t<Trig1L_obj1::is1L() && Trig1L_obj2::is1L() &&
428  bool> {
429  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_Several1L() at line "
430  << __LINE__);
431  if (trigs1.size() == 1 && trigs2.size() == 1) {
432  return globalEfficiency(leptons, runNumber, *trigs1.cbegin(),
433  *trigs2.cbegin(), globalEfficiencies);
434  }
435  if (!trigs1.size())
436  return globalEfficiency(leptons, runNumber, trigs2, globalEfficiencies);
437  if (!trigs2.size())
438  return globalEfficiency(leptons, runNumber, trigs1, globalEfficiencies);
439  globalEfficiencies = {1.};
440  bool success = true;
441  for (auto& lepton : leptons) {
442  std::size_t loosestLeg;
443  if (Trig1L_obj1::relevantFor(lepton))
444  loosestLeg = getLoosestLegAboveThreshold(lepton, trigs1, success);
445  else if (Trig1L_obj2::relevantFor(lepton))
446  loosestLeg = getLoosestLegAboveThreshold(lepton, trigs2, success);
447  else
448  continue;
449  if (loosestLeg && success) {
450  auto efficiencies = getCachedTriggerLegEfficiencies(lepton, runNumber,
451  loosestLeg, success);
452  globalEfficiencies *= ~efficiencies;
453  }
454  }
455  globalEfficiencies = ~globalEfficiencies;
456  return success;
457 }
458 
462 template <typename Trig2Lmix>
463 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
464  const Trig2Lmix trig,
465  Efficiencies& globalEfficiencies)
466  -> std::enable_if_t<Trig2Lmix::is2Lmix(), bool> {
467  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_One2L() at line "
468  << __LINE__);
470  bool success =
471  globalEfficiency(leptons, runNumber, trig.side1(), efficiencies[0]) &&
472  globalEfficiency(leptons, runNumber, trig.side2(), efficiencies[1]);
473  if (success)
474  globalEfficiencies = efficiencies[0] * efficiencies[1];
475  else
476  globalEfficiencies = {0.};
477  return success;
478 }
479 
483 template <typename Trig2Lsym>
484 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
485  const Trig2Lsym trig,
486  Efficiencies& globalEfficiencies)
487  -> std::enable_if_t<Trig2Lsym::is2Lsym(), bool> {
488  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_One2L() at line "
489  << __LINE__);
490  globalEfficiencies = {0.};
491  if (!trig)
492  return true;
493  Efficiencies singleInefficiencies(1.);
494  bool success = true;
495  for (auto& lepton : leptons) {
496  if (trig.irrelevantFor(lepton) || !aboveThreshold(lepton, trig()))
497  continue;
498  auto efficiencies =
499  getCachedTriggerLegEfficiencies(lepton, runNumber, trig(), success);
500  globalEfficiencies = ~efficiencies * globalEfficiencies +
501  efficiencies * ~singleInefficiencies;
502  singleInefficiencies *= ~efficiencies;
503  }
504  return success;
505 }
506 
510 template <typename Trig2Lasym>
511 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
512  const Trig2Lasym trig,
513  Efficiencies& globalEfficiencies)
514  -> std::enable_if_t<Trig2Lasym::is2Lasym(), bool> {
515  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_One2L() at line "
516  << __LINE__);
517  if (trig.symmetric())
518  return globalEfficiency(leptons, runNumber, trig.to_symmetric(),
519  globalEfficiencies);
520  globalEfficiencies = {0.};
521  if (!trig)
522  return true;
523  Efficiencies singleInefficiencies[2] = {{1.}, {1.}},
524  twoSingleInefficiencies = {1.};
525  bool success = true;
526  for (auto& lepton : leptons) {
527  if (trig.irrelevantFor(lepton))
528  continue;
529  Efficiencies efficiencies[2] = {{0.}, {0.}};
530  int loosest = 0;
531  if (aboveThreshold(lepton, trig(0))) {
532  efficiencies[0] =
533  getCachedTriggerLegEfficiencies(lepton, runNumber, trig(0), success);
534  if (aboveThreshold(lepton, trig(1))) {
535  efficiencies[1] = getCachedTriggerLegEfficiencies(lepton, runNumber,
536  trig(1), success);
537  loosest = m_parent->getLoosestLeg(lepton, trig(0), trig(1), success) ==
538  trig(1);
539  }
540  } else if (aboveThreshold(lepton, trig(1))) {
541  efficiencies[1] =
542  getCachedTriggerLegEfficiencies(lepton, runNumber, trig(1), success);
543  loosest = 1;
544  } else
545  continue;
546  const int tightest = 1 - loosest;
547  globalEfficiencies = ~efficiencies[loosest] * globalEfficiencies +
548  (efficiencies[loosest] - efficiencies[tightest]) *
549  ~singleInefficiencies[tightest] +
550  efficiencies[tightest] * ~twoSingleInefficiencies;
551  twoSingleInefficiencies *= ~efficiencies[loosest];
552  for (int i = 0; i < 2; ++i)
553  singleInefficiencies[i] *= ~efficiencies[i];
554  }
555  return success;
556 }
557 
561 template <typename Trig2Lmix, typename Trig1L_obj1, typename Trig1L_obj2>
562 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
563  const Trig2Lmix trig2Lmix,
564  const flat_set<Trig1L_obj1>& trigs1L1,
565  const flat_set<Trig1L_obj2>& trigs1L2,
566  Efficiencies& globalEfficiencies)
567  -> std::enable_if_t<Trig2Lmix::is2Lmix() && Trig1L_obj1::is1L() &&
568  Trig2Lmix::object1() == Trig1L_obj1::object() &&
569  Trig1L_obj2::is1L() &&
570  Trig2Lmix::object2() == Trig1L_obj2::object(),
571  bool> {
572  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_One2LSeveral1L() at line "
573  << __LINE__);
574  if (!(trigs1L1.size() + trigs1L2.size()))
575  return globalEfficiency(leptons, runNumber, trig2Lmix, globalEfficiencies);
576  if (trig2Lmix.hiddenBy(trigs1L1) || trig2Lmix.hiddenBy(trigs1L2))
577  return globalEfficiency(leptons, runNumber, trigs1L1, trigs1L2,
578  globalEfficiencies);
580  bool success =
581  globalEfficiency(leptons, runNumber, trigs1L1, efficiencies[0]) &&
582  globalEfficiency(leptons, runNumber, trigs1L2, efficiencies[1]) &&
583  globalEfficiency(leptons, runNumber, trig2Lmix.addTo(trigs1L1),
584  efficiencies[2]) &&
585  globalEfficiency(leptons, runNumber, trig2Lmix.addTo(trigs1L2),
586  efficiencies[3]);
587  if (success) {
588  globalEfficiencies = Efficiencies(1.) -
589  ~efficiencies[0] * ~efficiencies[1] +
590  (efficiencies[2] - efficiencies[0]) *
591  (efficiencies[3] - efficiencies[1]);
592  } else
593  globalEfficiencies = {0.};
594  return success;
595 }
596 
600 template <typename Trig2L, typename Trig1L>
601 inline auto Calculator::globalEfficiency(const LeptonList& leptons,
602  unsigned runNumber,
603  const Trig2L trig2L,
604  const Trig1L trig1L,
605  Efficiencies& globalEfficiencies)
606  -> std::enable_if_t<Trig2L::is2Lnomix() && Trig1L::is1L() &&
608  bool> {
609  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_One2LSeveral1L() at line "
610  << __LINE__);
611  return globalEfficiency(leptons, runNumber, trig2L, flat_set<Trig1L>{trig1L},
612  globalEfficiencies);
613 }
614 
618 template <typename Trig2Lsym, typename Trig1L>
619 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
620  const Trig2Lsym trig2L,
621  const flat_set<Trig1L>& trigs1L,
622  Efficiencies& globalEfficiencies)
623  -> std::enable_if_t<Trig2Lsym::is2Lsym() && Trig1L::is1L() &&
625  bool> {
626  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_One2LSeveral1L() at line "
627  << __LINE__);
628  if (!trigs1L.size())
629  return globalEfficiency(leptons, runNumber, trig2L, globalEfficiencies);
630  if (!trig2L || trig2L.hiddenBy(trigs1L))
631  return globalEfficiency(leptons, runNumber, trigs1L, globalEfficiencies);
632  globalEfficiencies = {0.};
633  Efficiencies twoSingleInefficiencies = {1.};
634  bool success = true;
635  for (auto& lepton : leptons) {
636  if (trig2L.irrelevantFor(lepton))
637  continue;
638  Efficiencies efficiencies1L(0.), efficiencies2L(0.);
639  const Efficiencies* loosestLegEfficiency;
640  std::size_t loosest1lepLeg =
641  getLoosestLegAboveThreshold(lepton, trigs1L, success);
642  if (loosest1lepLeg) {
643  efficiencies1L = getCachedTriggerLegEfficiencies(lepton, runNumber,
644  loosest1lepLeg, success);
645  if (aboveThreshold(lepton, trig2L())) {
646  efficiencies2L = getCachedTriggerLegEfficiencies(lepton, runNumber,
647  trig2L(), success);
648  loosestLegEfficiency =
649  (m_parent->getLoosestLeg(lepton, trig2L(), loosest1lepLeg,
650  success) == trig2L())
651  ? &efficiencies2L
652  : &efficiencies1L;
653  } else
654  loosestLegEfficiency = &efficiencies1L;
655  } else if (aboveThreshold(lepton, trig2L())) {
656  efficiencies2L =
657  getCachedTriggerLegEfficiencies(lepton, runNumber, trig2L(), success);
658  loosestLegEfficiency = &efficiencies2L;
659  } else
660  continue;
661  globalEfficiencies =
662  ~(*loosestLegEfficiency) * globalEfficiencies + efficiencies1L;
663  if (loosestLegEfficiency == &efficiencies2L)
664  globalEfficiencies +=
665  ~twoSingleInefficiencies * (efficiencies2L - efficiencies1L);
666  twoSingleInefficiencies *= ~(*loosestLegEfficiency);
667  }
668  return success;
669 }
670 
674 template <typename Trig2Lasym, typename Trig1L>
675 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
676  const Trig2Lasym trig2L,
677  const flat_set<Trig1L>& trigs1L,
678  Efficiencies& globalEfficiencies)
679  -> std::enable_if_t<Trig2Lasym::is2Lasym() && Trig1L::is1L() &&
681  bool> {
682  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_One2LSeveral1L() at line "
683  << __LINE__);
684  if (trig2L.symmetric())
685  return globalEfficiency(leptons, runNumber, trig2L.to_symmetric(), trigs1L,
686  globalEfficiencies);
687  if (!trigs1L.size())
688  return globalEfficiency(leptons, runNumber, trig2L, globalEfficiencies);
689  if (!trig2L || trig2L.hiddenBy(trigs1L))
690  return globalEfficiency(leptons, runNumber, trigs1L, globalEfficiencies);
691  globalEfficiencies = {0.};
692  Efficiencies twoSingleInefficiencies[2] = {{1.}, {1.}},
693  threeSingleInefficiencies = {1.};
694  bool success = true;
695  for (auto& lepton : leptons) {
696  if (trig2L.irrelevantFor(lepton))
697  continue;
698  flat_set<std::size_t> validLegs;
699  for (std::size_t leg : trig2L.legs)
700  if (aboveThreshold(lepton, leg))
701  validLegs.insert(leg);
702  Efficiencies efficiencies1L = {0.};
703  std::size_t loosest1lepLeg =
704  getLoosestLegAboveThreshold(lepton, trigs1L, success);
705  if (loosest1lepLeg) {
706  efficiencies1L = getCachedTriggerLegEfficiencies(lepton, runNumber,
707  loosest1lepLeg, success);
708  validLegs.insert(loosest1lepLeg);
709  }
710  if (!validLegs.size())
711  continue;
712  auto looseLegs = m_parent->getTwoLoosestLegs(lepton, validLegs, success);
713  auto efficienciesLoose =
714  (looseLegs.first == loosest1lepLeg)
715  ? efficiencies1L
716  : getCachedTriggerLegEfficiencies(lepton, runNumber,
717  looseLegs.first, success);
718  Efficiencies efficienciesMedium = {0.};
719  if (validLegs.size() >= 2)
720  efficienciesMedium =
721  (looseLegs.second == loosest1lepLeg)
722  ? efficiencies1L
723  : getCachedTriggerLegEfficiencies(lepton, runNumber,
724  looseLegs.second, success);
725  globalEfficiencies =
726  ~efficienciesLoose * globalEfficiencies + efficiencies1L;
727  if (loosest1lepLeg != looseLegs.first) {
728  globalEfficiencies +=
729  (efficienciesLoose - efficienciesMedium) *
730  ~twoSingleInefficiencies[looseLegs.first == trig2L.legs[0]];
731  if (loosest1lepLeg != looseLegs.second)
732  globalEfficiencies +=
733  (efficienciesMedium - efficiencies1L) * ~threeSingleInefficiencies;
734  }
735  threeSingleInefficiencies *= ~efficienciesLoose;
736  twoSingleInefficiencies[0] *= (looseLegs.first != trig2L.legs[1])
737  ? ~efficienciesLoose
738  : ~efficienciesMedium;
739  twoSingleInefficiencies[1] *= (looseLegs.first != trig2L.legs[0])
740  ? ~efficienciesLoose
741  : ~efficienciesMedium;
742  }
743  return success;
744 }
745 
749 template <typename Trig2Lsym, typename Trig1L>
750 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
751  const Trig2Lsym trig2L1,
752  const Trig2Lsym trig2L2,
753  const flat_set<Trig1L>& trigs1L,
754  Efficiencies& globalEfficiencies)
755  -> std::enable_if_t<Trig2Lsym::is2Lsym() && Trig1L::is1L() &&
757  bool> {
758  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_Two2LSeveral1L() at line "
759  << __LINE__);
760  if (!trig2L1 || trig2L1 == trig2L2 || trig2L1.hiddenBy(trigs1L))
761  return globalEfficiency(leptons, runNumber, trig2L2, trigs1L,
762  globalEfficiencies);
763  if (!trig2L2 || trig2L2.hiddenBy(trigs1L))
764  return globalEfficiency(leptons, runNumber, trig2L1, trigs1L,
765  globalEfficiencies);
766  globalEfficiencies = {0.};
767  Efficiencies singleInefficiencies{1.};
768  Efficiencies efficiencies2Lsym[2] = {{0.}, {0.}};
769 
770  bool success = true;
771  for (auto& lepton : leptons) {
772  if (trig2L1.irrelevantFor(lepton))
773  continue;
774  flat_set<std::size_t> validLegs;
775  std::map<std::size_t, Efficiencies> efficiencies{{0, 0.}};
776  std::size_t loosest1lepLeg =
777  getLoosestLegAboveThreshold(lepton, trigs1L, success);
778  for (std::size_t leg : {loosest1lepLeg, trig2L1(), trig2L2()}) {
779  if (leg && aboveThreshold(lepton, leg)) {
780  validLegs.insert(leg);
781  efficiencies.emplace(leg, getCachedTriggerLegEfficiencies(
782  lepton, runNumber, leg, success));
783  } else
784  efficiencies.emplace(leg, 0.);
785  }
786  if (!validLegs.size())
787  continue;
788  auto looseLegs = m_parent->getTwoLoosestLegs(lepton, validLegs, success);
789  std::size_t lambda13 =
790  (looseLegs.first != trig2L2()) ? looseLegs.first : looseLegs.second;
791  std::size_t lambda23 =
792  (looseLegs.first != trig2L1()) ? looseLegs.first : looseLegs.second;
793  globalEfficiencies = globalEfficiencies * ~efficiencies[looseLegs.first] +
794  efficiencies[loosest1lepLeg];
795  if (looseLegs.first == trig2L1())
796  globalEfficiencies +=
797  efficiencies2Lsym[1] *
798  (efficiencies[trig2L1()] - efficiencies[looseLegs.second]);
799  if (looseLegs.first == trig2L2())
800  globalEfficiencies +=
801  efficiencies2Lsym[0] *
802  (efficiencies[trig2L2()] - efficiencies[looseLegs.second]);
803  if (looseLegs.first != loosest1lepLeg)
804  globalEfficiencies +=
805  ~singleInefficiencies *
806  (efficiencies[looseLegs.second] - efficiencies[loosest1lepLeg]);
807  efficiencies2Lsym[0] =
808  ~efficiencies[looseLegs.first] * efficiencies2Lsym[0] +
809  efficiencies[lambda23];
810  efficiencies2Lsym[1] =
811  ~efficiencies[looseLegs.first] * efficiencies2Lsym[1] +
812  efficiencies[lambda13];
813  if (looseLegs.first == trig2L1())
814  efficiencies2Lsym[0] +=
815  (efficiencies[trig2L1()] - efficiencies[lambda23]) *
816  ~singleInefficiencies;
817  if (looseLegs.first == trig2L2())
818  efficiencies2Lsym[1] +=
819  (efficiencies[trig2L2()] - efficiencies[lambda13]) *
820  ~singleInefficiencies;
821  singleInefficiencies *= ~efficiencies[looseLegs.first];
822  }
823  return success;
824 }
825 
829 template <typename Trig2Lasym, typename Trig2Lsym, typename Trig1L>
830 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
831  const Trig2Lasym trig2Lasym,
832  const Trig2Lsym trig2Lsym,
833  const flat_set<Trig1L>& trigs1L,
834  Efficiencies& globalEfficiencies)
835  -> std::enable_if_t<Trig2Lasym::is2Lasym() && Trig2Lsym::is2Lsym() &&
837  Trig1L::is1L() &&
839  bool> {
840  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_Two2LSeveral1L() at line "
841  << __LINE__);
842  if (!trig2Lasym || trig2Lasym.hiddenBy(trigs1L))
843  return globalEfficiency(leptons, runNumber, trig2Lsym, trigs1L,
844  globalEfficiencies);
845  if (!trig2Lsym || trig2Lsym.hiddenBy(trigs1L))
846  return globalEfficiency(leptons, runNumber, trig2Lasym, trigs1L,
847  globalEfficiencies);
848  if (trig2Lasym(0) == trig2Lsym() || trig2Lasym(1) == trig2Lsym()) {
850  "implementation -- does this function work properly when the two 2L "
851  "triggers have one leg in common? Must be checked");
852  return false;
853  }
854  if (trig2Lasym.symmetric())
855  return globalEfficiency(leptons, runNumber, trig2Lasym.to_symmetric(),
856  trig2Lsym, trigs1L, globalEfficiencies);
857  globalEfficiencies = {0.};
858  Efficiencies singleInefficiencies[3] = {{1.}, {1.}, {1.}};
859  Efficiencies efficiencies2Lasym{0.},
860  efficiencies2Lsym[3] = {{0.}, {0.}, {0.}};
861 
862  bool success = true;
863  for (auto& lepton : leptons) {
864  if (trig2Lasym.irrelevantFor(lepton))
865  continue;
866  flat_set<std::size_t> validLegs;
867  std::map<std::size_t, Efficiencies> efficiencies{{0, 0.}};
868  std::size_t loosest1lepLeg =
869  getLoosestLegAboveThreshold(lepton, trigs1L, success);
870  for (std::size_t leg :
871  {trig2Lasym(0), trig2Lasym(1), trig2Lsym(), loosest1lepLeg}) {
872  if (leg && aboveThreshold(lepton, leg)) {
873  validLegs.insert(leg);
874  efficiencies.emplace(leg, getCachedTriggerLegEfficiencies(
875  lepton, runNumber, leg, success));
876  } else
877  efficiencies.emplace(leg, 0.);
878  }
879  if (!validLegs.size())
880  continue;
881 
882  const auto sortedLegs = m_parent->getSortedLegs(lepton, validLegs, success);
883  if (!success)
884  return false;
885  std::size_t loosestLeg = sortedLegs[0];
886  std::size_t secondLoosestLeg = validLegs.size() >= 2 ? sortedLegs[1] : 0;
887  std::size_t secondTightestLeg = validLegs.size() >= 3 ? sortedLegs[2] : 0;
888  std::size_t tightestLeg = validLegs.size() >= 4 ? sortedLegs[3] : 0;
889  std::size_t lambda124 =
890  (loosestLeg != trig2Lasym(1)) ? loosestLeg : secondLoosestLeg;
891  std::size_t lambda134 =
892  (loosestLeg != trig2Lasym(0)) ? loosestLeg : secondLoosestLeg;
893  std::size_t lambda234 =
894  (loosestLeg != trig2Lsym()) ? loosestLeg : secondLoosestLeg;
895  std::size_t lambda14 = (lambda124 != trig2Lasym(0)) ? lambda124
896  : (lambda134 != trig2Lasym(1)) ? lambda134
897  : secondTightestLeg;
898  std::size_t lambda24 = (lambda124 != trig2Lsym()) ? lambda124
899  : (lambda234 != trig2Lasym(1)) ? lambda234
900  : secondTightestLeg;
901  std::size_t lambda34 = (lambda134 != trig2Lsym()) ? lambda134
902  : (lambda234 != trig2Lasym(0)) ? lambda234
903  : secondTightestLeg;
904  std::size_t tau13 = 0, tau12 = 0, tau23 = 0;
905  if (loosestLeg == trig2Lsym() || loosestLeg == trig2Lasym(0))
906  tau12 = (loosestLeg == trig2Lsym()) ? trig2Lasym(0) : trig2Lsym();
907  else if (secondLoosestLeg == trig2Lsym() ||
908  secondLoosestLeg == trig2Lasym(0))
909  tau12 = (secondLoosestLeg == trig2Lsym()) ? trig2Lasym(0) : trig2Lsym();
910  else if (secondTightestLeg == trig2Lsym() ||
911  secondTightestLeg == trig2Lasym(0))
912  tau12 = (secondTightestLeg == trig2Lsym()) ? trig2Lasym(0) : trig2Lsym();
913  else if (tightestLeg == trig2Lsym() || tightestLeg == trig2Lasym(0))
914  tau12 = (tightestLeg == trig2Lsym()) ? trig2Lasym(0) : trig2Lsym();
915  if (loosestLeg == trig2Lsym() || loosestLeg == trig2Lasym(1))
916  tau13 = (loosestLeg == trig2Lsym()) ? trig2Lasym(1) : trig2Lsym();
917  else if (secondLoosestLeg == trig2Lsym() ||
918  secondLoosestLeg == trig2Lasym(1))
919  tau13 = (secondLoosestLeg == trig2Lsym()) ? trig2Lasym(1) : trig2Lsym();
920  else if (secondTightestLeg == trig2Lsym() ||
921  secondTightestLeg == trig2Lasym(1))
922  tau13 = (secondTightestLeg == trig2Lsym()) ? trig2Lasym(1) : trig2Lsym();
923  else if (tightestLeg == trig2Lsym() || tightestLeg == trig2Lasym(1))
924  tau13 = (tightestLeg == trig2Lsym()) ? trig2Lasym(1) : trig2Lsym();
925  if (loosestLeg == trig2Lasym(0) || loosestLeg == trig2Lasym(1))
926  tau23 = (loosestLeg == trig2Lasym(0)) ? trig2Lasym(1) : trig2Lasym(0);
927  else if (secondLoosestLeg == trig2Lasym(0) ||
928  secondLoosestLeg == trig2Lasym(1))
929  tau23 =
930  (secondLoosestLeg == trig2Lasym(0)) ? trig2Lasym(1) : trig2Lasym(0);
931  else if (secondTightestLeg == trig2Lasym(0) ||
932  secondTightestLeg == trig2Lasym(1))
933  tau23 =
934  (secondTightestLeg == trig2Lasym(0)) ? trig2Lasym(1) : trig2Lasym(0);
935  else if (tightestLeg == trig2Lasym(0) || tightestLeg == trig2Lasym(1))
936  tau23 = (tightestLeg == trig2Lasym(0)) ? trig2Lasym(1) : trig2Lasym(0);
937 
939  globalEfficiencies =
940  globalEfficiencies * ~efficiencies[loosestLeg] +
941  efficiencies[loosest1lepLeg] +
942  (efficiencies[tau13] - efficiencies[secondTightestLeg]) *
943  ~singleInefficiencies[0] +
944  (efficiencies[tau12] - efficiencies[secondTightestLeg]) *
945  ~singleInefficiencies[1] +
946  (efficiencies[tau23] - efficiencies[secondTightestLeg]) *
947  efficiencies2Lsym[2];
948  if (loosestLeg == trig2Lsym())
949  globalEfficiencies +=
950  (efficiencies[trig2Lsym()] - efficiencies[secondLoosestLeg]) *
951  efficiencies2Lasym;
952  else if (loosestLeg == trig2Lasym(1))
953  globalEfficiencies +=
954  (efficiencies[trig2Lasym(1)] - efficiencies[secondLoosestLeg]) *
955  efficiencies2Lsym[0];
956  else if (loosestLeg == trig2Lasym(0))
957  globalEfficiencies +=
958  (efficiencies[trig2Lasym(0)] - efficiencies[secondLoosestLeg]) *
959  efficiencies2Lsym[1];
960  if (secondTightestLeg &&
961  tightestLeg == loosest1lepLeg)
962  globalEfficiencies +=
964  (efficiencies[secondTightestLeg] - efficiencies[tightestLeg]) *
965  ~singleInefficiencies[2];
966 
967  efficiencies2Lasym =
968  ~efficiencies[loosestLeg] * efficiencies2Lasym + efficiencies[lambda14];
969  if (loosestLeg == trig2Lasym(0) || loosestLeg == trig2Lasym(1)) {
972  efficiencies2Lasym +=
973  (efficiencies[loosestLeg] - efficiencies[secondLoosestLeg]) *
974  ~singleInefficiencies[loosestLeg == trig2Lasym(0)] +
975  (efficiencies[secondLoosestLeg] - efficiencies[lambda14]) *
976  ~singleInefficiencies[2];
977  }
978  efficiencies2Lsym[0] = ~efficiencies[lambda124] * efficiencies2Lsym[0] +
979  efficiencies[lambda24];
980  efficiencies2Lsym[1] = ~efficiencies[lambda134] * efficiencies2Lsym[1] +
981  efficiencies[lambda34];
982  efficiencies2Lsym[2] = ~efficiencies[loosestLeg] * efficiencies2Lsym[2] +
983  efficiencies[lambda234];
984  if (lambda124 == trig2Lsym())
985  efficiencies2Lsym[0] +=
986  (efficiencies[trig2Lsym()] - efficiencies[lambda24]) *
987  ~singleInefficiencies[0];
988  if (lambda134 == trig2Lsym())
989  efficiencies2Lsym[1] +=
990  (efficiencies[trig2Lsym()] - efficiencies[lambda34]) *
991  ~singleInefficiencies[1];
992  if (loosestLeg == trig2Lsym())
993  efficiencies2Lsym[2] +=
994  (efficiencies[trig2Lsym()] - efficiencies[lambda234]) *
995  ~singleInefficiencies[2];
996  singleInefficiencies[0] *= ~efficiencies[lambda124];
997  singleInefficiencies[1] *= ~efficiencies[lambda134];
998  singleInefficiencies[2] *= ~efficiencies[loosestLeg];
999  }
1000  return success;
1001 }
1002 
1006 template <typename Trig3Lsym>
1007 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
1008  const Trig3Lsym trig,
1009  Efficiencies& globalEfficiencies)
1010  -> std::enable_if_t<Trig3Lsym::is3Lsym(), bool> {
1011  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_One3L() at line "
1012  << __LINE__);
1013  globalEfficiencies = {0.};
1014  Efficiencies singleInefficiencies{1.}, efficiencies2L{0.};
1015  bool success = true;
1016  for (auto& lepton : leptons) {
1017  if (trig.irrelevantFor(lepton) || !aboveThreshold(lepton, trig()))
1018  continue;
1019  auto efficiencies =
1020  getCachedTriggerLegEfficiencies(lepton, runNumber, trig(), success);
1021  globalEfficiencies =
1022  ~efficiencies * globalEfficiencies + efficiencies * efficiencies2L;
1023  efficiencies2L =
1024  ~efficiencies * efficiencies2L + efficiencies * ~singleInefficiencies;
1025  singleInefficiencies *= ~efficiencies;
1026  }
1027  return success;
1028 }
1029 
1033 template <typename Trig3Lhalfsym>
1034 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
1035  const Trig3Lhalfsym trig,
1036  Efficiencies& globalEfficiencies)
1037  -> std::enable_if_t<Trig3Lhalfsym::is3Lhalfsym(), bool> {
1038  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_One3L() at line "
1039  << __LINE__);
1040  if (trig.symmetric())
1041  return globalEfficiency(leptons, runNumber, trig.to_symmetric(),
1042  globalEfficiencies);
1043  globalEfficiencies = {0.};
1044  Efficiencies singleInefficiencies[2] = {{1.}, {1.}},
1045  twoSingleInefficiencies{1.};
1046  Efficiencies efficiencies2Lsym{0.}, efficiencies2Lasym{0.},
1047  efficiencies2L2L{0.};
1048  bool success = true;
1049  for (auto& lepton : leptons) {
1050  if (trig.irrelevantFor(lepton))
1051  continue;
1052  Efficiencies efficiencies[2] = {{0.}, {0.}};
1053  const int asym = 0, sym = 1;
1054  int loosestLeg;
1055  if (aboveThreshold(lepton, trig.asymLeg())) {
1056  efficiencies[asym] = getCachedTriggerLegEfficiencies(
1057  lepton, runNumber, trig.asymLeg(), success);
1058  if (aboveThreshold(lepton, trig.symLeg())) {
1059  efficiencies[sym] = getCachedTriggerLegEfficiencies(
1060  lepton, runNumber, trig.symLeg(), success);
1061  loosestLeg =
1062  m_parent->getLoosestLeg(lepton, trig.asymLeg(), trig.symLeg(),
1063  success) == trig.asymLeg()
1064  ? asym
1065  : sym;
1066  } else
1067  loosestLeg = asym;
1068  } else if (aboveThreshold(lepton, trig.symLeg())) {
1069  efficiencies[sym] = getCachedTriggerLegEfficiencies(
1070  lepton, runNumber, trig.symLeg(), success);
1071  loosestLeg = sym;
1072  } else
1073  continue;
1074  Efficiencies delta = efficiencies[asym] - efficiencies[sym];
1075  if (loosestLeg == asym) {
1076  globalEfficiencies = ~efficiencies[asym] * globalEfficiencies +
1077  efficiencies[sym] * efficiencies2L2L +
1078  delta * efficiencies2Lsym;
1079  efficiencies2L2L = ~efficiencies[asym] * efficiencies2L2L +
1080  efficiencies[sym] * ~twoSingleInefficiencies +
1081  delta * ~singleInefficiencies[sym];
1082  efficiencies2Lasym = ~efficiencies[asym] * efficiencies2Lasym +
1083  efficiencies[sym] * ~twoSingleInefficiencies +
1084  delta * ~singleInefficiencies[sym];
1085  } else {
1086  globalEfficiencies = ~efficiencies[sym] * globalEfficiencies +
1087  efficiencies[asym] * efficiencies2L2L -
1088  delta * efficiencies2Lasym;
1089  efficiencies2L2L = ~efficiencies[sym] * efficiencies2L2L +
1090  efficiencies[sym] * ~twoSingleInefficiencies;
1091  efficiencies2Lasym = ~efficiencies[sym] * efficiencies2Lasym +
1092  efficiencies[asym] * ~twoSingleInefficiencies -
1093  delta * ~singleInefficiencies[asym];
1094  }
1095  efficiencies2Lsym = ~efficiencies[sym] * efficiencies2Lsym +
1096  efficiencies[sym] * ~singleInefficiencies[sym];
1097  twoSingleInefficiencies *= ~efficiencies[loosestLeg];
1098  singleInefficiencies[sym] *= ~efficiencies[sym];
1099  singleInefficiencies[asym] *= ~efficiencies[asym];
1100  }
1101  return success;
1102 }
1103 
1107 template <typename Trig2L, typename Trig2Lmix>
1108 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
1109  const Trig2L trig2L,
1110  const Trig2Lmix trig2Lmix,
1111  Efficiencies& globalEfficiencies)
1112  -> std::enable_if_t<Trig2L::is2Lnomix() && Trig2Lmix::is2Lmix() &&
1113  (Trig2Lmix::object1() == Trig2L::object() ||
1114  Trig2Lmix::object2() == Trig2L::object()),
1115  bool> {
1116  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_Two2L() at line "
1117  << __LINE__);
1118  Efficiencies efficiencies1L, efficiencies2L, efficiencies2Lor1L;
1119  bool success =
1120  globalEfficiency(leptons, runNumber,
1121  trig2Lmix.template antiside<Trig2L>(), efficiencies1L);
1122  success =
1123  success && globalEfficiency(leptons, runNumber, trig2L, efficiencies2L);
1124  success = success && globalEfficiency(leptons, runNumber, trig2L,
1125  trig2Lmix.template side<Trig2L>(),
1126  efficiencies2Lor1L);
1127  globalEfficiencies =
1128  efficiencies2L * ~efficiencies1L + efficiencies1L * efficiencies2Lor1L;
1129  return success;
1130 }
1131 
1136 template <typename Trig2L_obj1, typename Trig2L_obj2, typename Trig2Lmix>
1137 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
1138  const Trig2L_obj1 trig2L_obj1,
1139  const Trig2L_obj2 trig2L_obj2,
1140  const Trig2Lmix trig2Lmix,
1141  Efficiencies& globalEfficiencies)
1142  -> std::enable_if_t<Trig2Lmix::is2Lmix() && Trig2L_obj1::is2Lnomix() &&
1143  Trig2L_obj1::object() == Trig2Lmix::object1() &&
1144  Trig2L_obj2::is2Lnomix() &&
1145  Trig2L_obj2::object() == Trig2Lmix::object2(),
1146 
1147  bool> {
1148  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_Three2L() at line "
1149  << __LINE__);
1150  Efficiencies efficiencies2L[2] = {{0.}, {0.}},
1151  efficiencies2Lor1L[2] = {{0.}, {0.}};
1152  bool success = true;
1153  if (trig2L_obj1) {
1154  success = success && globalEfficiency(leptons, runNumber, trig2L_obj1,
1155  efficiencies2L[0]);
1156  if (trig2Lmix)
1157  success =
1158  success && globalEfficiency(leptons, runNumber, trig2L_obj1,
1159  trig2Lmix.template side<Trig2L_obj1>(),
1160  efficiencies2Lor1L[0]);
1161  else
1162  efficiencies2Lor1L[0] = efficiencies2L[0];
1163  } else if (trig2Lmix)
1164  success =
1165  success && globalEfficiency(leptons, runNumber,
1166  trig2Lmix.template side<Trig2L_obj1>(),
1167  efficiencies2Lor1L[0]);
1168  if (trig2L_obj2) {
1169  success = success && globalEfficiency(leptons, runNumber, trig2L_obj2,
1170  efficiencies2L[1]);
1171  if (trig2Lmix)
1172  success =
1173  success && globalEfficiency(leptons, runNumber, trig2L_obj2,
1174  trig2Lmix.template side<Trig2L_obj2>(),
1175  efficiencies2Lor1L[1]);
1176  else
1177  efficiencies2Lor1L[1] = efficiencies2L[1];
1178  } else if (trig2Lmix)
1179  success =
1180  success && globalEfficiency(leptons, runNumber,
1181  trig2Lmix.template side<Trig2L_obj2>(),
1182  efficiencies2Lor1L[1]);
1183  globalEfficiencies = efficiencies2L[0] * ~efficiencies2Lor1L[1] +
1184  efficiencies2L[1] * ~efficiencies2Lor1L[0] +
1185  efficiencies2Lor1L[0] * efficiencies2Lor1L[1];
1186  return success;
1187 }
1188 
1192 template <typename Trig2L_obj1, typename Trig2L_obj2, typename Trig2Lmix,
1193  typename Trig1L_obj1, typename Trig1L_obj2>
1194 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
1195  const Trig2L_obj1 trig2L_obj1,
1196  const Trig2L_obj2 trig2L_obj2,
1197  const Trig2Lmix trig2Lmix,
1198  const flat_set<Trig1L_obj1>& trigs1L_obj1,
1199  const flat_set<Trig1L_obj2>& trigs1L_obj2,
1200  Efficiencies& globalEfficiencies)
1201  -> std::enable_if_t<Trig2Lmix::is2Lmix() && Trig2L_obj1::is2Lnomix() &&
1202  Trig2L_obj1::object() == Trig2Lmix::object1() &&
1203  Trig2L_obj2::is2Lnomix() &&
1204  Trig2L_obj2::object() == Trig2Lmix::object2() &&
1205  Trig1L_obj1::is1L() &&
1206  Trig1L_obj1::object() == Trig2Lmix::object1() &&
1207  Trig1L_obj2::is1L() &&
1208  Trig1L_obj2::object() == Trig2Lmix::object2(),
1209 
1210  bool> {
1211  ATH_MSG_DEBUG(
1212  "Entered Calculator::globalEfficiency_Three2LSeveral1L() at line "
1213  << __LINE__);
1215  bool success = true;
1216  if (trig2L_obj1)
1217  success = success && globalEfficiency(leptons, runNumber, trig2L_obj1,
1218  trigs1L_obj1, efficiencies[0]);
1219  else
1220  success = success && globalEfficiency(leptons, runNumber, trigs1L_obj1,
1221  efficiencies[0]);
1222  if (trig2L_obj2)
1223  success = success && globalEfficiency(leptons, runNumber, trig2L_obj2,
1224  trigs1L_obj2, efficiencies[1]);
1225  else
1226  success = success && globalEfficiency(leptons, runNumber, trigs1L_obj2,
1227  efficiencies[1]);
1228  if (trig2Lmix && !trig2Lmix.hiddenBy(trigs1L_obj1)) {
1229  auto t = trig2Lmix.addTo(trigs1L_obj1);
1230  if (trig2L_obj1)
1231  success = success && globalEfficiency(leptons, runNumber, trig2L_obj1, t,
1232  efficiencies[2]);
1233  else
1234  success =
1235  success && globalEfficiency(leptons, runNumber, t, efficiencies[2]);
1236  } else
1237  efficiencies[2] = efficiencies[0];
1238  if (trig2Lmix && !trig2Lmix.hiddenBy(trigs1L_obj2)) {
1239  auto t = trig2Lmix.addTo(trigs1L_obj2);
1240  if (trig2L_obj2)
1241  success = success && globalEfficiency(leptons, runNumber, trig2L_obj2, t,
1242  efficiencies[3]);
1243  else
1244  success =
1245  success && globalEfficiency(leptons, runNumber, t, efficiencies[3]);
1246  } else
1247  efficiencies[3] = efficiencies[1];
1248  globalEfficiencies =
1249  Efficiencies(1.) - ~efficiencies[0] * ~efficiencies[1] +
1250  (efficiencies[2] - efficiencies[0]) * (efficiencies[3] - efficiencies[1]);
1251  return success;
1252 }
1253 
1258 template <typename Trig2L_obj1, typename Trig2Lsym_obj1, typename Trig2L_obj2,
1259  typename Trig2Lsym_obj2, typename Trig2Lmix, typename Trig1L_obj1,
1260  typename Trig1L_obj2>
1262  const LeptonList& leptons, unsigned runNumber,
1263  const Trig2L_obj1 trig2L_obj1, const Trig2Lsym_obj1 trig2Lsym_obj1,
1264  const Trig2L_obj2 trig2L_obj2, const Trig2Lsym_obj2 trig2Lsym_obj2,
1265  const Trig2Lmix trig2Lmix1, const Trig2Lmix trig2Lmix2,
1266  const flat_set<Trig1L_obj1>& trigs1L_obj1,
1267  const flat_set<Trig1L_obj2>& trigs1L_obj2, Efficiencies& globalEfficiencies)
1268  -> std::enable_if_t<Trig2Lmix::is2Lmix() && Trig2L_obj1::is2Lnomix() &&
1269  Trig2L_obj1::object() == Trig2Lmix::object1() &&
1270  Trig2L_obj2::is2Lnomix() &&
1271  Trig2L_obj2::object() == Trig2Lmix::object2() &&
1272  Trig2Lsym_obj1::is2Lsym() &&
1273  Trig2Lsym_obj1::object() == Trig2Lmix::object1() &&
1274  Trig2Lsym_obj2::is2Lsym() &&
1275  Trig2Lsym_obj2::object() == Trig2Lmix::object2() &&
1276  Trig1L_obj1::is1L() &&
1277  Trig1L_obj1::object() == Trig2Lmix::object1() &&
1278  Trig1L_obj2::is1L() &&
1279  Trig1L_obj2::object() == Trig2Lmix::object2(),
1280  bool> {
1281  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_Six2LSeveral1L() at line "
1282  << __LINE__);
1283 
1284  auto singleObjectFactor = [=](auto trig2L, auto trig2Lsym, auto& trigs1L,
1285  Efficiencies(&efficiencies)[4]) -> bool {
1286  auto eval_for = [=](const auto& trigs1L_extended,
1287  Efficiencies& eff) -> bool {
1288  if (trig2L && trig2Lsym)
1289  return this->globalEfficiency(leptons, runNumber, trig2L, trig2Lsym,
1290  trigs1L_extended, eff);
1291  else if (trig2L)
1292  return this->globalEfficiency(leptons, runNumber, trig2L,
1293  trigs1L_extended, eff);
1294  else if (trig2Lsym)
1295  return this->globalEfficiency(leptons, runNumber, trig2Lsym,
1296  trigs1L_extended, eff);
1297  else
1298  return this->globalEfficiency(leptons, runNumber, trigs1L_extended,
1299  eff);
1300  };
1301 
1302  bool success = eval_for(trigs1L, efficiencies[0]);
1303  if (trig2Lmix1)
1304  success = success && eval_for(trig2Lmix1.addTo(trigs1L), efficiencies[1]);
1305  else
1306  efficiencies[1] = efficiencies[0];
1307  if (trig2Lmix2) {
1308  auto t = trig2Lmix2.addTo(trigs1L);
1309  success = success && eval_for(t, efficiencies[2]);
1310  if (trig2Lmix1)
1311  success&& eval_for(trig2Lmix1.addTo(t), efficiencies[3]);
1312  else
1313  efficiencies[3] = efficiencies[2];
1314  } else {
1315  efficiencies[2] = efficiencies[0];
1316  efficiencies[3] = efficiencies[1];
1317  }
1318  return success;
1319  };
1320 
1321  Efficiencies efficiencies1[4], efficiencies2[4];
1322  bool success = singleObjectFactor(trig2L_obj1, trig2Lsym_obj1, trigs1L_obj1,
1323  efficiencies1) &&
1324  singleObjectFactor(trig2L_obj2, trig2Lsym_obj2, trigs1L_obj2,
1325  efficiencies2);
1326  globalEfficiencies = Efficiencies(1.) -
1327  ~efficiencies1[0] * ~efficiencies2[0] +
1328  (efficiencies1[1] - efficiencies1[0]) *
1329  (efficiencies2[1] - efficiencies2[0]) +
1330  (efficiencies1[2] - efficiencies1[0]) *
1331  (efficiencies2[2] - efficiencies2[0]) -
1332  (efficiencies1[0] - efficiencies1[1] - efficiencies1[2] +
1333  efficiencies1[3]) *
1334  (efficiencies2[0] - efficiencies2[1] -
1335  efficiencies2[2] + efficiencies2[3]);
1336  return success;
1337 }
1338 
1342 template <typename Trig3Lmix>
1343 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
1344  const Trig3Lmix trig,
1345  Efficiencies& globalEfficiencies)
1346  -> std::enable_if_t<Trig3Lmix::is3Lmix(), bool> {
1347  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_One3L() at line "
1348  << __LINE__);
1349  Efficiencies efficiencies[2] = {{0.}, {0.}};
1350  bool success = globalEfficiency(leptons, runNumber,
1351  trig.template side<Trig3Lmix::object1()>(),
1352  efficiencies[0]) &&
1353  globalEfficiency(leptons, runNumber,
1354  trig.template side<Trig3Lmix::object2()>(),
1355  efficiencies[1]);
1356  globalEfficiencies = efficiencies[0] * efficiencies[1];
1357  return success;
1358 }
1359 
1363 template <typename Trig3Lmix1, typename Trig3Lmix2>
1364 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
1365  const Trig3Lmix1 trig1,
1366  const Trig3Lmix2 trig2,
1367  Efficiencies& globalEfficiencies)
1368  -> std::enable_if_t<Trig3Lmix1::is3Lmix() && Trig3Lmix2::is3Lmix() &&
1369  Trig3Lmix1::object1() == Trig3Lmix2::object2() &&
1370  Trig3Lmix1::object2() == Trig3Lmix2::object1(),
1371  bool> {
1372  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_Two3L() at line "
1373  << __LINE__);
1374  Efficiencies efficiencies[6] = {{0.}, {0.}, {0.}, {0.}, {0.}, {0.}};
1375  auto trig2La = trig1.template side<Trig3Lmix1::object1()>();
1376  auto trig1La = trig2.template side<Trig3Lmix2::object2()>();
1377  bool success =
1378  globalEfficiency(leptons, runNumber, trig1La, efficiencies[0]) &&
1379  globalEfficiency(leptons, runNumber, trig2La, efficiencies[1]);
1380  if (!trig2La.hiddenBy(trig1La))
1381  success = success && globalEfficiency(leptons, runNumber, trig2La, trig1La,
1382  efficiencies[2]);
1383  else
1384  efficiencies[2] = efficiencies[0];
1385  auto trig2Lb = trig2.template side<Trig3Lmix2::object1()>();
1386  auto trig1Lb = trig1.template side<Trig3Lmix1::object2()>();
1387  success = success &&
1388  globalEfficiency(leptons, runNumber, trig1Lb, efficiencies[3]) &&
1389  globalEfficiency(leptons, runNumber, trig2Lb, efficiencies[4]);
1390  if (!trig2Lb.hiddenBy(trig1Lb))
1391  success = success && globalEfficiency(leptons, runNumber, trig2Lb, trig1Lb,
1392  efficiencies[5]);
1393  else
1394  efficiencies[5] = efficiencies[3];
1395  globalEfficiencies =
1397  (efficiencies[2] - efficiencies[0] - efficiencies[1]) *
1398  (efficiencies[3] + efficiencies[4] - efficiencies[5]);
1399  return success;
1400 }
1401 
1405 template <typename Trig4Lsym>
1406 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
1407  const Trig4Lsym trig,
1408  Efficiencies& globalEfficiencies)
1409  -> std::enable_if_t<Trig4Lsym::is4Lsym(), bool> {
1410  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_One4L() at line "
1411  << __LINE__);
1412  globalEfficiencies = {0.};
1413  Efficiencies singleInefficiencies{1.}, efficiencies2L{0.}, efficiencies3L{0.};
1414  bool success = true;
1415  for (auto& lepton : leptons) {
1416  if (trig.irrelevantFor(lepton) || !aboveThreshold(lepton, trig()))
1417  continue;
1418  auto efficiencies =
1419  getCachedTriggerLegEfficiencies(lepton, runNumber, trig(), success);
1420  globalEfficiencies =
1421  ~efficiencies * globalEfficiencies + efficiencies * efficiencies3L;
1422  efficiencies3L =
1423  ~efficiencies * efficiencies3L + efficiencies * efficiencies2L;
1424  efficiencies2L =
1425  ~efficiencies * efficiencies2L + efficiencies * ~singleInefficiencies;
1426  singleInefficiencies *= ~efficiencies;
1427  }
1428  return success;
1429 }
1430 
1432  const LeptonList& leptons, unsigned runNumber, GlobEffFunc func1,
1433  GlobEffFunc func2, Efficiencies& globalEfficiencies) {
1435  if (!func1(this, leptons, runNumber, efficiencies[0]))
1436  return false;
1437  if (!func2(this, leptons, runNumber, efficiencies[1]))
1438  return false;
1439  globalEfficiencies = ~(~efficiencies[0] * ~efficiencies[1]);
1440  return true;
1441 }
1442 
1444  const LeptonList& leptons, unsigned runNumber, GlobEffFunc func1,
1445  GlobEffFunc func2, GlobEffFunc func3, Efficiencies& globalEfficiencies) {
1447  if (!func1(this, leptons, runNumber, efficiencies[0]))
1448  return false;
1449  if (!func2(this, leptons, runNumber, efficiencies[1]))
1450  return false;
1451  if (!func3(this, leptons, runNumber, efficiencies[2]))
1452  return false;
1453  globalEfficiencies =
1454  ~(~efficiencies[0] * ~efficiencies[1] * ~efficiencies[2]);
1455  return true;
1456 }
1457 
1459  const std::vector<TrigDef>& triggers,
1460  flat_set<std::size_t>& validLegs) const {
1461  validLegs.clear();
1462  for (auto& trig : triggers) {
1463  TriggerProperties tp(trig);
1464  if (!tp.valid()) {
1465  ATH_MSG_ERROR("Unrecognized trigger type " << trig.type);
1466  return false;
1467  }
1468  auto end = tp.cend(lepton.type());
1469  for (auto itr = tp.cbegin(lepton.type()); itr != end; ++itr)
1470  if (aboveThreshold(lepton, *itr))
1471  validLegs.emplace(*itr);
1472  }
1473  return true;
1474 }
1475 
1477  const TrigDef& trig,
1478  const std::vector<flat_set<std::size_t>>& firedLegs) const {
1479  const int nLegs = static_cast<int>(std::count_if(
1480  trig.leg.begin(), trig.leg.end(), [](auto x) { return x != 0ul; }));
1481  const int sameLegs = static_cast<int>(
1482  std::count(trig.leg.begin(), trig.leg.end(), trig.leg[0]));
1483  if (sameLegs == nLegs) {
1484  // single-lepton and symmetric multilepton triggers
1485  return std::count_if(firedLegs.cbegin(), firedLegs.cend(), [&](auto& legs) {
1486  return legs.count(trig.leg[0]);
1487  }) >= nLegs;
1488  } else if (nLegs == 2) {
1489  // asymmetric or mixed-flavour dilepton triggers
1490  bool n0 = false, n1 = false;
1491  for (auto& legs : firedLegs) {
1492  if (n0 && legs.count(trig.leg[1]))
1493  return true;
1494  if (n1 && legs.count(trig.leg[0]))
1495  return true;
1496  n0 = n0 || legs.count(trig.leg[0]);
1497  n1 = n1 || legs.count(trig.leg[1]);
1498  }
1499  } else if (nLegs == 3) {
1500  // other trilepton triggers
1501  auto end = firedLegs.end();
1502  for (auto legs0 = firedLegs.begin(); legs0 != end; ++legs0) {
1503  for (int i = 0; i < 3; ++i) {
1504  if (!legs0->count(trig.leg[i]))
1505  continue;
1506  for (auto legs1 = legs0 + 1; legs1 != end; ++legs1) {
1507  for (int j = 1; j < 3; ++j) {
1508  if (!legs1->count(trig.leg[(i + j) % 3]))
1509  continue;
1510  for (auto legs2 = legs1 + 1; legs2 != end; ++legs2) {
1511  if (legs2->count(trig.leg[(i + 3 - j) % 3]))
1512  return true;
1513  }
1514  }
1515  }
1516  }
1517  }
1518  } else {
1519  ATH_MSG_ERROR("incomplete support of 4-lepton triggers.");
1520  }
1521  return false;
1522 }
1523 
1525  unsigned runNumber,
1526  const std::vector<TrigDef>& triggers,
1527  Efficiencies& globalEfficiencies) {
1528  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_Toys() at line "
1529  << __LINE__);
1530  globalEfficiencies = {0.};
1531  if (m_parent->m_numberOfToys <= 0) {
1532  ATH_MSG_ERROR("The specified number of toys is <= 0");
1533  return false;
1534  }
1535  std::map<const Lepton*, std::vector<std::pair<std::size_t, Efficiencies>>>
1536  leptonEfficiencies;
1537  for (auto& lepton : leptons) {
1538  flat_set<std::size_t> validLegs;
1539  if (!fillListOfLegsFor(lepton, triggers, validLegs))
1540  return false;
1541  auto& efficiencies = leptonEfficiencies[&lepton];
1542  const int nLegs = validLegs.size();
1543  if (nLegs) {
1544  bool success = true;
1545  for (std::size_t leg :
1546  m_parent->getSortedLegs(lepton, validLegs, success)) {
1548  lepton, runNumber, leg, success));
1549  }
1550  if (!success)
1551  return false;
1552  }
1553  }
1554  unsigned long seed;
1555  if (!m_parent->m_useInternalSeed) {
1556  if (!m_parent->retrieveEventNumber(seed)) {
1557  ATH_MSG_WARNING("Will use internal seed instead of event number");
1558  seed = m_parent->m_seed++;
1559  }
1560  } else
1561  seed = m_parent->m_seed++;
1562  std::mt19937_64 randomEngine(seed);
1563  std::uniform_real_distribution<double> uniformPdf(0., 1.);
1564  std::vector<flat_set<std::size_t>> firedLegs(leptonEfficiencies.size());
1565  unsigned long nPassed[2] = {0, 0};
1566  for (unsigned long toy = 0; toy < m_parent->m_numberOfToys; ++toy) {
1567  for (int step = 0; step < 2; ++step)
1568  {
1569  auto legs = firedLegs.begin();
1570  for (auto& kv : leptonEfficiencies) {
1571  legs->clear();
1572  double x = uniformPdf(randomEngine);
1573  for (auto& p : kv.second) {
1574  if (x < (step ? p.second.mc() : p.second.data()))
1575  legs->emplace(p.first);
1576  }
1577  ++legs;
1578  }
1579  for (auto& trig : triggers) {
1580  if (!canTriggerBeFired(trig, firedLegs))
1581  continue;
1582  ++nPassed[step];
1583  break;
1584  }
1585  }
1586  }
1587  globalEfficiencies.data() =
1588  double(nPassed[0]) / double(m_parent->m_numberOfToys);
1589  globalEfficiencies.mc() =
1590  double(nPassed[1]) / double(m_parent->m_numberOfToys);
1591  return true;
1592 }
1593 
1594 Calculator::Helper::Helper(const std::vector<TrigDef>& defs)
1595  : m_formula(nullptr), m_defs(defs) {}
1596 
1598  for (auto itr1 = m_defs.cbegin(); itr1 != m_defs.cend(); ++itr1)
1599  for (auto itr2 = itr1 + 1; itr2 != m_defs.cend(); ++itr2)
1600  if (itr1->type == itr2->type && itr1->leg == itr2->leg)
1601  return true;
1602  return false;
1603 }
1604 
1606 {
1608 template <typename T>
1610  using TrigType = T;
1611  using ArgType = std::add_const_t<T>;
1612  static constexpr bool multiple() { return false; }
1613  static constexpr bool optional() { return false; }
1614  static void add(T& arg, ImportData::TrigDef& def) { arg.setDefinition(def); }
1615  static constexpr bool valid(const T& arg) { return bool(arg); }
1616 };
1617 
1618 template <typename T>
1620  using TrigType = T;
1621  using ArgType = const flat_set<T>&;
1622  static constexpr bool multiple() { return true; }
1623  static constexpr bool optional() { return false; }
1624  static void add(flat_set<T>& arg, ImportData::TrigDef& def) {
1625  arg.emplace().first->setDefinition(def);
1626  }
1627  static constexpr bool valid(const flat_set<T>& arg) { return arg.size(); }
1628 };
1629 
1630 template <typename T>
1632  Calculator::Helper::Optional<T>> {
1635  static constexpr bool multiple() { return BindPackedParam<T>::multiple(); }
1636  static constexpr bool optional() { return true; }
1637  static void add(std::remove_cv_t<std::remove_reference_t<ArgType>>& arg,
1638  ImportData::TrigDef def) {
1640  }
1641  static constexpr bool valid(ArgType& arg) {
1643  }
1644 };
1645 } // namespace TrigGlobEffCorr
1646 
1647 template <typename Param>
1649  std::remove_cv_t<std::remove_reference_t<typename Param::ArgType>> trigs;
1650  for (auto& def : m_defs) {
1651  if (def.used || def.type != Param::TrigType::type())
1652  continue;
1653  def.used = true;
1654  Param::add(trigs, def);
1655  if (!Param::multiple())
1656  break;
1657  }
1658  if (!Param::optional() && !Param::valid(trigs))
1659  throw NoSuchTrigger();
1660  return trigs;
1661 }
1662 
1663 template <typename... Trigs>
1665  for (auto& def : m_defs)
1666  def.used = false;
1667  using fnptr = bool (Calculator::*)(
1669  Efficiencies&);
1670  try {
1671  m_formula =
1672  std::bind<fnptr>(&Calculator::globalEfficiency, ::_1, ::_2, ::_3,
1673  extract<BindPackedParam<Trigs>>()..., ::_4);
1674  if (std::all_of(m_defs.cbegin(), m_defs.cend(),
1675  [](auto& def) { return def.used; }))
1676  return true;
1677  } catch (NoSuchTrigger) {
1678  }
1679  m_formula = nullptr;
1680  return false;
1681 }
1682 
1683 template <TriggerType object_flag>
1685 {
1687  using A = TriggerClass<object_flag>;
1688  using A1L = flat_set<typename A::T_1>;
1689  using A_2sym = typename A::T_2sym;
1690  using A_2asym = typename A::T_2asym;
1691  if (m_n2L + m_n3L + m_n4L == 0) {
1692  return bindFunction<typename A::T_1>() || bindFunction<A1L>();
1693  } else if (m_n2L == 1 && m_n3L + m_n4L == 0) {
1694  return bindFunction<A_2sym>() || bindFunction<A_2asym>() ||
1695  bindFunction<A_2sym, A1L>() || bindFunction<A_2asym, A1L>();
1696  } else if (m_n2L == 2 && m_n3L + m_n4L == 0) {
1697  return bindFunction<A_2sym, A_2sym, Optional<A1L>>() ||
1698  bindFunction<A_2asym, A_2sym, Optional<A1L>>();
1699  } else if (m_n3L == 1 && m_n1L + m_n2L + m_n4L == 0) {
1700  return bindFunction<typename A::T_3sym>() ||
1701  bindFunction<typename A::T_3halfsym>();
1702  } else if (m_n4L == 1 && m_n1L + m_n2L + m_n3L == 0) {
1703  return bindFunction<typename A::T_4sym>();
1704  }
1705  return false;
1706 }
1707 
1708 template <TriggerType object_flag1, TriggerType object_flag2>
1710 {
1713  using A = TriggerClass<object_flag1>;
1714  using B = TriggerClass<object_flag2>;
1716  using A_1 = typename A::T_1;
1717  using B_1 = typename B::T_1;
1718  using OA1L = Optional<flat_set<A_1>>;
1719  using OB1L = Optional<flat_set<B_1>>;
1720  using A_2sym = typename A::T_2sym;
1721  using B_2sym = typename B::T_2sym;
1722  using A_2asym = typename A::T_2asym;
1723  using B_2asym = typename B::T_2asym;
1724  using AB_1_1 = typename AB::T_1_1;
1725 
1728  if (m_n1L > 0 && m_n2L + m_n3L + m_n4L == 0) {
1729  return bindFunction<A_1, B_1>() ||
1730  bindFunction<flat_set<A_1>, flat_set<B_1>>();
1731  } else if (m_n2L == 1 &&
1732  m_n3L + m_n4L ==
1733  0) { // one dilepton trigger (+ single-lepton triggers)
1734  return bindFunction<AB_1_1>() ||
1735  bindFunction<AB_1_1, flat_set<A_1>, flat_set<B_1>>();
1736  } else if (m_n2L >= 2 && m_n2L <= 6 &&
1737  m_n3L + m_n4L ==
1738  0) { // several dilepton triggers (+ single-lepton triggers)
1739  return
1741  bindFunction<A_2sym, AB_1_1>() || bindFunction<A_2asym, AB_1_1>() ||
1742  bindFunction<B_2sym, AB_1_1>() ||
1743  bindFunction<B_2asym, AB_1_1>()
1745  || bindFunction<Optional<A_2sym>, Optional<B_2sym>, Optional<AB_1_1>,
1746  OA1L, OB1L>() ||
1748  OA1L, OB1L>() ||
1749  bindFunction<Optional<A_2sym>, Optional<B_2asym>, Optional<AB_1_1>,
1750  OA1L, OB1L>() ||
1752  OA1L, OB1L>()
1754  || bindFunction<Optional<A_2sym>, Optional<A_2sym>, Optional<B_2sym>,
1756  OA1L, OB1L>() ||
1759  OB1L>() ||
1760  bindFunction<Optional<A_2sym>, Optional<A_2sym>, Optional<B_2asym>,
1762  OB1L>() ||
1765  OB1L>();
1766  } else if (m_n3L == 1 &&
1767  m_n1L + m_n2L + m_n4L == 0) { // one mixed trilepton trigger
1768  return bindFunction<typename AB::T_2sym_1>() ||
1769  bindFunction<typename AB::T_1_2sym>() ||
1770  bindFunction<typename AB::T_2asym_1>() ||
1771  bindFunction<typename AB::T_1_2asym>();
1772  } else if (m_n3L == 2 &&
1773  m_n1L + m_n2L + m_n4L == 0) { // two mixed trilepton triggers
1774  return bindFunction<typename AB::T_2sym_1, typename AB::T_1_2sym>() ||
1775  bindFunction<typename AB::T_2asym_1, typename AB::T_1_2sym>() ||
1776  bindFunction<typename AB::T_2sym_1, typename AB::T_1_2asym>() ||
1777  bindFunction<typename AB::T_2asym_1, typename AB::T_1_2asym>();
1778  }
1779  return false;
1780 }
1781 
1783 {
1784  auto countTriggers = [&](auto nlep_flag) {
1785  return std::count_if(m_defs.cbegin(), m_defs.cend(),
1786  [=](auto& def) { return def.type & nlep_flag; });
1787  };
1788  m_n1L = countTriggers(TT_SINGLELEPTON_FLAG);
1789  m_n2L = countTriggers(TT_DILEPTON_FLAG);
1790  m_n3L = countTriggers(TT_TRILEPTON_FLAG);
1791  m_n4L = countTriggers(TT_TETRALEPTON_FLAG);
1792  auto exclusively = [&](auto obj_flags) {
1793  return std::none_of(m_defs.cbegin(), m_defs.cend(), [=](auto& def) {
1794  return def.type & TT_MASK_FLAVOUR & ~obj_flags;
1795  });
1796  };
1797 
1799  if (exclusively(TT_ELECTRON_FLAG))
1800  return findAndBindFunction<TT_ELECTRON_FLAG>();
1801  if (exclusively(TT_MUON_FLAG))
1802  return findAndBindFunction<TT_MUON_FLAG>();
1803  if (exclusively(TT_PHOTON_FLAG))
1804  return findAndBindFunction<TT_PHOTON_FLAG>();
1805 
1808  bool success = false;
1809  if (exclusively(TT_ELECTRON_FLAG | TT_MUON_FLAG))
1810  success = findAndBindFunction<TT_ELECTRON_FLAG, TT_MUON_FLAG>();
1811  else if (exclusively(TT_ELECTRON_FLAG | TT_PHOTON_FLAG))
1812  success = findAndBindFunction<TT_ELECTRON_FLAG, TT_PHOTON_FLAG>();
1813  else if (exclusively(TT_MUON_FLAG | TT_PHOTON_FLAG))
1814  success = findAndBindFunction<TT_MUON_FLAG, TT_PHOTON_FLAG>();
1815  if (success)
1816  return true;
1817 
1819  std::vector<Helper> helpers;
1820  for (auto obj_flag : {TT_ELECTRON_FLAG, TT_MUON_FLAG, TT_PHOTON_FLAG}) {
1821  if (std::any_of(m_defs.cbegin(),
1822  m_defs.cend(),
1823  [&](auto& def) {
1825  return (def.type & obj_flag) &&
1826  TriggerProperties(def.type).mixed();
1827  }))
1828  continue;
1829  std::vector<ImportData::TrigDef> trigs1, trigs2;
1830  std::partition_copy(m_defs.begin(), m_defs.end(),
1831  std::back_inserter(trigs1), std::back_inserter(trigs2),
1832  [&](auto& def) { return (def.type & obj_flag); });
1833  m_defs.swap(trigs2);
1834  if (!trigs1.size())
1835  continue;
1836  helpers.emplace_back(trigs1);
1837  if (!helpers.back().findAndBindFunction())
1838  return false;
1839  }
1840  if (helpers.size()) {
1841  if (m_defs.size()) {
1842  if (!findAndBindFunction())
1843  return false;
1844  if (helpers.size() == 1)
1846  ::_2, ::_3, std::move(m_formula),
1847  std::move(helpers[0].m_formula), ::_4);
1848  else if (helpers.size() == 2)
1850  ::_2, ::_3, std::move(m_formula),
1851  std::move(helpers[0].m_formula),
1852  std::move(helpers[1].m_formula), ::_4);
1853  else {
1854  m_formula = nullptr;
1855  return false;
1856  }
1857  } else {
1858  if (helpers.size() == 2)
1860  ::_2, ::_3, std::move(helpers[0].m_formula),
1861  std::move(helpers[1].m_formula), ::_4);
1862  else if (helpers.size() == 3)
1864  ::_2, ::_3, std::move(helpers[0].m_formula),
1865  std::move(helpers[1].m_formula),
1866  std::move(helpers[2].m_formula), ::_4);
1867  else
1868  return false;
1869  }
1870  return true;
1871  }
1872 
1873  return false;
1874 }
sTgcDigitEffiDump.efficiencies
list efficiencies
translate the station name indices into the string staiton name
Definition: sTgcDigitEffiDump.py:23
python.AtlRunQueryAMI.period
period
Definition: AtlRunQueryAMI.py:224
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam::add
static void add(T &arg, ImportData::TrigDef &def)
Definition: Calculator.cxx:1614
TrigGlobEffCorr::Calculator::addPeriod
bool addPeriod(ImportData &data, const std::pair< unsigned, unsigned > &boundaries, const std::string &combination, bool useToys, std::size_t &uniqueElectronLeg, std::size_t &uniquePhotonLeg)
Definition: Calculator.cxx:29
TrigGlobalEfficiencyCorrectionTool::getSortedLegs
std::vector< std::size_t > getSortedLegs(const TrigGlobEffCorr::Lepton &lepton, const flat_set< std::size_t > &legs, bool &success)
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
TrigGlobEffCorr::Calculator::m_forceUnitSF
bool m_forceUnitSF
Definition: Calculator.h:72
xAOD::Electron
Electron_v1 Electron
Definition of the current "egamma version".
Definition: Event/xAOD/xAODEgamma/xAODEgamma/Electron.h:17
Calculator.h
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam
Definition: Calculator.cxx:1609
runLayerRecalibration.chain
chain
Definition: runLayerRecalibration.py:175
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam::valid
static constexpr bool valid(const T &arg)
Definition: Calculator.cxx:1615
ObjectType
ObjectType
Definition: BaseObject.h:11
TrigGlobEffCorr::Calculator::m_periods
std::vector< Period > m_periods
pointer updated at each call to compute() because the parent tool might have been moved in-between
Definition: Calculator.h:69
TrigGlobEffCorr::Calculator::findUniqueLeg
bool findUniqueLeg(xAOD::Type::ObjectType obj, std::size_t &uniqueLeg, const std::vector< TrigDef > &defs)
Definition: Calculator.cxx:89
TrigGlobEffCorr::Lepton::photon
const xAOD::Photon * photon() const
Definition: Lepton.h:37
TrigGlobEffCorr
the template specializations below must be enclosed in this namespace
Definition: Calculator.cxx:1607
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam< flat_set< T > >::ArgType
const flat_set< T > & ArgType
Definition: Calculator.cxx:1621
asg
Definition: DataHandleTestTool.h:28
Efficiencies
TrigGlobEffCorr::Efficiencies Efficiencies
Definition: TrigGlobalEfficiencyCorrectionTool.cxx:30
ParticleTest.tp
tp
Definition: ParticleTest.py:25
TrigGlobEffCorr::TT_SINGLELEPTON_FLAG
@ TT_SINGLELEPTON_FLAG
Definition: ImportData.h:35
TrigGlobalEfficiencyCorrectionTool::m_useInternalSeed
bool m_useInternalSeed
Definition: TrigGlobalEfficiencyCorrectionTool.h:165
TrigGlobEffCorr::Efficiencies
Definition: Efficiencies.h:14
Lepton.h
TrigGlobEffCorr::Calculator::Helper::Helper
Helper(const std::vector< TrigDef > &defs)
Definition: Calculator.cxx:1594
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
python.TrigTLAMonitorAlgorithm.triggers
triggers
Definition: TrigTLAMonitorAlgorithm.py:196
Trigger.h
CheckTagAssociation.notfound
notfound
Definition: CheckTagAssociation.py:105
TrigGlobEffCorr::Calculator::Helper::BindPackedParam
to decorate the parameters of the findAndBind() function(s)
Definition: Calculator.h:317
x
#define x
TrigGlobEffCorr::TT_MUON_FLAG
@ TT_MUON_FLAG
Definition: ImportData.h:26
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam< flat_set< T > >::TrigType
T TrigType
Definition: Calculator.cxx:1620
xAOD::unsigned
unsigned
Definition: RingSetConf_v1.cxx:662
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
XMLtoHeader.count
count
Definition: XMLtoHeader.py:84
flat_set
boost::container::flat_set< Key > flat_set
Definition: CheckConfig.cxx:14
TrigGlobEffCorr::Calculator::aboveThreshold
bool aboveThreshold(const Lepton &p, std::size_t leg) const
Definition: Calculator.h:74
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:92
TrigGlobalEfficiencyCorrectionTool::m_seed
unsigned long m_seed
Definition: TrigGlobalEfficiencyCorrectionTool.h:188
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam< Calculator::Helper::Optional< T > >::optional
static constexpr bool optional()
Definition: Calculator.cxx:1636
TrigGlobEffCorr::TT_ELECTRON_FLAG
@ TT_ELECTRON_FLAG
Definition: ImportData.h:25
TRT::Hit::side
@ side
Definition: HitInfo.h:83
ImportData.h
runBeamSpotCalibration.helper
helper
Definition: runBeamSpotCalibration.py:115
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam< Calculator::Helper::Optional< T > >::multiple
static constexpr bool multiple()
Definition: Calculator.cxx:1635
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam::ArgType
std::add_const_t< T > ArgType
Definition: Calculator.cxx:1611
TrigGlobEffCorr::Calculator::compute
bool compute(TrigGlobalEfficiencyCorrectionTool &parent, const LeptonList &leptons, unsigned runNumber, Efficiencies &efficiencies)
Definition: Calculator.cxx:125
TrigGlobEffCorr::Lepton::tag
std::size_t tag() const
Definition: Lepton.h:30
TrigGlobalEfficiencyCorrectionTool::TLE_ERROR
@ TLE_ERROR
Definition: TrigGlobalEfficiencyCorrectionTool.h:243
calibdata.valid
list valid
Definition: calibdata.py:44
TrigGlobEffCorr::Calculator::Helper::extract
auto extract()
Definition: Calculator.cxx:1648
TrigGlobEffCorr::Calculator::globalEfficiency_Factorized2
bool globalEfficiency_Factorized2(const LeptonList &leptons, unsigned runNumber, GlobEffFunc func1, GlobEffFunc func2, Efficiencies &globalEfficiencies)
Definition: Calculator.cxx:1431
TrigGlobEffCorr::Calculator::Helper::duplicates
bool duplicates() const
Definition: Calculator.cxx:1597
A
TrigGlobEffCorr::Lepton::muon
const xAOD::Muon * muon() const
Definition: Lepton.h:34
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:209
TrigGlobEffCorr::ImportData::TrigDef::leg
std::array< std::size_t, 4 > leg
Definition: ImportData.h:93
TrigGlobEffCorr::Calculator::Helper::bindFunction
bool bindFunction()
Definition: Calculator.cxx:1664
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
TrigGlobEffCorr::TT_PHOTON_FLAG
@ TT_PHOTON_FLAG
Definition: ImportData.h:27
TrigGlobEffCorr::Calculator
Definition: Calculator.h:26
lumiFormat.i
int i
Definition: lumiFormat.py:85
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam::multiple
static constexpr bool multiple()
Definition: Calculator.cxx:1612
TrigGlobEffCorr::Calculator::m_cachedEfficiencies
std::map< std::pair< const Lepton *, std::size_t >, Efficiencies > m_cachedEfficiencies
Definition: Calculator.h:71
TrigGlobEffCorr::Calculator::Helper::m_n1L
unsigned m_n1L
Definition: Calculator.h:301
TrigGlobEffCorr::ImportData
Definition: ImportData.h:86
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
master.flag
bool flag
Definition: master.py:29
TrigGlobEffCorr::Calculator::m_parent
TrigGlobalEfficiencyCorrectionTool * m_parent
Definition: Calculator.h:66
res
std::pair< std::vector< unsigned int >, bool > res
Definition: JetGroupProductTest.cxx:11
asg::AsgMessaging::msg
MsgStream & msg() const
The standard message stream.
Definition: AsgMessaging.cxx:49
test_pyathena.parent
parent
Definition: test_pyathena.py:15
compute_lumi.leg
leg
Definition: compute_lumi.py:95
add
bool add(const std::string &hname, TKey *tobj)
Definition: fastadd.cxx:55
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam< flat_set< T > >::multiple
static constexpr bool multiple()
Definition: Calculator.cxx:1622
TrigGlobEffCorr::TT_TETRALEPTON_FLAG
@ TT_TETRALEPTON_FLAG
Definition: ImportData.h:79
TrigGlobalEfficiencyCorrectionTool::m_validTrigMatchTool
bool m_validTrigMatchTool
Definition: TrigGlobalEfficiencyCorrectionTool.h:189
xAOD::double
double
Definition: CompositeParticle_v1.cxx:159
TrigGlobalEfficiencyCorrectionTool::TLE_OK
@ TLE_OK
Definition: TrigGlobalEfficiencyCorrectionTool.h:243
TrigGlobEffCorr::TT_TRILEPTON_FLAG
@ TT_TRILEPTON_FLAG
Definition: ImportData.h:53
TrigGlobalEfficiencyCorrectionTool::TLE_UNAVAILABLE
@ TLE_UNAVAILABLE
Definition: TrigGlobalEfficiencyCorrectionTool.h:243
create_dcsc_inputs_sqlite.arg
list arg
Definition: create_dcsc_inputs_sqlite.py:48
TrigGlobEffCorr::Calculator::Helper::m_defs
std::vector< TrigDef > m_defs
Definition: Calculator.h:300
TrigGlobEffCorr::Calculator::Helper::NoSuchTrigger
Definition: Calculator.h:312
TrigGlobEffCorr::Efficiencies::mc
double & mc()
Definition: Efficiencies.h:24
TrigGlobEffCorr::Calculator::LeptonList
TrigGlobalEfficiencyCorrectionTool::LeptonList LeptonList
Definition: Calculator.h:27
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam< Calculator::Helper::Optional< T > >::ArgType
typename BindPackedParam< T >::ArgType ArgType
Definition: Calculator.cxx:1634
TrigGlobEffCorr::Lepton
Definition: Lepton.h:16
TrigGlobEffCorr::Calculator::checkTriggerMatching
bool checkTriggerMatching(TrigGlobalEfficiencyCorrectionTool &parent, bool &matched, const LeptonList &leptons, unsigned runNumber)
python.ElectronD3PDObject.matched
matched
Definition: ElectronD3PDObject.py:138
TrigGlobEffCorr::Calculator::globalEfficiency_Factorized3
bool globalEfficiency_Factorized3(const LeptonList &leptons, unsigned runNumber, GlobEffFunc func1, GlobEffFunc func2, GlobEffFunc func3, Efficiencies &globalEfficiencies)
Definition: Calculator.cxx:1443
TrigGlobalEfficiencyCorrectionTool
Definition: TrigGlobalEfficiencyCorrectionTool.h:37
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam< flat_set< T > >::valid
static constexpr bool valid(const flat_set< T > &arg)
Definition: Calculator.cxx:1627
TrigGlobEffCorr::Lepton::type
xAOD::Type::ObjectType type() const
Definition: Lepton.h:29
TrigGlobEffCorr::ImportData::TrigDef
Definition: ImportData.h:90
xAOD::Photon
Photon_v1 Photon
Definition of the current "egamma version".
Definition: Event/xAOD/xAODEgamma/xAODEgamma/Photon.h:17
Muon
struct TBPatternUnitContext Muon
Rtt_histogram.n1
n1
Definition: Rtt_histogram.py:21
TrigGlobalEfficiencyCorrectionTool::getTriggerLegEfficiencies
TLE_RESULT getTriggerLegEfficiencies(const xAOD::Electron *p, unsigned runNumber, std::size_t leg, std::size_t tag, TrigGlobEffCorr::Efficiencies &efficiencies)
DeMoAtlasDataLoss.runNumber
string runNumber
Definition: DeMoAtlasDataLoss.py:64
TrigGlobEffCorr::Calculator::Calculator
Calculator(TrigGlobalEfficiencyCorrectionTool &parent, unsigned nPeriodsToReserve)
Definition: Calculator.cxx:22
TrigGlobEffCorr::Calculator::getCachedTriggerLegEfficiencies
Efficiencies getCachedTriggerLegEfficiencies(const Lepton &lepton, unsigned runNumber, std::size_t leg, bool &success)
Definition: Calculator.cxx:276
TrigGlobalEfficiencyCorrectionTool::m_trigMatchTool
ToolHandle< Trig::IMatchingTool > m_trigMatchTool
Definition: TrigGlobalEfficiencyCorrectionTool.h:166
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
TrigGlobEffCorr::Calculator::Helper::m_n3L
unsigned m_n3L
Definition: Calculator.h:301
TrigGlobEffCorr::Calculator::Helper::m_n4L
unsigned m_n4L
Definition: Calculator.h:301
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam< flat_set< T > >::add
static void add(flat_set< T > &arg, ImportData::TrigDef &def)
Definition: Calculator.cxx:1624
TrigGlobalEfficiencyCorrectionTool::m_numberOfToys
unsigned long m_numberOfToys
Definition: TrigGlobalEfficiencyCorrectionTool.h:164
TrigGlobEffCorr::Calculator::Helper::m_formula
std::function< bool(Calculator *, const LeptonList &, unsigned, Efficiencies &)> m_formula
Definition: Calculator.h:295
if
if(febId1==febId2)
Definition: LArRodBlockPhysicsV0.cxx:567
TrigGlobEffCorr::TT_DILEPTON_FLAG
@ TT_DILEPTON_FLAG
Definition: ImportData.h:40
TrigGlobEffCorr::Calculator::Helper::findAndBindFunction
bool findAndBindFunction()
top-level function
Definition: Calculator.cxx:1782
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam< Calculator::Helper::Optional< T > >::add
static void add(std::remove_cv_t< std::remove_reference_t< ArgType >> &arg, ImportData::TrigDef def)
Definition: Calculator.cxx:1637
LArCellBinning.step
step
Definition: LArCellBinning.py:158
TrigGlobEffCorr::TriggerProperties
Definition: Trigger.h:27
TrigGlobEffCorr::Calculator::globalEfficiency
auto globalEfficiency(const LeptonList &, unsigned, const Trig1L, Efficiencies &) -> std::enable_if_t< Trig1L::is1L(), bool >
One single-lepton trigger.
Definition: Calculator.cxx:324
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam< flat_set< T > >::optional
static constexpr bool optional()
Definition: Calculator.cxx:1623
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam< Calculator::Helper::Optional< T > >::TrigType
typename BindPackedParam< T >::TrigType TrigType
Definition: Calculator.cxx:1633
TrigGlobEffCorr::Calculator::Helper
Definition: Calculator.h:288
TrigGlobEffCorr::Calculator::fillListOfLegsFor
bool fillListOfLegsFor(const Lepton &lepton, const std::vector< TrigDef > &triggers, flat_set< std::size_t > &validLegs) const
Definition: Calculator.cxx:1458
pickleTool.object
object
Definition: pickleTool.py:29
dqt_zlumi_alleff_HIST.eff
int eff
Definition: dqt_zlumi_alleff_HIST.py:113
TrigGlobEffCorr::Calculator::canTriggerBeFired
bool canTriggerBeFired(const TrigDef &trig, const std::vector< flat_set< std::size_t > > &firedLegs) const
Definition: Calculator.cxx:1476
TrigGlobEffCorr::Efficiencies::data
double & data()
Definition: Efficiencies.h:23
TrigGlobalEfficiencyCorrectionTool::retrieveEventNumber
bool retrieveEventNumber(unsigned long &eventNumber)
TrigGlobEffCorr::Calculator::globalEfficiency_Toys
bool globalEfficiency_Toys(const LeptonList &, unsigned, const std::vector< TrigDef > &triggers, Efficiencies &)
Definition: Calculator.cxx:1524
TrigGlobEffCorr::Calculator::getRelevantTriggersForUser
bool getRelevantTriggersForUser(TrigGlobalEfficiencyCorrectionTool &parent, std::vector< std::string > &triggers, unsigned runNumber)
Definition: Calculator.cxx:244
python.PyAthena.obj
obj
Definition: PyAthena.py:132
TrigGlobEffCorr::TriggerClass
Definition: Trigger.h:373
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam::optional
static constexpr bool optional()
Definition: Calculator.cxx:1613
xAOD::bool
setBGCode setTAP setLVL2ErrorBits bool
Definition: TrigDecision_v1.cxx:60
TrigGlobalEfficiencyCorrectionTool::m_dictionary
std::map< std::size_t, std::string > m_dictionary
Definition: TrigGlobalEfficiencyCorrectionTool.h:180
TrigGlobEffCorr::Calculator::Helper::m_n2L
unsigned m_n2L
Definition: Calculator.h:301
TrigGlobEffCorr::Calculator::GlobEffFunc
std::function< bool(Calculator *, const LeptonList &, unsigned, Efficiencies &)> GlobEffFunc
Definition: Calculator.h:30
TrigGlobEffCorr::Calculator::Period
Definition: Calculator.h:53
TrigGlobEffCorr::Lepton::electron
const xAOD::Electron * electron() const
Definition: Lepton.h:31
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam< Calculator::Helper::Optional< T > >::valid
static constexpr bool valid(ArgType &arg)
Definition: Calculator.cxx:1641
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam::TrigType
T TrigType
Definition: Calculator.cxx:1610
TrigGlobEffCorr::Calculator::Helper::Optional
Definition: Calculator.h:314
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
TrigGlobEffCorr::Calculator::getPeriod
const Period * getPeriod(unsigned runNumber) const
Definition: Calculator.cxx:111