ATLAS Offline Software
Loading...
Searching...
No Matches
TruthClassifiers.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4#ifndef TRUTHUTILS_TRUTHCLASSIFIERS_H
5#define TRUTHUTILS_TRUTHCLASSIFIERS_H
8#include <utility>
9#include <bitset>
10#include <vector>
11#include <string>
17 if (pType == CCbarMesonPart && abs(motherPDG) == MC::JPSI) return JPsi;
18 if (pType == BBbarMesonPart) return BBbarMeson;
19 if (pType == BottomMesonPart) return BottomMeson;
20 if (pType == BottomBaryonPart) return BottomBaryon;
21 if (pType == CCbarMesonPart) return CCbarMeson;
22 if (pType == CharmedMesonPart) return CharmedMeson;
23 if (pType == CharmedBaryonPart) return CharmedBaryon;
24 if (pType == StrangeBaryonPart) return StrangeBaryon;
25 if (pType == StrangeMesonPart) return StrangeMeson;
26 if (pType == LightBaryonPart) return LightBaryon;
27 if (pType == LightMesonPart) return LightMeson;
28 return NonDefined;
32 if (abs(pdg) == MC::JPSI) return JPsi;
33 if (MC::isBBbarMeson(pdg)) return BBbarMeson;
34 if (MC::isCCbarMeson(pdg)) return CCbarMeson;
42 if (MC::isLightMeson(pdg)) return LightMeson;
43 return NonDefined;
50 if (MC::isCharmMeson(pdg)) return CharmedMesonPart;
51 if (MC::isBottomBaryon(pdg)) return BottomBaryonPart;
54 if (MC::isLightBaryon(pdg)) return LightBaryonPart;
57 return Unknown;
59
63 if (EleOrig == NonDefined)
66 if (EleOrig == WBoson || EleOrig == ZBoson || EleOrig == top || EleOrig == SingleElec || EleOrig == Higgs ||
67 EleOrig == HiggsMSSM || EleOrig == HeavyBoson || EleOrig == WBosonLRSM || EleOrig == NuREle || EleOrig == NuRMu ||
68 EleOrig == NuRTau || EleOrig == LQ || EleOrig == SUSY || EleOrig == DiBoson || EleOrig == ZorHeavyBoson ||
69 EleOrig == OtherBSM || EleOrig == MultiBoson || isPrompt) {
71 }
72 if (EleOrig == JPsi || EleOrig == BottomMeson || EleOrig == CharmedMeson || EleOrig == BottomBaryon ||
73 EleOrig == CharmedBaryon || EleOrig == TauLep || EleOrig == Mu || EleOrig == QuarkWeakDec) {
75 }
77}
82 if (MuOrig == NonDefined) return UnknownMuon;
84 if (MuOrig == WBoson || MuOrig == ZBoson || MuOrig == top || MuOrig == SingleMuon || MuOrig == Higgs ||
85 MuOrig == HiggsMSSM || MuOrig == HeavyBoson || MuOrig == WBosonLRSM || MuOrig == NuREle || MuOrig == NuRMu ||
86 MuOrig == NuRTau || MuOrig == LQ || MuOrig == SUSY || MuOrig == DiBoson || MuOrig == ZorHeavyBoson ||
87 MuOrig == OtherBSM || MuOrig == MultiBoson || isPrompt) {
88 return IsoMuon;
89 }
90 if (MuOrig == JPsi || MuOrig == BottomMeson || MuOrig == CharmedMeson || MuOrig == BottomBaryon ||
91 MuOrig == CharmedBaryon || MuOrig == TauLep || MuOrig == QuarkWeakDec) {
92 return NonIsoMuon;
93 }
94 // if (MuOrig == Pion || MuOrig == Kaon ) return DecayMuon;
95 return BkgMuon;
99 if (TauOrig == NonDefined) return UnknownTau;
101 if (TauOrig == WBoson || TauOrig == ZBoson || TauOrig == top || TauOrig == SingleMuon || TauOrig == Higgs ||
102 TauOrig == HiggsMSSM || TauOrig == HeavyBoson || TauOrig == WBosonLRSM || TauOrig == NuREle || TauOrig == NuRMu ||
103 TauOrig == NuRTau || TauOrig == SUSY || TauOrig == DiBoson || TauOrig == ZorHeavyBoson || TauOrig == OtherBSM ||
104 TauOrig == MultiBoson)
105 return IsoTau;
107 if (TauOrig == JPsi || TauOrig == BottomMeson || TauOrig == CharmedMeson || TauOrig == BottomBaryon ||
108 TauOrig == CharmedBaryon || TauOrig == QuarkWeakDec)
109 return NonIsoTau;
111 return BkgTau;
117 if (PhotOrig == NonDefined) return UnknownPhoton;
119 if (PhotOrig == WBoson || PhotOrig == ZBoson || PhotOrig == SinglePhot || PhotOrig == Higgs ||
120 PhotOrig == HiggsMSSM || PhotOrig == HeavyBoson || PhotOrig == PromptPhot || PhotOrig == SUSY ||
121 PhotOrig == OtherBSM)
122 return IsoPhoton;
124 if (PhotOrig == ISRPhot || PhotOrig == FSRPhot || PhotOrig == TauLep || PhotOrig == Mu || PhotOrig == NuREle ||
125 PhotOrig == NuRMu || PhotOrig == NuRTau)
126 return NonIsoPhoton;
127
128 return BkgPhoton;
129}
130
131template <class T> ParticleOrigin defJetOrig(const T& allJetMothers) {
132 ParticleOrigin partOrig = NonDefined;
133 for (const auto& it: allJetMothers) {
134 int pdg = abs(it->pdg_id());
135 if (MC::isTop(pdg)) partOrig = top;
136 if (MC::isZ(pdg)) partOrig = ZBoson;
137 if (MC::isW(pdg) && !(partOrig == top)) partOrig = WBoson;
138 if ((MC::isQuark(pdg) || MC::isGluon(pdg)) && partOrig != top && partOrig != ZBoson && partOrig != WBoson) partOrig = QCD;
139 if (MC::isHiggs(pdg)) return Higgs;
140 if (pdg == 35 || pdg == 36 || pdg == 37) return HiggsMSSM;
141 if (pdg == 32 || pdg == 33 || pdg == 34) return HeavyBoson;
142 if (pdg == 42) return LQ;
143 if (MC::isSUSY(pdg)) return SUSY;
144 if (MC::isBSM(pdg)) return OtherBSM;
145 }
146 return partOrig;
147}
148 enum MCTC_bits : unsigned int { HadTau=0, Tau, hadron, frombsm, uncat, isbsm, isgeant, stable, totalBits };
149
150template <class T>
151std::tuple<unsigned int, T> defOrigOfParticle(T thePart) {
152
153 T parent_hadron_ptr = nullptr;
154
155 bool uncat = 0, fromHad = 0, fromTau = 0;
156 bool isPhysical = MC::isPhysical(thePart);
157 bool isGeant = HepMC::is_simulation_particle(thePart);
158 bool isBSM = MC::isBSM(thePart);
159 bool fromBSM = isBSM; // just to initialise
160
161 auto prodVtx = thePart->production_vertex();
162 if (isPhysical && prodVtx && !isGeant) {
163 fromHad = MC::isFromHadron(thePart, parent_hadron_ptr, fromTau, fromBSM);
164 }
165 else uncat = 1;
166
167 std::bitset<MCTC_bits::totalBits> classifier;
168 classifier[MCTC_bits::stable] = isPhysical;
169 classifier[MCTC_bits::isgeant] = isGeant;
170 classifier[MCTC_bits::isbsm] = isBSM;
171 classifier[MCTC_bits::uncat] = uncat;
172 classifier[MCTC_bits::frombsm] = fromBSM;
173 classifier[MCTC_bits::hadron] = fromHad;
174 classifier[MCTC_bits::Tau] = fromTau;
175 classifier[MCTC_bits::HadTau] = fromHad && fromTau;
176 unsigned int outputvalue = static_cast<unsigned int>(classifier.to_ulong());
177
178 return std::make_tuple(outputvalue,parent_hadron_ptr);
179}
180 inline int isPrompt(const unsigned int classify, bool allow_prompt_tau_decays = true) {
181 std::bitset<MCTC_bits::totalBits> res(classify);
182 if (res.test(MCTC_bits::uncat)) return -1;
183 bool fromPromptTau = res.test(MCTC_bits::Tau) && !res.test(MCTC_bits::HadTau);
184 if (fromPromptTau) return int(allow_prompt_tau_decays);
185 return !res.test(MCTC_bits::hadron);
186 }
187
188template <class T>
190 ParticleOutCome PartOutCome = UnknownOutCome;
191 auto EndVert = MC::findSimulatedEndVertex(thePart);
192 if (EndVert == nullptr) return NonInteract;
193
194 int ElecOutNumOfNucFr(0);
195 int ElecOutNumOfElec(0);
196 int NumOfHadr(0);
197 auto outgoing = EndVert->particles_out();
198 int NumOfElecDaug = outgoing.size();
199 for (const auto& p: outgoing) {
200 if (!p) continue;
201 int EndDaugType = p->pdg_id();
202 if (MC::isElectron(EndDaugType)) ElecOutNumOfElec++;
203 if (MC::isHadron(p) && !MC::isBeam(p)) NumOfHadr++;
204 if (EndDaugType > 1000000000 || EndDaugType == 0 || abs(EndDaugType) == 2212 || abs(EndDaugType) == 2112) ElecOutNumOfNucFr++;
205 }
206
207 if (ElecOutNumOfNucFr != 0 || NumOfHadr != 0) PartOutCome = NuclInteraction;
208 if (ElecOutNumOfElec == 1 && NumOfElecDaug == 1) PartOutCome = ElectrMagInter;
209
210 return PartOutCome;
211}
212template <class T>
214 ParticleOutCome PartOutCome = UnknownOutCome;
215 auto EndVert = MC::findSimulatedEndVertex(thePart);
216 if (EndVert == nullptr) return NonInteract;
217 int MuOutNumOfNucFr(0);
218 int NumOfHadr(0);
219 int NumOfEleNeutr(0);
220 int NumOfMuonNeutr(0);
221 int NumOfElec(0);
222 auto outgoing = EndVert->particles_out();
223 int NumOfMuDaug = outgoing.size();
224 for (const auto& p: outgoing) {
225 if (!p) continue;
226 int EndDaugType = p->pdg_id();
227 if (MC::isElectron(EndDaugType)) NumOfElec++;
228 if (abs(EndDaugType) == 12) NumOfEleNeutr++;
229 if (abs(EndDaugType) == 14) NumOfMuonNeutr++;
230 if (MC::isHadron(p) && !MC::isBeam(p)) NumOfHadr++;
231 if (EndDaugType > 1000000000 || EndDaugType == 0 || abs(EndDaugType) == 2212 || abs(EndDaugType) == 2112) MuOutNumOfNucFr++;
232 }
233
234 if (MuOutNumOfNucFr != 0 || NumOfHadr != 0) PartOutCome = NuclInteraction;
235 if (NumOfMuDaug == 3 && NumOfElec == 1 && NumOfEleNeutr == 1 && NumOfMuonNeutr == 1) PartOutCome = DecaytoElectron;
236
237 return PartOutCome;
238}
239template <class T>
241 ParticleOutCome PartOutCome = UnknownOutCome;
242 auto EndVert = MC::findSimulatedEndVertex(thePart);
243 if (EndVert == nullptr) return NonInteract;
244 int NumOfTauDaug = EndVert->nOutgoingParticles();
245 auto tauFinalStatePart = MC::findFinalStateParticles(EndVert);
246 auto PD = DecayProducts(tauFinalStatePart);
247 int NumOfElec = PD.apd(11);
248 int NumOfMuon = PD.apd(13);
249 int NumOfElecNeut = PD.apd(12);
250 int NumOfMuonNeut = PD.apd(14);
251 int NumOfPhot = PD.apd(22);
252 int NumOfPi = PD.apd(211);
253 int NumOfKaon = PD.apd(321);
254 int NumOfNucFr = PD.apd(0) + PD.apd(1000000000, std::numeric_limits<int>::max());
255
256 if (NumOfNucFr != 0) PartOutCome = NuclInteraction;
257 if ((NumOfTauDaug == 3 && NumOfElec == 1 && NumOfElecNeut == 1) || (NumOfTauDaug == (3 + NumOfPhot) && NumOfElecNeut == 1)) PartOutCome = DecaytoElectron;
258 if ((NumOfTauDaug == 3 && NumOfMuon == 1 && NumOfMuonNeut == 1) || (NumOfTauDaug == (3 + NumOfPhot) && NumOfMuonNeut == 1)) PartOutCome = DecaytoMuon;
259
260 if (NumOfPi == 1 || NumOfKaon == 1) PartOutCome = OneProng;
261 if (NumOfPi + NumOfKaon == 3) PartOutCome = ThreeProng;
262 if (NumOfPi + NumOfKaon == 5) PartOutCome = FiveProng;
263
264
265 return PartOutCome;
266}
267template <class T>
269 ParticleOutCome PartOutCome = UnknownOutCome;
270 auto EndVert = MC::findSimulatedEndVertex(thePart);
271 if (EndVert == nullptr) return UnConverted;
272
273 int PhtOutNumOfNucFr(0);
274 int PhtOutNumOfEl(0);
275 int PhtOutNumOfPos(0);
276 int PhtOutNumOfHadr(0);
277
278 auto outgoing = EndVert->particles_out();
279 int NumOfPhtDaug = outgoing.size();
280 for (const auto& p: outgoing) {
281 if (!p) continue;
282 int EndDaugType = p->pdg_id();
283 if (EndDaugType > 1000000000 || EndDaugType == 0 || abs(EndDaugType) == 2212 || abs(EndDaugType) == 2112) PhtOutNumOfNucFr++;
284 if (EndDaugType == 11) PhtOutNumOfEl++;
285 if (EndDaugType == -11) PhtOutNumOfPos++;
286 if (MC::isHadron(p)&& !MC::isBeam(p) ) PhtOutNumOfHadr++;
287 }
288
289 if (PhtOutNumOfEl == 1 && PhtOutNumOfPos == 1 && NumOfPhtDaug == 2) PartOutCome = Converted;
290 if ((NumOfPhtDaug > 1 && PhtOutNumOfNucFr != 0) || PhtOutNumOfHadr > 0) PartOutCome = NuclInteraction;
291
292 return PartOutCome;
293}
294
295
296
297}
298#endif
bool isBSM(const T &p)
APID: graviton and all Higgs extensions are BSM.
Definition AtlasPID.h:846
ATLAS-specific HepMC functions.
std::pair< std::vector< unsigned int >, bool > res
bool is_simulation_particle(const T &p)
Method to establish if a particle (or barcode) was created during the simulation (TODO update to be s...
ParticleOutCome defOutComeOfElectron(T thePart)
ParticleOutCome defOutComeOfPhoton(T thePart)
ParticleOrigin defJetOrig(const T &allJetMothers)
ParticleType defTypeOfPhoton(ParticleOrigin PhotOrig)
ParticleOrigin convHadronTypeToOrig(ParticleType pType, int motherPDG)
ParticleOutCome defOutComeOfTau(T thePart)
ParticleType defTypeOfTau(ParticleOrigin TauOrig)
ParticleType defTypeOfMuon(ParticleOrigin MuOrig, bool isPrompt)
ParticleOrigin defHadronType(int pdg)
ParticleType defTypeOfHadron(int pdg)
int isPrompt(const unsigned int classify, bool allow_prompt_tau_decays=true)
ParticleOutCome defOutComeOfMuon(T thePart)
ParticleType defTypeOfElectron(ParticleOrigin EleOrig, bool isPrompt)
std::tuple< unsigned int, T > defOrigOfParticle(T thePart)
bool isZ(const T &p)
bool isStrangeBaryon(const T &p)
bool isLightBaryon(const T &p)
bool isLightMeson(const T &p)
bool isStrangeMeson(const T &p)
bool isBottomMeson(const T &p)
bool isCharmBaryon(const T &p)
bool isW(const T &p)
bool isCCbarMeson(const T &p)
bool isBottomBaryon(const T &p)
bool isCharmMeson(const T &p)
bool isElectron(const T &p)
bool isBBbarMeson(const T &p)
bool isTop(const T &p)
bool isFromHadron(T p, T hadron, bool &fromTau, bool &fromBSM)
Function to classify the particle.
bool isSUSY(const T &p)
auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out())
Function to find the stable particle descendants of the given vertex..
bool isQuark(const T &p)
PDG rule 2: Quarks and leptons are numbered consecutively starting from 1 and 11 respectively; to do ...
static const int JPSI
bool isHiggs(const T &p)
APID: HIGGS boson is only one particle.
bool isBeam(const T &p)
Identify if the particle is beam particle.
bool isHadron(const T &p)
bool isGluon(const T &p)
auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex())
Function to find the end vertex of a particle.
bool isPhysical(const T &p)
Identify if the particle is physical, i.e. is stable or decayed.
bool isBSM(const T &p)
APID: graviton and all Higgs extensions are BSM.