ATLAS Offline Software
Loading...
Searching...
No Matches
Trigger.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5// contact: jmaurer@cern.ch
6
7#ifndef TRIGGLOBALEFFICIENCYCORRECTION_TRIGGER_H
8#define TRIGGLOBALEFFICIENCYCORRECTION_TRIGGER_H 1
9
10#include <algorithm>
11#include <array>
12#include <type_traits>
13
15#include "xAODBase/ObjectType.h"
16#include "CxxUtils/flat_set.h"
17template <typename Key>
19
20namespace TrigGlobEffCorr {
21
22class UnusedArg {
23 public:
24 static constexpr xAOD::Type::ObjectType object() { return xAOD::Type::Other; }
25};
26
28 public:
29 explicit constexpr TriggerProperties(TriggerType tt) : m_type(tt), m_legs{} {}
31 : m_type(def.type) {
32 loadLegs(def, m_legs);
33 }
34 constexpr TriggerType type() const { return m_type; }
35 constexpr bool valid() const {
36 return !((m_type & TT_MASK_FLAVOUR) &
39 }
40 constexpr bool mixed() const {
41 auto x = m_type & TT_MASK_FLAVOUR;
42 return (x != TT_ELECTRON_FLAG) && (x != TT_MUON_FLAG) &&
43 (x != TT_PHOTON_FLAG);
44 }
45 constexpr unsigned nDistinctLegs() const {
46 auto x = m_type & TT_MASK_SYMMETRY;
48 return 1;
49 else if (m_type & TT_DILEPTON_FLAG)
50 return 2 - 1 * (x == TT_SYM);
51 else if (m_type & TT_TRILEPTON_FLAG)
52 return (x == TT_ASYM) ? 3 : 1 + 1 * (mixed() || (x != TT_SYM));
53 else if ((m_type & TT_TETRALEPTON_FLAG) && x == TT_SYM)
54 return 1;
55 return 0;
56 }
57 constexpr unsigned nDistinctLegs(xAOD::Type::ObjectType obj) const {
58 bool firstPos = true;
59 switch (obj) {
61 if (!(m_type & TT_ELECTRON_FLAG))
62 return 0;
63 break;
65 if (!(m_type & TT_MUON_FLAG))
66 return 0;
67 firstPos = (m_type & TT_PHOTON_FLAG);
68 break;
70 if (!(m_type & TT_PHOTON_FLAG))
71 return 0;
72 firstPos = false;
73 break;
74 default:
75 return 0;
76 }
77 if (!mixed())
78 return nDistinctLegs();
79 return (firstPos == (m_type & TT_X2Y_FLAG)) ? 1 : nDistinctLegs() - 1;
80 }
81 template <typename Array>
82 void loadLegs(const ImportData::TrigDef& src, Array& dest) {
83 if (src.type != m_type)
84 throw std::runtime_error(
85 "Calculator bug");
87 std::fill(dest.begin(), dest.end(), 0);
91 {
92 dest[0] = src.leg[0];
93 dest[1] = src.leg[2];
94 } else
96 {
97 std::copy_n(src.leg.cbegin(), nDistinctLegs(), dest.begin());
98 }
99 }
100
106
107 constexpr auto cbegin(xAOD::Type::ObjectType obj) const {
108 return m_legs.cbegin() + cbegin_offset(obj);
109 }
110
111 constexpr int cend_offset(xAOD::Type::ObjectType obj) const {
112 return -((obj != xAOD::Type::Photon) *
115 }
116
117 constexpr auto cend(xAOD::Type::ObjectType obj) const {
118 return m_legs.cbegin() + nDistinctLegs() + cend_offset(obj);
119 }
120
121 protected:
123 std::array<std::size_t, 4> m_legs;
124};
125
126template <TriggerType tt, typename CastType1 = UnusedArg,
127 typename CastType2 = UnusedArg>
128class Trigger {
129 static_assert(TriggerProperties(tt).valid(), "trigger type not supported");
130
131 private:
132 static constexpr bool extraCheck(xAOD::Type::ObjectType obj) {
133 return (object() == obj || obj == xAOD::Type::Other);
134 }
135 template <typename T>
136 struct Optional {};
137
138 public:
139 static constexpr TriggerType type() { return tt; }
140
141 static constexpr bool mixed() { return TriggerProperties(tt).mixed(); }
142
143 static constexpr unsigned nDistinctLegs() {
144 return TriggerProperties(tt).nDistinctLegs();
145 }
146
147 static constexpr unsigned nDistinctLegs(xAOD::Type::ObjectType obj) {
148 return TriggerProperties(tt).nDistinctLegs(obj);
149 }
150
151 static constexpr xAOD::Type::ObjectType object1() {
152 if (!is3Lmix()) {
153 if (tt & TT_ELECTRON_FLAG)
155 if (tt & TT_MUON_FLAG)
156 return xAOD::Type::Muon;
157 if (tt & TT_PHOTON_FLAG)
158 return xAOD::Type::Photon;
159 return xAOD::Type::Other;
160 }
161 if ((tt & TT_ELECTRON_FLAG) && !(tt & TT_X2Y_FLAG))
163 if ((tt & TT_PHOTON_FLAG) && (tt & TT_X2Y_FLAG))
164 return xAOD::Type::Photon;
166 }
167
168 static constexpr xAOD::Type::ObjectType object2() {
169 if (is2Lmix()) {
170 if ((tt & TT_ELECTRON_FLAG) && (tt & TT_MUON_FLAG))
171 return xAOD::Type::Muon;
172 if ((tt & (TT_ELECTRON_FLAG | TT_MUON_FLAG)) && (tt & TT_PHOTON_FLAG))
173 return xAOD::Type::Photon;
174 return xAOD::Type::Other;
175 } else if (!is3Lmix())
176 return xAOD::Type::Other;
177 if ((tt & TT_ELECTRON_FLAG) && (tt & TT_X2Y_FLAG))
179 if ((tt & TT_PHOTON_FLAG) && !(tt & TT_X2Y_FLAG))
180 return xAOD::Type::Photon;
182 }
183
184 static constexpr xAOD::Type::ObjectType object() {
185 if (mixed())
186 return xAOD::Type::Other;
187 return object1();
188 }
189
190 static bool relevantFor(const Lepton& lepton) {
191 return lepton.type() == object();
192 }
193 static bool irrelevantFor(const Lepton& lepton) {
194 return !relevantFor(lepton);
195 }
196
197 static constexpr bool is1L() { return (tt & TT_SINGLELEPTON_FLAG); }
198 static constexpr bool is2Lnomix() {
199 return (tt & TT_DILEPTON_FLAG) && !mixed();
200 }
201 static constexpr bool is2Lasym() {
202 return ((tt & TT_MASK_TYPE) == TT_DILEPTON_ASYM);
203 }
204 static constexpr bool is2Lsym() {
205 return ((tt & TT_MASK_TYPE) == TT_DILEPTON_SYM);
206 }
207 static constexpr bool is3Lsym() {
208 return ((tt & TT_MASK_TYPE) == TT_TRILEPTON_SYM) && !mixed();
209 }
210 static constexpr bool is3Lhalfsym() {
211 return ((tt & TT_MASK_TYPE) == TT_TRILEPTON_HALFSYM) && !mixed();
212 }
213 static constexpr bool is2Lmix() { return (tt & TT_DILEPTON_FLAG) && mixed(); }
214 static constexpr bool is3Lmix() {
215 return (tt & TT_TRILEPTON_FLAG) && mixed();
216 }
217 static constexpr bool is4Lsym() {
218 return ((tt & TT_MASK_TYPE) == TT_TETRALEPTON_SYM);
219 }
220
221 std::array<std::size_t, nDistinctLegs()> legs;
222
223 explicit Trigger() { std::fill(legs.begin(), legs.end(), 0); }
224
226 : Trigger()
227 {
229 }
230
233 }
234
235 template <bool = true>
236 std::size_t operator()(void) const {
237 static_assert(nDistinctLegs() == 1,
238 "this function is not meaningful for this type of trigger, "
239 "hence should not be used.");
240 return legs[0];
241 }
242
243 std::size_t operator()(unsigned index) const { return legs[index]; }
244
245 template <bool = true>
246 std::size_t operator<(const Trigger& rhs) const {
247 static_assert(is1L(),
248 "this function is not meaningful for this type of trigger, "
249 "hence should not be used.");
250 return legs[0] < rhs.legs[0];
251 }
252
253 explicit operator bool() const {
254 return std::all_of(legs.cbegin(), legs.cend(),
255 [](std::size_t x) -> bool { return x; });
256 }
257
258 bool operator==(const Trigger& rhs) const { return legs == rhs.legs; }
259
260 template <xAOD::Type::ObjectType obj = object()>
261 constexpr auto cbegin() const {
262 return legs.cbegin() + TriggerProperties(tt).cbegin_offset(obj);
263 }
264
265 template <xAOD::Type::ObjectType obj = object()>
266 constexpr auto cend() const {
267 return legs.cend() + TriggerProperties(tt).cend_offset(obj);
268 }
269
270 template <typename Trig1L>
271 auto hiddenBy(const Trig1L trig) const ->
272 typename std::enable_if<Trig1L::is1L(), bool>::type {
273 static_assert(Trig1L::is1L(),
274 "this function is not meaningful for this type of trigger, "
275 "hence should not be used.");
276 constexpr auto obj = Trig1L::object();
277 return std::find(cbegin<obj>(), cend<obj>(), trig()) != cend<obj>();
278 }
279
280 template <typename Trig1L>
281 auto hiddenBy(const flat_set<Trig1L>& trigs) const ->
282 typename std::enable_if<Trig1L::is1L(), bool>::type {
283 static_assert(Trig1L::is1L(),
284 "this function is not meaningful for this type of trigger, "
285 "hence should not be used.");
286 return std::any_of(trigs.cbegin(), trigs.cend(),
287 [&](Trig1L t) -> bool { return hiddenBy(t); });
288 }
289
292 template <xAOD::Type::ObjectType obj, bool anti = false>
293 auto side() const -> std::conditional_t<anti ^ (CastType1::object() == obj),
294 CastType1, CastType2> {
295 static_assert(mixed(),
296 "this function is not meaningful for this type of trigger, "
297 "hence should not be used.");
298 static_assert(obj != xAOD::Type::Other, "implementation incomplete");
299 using CastType = decltype(side<obj, anti>());
300 CastType trig;
301 std::copy_n(this->cbegin<CastType::object()>(),
302 nDistinctLegs(CastType::object()), trig.legs.begin());
303 return trig;
304 }
305
307 template <typename TrigX>
308 auto side() const -> decltype(side<TrigX::object()>()) {
309 return side<TrigX::object()>();
310 }
311
312 template <typename TrigX>
313 auto antiside() const -> decltype(side<TrigX::object(), true>()) {
315 }
316
317 CastType1 side1() const { return side<CastType1::object()>(); }
318 CastType2 side2() const { return side<CastType2::object()>(); }
319
320 template <typename Trig1L>
321 auto addTo(const flat_set<Trig1L>& trigs1L) const
322 -> std::enable_if_t<Trig1L::is1L() &&
323 nDistinctLegs(Trig1L::object()) == 1,
325 static_assert(mixed(),
326 "this function is not meaningful for this type of trigger, "
327 "hence should not be used.");
328 flat_set<Trig1L> trigs(trigs1L);
329 trigs.insert(side<Trig1L>());
330 return trigs;
331 }
332
333 template <typename Trig1L>
334 static auto anonymize(const flat_set<Trig1L>& triggers)
335 -> std::enable_if_t<is1L() && tt == Trig1L::type(),
336 const flat_set<std::size_t>&> {
337 static_assert(sizeof(Trig1L) == sizeof(std::size_t),
338 "invalid cast if the key sizes differ");
339 return reinterpret_cast<const flat_set<std::size_t>&>(triggers);
340 }
341
342 template <bool = true>
343 bool symmetric() const {
344 static_assert(!std::is_same<CastType1, UnusedArg>::value,
345 "this function is not meaningful for this type of trigger, "
346 "hence should not be used.");
347 return std::all_of(legs.cbegin() + 1, legs.cend(),
348 [&](std::size_t l) -> bool { return l == legs[0]; });
349 }
350
351 template <bool = true>
352 CastType1 to_symmetric() const {
353 static_assert(!std::is_same<CastType1, UnusedArg>::value,
354 "this function is not meaningful for this type of trigger, "
355 "hence should not be used.");
356 CastType1 trig;
357 trig.legs[0] = this->legs[0];
358 return trig;
359 }
360
361 template <bool = true>
362 std::size_t asymLeg() const {
363 static_assert((tt & TT_MASK_SYMMETRY) == TT_HALFSYM,
364 "this function is not meaningful for this type of trigger, "
365 "hence should not be used.");
366 return legs[0];
367 }
368
369 template <bool = true>
370 std::size_t symLeg() const {
371 static_assert((tt & TT_MASK_SYMMETRY) == TT_HALFSYM,
372 "this function is not meaningful for this type of trigger, "
373 "hence should not be used.");
374 return legs[1];
375 }
376};
377
378template <TriggerType, TriggerType = TT_UNKNOWN>
379struct TriggerClass;
380
381template <TriggerType object_flag>
382struct TriggerClass<object_flag, TT_UNKNOWN> {
383 static constexpr auto addObjFlag(int tt) {
384 return static_cast<TriggerType>(tt | object_flag);
385 }
386
388 struct T_1 : public Trigger<addObjFlag(TT_SINGLELEPTON_FLAG)> {};
390 struct T_2sym : public Trigger<addObjFlag(TT_DILEPTON_SYM)> {};
392 struct T_2asym : public Trigger<addObjFlag(TT_DILEPTON_ASYM), T_2sym> {};
394 struct T_3sym : public Trigger<addObjFlag(TT_TRILEPTON_SYM)> {};
396 struct T_3halfsym : public Trigger<addObjFlag(TT_TRILEPTON_HALFSYM), T_3sym> {
397 };
398
399 struct T_4sym : public Trigger<addObjFlag(TT_TETRALEPTON_SYM)> {};
400};
401
402template <TriggerType object1_flag, TriggerType object2_flag>
406 static constexpr auto addObjFlags(int tt) {
407 return static_cast<TriggerType>(tt | object1_flag | object2_flag);
408 }
409
412 struct T_1_1 : public Trigger<addObjFlags(TT_DILEPTON_FLAG), typename A::T_1,
413 typename B::T_1> {};
414
415 struct T_2sym_1 : public Trigger<addObjFlags(TT_TRILEPTON_SYM),
416 typename A::T_2sym, typename B::T_1> {};
417
418 struct T_2asym_1 : public Trigger<addObjFlags(TT_TRILEPTON_ASYM),
419 typename A::T_2asym, typename B::T_1> {};
420
421 struct T_1_2sym : public Trigger<addObjFlags(TT_TRILEPTON_SYM | TT_X2Y_FLAG),
422 typename A::T_1, typename B::T_2sym> {};
423
424 struct T_1_2asym : public Trigger<addObjFlags(TT_TRILEPTON_SYM | TT_X2Y_FLAG),
425 typename A::T_1, typename B::T_2asym> {};
426};
427
428} // namespace TrigGlobEffCorr
429
430#endif
CxxUtils::flat_set< Key > flat_set
#define x
xAOD::Type::ObjectType type() const
Definition Lepton.h:29
constexpr TriggerType type() const
Definition Trigger.h:34
constexpr auto cbegin(xAOD::Type::ObjectType obj) const
Definition Trigger.h:107
constexpr int cbegin_offset(xAOD::Type::ObjectType obj) const
Definition Trigger.h:101
constexpr unsigned nDistinctLegs() const
Definition Trigger.h:45
TriggerProperties(const ImportData::TrigDef &def)
Definition Trigger.h:30
constexpr auto cend(xAOD::Type::ObjectType obj) const
Definition Trigger.h:117
std::array< std::size_t, 4 > m_legs
Definition Trigger.h:123
constexpr bool mixed() const
Definition Trigger.h:40
void loadLegs(const ImportData::TrigDef &src, Array &dest)
Definition Trigger.h:82
constexpr unsigned nDistinctLegs(xAOD::Type::ObjectType obj) const
Definition Trigger.h:57
constexpr TriggerProperties(TriggerType tt)
Definition Trigger.h:29
constexpr int cend_offset(xAOD::Type::ObjectType obj) const
Definition Trigger.h:111
constexpr bool valid() const
Definition Trigger.h:35
static bool irrelevantFor(const Lepton &lepton)
Definition Trigger.h:193
static constexpr unsigned nDistinctLegs(xAOD::Type::ObjectType obj)
Definition Trigger.h:147
static constexpr bool mixed()
Definition Trigger.h:141
CastType2 side2() const
Definition Trigger.h:318
std::array< std::size_t, nDistinctLegs()> legs
Definition Trigger.h:221
auto addTo(const flat_set< Trig1L > &trigs1L) const -> std::enable_if_t< Trig1L::is1L() &&nDistinctLegs(Trig1L::object())==1, flat_set< Trig1L > >
Definition Trigger.h:321
static constexpr xAOD::Type::ObjectType object1()
Definition Trigger.h:151
static constexpr bool is3Lhalfsym()
Definition Trigger.h:210
CastType1 to_symmetric() const
Definition Trigger.h:352
static constexpr xAOD::Type::ObjectType object2()
Definition Trigger.h:168
static constexpr bool is2Lmix()
Definition Trigger.h:213
static constexpr TriggerType type()
Definition Trigger.h:139
auto hiddenBy(const flat_set< Trig1L > &trigs) const -> typename std::enable_if< Trig1L::is1L(), bool >::type
Definition Trigger.h:281
auto hiddenBy(const Trig1L trig) const -> typename std::enable_if< Trig1L::is1L(), bool >::type
Definition Trigger.h:271
CastType1 side1() const
Returns a pseudo trigger of type CastType1/2.
Definition Trigger.h:317
auto side() const -> std::conditional_t< anti ^(CastType1::object()==obj), CastType1, CastType2 >
Returns a pseudo trigger built only from the legs of flavour 'obj' If anti==true, uses instead only l...
Definition Trigger.h:293
void setDefinition(const ImportData::TrigDef &def)
Definition Trigger.h:231
static constexpr bool is2Lsym()
Definition Trigger.h:204
static constexpr bool is2Lnomix()
Definition Trigger.h:198
std::size_t operator()(unsigned index) const
Definition Trigger.h:243
static constexpr bool is4Lsym()
Definition Trigger.h:217
bool symmetric() const
Definition Trigger.h:343
std::size_t operator()(void) const
Definition Trigger.h:236
constexpr auto cbegin() const
Definition Trigger.h:261
static constexpr unsigned nDistinctLegs()
Definition Trigger.h:143
static constexpr bool is3Lmix()
Definition Trigger.h:214
auto antiside() const -> decltype(side< TrigX::object(), true >())
Complement to the previous function.
Definition Trigger.h:313
std::size_t asymLeg() const
Definition Trigger.h:362
constexpr auto cend() const
Definition Trigger.h:266
Trigger(const ImportData::TrigDef &def)
Definition Trigger.h:225
static auto anonymize(const flat_set< Trig1L > &triggers) -> std::enable_if_t< is1L() &&tt==Trig1L::type(), const flat_set< std::size_t > & >
Definition Trigger.h:334
static constexpr bool is1L()
Definition Trigger.h:197
static constexpr xAOD::Type::ObjectType object()
Definition Trigger.h:184
static constexpr bool is3Lsym()
Definition Trigger.h:207
std::size_t operator<(const Trigger &rhs) const
Definition Trigger.h:246
static constexpr bool is2Lasym()
Definition Trigger.h:201
static constexpr bool extraCheck(xAOD::Type::ObjectType obj)
Definition Trigger.h:132
bool operator==(const Trigger &rhs) const
Definition Trigger.h:258
auto side() const -> decltype(side< TrigX::object()>())
Returns a pseudo trigger built only from the legs of the same flavour as the trigger 'TrigX'.
Definition Trigger.h:308
std::size_t symLeg() const
Definition Trigger.h:370
static bool relevantFor(const Lepton &lepton)
Definition Trigger.h:190
static constexpr xAOD::Type::ObjectType object()
Definition Trigger.h:24
Wrapper for C++23 std::flat_set.
boost::container::flat_set< KEY, COMPARE, KEYCONTAINER > flat_set
Definition flat_set.h:40
the template specializations below must be enclosed in this namespace
Definition index.py:1
STL namespace.
ObjectType
Type of objects that have a representation in the xAOD EDM.
Definition ObjectType.h:32
@ Photon
The object is a photon.
Definition ObjectType.h:47
@ Other
An object not falling into any of the other categories.
Definition ObjectType.h:34
@ Muon
The object is a muon.
Definition ObjectType.h:48
@ Electron
The object is an electron.
Definition ObjectType.h:46
mixed-flavour dilepton trigger (e17_lhloose_nod0_mu14, e7_lhmedium_mu24, ...):
Definition Trigger.h:413
mixed-flavour trilepton trigger type x_y_y
Definition Trigger.h:425
mixed-flavour trilepton trigger type x_2y (e12_lhloose_2mu10, ...)
Definition Trigger.h:422
mixed-flavour trilepton trigger type x_x_y
Definition Trigger.h:419
mixed-flavour trilepton trigger type 2x_y (2e12_lhloose_mu10, ...)
Definition Trigger.h:416
single-lepton trigger (e24_lhmedium_L1EM20VH, mu24_imedium_OR_mu40...)
Definition Trigger.h:388
asymmetric dilepton trigger (mu18_mu8noL1, g35_loose_g25_loose, ...):
Definition Trigger.h:392
symmetric dilepton trigger (2e17_lhvloose_nod0, 2mu14...)
Definition Trigger.h:390
half-symmetric trilepton trigger (e17_lhloose_2e9_lhloose, mu6_2mu4, ...):
Definition Trigger.h:396
symmetric tetralepton trigger (4mu4, ...):
Definition Trigger.h:399
TriggerClass< object2_flag > B
Definition Trigger.h:405
static constexpr auto addObjFlags(int tt)
Definition Trigger.h:406
TriggerClass< object1_flag > A
Definition Trigger.h:404