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  const LeptonList& leptons, unsigned runNumber) {
147  matched = false;
148  m_parent = &parent;
149  auto period = getPeriod(runNumber);
150  if (!period)
151  return false;
152  if (!period->m_triggers.size()) {
153  ATH_MSG_ERROR("Empty list of triggers for run number " << runNumber);
154  return false;
155  }
156  auto& trigMatchTool = m_parent->m_trigMatchTool;
157 
160  const unsigned nLep = leptons.size();
161  std::vector<flat_set<std::size_t>> validLegs(leptons.size());
162  for (unsigned i = 0; i < nLep; ++i) {
163  if (!fillListOfLegsFor(leptons[i], period->m_triggers, validLegs[i]))
164  return false;
165  }
166 
169  std::vector<flat_set<std::size_t>> firedLegs;
170  std::vector<const xAOD::IParticle*> trigLeptons;
171  const std::size_t magicWordHLT = 0xf7b8b87ef2917d66;
172 
173  for (auto& trig : period->m_triggers) {
175  auto itr = m_parent->m_dictionary.find(trig.name ^ magicWordHLT);
176  if (itr == m_parent->m_dictionary.end()) {
177  itr = m_parent->m_dictionary
178  .emplace(trig.name ^ magicWordHLT,
179  "HLT_" + m_parent->m_dictionary.at(trig.name))
180  .first;
181  }
182  const std::string& chain = itr->second;
183 
184  unsigned nLegs = 0;
185  if (trig.type & TT_SINGLELEPTON_FLAG)
186  nLegs = 1;
187  else if (trig.type & TT_DILEPTON_FLAG)
188  nLegs = 2;
189  else if (trig.type & TT_TRILEPTON_FLAG)
190  nLegs = 3;
191  else {
192  ATH_MSG_ERROR("Unsupported trigger (type = "
193  << std::hex << trig.type << std::dec << ") " << chain);
194  return false;
195  }
196  firedLegs.resize(nLegs);
197  trigLeptons.resize(nLegs);
198  for (unsigned i0 = 0; i0 < nLep; ++i0) {
199  firedLegs[0].swap(validLegs[i0]);
200  trigLeptons[0] = leptons[i0].particle();
202  if (nLegs == 1) {
203  if (canTriggerBeFired(
204  trig, firedLegs)
205  && trigMatchTool->match(trigLeptons, chain))
206  return (matched = true);
207  } else
208  for (unsigned i1 = i0 + 1; i1 < nLep; ++i1) {
209  firedLegs[1].swap(validLegs[i1]);
210  trigLeptons[1] = leptons[i1].particle();
211  if (nLegs == 2) {
212  if (canTriggerBeFired(trig, firedLegs) &&
213  trigMatchTool->match(trigLeptons, chain))
214  return (matched = true);
215  } else
216  for (unsigned i2 = i1 + 1; i2 < nLep; ++i2) {
217  firedLegs[2].swap(validLegs[i2]);
218  trigLeptons[2] = leptons[i2].particle();
219  if (canTriggerBeFired(trig, firedLegs) &&
220  trigMatchTool->match(trigLeptons, chain))
221  return (matched = true);
222  firedLegs[2].swap(validLegs[i2]);
223  }
224  firedLegs[1].swap(validLegs[i1]);
225  }
226  firedLegs[0].swap(
227  validLegs[i0]);
228  }
229  }
230  return true;
231 }
232 
235  std::vector<std::string>& triggers, unsigned runNumber) {
236  triggers.clear();
237  m_parent = &parent;
238  auto period = getPeriod(runNumber);
239  if (!period)
240  return false;
241  if (!period->m_triggers.size()) {
242  ATH_MSG_ERROR("Empty list of triggers for run number "
243  << runNumber
244  << " (was there a configuration issue? please check for "
245  "warnings during initialization)");
246  return false;
247  }
248  bool success = true;
249  auto notfound = parent.m_dictionary.end();
250  for (auto& trig : period->m_triggers) {
251  auto itr = parent.m_dictionary.find(trig.name);
252  if (itr == notfound) {
253  ATH_MSG_ERROR("can't retrieve name of trigger with hash "
254  << trig.name
255  << " (shouldn't happen; contact tool developers!)");
256  success = false;
257  } else
258  triggers.push_back(itr->second);
259  }
260  if (!success)
261  triggers.clear();
262  return success;
263 }
264 
266  unsigned runNumber,
267  std::size_t leg,
268  bool& success) {
269  auto insertion = m_cachedEfficiencies.emplace(std::make_pair(&lepton, leg),
270  Efficiencies());
271  Efficiencies& efficiencies = insertion.first->second;
272  if (insertion.second) {
274  switch (lepton.type()) {
277  lepton.electron(), runNumber, leg, lepton.tag(), efficiencies);
278  break;
279  case xAOD::Type::Muon:
281  lepton.tag(), efficiencies);
282  break;
283  case xAOD::Type::Photon:
285  lepton.photon(), runNumber, leg, lepton.tag(), efficiencies);
286  break;
287  default:
288  ATH_MSG_ERROR("Unsupported particle type");
289  }
290  switch (res) {
292  break;
294  m_forceUnitSF = true;
295  break;
297  [[fallthrough]];
298  default:
299  success = false;
300  efficiencies.data() = -777.;
301  efficiencies.mc() = -777.;
302  }
303  }
304  if (efficiencies.mc() == -777. && !m_forceUnitSF)
305  success = false;
306  return efficiencies;
307 }
308 
312 template <typename Trig1L>
313 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
314  const Trig1L trig,
315  Efficiencies& globalEfficiencies)
316  -> std::enable_if_t<Trig1L::is1L(), bool> {
317  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_One1L() at line "
318  << __LINE__);
319  if (!trig) {
320  globalEfficiencies = {0.};
321  return true;
322  }
323  globalEfficiencies = {1.};
324  bool success = true;
325  for (auto& lepton : leptons) {
326  if (trig.irrelevantFor(lepton) || !aboveThreshold(lepton, trig()))
327  continue;
328  auto efficiencies =
329  getCachedTriggerLegEfficiencies(lepton, runNumber, trig(), success);
330  globalEfficiencies *= ~efficiencies;
331  }
332  globalEfficiencies = ~globalEfficiencies;
333  return success;
334 }
335 
339 template <typename Trig1L_obj1, typename Trig1L_obj2>
340 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
341  const Trig1L_obj1 trig1,
342  const Trig1L_obj2 trig2,
343  Efficiencies& globalEfficiencies)
344  -> std::enable_if_t<Trig1L_obj1::is1L() && Trig1L_obj2::is1L() &&
346  bool> {
347  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_Two1L() at line "
348  << __LINE__);
349  if (!trig1)
350  return globalEfficiency(leptons, runNumber, trig2, globalEfficiencies);
351  if (!trig2)
352  return globalEfficiency(leptons, runNumber, trig1, globalEfficiencies);
353  globalEfficiencies = {1.};
354  bool success = true;
355  for (auto& lepton : leptons) {
356  std::size_t leg;
357  if (trig1.relevantFor(lepton))
358  leg = trig1();
359  else if (trig2.relevantFor(lepton))
360  leg = trig2();
361  else
362  continue;
363  if (!aboveThreshold(lepton, leg))
364  continue;
365  auto efficiencies =
366  getCachedTriggerLegEfficiencies(lepton, runNumber, leg, success);
367  globalEfficiencies *= ~efficiencies;
368  }
369  globalEfficiencies = ~globalEfficiencies;
370  return success;
371 }
372 
376 template <typename Trig1L>
377 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
378  const flat_set<Trig1L>& trigs,
379  Efficiencies& globalEfficiencies)
380  -> std::enable_if_t<Trig1L::is1L(), bool> {
381  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_Several1L() at line "
382  << __LINE__);
383  if (trigs.size() == 1)
384  return globalEfficiency(leptons, runNumber, *trigs.cbegin(),
385  globalEfficiencies);
386  if (!trigs.size()) {
387  globalEfficiencies = {0.};
388  return true;
389  }
390  globalEfficiencies = {1.};
391  bool success = true;
392  for (auto& lepton : leptons) {
393  if (Trig1L::irrelevantFor(lepton))
394  continue;
395  std::size_t loosestLeg =
396  getLoosestLegAboveThreshold(lepton, trigs, success);
397  if (loosestLeg && success) {
398  auto efficiencies = getCachedTriggerLegEfficiencies(lepton, runNumber,
399  loosestLeg, success);
400  globalEfficiencies *= ~efficiencies;
401  }
402  }
403  globalEfficiencies = ~globalEfficiencies;
404  return success;
405 }
406 
410 template <typename Trig1L_obj1, typename Trig1L_obj2>
411 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
412  const flat_set<Trig1L_obj1>& trigs1,
413  const flat_set<Trig1L_obj2>& trigs2,
414  Efficiencies& globalEfficiencies)
415  -> std::enable_if_t<Trig1L_obj1::is1L() && Trig1L_obj2::is1L() &&
417  bool> {
418  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_Several1L() at line "
419  << __LINE__);
420  if (trigs1.size() == 1 && trigs2.size() == 1) {
421  return globalEfficiency(leptons, runNumber, *trigs1.cbegin(),
422  *trigs2.cbegin(), globalEfficiencies);
423  }
424  if (!trigs1.size())
425  return globalEfficiency(leptons, runNumber, trigs2, globalEfficiencies);
426  if (!trigs2.size())
427  return globalEfficiency(leptons, runNumber, trigs1, globalEfficiencies);
428  globalEfficiencies = {1.};
429  bool success = true;
430  for (auto& lepton : leptons) {
431  std::size_t loosestLeg;
432  if (Trig1L_obj1::relevantFor(lepton))
433  loosestLeg = getLoosestLegAboveThreshold(lepton, trigs1, success);
434  else if (Trig1L_obj2::relevantFor(lepton))
435  loosestLeg = getLoosestLegAboveThreshold(lepton, trigs2, success);
436  else
437  continue;
438  if (loosestLeg && success) {
439  auto efficiencies = getCachedTriggerLegEfficiencies(lepton, runNumber,
440  loosestLeg, success);
441  globalEfficiencies *= ~efficiencies;
442  }
443  }
444  globalEfficiencies = ~globalEfficiencies;
445  return success;
446 }
447 
451 template <typename Trig2Lmix>
452 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
453  const Trig2Lmix trig,
454  Efficiencies& globalEfficiencies)
455  -> std::enable_if_t<Trig2Lmix::is2Lmix(), bool> {
456  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_One2L() at line "
457  << __LINE__);
459  bool success =
460  globalEfficiency(leptons, runNumber, trig.side1(), efficiencies[0]) &&
461  globalEfficiency(leptons, runNumber, trig.side2(), efficiencies[1]);
462  if (success)
463  globalEfficiencies = efficiencies[0] * efficiencies[1];
464  else
465  globalEfficiencies = {0.};
466  return success;
467 }
468 
472 template <typename Trig2Lsym>
473 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
474  const Trig2Lsym trig,
475  Efficiencies& globalEfficiencies)
476  -> std::enable_if_t<Trig2Lsym::is2Lsym(), bool> {
477  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_One2L() at line "
478  << __LINE__);
479  globalEfficiencies = {0.};
480  if (!trig)
481  return true;
482  Efficiencies singleInefficiencies(1.);
483  bool success = true;
484  for (auto& lepton : leptons) {
485  if (trig.irrelevantFor(lepton) || !aboveThreshold(lepton, trig()))
486  continue;
487  auto efficiencies =
488  getCachedTriggerLegEfficiencies(lepton, runNumber, trig(), success);
489  globalEfficiencies = ~efficiencies * globalEfficiencies +
490  efficiencies * ~singleInefficiencies;
491  singleInefficiencies *= ~efficiencies;
492  }
493  return success;
494 }
495 
499 template <typename Trig2Lasym>
500 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
501  const Trig2Lasym trig,
502  Efficiencies& globalEfficiencies)
503  -> std::enable_if_t<Trig2Lasym::is2Lasym(), bool> {
504  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_One2L() at line "
505  << __LINE__);
506  if (trig.symmetric())
507  return globalEfficiency(leptons, runNumber, trig.to_symmetric(),
508  globalEfficiencies);
509  globalEfficiencies = {0.};
510  if (!trig)
511  return true;
512  Efficiencies singleInefficiencies[2] = {{1.}, {1.}},
513  twoSingleInefficiencies = {1.};
514  bool success = true;
515  for (auto& lepton : leptons) {
516  if (trig.irrelevantFor(lepton))
517  continue;
518  Efficiencies efficiencies[2] = {{0.}, {0.}};
519  int loosest = 0;
520  if (aboveThreshold(lepton, trig(0))) {
521  efficiencies[0] =
522  getCachedTriggerLegEfficiencies(lepton, runNumber, trig(0), success);
523  if (aboveThreshold(lepton, trig(1))) {
524  efficiencies[1] = getCachedTriggerLegEfficiencies(lepton, runNumber,
525  trig(1), success);
526  loosest = m_parent->getLoosestLeg(lepton, trig(0), trig(1), success) ==
527  trig(1);
528  }
529  } else if (aboveThreshold(lepton, trig(1))) {
530  efficiencies[1] =
531  getCachedTriggerLegEfficiencies(lepton, runNumber, trig(1), success);
532  loosest = 1;
533  } else
534  continue;
535  const int tightest = 1 - loosest;
536  globalEfficiencies = ~efficiencies[loosest] * globalEfficiencies +
537  (efficiencies[loosest] - efficiencies[tightest]) *
538  ~singleInefficiencies[tightest] +
539  efficiencies[tightest] * ~twoSingleInefficiencies;
540  twoSingleInefficiencies *= ~efficiencies[loosest];
541  for (int i = 0; i < 2; ++i)
542  singleInefficiencies[i] *= ~efficiencies[i];
543  }
544  return success;
545 }
546 
550 template <typename Trig2Lmix, typename Trig1L_obj1, typename Trig1L_obj2>
551 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
552  const Trig2Lmix trig2Lmix,
553  const flat_set<Trig1L_obj1>& trigs1L1,
554  const flat_set<Trig1L_obj2>& trigs1L2,
555  Efficiencies& globalEfficiencies)
556  -> std::enable_if_t<Trig2Lmix::is2Lmix() && Trig1L_obj1::is1L() &&
557  Trig2Lmix::object1() == Trig1L_obj1::object() &&
558  Trig1L_obj2::is1L() &&
559  Trig2Lmix::object2() == Trig1L_obj2::object(),
560  bool> {
561  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_One2LSeveral1L() at line "
562  << __LINE__);
563  if (!(trigs1L1.size() + trigs1L2.size()))
564  return globalEfficiency(leptons, runNumber, trig2Lmix, globalEfficiencies);
565  if (trig2Lmix.hiddenBy(trigs1L1) || trig2Lmix.hiddenBy(trigs1L2))
566  return globalEfficiency(leptons, runNumber, trigs1L1, trigs1L2,
567  globalEfficiencies);
569  bool success =
570  globalEfficiency(leptons, runNumber, trigs1L1, efficiencies[0]) &&
571  globalEfficiency(leptons, runNumber, trigs1L2, efficiencies[1]) &&
572  globalEfficiency(leptons, runNumber, trig2Lmix.addTo(trigs1L1),
573  efficiencies[2]) &&
574  globalEfficiency(leptons, runNumber, trig2Lmix.addTo(trigs1L2),
575  efficiencies[3]);
576  if (success) {
577  globalEfficiencies = Efficiencies(1.) -
578  ~efficiencies[0] * ~efficiencies[1] +
579  (efficiencies[2] - efficiencies[0]) *
580  (efficiencies[3] - efficiencies[1]);
581  } else
582  globalEfficiencies = {0.};
583  return success;
584 }
585 
589 template <typename Trig2L, typename Trig1L>
590 inline auto Calculator::globalEfficiency(const LeptonList& leptons,
591  unsigned runNumber,
592  const Trig2L trig2L,
593  const Trig1L trig1L,
594  Efficiencies& globalEfficiencies)
595  -> std::enable_if_t<Trig2L::is2Lnomix() && Trig1L::is1L() &&
597  bool> {
598  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_One2LSeveral1L() at line "
599  << __LINE__);
600  return globalEfficiency(leptons, runNumber, trig2L, flat_set<Trig1L>{trig1L},
601  globalEfficiencies);
602 }
603 
607 template <typename Trig2Lsym, typename Trig1L>
608 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
609  const Trig2Lsym trig2L,
610  const flat_set<Trig1L>& trigs1L,
611  Efficiencies& globalEfficiencies)
612  -> std::enable_if_t<Trig2Lsym::is2Lsym() && Trig1L::is1L() &&
614  bool> {
615  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_One2LSeveral1L() at line "
616  << __LINE__);
617  if (!trigs1L.size())
618  return globalEfficiency(leptons, runNumber, trig2L, globalEfficiencies);
619  if (!trig2L || trig2L.hiddenBy(trigs1L))
620  return globalEfficiency(leptons, runNumber, trigs1L, globalEfficiencies);
621  globalEfficiencies = {0.};
622  Efficiencies twoSingleInefficiencies = {1.};
623  bool success = true;
624  for (auto& lepton : leptons) {
625  if (trig2L.irrelevantFor(lepton))
626  continue;
627  Efficiencies efficiencies1L(0.), efficiencies2L(0.);
628  const Efficiencies* loosestLegEfficiency;
629  std::size_t loosest1lepLeg =
630  getLoosestLegAboveThreshold(lepton, trigs1L, success);
631  if (loosest1lepLeg) {
632  efficiencies1L = getCachedTriggerLegEfficiencies(lepton, runNumber,
633  loosest1lepLeg, success);
634  if (aboveThreshold(lepton, trig2L())) {
635  efficiencies2L = getCachedTriggerLegEfficiencies(lepton, runNumber,
636  trig2L(), success);
637  loosestLegEfficiency =
638  (m_parent->getLoosestLeg(lepton, trig2L(), loosest1lepLeg,
639  success) == trig2L())
640  ? &efficiencies2L
641  : &efficiencies1L;
642  } else
643  loosestLegEfficiency = &efficiencies1L;
644  } else if (aboveThreshold(lepton, trig2L())) {
645  efficiencies2L =
646  getCachedTriggerLegEfficiencies(lepton, runNumber, trig2L(), success);
647  loosestLegEfficiency = &efficiencies2L;
648  } else
649  continue;
650  globalEfficiencies =
651  ~(*loosestLegEfficiency) * globalEfficiencies + efficiencies1L;
652  if (loosestLegEfficiency == &efficiencies2L)
653  globalEfficiencies +=
654  ~twoSingleInefficiencies * (efficiencies2L - efficiencies1L);
655  twoSingleInefficiencies *= ~(*loosestLegEfficiency);
656  }
657  return success;
658 }
659 
663 template <typename Trig2Lasym, typename Trig1L>
664 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
665  const Trig2Lasym trig2L,
666  const flat_set<Trig1L>& trigs1L,
667  Efficiencies& globalEfficiencies)
668  -> std::enable_if_t<Trig2Lasym::is2Lasym() && Trig1L::is1L() &&
670  bool> {
671  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_One2LSeveral1L() at line "
672  << __LINE__);
673  if (trig2L.symmetric())
674  return globalEfficiency(leptons, runNumber, trig2L.to_symmetric(), trigs1L,
675  globalEfficiencies);
676  if (!trigs1L.size())
677  return globalEfficiency(leptons, runNumber, trig2L, globalEfficiencies);
678  if (!trig2L || trig2L.hiddenBy(trigs1L))
679  return globalEfficiency(leptons, runNumber, trigs1L, globalEfficiencies);
680  globalEfficiencies = {0.};
681  Efficiencies twoSingleInefficiencies[2] = {{1.}, {1.}},
682  threeSingleInefficiencies = {1.};
683  bool success = true;
684  for (auto& lepton : leptons) {
685  if (trig2L.irrelevantFor(lepton))
686  continue;
687  flat_set<std::size_t> validLegs;
688  for (std::size_t leg : trig2L.legs)
689  if (aboveThreshold(lepton, leg))
690  validLegs.insert(leg);
691  Efficiencies efficiencies1L = {0.};
692  std::size_t loosest1lepLeg =
693  getLoosestLegAboveThreshold(lepton, trigs1L, success);
694  if (loosest1lepLeg) {
695  efficiencies1L = getCachedTriggerLegEfficiencies(lepton, runNumber,
696  loosest1lepLeg, success);
697  validLegs.insert(loosest1lepLeg);
698  }
699  if (!validLegs.size())
700  continue;
701  auto looseLegs = m_parent->getTwoLoosestLegs(lepton, validLegs, success);
702  auto efficienciesLoose =
703  (looseLegs.first == loosest1lepLeg)
704  ? efficiencies1L
705  : getCachedTriggerLegEfficiencies(lepton, runNumber,
706  looseLegs.first, success);
707  Efficiencies efficienciesMedium = {0.};
708  if (validLegs.size() >= 2)
709  efficienciesMedium =
710  (looseLegs.second == loosest1lepLeg)
711  ? efficiencies1L
712  : getCachedTriggerLegEfficiencies(lepton, runNumber,
713  looseLegs.second, success);
714  globalEfficiencies =
715  ~efficienciesLoose * globalEfficiencies + efficiencies1L;
716  if (loosest1lepLeg != looseLegs.first) {
717  globalEfficiencies +=
718  (efficienciesLoose - efficienciesMedium) *
719  ~twoSingleInefficiencies[looseLegs.first == trig2L.legs[0]];
720  if (loosest1lepLeg != looseLegs.second)
721  globalEfficiencies +=
722  (efficienciesMedium - efficiencies1L) * ~threeSingleInefficiencies;
723  }
724  threeSingleInefficiencies *= ~efficienciesLoose;
725  twoSingleInefficiencies[0] *= (looseLegs.first != trig2L.legs[1])
726  ? ~efficienciesLoose
727  : ~efficienciesMedium;
728  twoSingleInefficiencies[1] *= (looseLegs.first != trig2L.legs[0])
729  ? ~efficienciesLoose
730  : ~efficienciesMedium;
731  }
732  return success;
733 }
734 
738 template <typename Trig2Lsym, typename Trig1L>
739 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
740  const Trig2Lsym trig2L1,
741  const Trig2Lsym trig2L2,
742  const flat_set<Trig1L>& trigs1L,
743  Efficiencies& globalEfficiencies)
744  -> std::enable_if_t<Trig2Lsym::is2Lsym() && Trig1L::is1L() &&
746  bool> {
747  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_Two2LSeveral1L() at line "
748  << __LINE__);
749  if (!trig2L1 || trig2L1 == trig2L2 || trig2L1.hiddenBy(trigs1L))
750  return globalEfficiency(leptons, runNumber, trig2L2, trigs1L,
751  globalEfficiencies);
752  if (!trig2L2 || trig2L2.hiddenBy(trigs1L))
753  return globalEfficiency(leptons, runNumber, trig2L1, trigs1L,
754  globalEfficiencies);
755  globalEfficiencies = {0.};
756  Efficiencies singleInefficiencies{1.};
757  Efficiencies efficiencies2Lsym[2] = {{0.}, {0.}};
758 
759  bool success = true;
760  for (auto& lepton : leptons) {
761  if (trig2L1.irrelevantFor(lepton))
762  continue;
763  flat_set<std::size_t> validLegs;
764  std::map<std::size_t, Efficiencies> efficiencies{{0, 0.}};
765  std::size_t loosest1lepLeg =
766  getLoosestLegAboveThreshold(lepton, trigs1L, success);
767  for (std::size_t leg : {loosest1lepLeg, trig2L1(), trig2L2()}) {
768  if (leg && aboveThreshold(lepton, leg)) {
769  validLegs.insert(leg);
770  efficiencies.emplace(leg, getCachedTriggerLegEfficiencies(
771  lepton, runNumber, leg, success));
772  } else
773  efficiencies.emplace(leg, 0.);
774  }
775  if (!validLegs.size())
776  continue;
777  auto looseLegs = m_parent->getTwoLoosestLegs(lepton, validLegs, success);
778  std::size_t lambda13 =
779  (looseLegs.first != trig2L2()) ? looseLegs.first : looseLegs.second;
780  std::size_t lambda23 =
781  (looseLegs.first != trig2L1()) ? looseLegs.first : looseLegs.second;
782  globalEfficiencies = globalEfficiencies * ~efficiencies[looseLegs.first] +
783  efficiencies[loosest1lepLeg];
784  if (looseLegs.first == trig2L1())
785  globalEfficiencies +=
786  efficiencies2Lsym[1] *
787  (efficiencies[trig2L1()] - efficiencies[looseLegs.second]);
788  if (looseLegs.first == trig2L2())
789  globalEfficiencies +=
790  efficiencies2Lsym[0] *
791  (efficiencies[trig2L2()] - efficiencies[looseLegs.second]);
792  if (looseLegs.first != loosest1lepLeg)
793  globalEfficiencies +=
794  ~singleInefficiencies *
795  (efficiencies[looseLegs.second] - efficiencies[loosest1lepLeg]);
796  efficiencies2Lsym[0] =
797  ~efficiencies[looseLegs.first] * efficiencies2Lsym[0] +
798  efficiencies[lambda23];
799  efficiencies2Lsym[1] =
800  ~efficiencies[looseLegs.first] * efficiencies2Lsym[1] +
801  efficiencies[lambda13];
802  if (looseLegs.first == trig2L1())
803  efficiencies2Lsym[0] +=
804  (efficiencies[trig2L1()] - efficiencies[lambda23]) *
805  ~singleInefficiencies;
806  if (looseLegs.first == trig2L2())
807  efficiencies2Lsym[1] +=
808  (efficiencies[trig2L2()] - efficiencies[lambda13]) *
809  ~singleInefficiencies;
810  singleInefficiencies *= ~efficiencies[looseLegs.first];
811  }
812  return success;
813 }
814 
818 template <typename Trig2Lasym, typename Trig2Lsym, typename Trig1L>
819 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
820  const Trig2Lasym trig2Lasym,
821  const Trig2Lsym trig2Lsym,
822  const flat_set<Trig1L>& trigs1L,
823  Efficiencies& globalEfficiencies)
824  -> std::enable_if_t<Trig2Lasym::is2Lasym() && Trig2Lsym::is2Lsym() &&
826  Trig1L::is1L() &&
828  bool> {
829  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_Two2LSeveral1L() at line "
830  << __LINE__);
831  if (!trig2Lasym || trig2Lasym.hiddenBy(trigs1L))
832  return globalEfficiency(leptons, runNumber, trig2Lsym, trigs1L,
833  globalEfficiencies);
834  if (!trig2Lsym || trig2Lsym.hiddenBy(trigs1L))
835  return globalEfficiency(leptons, runNumber, trig2Lasym, trigs1L,
836  globalEfficiencies);
837  if (trig2Lasym(0) == trig2Lsym() || trig2Lasym(1) == trig2Lsym()) {
839  "implementation -- does this function work properly when the two 2L "
840  "triggers have one leg in common? Must be checked");
841  return false;
842  }
843  if (trig2Lasym.symmetric())
844  return globalEfficiency(leptons, runNumber, trig2Lasym.to_symmetric(),
845  trig2Lsym, trigs1L, globalEfficiencies);
846  globalEfficiencies = {0.};
847  Efficiencies singleInefficiencies[3] = {{1.}, {1.}, {1.}};
848  Efficiencies efficiencies2Lasym{0.},
849  efficiencies2Lsym[3] = {{0.}, {0.}, {0.}};
850 
851  bool success = true;
852  for (auto& lepton : leptons) {
853  if (trig2Lasym.irrelevantFor(lepton))
854  continue;
855  flat_set<std::size_t> validLegs;
856  std::map<std::size_t, Efficiencies> efficiencies{{0, 0.}};
857  std::size_t loosest1lepLeg =
858  getLoosestLegAboveThreshold(lepton, trigs1L, success);
859  for (std::size_t leg :
860  {trig2Lasym(0), trig2Lasym(1), trig2Lsym(), loosest1lepLeg}) {
861  if (leg && aboveThreshold(lepton, leg)) {
862  validLegs.insert(leg);
863  efficiencies.emplace(leg, getCachedTriggerLegEfficiencies(
864  lepton, runNumber, leg, success));
865  } else
866  efficiencies.emplace(leg, 0.);
867  }
868  if (!validLegs.size())
869  continue;
870 
871  const auto sortedLegs = m_parent->getSortedLegs(lepton, validLegs, success);
872  if (!success)
873  return false;
874  std::size_t loosestLeg = sortedLegs[0];
875  std::size_t secondLoosestLeg = validLegs.size() >= 2 ? sortedLegs[1] : 0;
876  std::size_t secondTightestLeg = validLegs.size() >= 3 ? sortedLegs[2] : 0;
877  std::size_t tightestLeg = validLegs.size() >= 4 ? sortedLegs[3] : 0;
878  std::size_t lambda124 =
879  (loosestLeg != trig2Lasym(1)) ? loosestLeg : secondLoosestLeg;
880  std::size_t lambda134 =
881  (loosestLeg != trig2Lasym(0)) ? loosestLeg : secondLoosestLeg;
882  std::size_t lambda234 =
883  (loosestLeg != trig2Lsym()) ? loosestLeg : secondLoosestLeg;
884  std::size_t lambda14 = (lambda124 != trig2Lasym(0)) ? lambda124
885  : (lambda134 != trig2Lasym(1)) ? lambda134
886  : secondTightestLeg;
887  std::size_t lambda24 = (lambda124 != trig2Lsym()) ? lambda124
888  : (lambda234 != trig2Lasym(1)) ? lambda234
889  : secondTightestLeg;
890  std::size_t lambda34 = (lambda134 != trig2Lsym()) ? lambda134
891  : (lambda234 != trig2Lasym(0)) ? lambda234
892  : secondTightestLeg;
893  std::size_t tau13 = 0, tau12 = 0, tau23 = 0;
894  if (loosestLeg == trig2Lsym() || loosestLeg == trig2Lasym(0))
895  tau12 = (loosestLeg == trig2Lsym()) ? trig2Lasym(0) : trig2Lsym();
896  else if (secondLoosestLeg == trig2Lsym() ||
897  secondLoosestLeg == trig2Lasym(0))
898  tau12 = (secondLoosestLeg == trig2Lsym()) ? trig2Lasym(0) : trig2Lsym();
899  else if (secondTightestLeg == trig2Lsym() ||
900  secondTightestLeg == trig2Lasym(0))
901  tau12 = (secondTightestLeg == trig2Lsym()) ? trig2Lasym(0) : trig2Lsym();
902  else if (tightestLeg == trig2Lsym() || tightestLeg == trig2Lasym(0))
903  tau12 = (tightestLeg == trig2Lsym()) ? trig2Lasym(0) : trig2Lsym();
904  if (loosestLeg == trig2Lsym() || loosestLeg == trig2Lasym(1))
905  tau13 = (loosestLeg == trig2Lsym()) ? trig2Lasym(1) : trig2Lsym();
906  else if (secondLoosestLeg == trig2Lsym() ||
907  secondLoosestLeg == trig2Lasym(1))
908  tau13 = (secondLoosestLeg == trig2Lsym()) ? trig2Lasym(1) : trig2Lsym();
909  else if (secondTightestLeg == trig2Lsym() ||
910  secondTightestLeg == trig2Lasym(1))
911  tau13 = (secondTightestLeg == trig2Lsym()) ? trig2Lasym(1) : trig2Lsym();
912  else if (tightestLeg == trig2Lsym() || tightestLeg == trig2Lasym(1))
913  tau13 = (tightestLeg == trig2Lsym()) ? trig2Lasym(1) : trig2Lsym();
914  if (loosestLeg == trig2Lasym(0) || loosestLeg == trig2Lasym(1))
915  tau23 = (loosestLeg == trig2Lasym(0)) ? trig2Lasym(1) : trig2Lasym(0);
916  else if (secondLoosestLeg == trig2Lasym(0) ||
917  secondLoosestLeg == trig2Lasym(1))
918  tau23 =
919  (secondLoosestLeg == trig2Lasym(0)) ? trig2Lasym(1) : trig2Lasym(0);
920  else if (secondTightestLeg == trig2Lasym(0) ||
921  secondTightestLeg == trig2Lasym(1))
922  tau23 =
923  (secondTightestLeg == trig2Lasym(0)) ? trig2Lasym(1) : trig2Lasym(0);
924  else if (tightestLeg == trig2Lasym(0) || tightestLeg == trig2Lasym(1))
925  tau23 = (tightestLeg == trig2Lasym(0)) ? trig2Lasym(1) : trig2Lasym(0);
926 
928  globalEfficiencies =
929  globalEfficiencies * ~efficiencies[loosestLeg] +
930  efficiencies[loosest1lepLeg] +
931  (efficiencies[tau13] - efficiencies[secondTightestLeg]) *
932  ~singleInefficiencies[0] +
933  (efficiencies[tau12] - efficiencies[secondTightestLeg]) *
934  ~singleInefficiencies[1] +
935  (efficiencies[tau23] - efficiencies[secondTightestLeg]) *
936  efficiencies2Lsym[2];
937  if (loosestLeg == trig2Lsym())
938  globalEfficiencies +=
939  (efficiencies[trig2Lsym()] - efficiencies[secondLoosestLeg]) *
940  efficiencies2Lasym;
941  else if (loosestLeg == trig2Lasym(1))
942  globalEfficiencies +=
943  (efficiencies[trig2Lasym(1)] - efficiencies[secondLoosestLeg]) *
944  efficiencies2Lsym[0];
945  else if (loosestLeg == trig2Lasym(0))
946  globalEfficiencies +=
947  (efficiencies[trig2Lasym(0)] - efficiencies[secondLoosestLeg]) *
948  efficiencies2Lsym[1];
949  if (secondTightestLeg &&
950  tightestLeg == loosest1lepLeg)
951  globalEfficiencies +=
953  (efficiencies[secondTightestLeg] - efficiencies[tightestLeg]) *
954  ~singleInefficiencies[2];
955 
956  efficiencies2Lasym =
957  ~efficiencies[loosestLeg] * efficiencies2Lasym + efficiencies[lambda14];
958  if (loosestLeg == trig2Lasym(0) || loosestLeg == trig2Lasym(1)) {
961  efficiencies2Lasym +=
962  (efficiencies[loosestLeg] - efficiencies[secondLoosestLeg]) *
963  ~singleInefficiencies[loosestLeg == trig2Lasym(0)] +
964  (efficiencies[secondLoosestLeg] - efficiencies[lambda14]) *
965  ~singleInefficiencies[2];
966  }
967  efficiencies2Lsym[0] = ~efficiencies[lambda124] * efficiencies2Lsym[0] +
968  efficiencies[lambda24];
969  efficiencies2Lsym[1] = ~efficiencies[lambda134] * efficiencies2Lsym[1] +
970  efficiencies[lambda34];
971  efficiencies2Lsym[2] = ~efficiencies[loosestLeg] * efficiencies2Lsym[2] +
972  efficiencies[lambda234];
973  if (lambda124 == trig2Lsym())
974  efficiencies2Lsym[0] +=
975  (efficiencies[trig2Lsym()] - efficiencies[lambda24]) *
976  ~singleInefficiencies[0];
977  if (lambda134 == trig2Lsym())
978  efficiencies2Lsym[1] +=
979  (efficiencies[trig2Lsym()] - efficiencies[lambda34]) *
980  ~singleInefficiencies[1];
981  if (loosestLeg == trig2Lsym())
982  efficiencies2Lsym[2] +=
983  (efficiencies[trig2Lsym()] - efficiencies[lambda234]) *
984  ~singleInefficiencies[2];
985  singleInefficiencies[0] *= ~efficiencies[lambda124];
986  singleInefficiencies[1] *= ~efficiencies[lambda134];
987  singleInefficiencies[2] *= ~efficiencies[loosestLeg];
988  }
989  return success;
990 }
991 
995 template <typename Trig3Lsym>
996 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
997  const Trig3Lsym trig,
998  Efficiencies& globalEfficiencies)
999  -> std::enable_if_t<Trig3Lsym::is3Lsym(), bool> {
1000  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_One3L() at line "
1001  << __LINE__);
1002  globalEfficiencies = {0.};
1003  Efficiencies singleInefficiencies{1.}, efficiencies2L{0.};
1004  bool success = true;
1005  for (auto& lepton : leptons) {
1006  if (trig.irrelevantFor(lepton) || !aboveThreshold(lepton, trig()))
1007  continue;
1008  auto efficiencies =
1009  getCachedTriggerLegEfficiencies(lepton, runNumber, trig(), success);
1010  globalEfficiencies =
1011  ~efficiencies * globalEfficiencies + efficiencies * efficiencies2L;
1012  efficiencies2L =
1013  ~efficiencies * efficiencies2L + efficiencies * ~singleInefficiencies;
1014  singleInefficiencies *= ~efficiencies;
1015  }
1016  return success;
1017 }
1018 
1022 template <typename Trig3Lhalfsym>
1023 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
1024  const Trig3Lhalfsym trig,
1025  Efficiencies& globalEfficiencies)
1026  -> std::enable_if_t<Trig3Lhalfsym::is3Lhalfsym(), bool> {
1027  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_One3L() at line "
1028  << __LINE__);
1029  if (trig.symmetric())
1030  return globalEfficiency(leptons, runNumber, trig.to_symmetric(),
1031  globalEfficiencies);
1032  globalEfficiencies = {0.};
1033  Efficiencies singleInefficiencies[2] = {{1.}, {1.}},
1034  twoSingleInefficiencies{1.};
1035  Efficiencies efficiencies2Lsym{0.}, efficiencies2Lasym{0.},
1036  efficiencies2L2L{0.};
1037  bool success = true;
1038  for (auto& lepton : leptons) {
1039  if (trig.irrelevantFor(lepton))
1040  continue;
1041  Efficiencies efficiencies[2] = {{0.}, {0.}};
1042  const int asym = 0, sym = 1;
1043  int loosestLeg;
1044  if (aboveThreshold(lepton, trig.asymLeg())) {
1045  efficiencies[asym] = getCachedTriggerLegEfficiencies(
1046  lepton, runNumber, trig.asymLeg(), success);
1047  if (aboveThreshold(lepton, trig.symLeg())) {
1048  efficiencies[sym] = getCachedTriggerLegEfficiencies(
1049  lepton, runNumber, trig.symLeg(), success);
1050  loosestLeg =
1051  m_parent->getLoosestLeg(lepton, trig.asymLeg(), trig.symLeg(),
1052  success) == trig.asymLeg()
1053  ? asym
1054  : sym;
1055  } else
1056  loosestLeg = asym;
1057  } else if (aboveThreshold(lepton, trig.symLeg())) {
1058  efficiencies[sym] = getCachedTriggerLegEfficiencies(
1059  lepton, runNumber, trig.symLeg(), success);
1060  loosestLeg = sym;
1061  } else
1062  continue;
1063  Efficiencies delta = efficiencies[asym] - efficiencies[sym];
1064  if (loosestLeg == asym) {
1065  globalEfficiencies = ~efficiencies[asym] * globalEfficiencies +
1066  efficiencies[sym] * efficiencies2L2L +
1067  delta * efficiencies2Lsym;
1068  efficiencies2L2L = ~efficiencies[asym] * efficiencies2L2L +
1069  efficiencies[sym] * ~twoSingleInefficiencies +
1070  delta * ~singleInefficiencies[sym];
1071  efficiencies2Lasym = ~efficiencies[asym] * efficiencies2Lasym +
1072  efficiencies[sym] * ~twoSingleInefficiencies +
1073  delta * ~singleInefficiencies[sym];
1074  } else {
1075  globalEfficiencies = ~efficiencies[sym] * globalEfficiencies +
1076  efficiencies[asym] * efficiencies2L2L -
1077  delta * efficiencies2Lasym;
1078  efficiencies2L2L = ~efficiencies[sym] * efficiencies2L2L +
1079  efficiencies[sym] * ~twoSingleInefficiencies;
1080  efficiencies2Lasym = ~efficiencies[sym] * efficiencies2Lasym +
1081  efficiencies[asym] * ~twoSingleInefficiencies -
1082  delta * ~singleInefficiencies[asym];
1083  }
1084  efficiencies2Lsym = ~efficiencies[sym] * efficiencies2Lsym +
1085  efficiencies[sym] * ~singleInefficiencies[sym];
1086  twoSingleInefficiencies *= ~efficiencies[loosestLeg];
1087  singleInefficiencies[sym] *= ~efficiencies[sym];
1088  singleInefficiencies[asym] *= ~efficiencies[asym];
1089  }
1090  return success;
1091 }
1092 
1096 template <typename Trig2L, typename Trig2Lmix>
1097 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
1098  const Trig2L trig2L,
1099  const Trig2Lmix trig2Lmix,
1100  Efficiencies& globalEfficiencies)
1101  -> std::enable_if_t<Trig2L::is2Lnomix() && Trig2Lmix::is2Lmix() &&
1102  (Trig2Lmix::object1() == Trig2L::object() ||
1103  Trig2Lmix::object2() == Trig2L::object()),
1104  bool> {
1105  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_Two2L() at line "
1106  << __LINE__);
1107  Efficiencies efficiencies1L, efficiencies2L, efficiencies2Lor1L;
1108  bool success =
1109  globalEfficiency(leptons, runNumber,
1110  trig2Lmix.template antiside<Trig2L>(), efficiencies1L);
1111  success =
1112  success && globalEfficiency(leptons, runNumber, trig2L, efficiencies2L);
1113  success = success && globalEfficiency(leptons, runNumber, trig2L,
1114  trig2Lmix.template side<Trig2L>(),
1115  efficiencies2Lor1L);
1116  globalEfficiencies =
1117  efficiencies2L * ~efficiencies1L + efficiencies1L * efficiencies2Lor1L;
1118  return success;
1119 }
1120 
1125 template <typename Trig2L_obj1, typename Trig2L_obj2, typename Trig2Lmix>
1126 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
1127  const Trig2L_obj1 trig2L_obj1,
1128  const Trig2L_obj2 trig2L_obj2,
1129  const Trig2Lmix trig2Lmix,
1130  Efficiencies& globalEfficiencies)
1131  -> std::enable_if_t<Trig2Lmix::is2Lmix() && Trig2L_obj1::is2Lnomix() &&
1132  Trig2L_obj1::object() == Trig2Lmix::object1() &&
1133  Trig2L_obj2::is2Lnomix() &&
1134  Trig2L_obj2::object() == Trig2Lmix::object2(),
1135 
1136  bool> {
1137  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_Three2L() at line "
1138  << __LINE__);
1139  Efficiencies efficiencies2L[2] = {{0.}, {0.}},
1140  efficiencies2Lor1L[2] = {{0.}, {0.}};
1141  bool success = true;
1142  if (trig2L_obj1) {
1143  success = success && globalEfficiency(leptons, runNumber, trig2L_obj1,
1144  efficiencies2L[0]);
1145  if (trig2Lmix)
1146  success =
1147  success && globalEfficiency(leptons, runNumber, trig2L_obj1,
1148  trig2Lmix.template side<Trig2L_obj1>(),
1149  efficiencies2Lor1L[0]);
1150  else
1151  efficiencies2Lor1L[0] = efficiencies2L[0];
1152  } else if (trig2Lmix)
1153  success =
1154  success && globalEfficiency(leptons, runNumber,
1155  trig2Lmix.template side<Trig2L_obj1>(),
1156  efficiencies2Lor1L[0]);
1157  if (trig2L_obj2) {
1158  success = success && globalEfficiency(leptons, runNumber, trig2L_obj2,
1159  efficiencies2L[1]);
1160  if (trig2Lmix)
1161  success =
1162  success && globalEfficiency(leptons, runNumber, trig2L_obj2,
1163  trig2Lmix.template side<Trig2L_obj2>(),
1164  efficiencies2Lor1L[1]);
1165  else
1166  efficiencies2Lor1L[1] = efficiencies2L[1];
1167  } else if (trig2Lmix)
1168  success =
1169  success && globalEfficiency(leptons, runNumber,
1170  trig2Lmix.template side<Trig2L_obj2>(),
1171  efficiencies2Lor1L[1]);
1172  globalEfficiencies = efficiencies2L[0] * ~efficiencies2Lor1L[1] +
1173  efficiencies2L[1] * ~efficiencies2Lor1L[0] +
1174  efficiencies2Lor1L[0] * efficiencies2Lor1L[1];
1175  return success;
1176 }
1177 
1181 template <typename Trig2L_obj1, typename Trig2L_obj2, typename Trig2Lmix,
1182  typename Trig1L_obj1, typename Trig1L_obj2>
1183 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
1184  const Trig2L_obj1 trig2L_obj1,
1185  const Trig2L_obj2 trig2L_obj2,
1186  const Trig2Lmix trig2Lmix,
1187  const flat_set<Trig1L_obj1>& trigs1L_obj1,
1188  const flat_set<Trig1L_obj2>& trigs1L_obj2,
1189  Efficiencies& globalEfficiencies)
1190  -> std::enable_if_t<Trig2Lmix::is2Lmix() && Trig2L_obj1::is2Lnomix() &&
1191  Trig2L_obj1::object() == Trig2Lmix::object1() &&
1192  Trig2L_obj2::is2Lnomix() &&
1193  Trig2L_obj2::object() == Trig2Lmix::object2() &&
1194  Trig1L_obj1::is1L() &&
1195  Trig1L_obj1::object() == Trig2Lmix::object1() &&
1196  Trig1L_obj2::is1L() &&
1197  Trig1L_obj2::object() == Trig2Lmix::object2(),
1198 
1199  bool> {
1200  ATH_MSG_DEBUG(
1201  "Entered Calculator::globalEfficiency_Three2LSeveral1L() at line "
1202  << __LINE__);
1204  bool success = true;
1205  if (trig2L_obj1)
1206  success = success && globalEfficiency(leptons, runNumber, trig2L_obj1,
1207  trigs1L_obj1, efficiencies[0]);
1208  else
1209  success = success && globalEfficiency(leptons, runNumber, trigs1L_obj1,
1210  efficiencies[0]);
1211  if (trig2L_obj2)
1212  success = success && globalEfficiency(leptons, runNumber, trig2L_obj2,
1213  trigs1L_obj2, efficiencies[1]);
1214  else
1215  success = success && globalEfficiency(leptons, runNumber, trigs1L_obj2,
1216  efficiencies[1]);
1217  if (trig2Lmix && !trig2Lmix.hiddenBy(trigs1L_obj1)) {
1218  auto t = trig2Lmix.addTo(trigs1L_obj1);
1219  if (trig2L_obj1)
1220  success = success && globalEfficiency(leptons, runNumber, trig2L_obj1, t,
1221  efficiencies[2]);
1222  else
1223  success =
1224  success && globalEfficiency(leptons, runNumber, t, efficiencies[2]);
1225  } else
1226  efficiencies[2] = efficiencies[0];
1227  if (trig2Lmix && !trig2Lmix.hiddenBy(trigs1L_obj2)) {
1228  auto t = trig2Lmix.addTo(trigs1L_obj2);
1229  if (trig2L_obj2)
1230  success = success && globalEfficiency(leptons, runNumber, trig2L_obj2, t,
1231  efficiencies[3]);
1232  else
1233  success =
1234  success && globalEfficiency(leptons, runNumber, t, efficiencies[3]);
1235  } else
1236  efficiencies[3] = efficiencies[1];
1237  globalEfficiencies =
1238  Efficiencies(1.) - ~efficiencies[0] * ~efficiencies[1] +
1239  (efficiencies[2] - efficiencies[0]) * (efficiencies[3] - efficiencies[1]);
1240  return success;
1241 }
1242 
1247 template <typename Trig2L_obj1, typename Trig2Lsym_obj1, typename Trig2L_obj2,
1248  typename Trig2Lsym_obj2, typename Trig2Lmix, typename Trig1L_obj1,
1249  typename Trig1L_obj2>
1251  const LeptonList& leptons, unsigned runNumber,
1252  const Trig2L_obj1 trig2L_obj1, const Trig2Lsym_obj1 trig2Lsym_obj1,
1253  const Trig2L_obj2 trig2L_obj2, const Trig2Lsym_obj2 trig2Lsym_obj2,
1254  const Trig2Lmix trig2Lmix1, const Trig2Lmix trig2Lmix2,
1255  const flat_set<Trig1L_obj1>& trigs1L_obj1,
1256  const flat_set<Trig1L_obj2>& trigs1L_obj2, Efficiencies& globalEfficiencies)
1257  -> std::enable_if_t<Trig2Lmix::is2Lmix() && Trig2L_obj1::is2Lnomix() &&
1258  Trig2L_obj1::object() == Trig2Lmix::object1() &&
1259  Trig2L_obj2::is2Lnomix() &&
1260  Trig2L_obj2::object() == Trig2Lmix::object2() &&
1261  Trig2Lsym_obj1::is2Lsym() &&
1262  Trig2Lsym_obj1::object() == Trig2Lmix::object1() &&
1263  Trig2Lsym_obj2::is2Lsym() &&
1264  Trig2Lsym_obj2::object() == Trig2Lmix::object2() &&
1265  Trig1L_obj1::is1L() &&
1266  Trig1L_obj1::object() == Trig2Lmix::object1() &&
1267  Trig1L_obj2::is1L() &&
1268  Trig1L_obj2::object() == Trig2Lmix::object2(),
1269  bool> {
1270  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_Six2LSeveral1L() at line "
1271  << __LINE__);
1272 
1273  auto singleObjectFactor = [=](auto trig2L, auto trig2Lsym, auto& trigs1L,
1274  Efficiencies(&efficiencies)[4]) -> bool {
1275  auto eval_for = [=](const auto& trigs1L_extended,
1276  Efficiencies& eff) -> bool {
1277  if (trig2L && trig2Lsym)
1278  return this->globalEfficiency(leptons, runNumber, trig2L, trig2Lsym,
1279  trigs1L_extended, eff);
1280  else if (trig2L)
1281  return this->globalEfficiency(leptons, runNumber, trig2L,
1282  trigs1L_extended, eff);
1283  else if (trig2Lsym)
1284  return this->globalEfficiency(leptons, runNumber, trig2Lsym,
1285  trigs1L_extended, eff);
1286  else
1287  return this->globalEfficiency(leptons, runNumber, trigs1L_extended,
1288  eff);
1289  };
1290 
1291  bool success = eval_for(trigs1L, efficiencies[0]);
1292  if (trig2Lmix1)
1293  success = success && eval_for(trig2Lmix1.addTo(trigs1L), efficiencies[1]);
1294  else
1295  efficiencies[1] = efficiencies[0];
1296  if (trig2Lmix2) {
1297  auto t = trig2Lmix2.addTo(trigs1L);
1298  success = success && eval_for(t, efficiencies[2]);
1299  if (trig2Lmix1)
1300  success&& eval_for(trig2Lmix1.addTo(t), efficiencies[3]);
1301  else
1302  efficiencies[3] = efficiencies[2];
1303  } else {
1304  efficiencies[2] = efficiencies[0];
1305  efficiencies[3] = efficiencies[1];
1306  }
1307  return success;
1308  };
1309 
1310  Efficiencies efficiencies1[4], efficiencies2[4];
1311  bool success = singleObjectFactor(trig2L_obj1, trig2Lsym_obj1, trigs1L_obj1,
1312  efficiencies1) &&
1313  singleObjectFactor(trig2L_obj2, trig2Lsym_obj2, trigs1L_obj2,
1314  efficiencies2);
1315  globalEfficiencies = Efficiencies(1.) -
1316  ~efficiencies1[0] * ~efficiencies2[0] +
1317  (efficiencies1[1] - efficiencies1[0]) *
1318  (efficiencies2[1] - efficiencies2[0]) +
1319  (efficiencies1[2] - efficiencies1[0]) *
1320  (efficiencies2[2] - efficiencies2[0]) -
1321  (efficiencies1[0] - efficiencies1[1] - efficiencies1[2] +
1322  efficiencies1[3]) *
1323  (efficiencies2[0] - efficiencies2[1] -
1324  efficiencies2[2] + efficiencies2[3]);
1325  return success;
1326 }
1327 
1331 template <typename Trig3Lmix>
1332 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
1333  const Trig3Lmix trig,
1334  Efficiencies& globalEfficiencies)
1335  -> std::enable_if_t<Trig3Lmix::is3Lmix(), bool> {
1336  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_One3L() at line "
1337  << __LINE__);
1338  Efficiencies efficiencies[2] = {{0.}, {0.}};
1339  bool success = globalEfficiency(leptons, runNumber,
1340  trig.template side<Trig3Lmix::object1()>(),
1341  efficiencies[0]) &&
1342  globalEfficiency(leptons, runNumber,
1343  trig.template side<Trig3Lmix::object2()>(),
1344  efficiencies[1]);
1345  globalEfficiencies = efficiencies[0] * efficiencies[1];
1346  return success;
1347 }
1348 
1352 template <typename Trig3Lmix1, typename Trig3Lmix2>
1353 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
1354  const Trig3Lmix1 trig1,
1355  const Trig3Lmix2 trig2,
1356  Efficiencies& globalEfficiencies)
1357  -> std::enable_if_t<Trig3Lmix1::is3Lmix() && Trig3Lmix2::is3Lmix() &&
1358  Trig3Lmix1::object1() == Trig3Lmix2::object2() &&
1359  Trig3Lmix1::object2() == Trig3Lmix2::object1(),
1360  bool> {
1361  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_Two3L() at line "
1362  << __LINE__);
1363  Efficiencies efficiencies[6] = {{0.}, {0.}, {0.}, {0.}, {0.}, {0.}};
1364  auto trig2La = trig1.template side<Trig3Lmix1::object1()>();
1365  auto trig1La = trig2.template side<Trig3Lmix2::object2()>();
1366  bool success =
1367  globalEfficiency(leptons, runNumber, trig1La, efficiencies[0]) &&
1368  globalEfficiency(leptons, runNumber, trig2La, efficiencies[1]);
1369  if (!trig2La.hiddenBy(trig1La))
1370  success = success && globalEfficiency(leptons, runNumber, trig2La, trig1La,
1371  efficiencies[2]);
1372  else
1373  efficiencies[2] = efficiencies[0];
1374  auto trig2Lb = trig2.template side<Trig3Lmix2::object1()>();
1375  auto trig1Lb = trig1.template side<Trig3Lmix1::object2()>();
1376  success = success &&
1377  globalEfficiency(leptons, runNumber, trig1Lb, efficiencies[3]) &&
1378  globalEfficiency(leptons, runNumber, trig2Lb, efficiencies[4]);
1379  if (!trig2Lb.hiddenBy(trig1Lb))
1380  success = success && globalEfficiency(leptons, runNumber, trig2Lb, trig1Lb,
1381  efficiencies[5]);
1382  else
1383  efficiencies[5] = efficiencies[3];
1384  globalEfficiencies =
1386  (efficiencies[2] - efficiencies[0] - efficiencies[1]) *
1387  (efficiencies[3] + efficiencies[4] - efficiencies[5]);
1388  return success;
1389 }
1390 
1394 template <typename Trig4Lsym>
1395 auto Calculator::globalEfficiency(const LeptonList& leptons, unsigned runNumber,
1396  const Trig4Lsym trig,
1397  Efficiencies& globalEfficiencies)
1398  -> std::enable_if_t<Trig4Lsym::is4Lsym(), bool> {
1399  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_One4L() at line "
1400  << __LINE__);
1401  globalEfficiencies = {0.};
1402  Efficiencies singleInefficiencies{1.}, efficiencies2L{0.}, efficiencies3L{0.};
1403  bool success = true;
1404  for (auto& lepton : leptons) {
1405  if (trig.irrelevantFor(lepton) || !aboveThreshold(lepton, trig()))
1406  continue;
1407  auto efficiencies =
1408  getCachedTriggerLegEfficiencies(lepton, runNumber, trig(), success);
1409  globalEfficiencies =
1410  ~efficiencies * globalEfficiencies + efficiencies * efficiencies3L;
1411  efficiencies3L =
1412  ~efficiencies * efficiencies3L + efficiencies * efficiencies2L;
1413  efficiencies2L =
1414  ~efficiencies * efficiencies2L + efficiencies * ~singleInefficiencies;
1415  singleInefficiencies *= ~efficiencies;
1416  }
1417  return success;
1418 }
1419 
1421  const LeptonList& leptons, unsigned runNumber, GlobEffFunc func1,
1422  GlobEffFunc func2, Efficiencies& globalEfficiencies) {
1424  if (!func1(this, leptons, runNumber, efficiencies[0]))
1425  return false;
1426  if (!func2(this, leptons, runNumber, efficiencies[1]))
1427  return false;
1428  globalEfficiencies = ~(~efficiencies[0] * ~efficiencies[1]);
1429  return true;
1430 }
1431 
1433  const LeptonList& leptons, unsigned runNumber, GlobEffFunc func1,
1434  GlobEffFunc func2, GlobEffFunc func3, Efficiencies& globalEfficiencies) {
1436  if (!func1(this, leptons, runNumber, efficiencies[0]))
1437  return false;
1438  if (!func2(this, leptons, runNumber, efficiencies[1]))
1439  return false;
1440  if (!func3(this, leptons, runNumber, efficiencies[2]))
1441  return false;
1442  globalEfficiencies =
1443  ~(~efficiencies[0] * ~efficiencies[1] * ~efficiencies[2]);
1444  return true;
1445 }
1446 
1448  const std::vector<TrigDef>& triggers,
1449  flat_set<std::size_t>& validLegs) const {
1450  validLegs.clear();
1451  for (auto& trig : triggers) {
1452  TriggerProperties tp(trig);
1453  if (!tp.valid()) {
1454  ATH_MSG_ERROR("Unrecognized trigger type " << trig.type);
1455  return false;
1456  }
1457  auto end = tp.cend(lepton.type());
1458  for (auto itr = tp.cbegin(lepton.type()); itr != end; ++itr)
1459  if (aboveThreshold(lepton, *itr))
1460  validLegs.emplace(*itr);
1461  }
1462  return true;
1463 }
1464 
1466  const TrigDef& trig,
1467  const std::vector<flat_set<std::size_t>>& firedLegs) const {
1468  const int nLegs = static_cast<int>(std::count_if(
1469  trig.leg.begin(), trig.leg.end(), [](auto x) { return x != 0ul; }));
1470  const int sameLegs = static_cast<int>(
1471  std::count(trig.leg.begin(), trig.leg.end(), trig.leg[0]));
1472  if (sameLegs == nLegs) {
1473  // single-lepton and symmetric multilepton triggers
1474  return std::count_if(firedLegs.cbegin(), firedLegs.cend(), [&](auto& legs) {
1475  return legs.count(trig.leg[0]);
1476  }) >= nLegs;
1477  } else if (nLegs == 2) {
1478  // asymmetric or mixed-flavour dilepton triggers
1479  bool n0 = false, n1 = false;
1480  for (auto& legs : firedLegs) {
1481  if (n0 && legs.count(trig.leg[1]))
1482  return true;
1483  if (n1 && legs.count(trig.leg[0]))
1484  return true;
1485  n0 = n0 || legs.count(trig.leg[0]);
1486  n1 = n1 || legs.count(trig.leg[1]);
1487  }
1488  } else if (nLegs == 3) {
1489  // other trilepton triggers
1490  auto end = firedLegs.end();
1491  for (auto legs0 = firedLegs.begin(); legs0 != end; ++legs0) {
1492  for (int i = 0; i < 3; ++i) {
1493  if (!legs0->count(trig.leg[i]))
1494  continue;
1495  for (auto legs1 = legs0 + 1; legs1 != end; ++legs1) {
1496  for (int j = 1; j < 3; ++j) {
1497  if (!legs1->count(trig.leg[(i + j) % 3]))
1498  continue;
1499  for (auto legs2 = legs1 + 1; legs2 != end; ++legs2) {
1500  if (legs2->count(trig.leg[(i + 3 - j) % 3]))
1501  return true;
1502  }
1503  }
1504  }
1505  }
1506  }
1507  } else {
1508  ATH_MSG_ERROR("incomplete support of 4-lepton triggers.");
1509  }
1510  return false;
1511 }
1512 
1514  unsigned runNumber,
1515  const std::vector<TrigDef>& triggers,
1516  Efficiencies& globalEfficiencies) {
1517  ATH_MSG_DEBUG("Entered Calculator::globalEfficiency_Toys() at line "
1518  << __LINE__);
1519  globalEfficiencies = {0.};
1520  if (m_parent->m_numberOfToys <= 0) {
1521  ATH_MSG_ERROR("The specified number of toys is <= 0");
1522  return false;
1523  }
1524  std::map<const Lepton*, std::vector<std::pair<std::size_t, Efficiencies>>>
1525  leptonEfficiencies;
1526  for (auto& lepton : leptons) {
1527  flat_set<std::size_t> validLegs;
1528  if (!fillListOfLegsFor(lepton, triggers, validLegs))
1529  return false;
1530  auto& efficiencies = leptonEfficiencies[&lepton];
1531  const int nLegs = validLegs.size();
1532  if (nLegs) {
1533  bool success = true;
1534  for (std::size_t leg :
1535  m_parent->getSortedLegs(lepton, validLegs, success)) {
1537  lepton, runNumber, leg, success));
1538  }
1539  if (!success)
1540  return false;
1541  }
1542  }
1543  unsigned long seed;
1544  if (!m_parent->m_useInternalSeed) {
1545  if (!m_parent->retrieveEventNumber(seed)) {
1546  ATH_MSG_WARNING("Will use internal seed instead of event number");
1547  seed = m_parent->m_seed++;
1548  }
1549  } else
1550  seed = m_parent->m_seed++;
1551  std::mt19937_64 randomEngine(seed);
1552  std::uniform_real_distribution<double> uniformPdf(0., 1.);
1553  std::vector<flat_set<std::size_t>> firedLegs(leptonEfficiencies.size());
1554  unsigned long nPassed[2] = {0, 0};
1555  for (unsigned long toy = 0; toy < m_parent->m_numberOfToys; ++toy) {
1556  for (int step = 0; step < 2; ++step)
1557  {
1558  auto legs = firedLegs.begin();
1559  for (auto& kv : leptonEfficiencies) {
1560  legs->clear();
1561  double x = uniformPdf(randomEngine);
1562  for (auto& p : kv.second) {
1563  if (x < (step ? p.second.mc() : p.second.data()))
1564  legs->emplace(p.first);
1565  }
1566  ++legs;
1567  }
1568  for (auto& trig : triggers) {
1569  if (!canTriggerBeFired(trig, firedLegs))
1570  continue;
1571  ++nPassed[step];
1572  break;
1573  }
1574  }
1575  }
1576  globalEfficiencies.data() =
1577  double(nPassed[0]) / double(m_parent->m_numberOfToys);
1578  globalEfficiencies.mc() =
1579  double(nPassed[1]) / double(m_parent->m_numberOfToys);
1580  return true;
1581 }
1582 
1583 Calculator::Helper::Helper(const std::vector<TrigDef>& defs)
1584  : m_formula(nullptr), m_defs(defs) {}
1585 
1587  for (auto itr1 = m_defs.cbegin(); itr1 != m_defs.cend(); ++itr1)
1588  for (auto itr2 = itr1 + 1; itr2 != m_defs.cend(); ++itr2)
1589  if (itr1->type == itr2->type && itr1->leg == itr2->leg)
1590  return true;
1591  return false;
1592 }
1593 
1595 {
1597 template <typename T>
1599  using TrigType = T;
1600  using ArgType = std::add_const_t<T>;
1601  static constexpr bool multiple() { return false; }
1602  static constexpr bool optional() { return false; }
1603  static void add(T& arg, ImportData::TrigDef& def) { arg.setDefinition(def); }
1604  static constexpr bool valid(const T& arg) { return bool(arg); }
1605 };
1606 
1607 template <typename T>
1609  using TrigType = T;
1610  using ArgType = const flat_set<T>&;
1611  static constexpr bool multiple() { return true; }
1612  static constexpr bool optional() { return false; }
1613  static void add(flat_set<T>& arg, ImportData::TrigDef& def) {
1614  arg.emplace().first->setDefinition(def);
1615  }
1616  static constexpr bool valid(const flat_set<T>& arg) { return arg.size(); }
1617 };
1618 
1619 template <typename T>
1621  Calculator::Helper::Optional<T>> {
1624  static constexpr bool multiple() { return BindPackedParam<T>::multiple(); }
1625  static constexpr bool optional() { return true; }
1626  static void add(std::remove_cv_t<std::remove_reference_t<ArgType>>& arg,
1627  ImportData::TrigDef def) {
1629  }
1630  static constexpr bool valid(ArgType& arg) {
1632  }
1633 };
1634 } // namespace TrigGlobEffCorr
1635 
1636 template <typename Param>
1638  std::remove_cv_t<std::remove_reference_t<typename Param::ArgType>> trigs;
1639  for (auto& def : m_defs) {
1640  if (def.used || def.type != Param::TrigType::type())
1641  continue;
1642  def.used = true;
1643  Param::add(trigs, def);
1644  if (!Param::multiple())
1645  break;
1646  }
1647  if (!Param::optional() && !Param::valid(trigs))
1648  throw NoSuchTrigger();
1649  return trigs;
1650 }
1651 
1652 template <typename... Trigs>
1654  for (auto& def : m_defs)
1655  def.used = false;
1656  using fnptr = bool (Calculator::*)(
1658  Efficiencies&);
1659  try {
1660  m_formula =
1661  std::bind<fnptr>(&Calculator::globalEfficiency, ::_1, ::_2, ::_3,
1662  extract<BindPackedParam<Trigs>>()..., ::_4);
1663  if (std::all_of(m_defs.cbegin(), m_defs.cend(),
1664  [](auto& def) { return def.used; }))
1665  return true;
1666  } catch (NoSuchTrigger) {
1667  }
1668  m_formula = nullptr;
1669  return false;
1670 }
1671 
1672 template <TriggerType object_flag>
1674 {
1676  using A = TriggerClass<object_flag>;
1677  using A1L = flat_set<typename A::T_1>;
1678  using A_2sym = typename A::T_2sym;
1679  using A_2asym = typename A::T_2asym;
1680  if (m_n2L + m_n3L + m_n4L == 0) {
1681  return bindFunction<typename A::T_1>() || bindFunction<A1L>();
1682  } else if (m_n2L == 1 && m_n3L + m_n4L == 0) {
1683  return bindFunction<A_2sym>() || bindFunction<A_2asym>() ||
1684  bindFunction<A_2sym, A1L>() || bindFunction<A_2asym, A1L>();
1685  } else if (m_n2L == 2 && m_n3L + m_n4L == 0) {
1686  return bindFunction<A_2sym, A_2sym, Optional<A1L>>() ||
1687  bindFunction<A_2asym, A_2sym, Optional<A1L>>();
1688  } else if (m_n3L == 1 && m_n1L + m_n2L + m_n4L == 0) {
1689  return bindFunction<typename A::T_3sym>() ||
1690  bindFunction<typename A::T_3halfsym>();
1691  } else if (m_n4L == 1 && m_n1L + m_n2L + m_n3L == 0) {
1692  return bindFunction<typename A::T_4sym>();
1693  }
1694  return false;
1695 }
1696 
1697 template <TriggerType object_flag1, TriggerType object_flag2>
1699 {
1702  using A = TriggerClass<object_flag1>;
1703  using B = TriggerClass<object_flag2>;
1705  using A_1 = typename A::T_1;
1706  using B_1 = typename B::T_1;
1707  using OA1L = Optional<flat_set<A_1>>;
1708  using OB1L = Optional<flat_set<B_1>>;
1709  using A_2sym = typename A::T_2sym;
1710  using B_2sym = typename B::T_2sym;
1711  using A_2asym = typename A::T_2asym;
1712  using B_2asym = typename B::T_2asym;
1713  using AB_1_1 = typename AB::T_1_1;
1714 
1717  if (m_n1L > 0 && m_n2L + m_n3L + m_n4L == 0) {
1718  return bindFunction<A_1, B_1>() ||
1719  bindFunction<flat_set<A_1>, flat_set<B_1>>();
1720  } else if (m_n2L == 1 &&
1721  m_n3L + m_n4L ==
1722  0) { // one dilepton trigger (+ single-lepton triggers)
1723  return bindFunction<AB_1_1>() ||
1724  bindFunction<AB_1_1, flat_set<A_1>, flat_set<B_1>>();
1725  } else if (m_n2L >= 2 && m_n2L <= 6 &&
1726  m_n3L + m_n4L ==
1727  0) { // several dilepton triggers (+ single-lepton triggers)
1728  return
1730  bindFunction<A_2sym, AB_1_1>() || bindFunction<A_2asym, AB_1_1>() ||
1731  bindFunction<B_2sym, AB_1_1>() ||
1732  bindFunction<B_2asym, AB_1_1>()
1734  || bindFunction<Optional<A_2sym>, Optional<B_2sym>, Optional<AB_1_1>,
1735  OA1L, OB1L>() ||
1737  OA1L, OB1L>() ||
1738  bindFunction<Optional<A_2sym>, Optional<B_2asym>, Optional<AB_1_1>,
1739  OA1L, OB1L>() ||
1741  OA1L, OB1L>()
1743  || bindFunction<Optional<A_2sym>, Optional<A_2sym>, Optional<B_2sym>,
1745  OA1L, OB1L>() ||
1748  OB1L>() ||
1749  bindFunction<Optional<A_2sym>, Optional<A_2sym>, Optional<B_2asym>,
1751  OB1L>() ||
1754  OB1L>();
1755  } else if (m_n3L == 1 &&
1756  m_n1L + m_n2L + m_n4L == 0) { // one mixed trilepton trigger
1757  return bindFunction<typename AB::T_2sym_1>() ||
1758  bindFunction<typename AB::T_1_2sym>() ||
1759  bindFunction<typename AB::T_2asym_1>() ||
1760  bindFunction<typename AB::T_1_2asym>();
1761  } else if (m_n3L == 2 &&
1762  m_n1L + m_n2L + m_n4L == 0) { // two mixed trilepton triggers
1763  return bindFunction<typename AB::T_2sym_1, typename AB::T_1_2sym>() ||
1764  bindFunction<typename AB::T_2asym_1, typename AB::T_1_2sym>() ||
1765  bindFunction<typename AB::T_2sym_1, typename AB::T_1_2asym>() ||
1766  bindFunction<typename AB::T_2asym_1, typename AB::T_1_2asym>();
1767  }
1768  return false;
1769 }
1770 
1772 {
1773  auto countTriggers = [&](auto nlep_flag) {
1774  return std::count_if(m_defs.cbegin(), m_defs.cend(),
1775  [=](auto& def) { return def.type & nlep_flag; });
1776  };
1777  m_n1L = countTriggers(TT_SINGLELEPTON_FLAG);
1778  m_n2L = countTriggers(TT_DILEPTON_FLAG);
1779  m_n3L = countTriggers(TT_TRILEPTON_FLAG);
1780  m_n4L = countTriggers(TT_TETRALEPTON_FLAG);
1781  auto exclusively = [&](auto obj_flags) {
1782  return std::none_of(m_defs.cbegin(), m_defs.cend(), [=](auto& def) {
1783  return def.type & TT_MASK_FLAVOUR & ~obj_flags;
1784  });
1785  };
1786 
1788  if (exclusively(TT_ELECTRON_FLAG))
1789  return findAndBindFunction<TT_ELECTRON_FLAG>();
1790  if (exclusively(TT_MUON_FLAG))
1791  return findAndBindFunction<TT_MUON_FLAG>();
1792  if (exclusively(TT_PHOTON_FLAG))
1793  return findAndBindFunction<TT_PHOTON_FLAG>();
1794 
1797  bool success = false;
1798  if (exclusively(TT_ELECTRON_FLAG | TT_MUON_FLAG))
1799  success = findAndBindFunction<TT_ELECTRON_FLAG, TT_MUON_FLAG>();
1800  else if (exclusively(TT_ELECTRON_FLAG | TT_PHOTON_FLAG))
1801  success = findAndBindFunction<TT_ELECTRON_FLAG, TT_PHOTON_FLAG>();
1802  else if (exclusively(TT_MUON_FLAG | TT_PHOTON_FLAG))
1803  success = findAndBindFunction<TT_MUON_FLAG, TT_PHOTON_FLAG>();
1804  if (success)
1805  return true;
1806 
1808  std::vector<Helper> helpers;
1809  for (auto obj_flag : {TT_ELECTRON_FLAG, TT_MUON_FLAG, TT_PHOTON_FLAG}) {
1810  if (std::any_of(m_defs.cbegin(),
1811  m_defs.cend(),
1812  [&](auto& def) {
1814  return (def.type & obj_flag) &&
1815  TriggerProperties(def.type).mixed();
1816  }))
1817  continue;
1818  std::vector<ImportData::TrigDef> trigs1, trigs2;
1819  std::partition_copy(m_defs.begin(), m_defs.end(),
1820  std::back_inserter(trigs1), std::back_inserter(trigs2),
1821  [&](auto& def) { return (def.type & obj_flag); });
1822  m_defs.swap(trigs2);
1823  if (!trigs1.size())
1824  continue;
1825  helpers.emplace_back(trigs1);
1826  if (!helpers.back().findAndBindFunction())
1827  return false;
1828  }
1829  if (helpers.size()) {
1830  if (m_defs.size()) {
1831  if (!findAndBindFunction())
1832  return false;
1833  if (helpers.size() == 1)
1835  ::_2, ::_3, std::move(m_formula),
1836  std::move(helpers[0].m_formula), ::_4);
1837  else if (helpers.size() == 2)
1839  ::_2, ::_3, std::move(m_formula),
1840  std::move(helpers[0].m_formula),
1841  std::move(helpers[1].m_formula), ::_4);
1842  else {
1843  m_formula = nullptr;
1844  return false;
1845  }
1846  } else {
1847  if (helpers.size() == 2)
1849  ::_2, ::_3, std::move(helpers[0].m_formula),
1850  std::move(helpers[1].m_formula), ::_4);
1851  else if (helpers.size() == 3)
1853  ::_2, ::_3, std::move(helpers[0].m_formula),
1854  std::move(helpers[1].m_formula),
1855  std::move(helpers[2].m_formula), ::_4);
1856  else
1857  return false;
1858  }
1859  return true;
1860  }
1861 
1862  return false;
1863 }
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:1603
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:68
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:1598
runLayerRecalibration.chain
chain
Definition: runLayerRecalibration.py:175
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam::valid
static constexpr bool valid(const T &arg)
Definition: Calculator.cxx:1604
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:65
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:1596
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam< flat_set< T > >::ArgType
const flat_set< T > & ArgType
Definition: Calculator.cxx:1610
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:162
TrigGlobEffCorr::Efficiencies
Definition: Efficiencies.h:14
Lepton.h
TrigGlobEffCorr::Calculator::Helper::Helper
Helper(const std::vector< TrigDef > &defs)
Definition: Calculator.cxx:1583
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:313
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:1609
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:70
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:92
TrigGlobalEfficiencyCorrectionTool::m_seed
unsigned long m_seed
Definition: TrigGlobalEfficiencyCorrectionTool.h:185
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam< Calculator::Helper::Optional< T > >::optional
static constexpr bool optional()
Definition: Calculator.cxx:1625
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:1624
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam::ArgType
std::add_const_t< T > ArgType
Definition: Calculator.cxx:1600
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:240
calibdata.valid
list valid
Definition: calibdata.py:44
TrigGlobEffCorr::Calculator::Helper::extract
auto extract()
Definition: Calculator.cxx:1637
TrigGlobEffCorr::Calculator::globalEfficiency_Factorized2
bool globalEfficiency_Factorized2(const LeptonList &leptons, unsigned runNumber, GlobEffFunc func1, GlobEffFunc func2, Efficiencies &globalEfficiencies)
Definition: Calculator.cxx:1420
TrigGlobEffCorr::Calculator::Helper::duplicates
bool duplicates() const
Definition: Calculator.cxx:1586
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:1653
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:1601
TrigGlobEffCorr::Calculator::m_cachedEfficiencies
std::map< std::pair< const Lepton *, std::size_t >, Efficiencies > m_cachedEfficiencies
Definition: Calculator.h:67
TrigGlobEffCorr::Calculator::Helper::m_n1L
unsigned m_n1L
Definition: Calculator.h:297
TrigGlobEffCorr::ImportData
Definition: ImportData.h:86
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TrigGlobEffCorr::Calculator::m_parent
TrigGlobalEfficiencyCorrectionTool * m_parent
Definition: Calculator.h:62
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:1611
TrigGlobEffCorr::TT_TETRALEPTON_FLAG
@ TT_TETRALEPTON_FLAG
Definition: ImportData.h:79
TrigGlobalEfficiencyCorrectionTool::m_validTrigMatchTool
bool m_validTrigMatchTool
Definition: TrigGlobalEfficiencyCorrectionTool.h:186
xAOD::double
double
Definition: CompositeParticle_v1.cxx:159
TrigGlobalEfficiencyCorrectionTool::TLE_OK
@ TLE_OK
Definition: TrigGlobalEfficiencyCorrectionTool.h:240
TrigGlobEffCorr::TT_TRILEPTON_FLAG
@ TT_TRILEPTON_FLAG
Definition: ImportData.h:53
TrigGlobalEfficiencyCorrectionTool::TLE_UNAVAILABLE
@ TLE_UNAVAILABLE
Definition: TrigGlobalEfficiencyCorrectionTool.h:240
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:296
TrigGlobEffCorr::Calculator::Helper::NoSuchTrigger
Definition: Calculator.h:308
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:1623
TrigGlobEffCorr::Lepton
Definition: Lepton.h:16
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:1432
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:1616
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::checkTriggerMatching
bool checkTriggerMatching(TrigGlobalEfficiencyCorrectionTool &parent, bool &matched, const LeptonList &leptons, unsigned runNumber)
Definition: Calculator.cxx:144
TrigGlobEffCorr::Calculator::getCachedTriggerLegEfficiencies
Efficiencies getCachedTriggerLegEfficiencies(const Lepton &lepton, unsigned runNumber, std::size_t leg, bool &success)
Definition: Calculator.cxx:265
TrigGlobalEfficiencyCorrectionTool::m_trigMatchTool
ToolHandle< Trig::IMatchingTool > m_trigMatchTool
Definition: TrigGlobalEfficiencyCorrectionTool.h:163
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
TrigGlobEffCorr::Calculator::Helper::m_n3L
unsigned m_n3L
Definition: Calculator.h:297
TrigGlobEffCorr::Calculator::Helper::m_n4L
unsigned m_n4L
Definition: Calculator.h:297
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam< flat_set< T > >::add
static void add(flat_set< T > &arg, ImportData::TrigDef &def)
Definition: Calculator.cxx:1613
TrigGlobalEfficiencyCorrectionTool::m_numberOfToys
unsigned long m_numberOfToys
Definition: TrigGlobalEfficiencyCorrectionTool.h:161
TrigGlobEffCorr::Calculator::Helper::m_formula
std::function< bool(Calculator *, const LeptonList &, unsigned, Efficiencies &)> m_formula
Definition: Calculator.h:291
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:1771
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:1626
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:313
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam< flat_set< T > >::optional
static constexpr bool optional()
Definition: Calculator.cxx:1612
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam< Calculator::Helper::Optional< T > >::TrigType
typename BindPackedParam< T >::TrigType TrigType
Definition: Calculator.cxx:1622
TrigGlobEffCorr::Calculator::Helper
Definition: Calculator.h:284
TrigGlobEffCorr::Calculator::fillListOfLegsFor
bool fillListOfLegsFor(const Lepton &lepton, const std::vector< TrigDef > &triggers, flat_set< std::size_t > &validLegs) const
Definition: Calculator.cxx:1447
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:1465
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:1513
TrigGlobEffCorr::Calculator::getRelevantTriggersForUser
bool getRelevantTriggersForUser(TrigGlobalEfficiencyCorrectionTool &parent, std::vector< std::string > &triggers, unsigned runNumber)
Definition: Calculator.cxx:233
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:1602
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:177
TrigGlobEffCorr::Calculator::Helper::m_n2L
unsigned m_n2L
Definition: Calculator.h:297
TrigGlobEffCorr::Calculator::GlobEffFunc
std::function< bool(Calculator *, const LeptonList &, unsigned, Efficiencies &)> GlobEffFunc
Definition: Calculator.h:30
TrigGlobEffCorr::Calculator::Period
Definition: Calculator.h:49
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:1630
TrigGlobEffCorr::TrigGlobEffCorr::Calculator::Helper::BindPackedParam::TrigType
T TrigType
Definition: Calculator.cxx:1599
TrigGlobEffCorr::Calculator::Helper::Optional
Definition: Calculator.h:310
TrigGlobEffCorr::Calculator::getPeriod
const Period * getPeriod(unsigned runNumber) const
Definition: Calculator.cxx:111