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