251{
253
254
258
259
261
264
266
268 info.setMotherProperties(ancestor);
270
271
273
274
275
277 int pPDG(0);
279 do {
280 pPDG = 0;
282
283
284 if (ancestor == ancestorParent) { break; }
286 ancestorParent = ancestor;
287 break;
288 }
289
290
291 if (ancestorParent) {
292 pPDG = ancestorParent->
pdgId();
294 ancestor = ancestorParent;
295 }
296 }
298
303 ancestor = ancestorParent;
304 }
305 }
306
307 info.setMotherProperties(ancestor);
308 const int ancestorPDG = ancestor->
pdgId();
313
314
315 auto DP = DecayProducts(partProdVtx);
320 const int NumOfgluon = DP.apd(
MC::GLUON);
321 const int NumOfElNeut = DP.apd(
MC::NU_E);
323 const int NumOfMuPl = DP.pd(-
MC::MUON);
324 const int NumOfMuMin = DP.pd(
MC::MUON);
325 const int NumOfMuNeut = DP.apd(
MC::NU_MU);
326 const int NumOfTau = DP.apd(
MC::TAU);
328
329 samePart = false;
330 int NumOfNucFr(0);
333 if (!aChild) continue;
334 const int childPDG = aChild->pdgId();
336 if (possibleNuclearFragment &&
339 NumOfNucFr++;
340 }
341
342
345 for (
const auto& photonParent: ancestorProdVtx->
particles_in()) {
346 if (!photonParent) continue;
347 info.photonMother = photonParent;
348 }
349 }
350
351 if ((
MC::isPhoton(ancestorPDG) && numberOfChildren == 2 && NumOfEl == 1 && NumOfPos == 1) || (
MC::isPhoton(ancestorPDG) && numberOfChildren == 1 && (NumOfEl == 1 || NumOfPos == 1)))
return PhotonConv;
352
353
355
356 if (numOfParents == 1 && std::abs(ancestorPDG) ==
MC::PIPLUS && numberOfChildren > 2 && NumOfNucFr != 0)
return ElMagProc;
357
358
360
361
363
364
365 if (ancestorPDG ==
MC::ELECTRON && numberOfChildren == 2 && NumOfEl == 2 && NumOfPos == 0)
return ElMagProc;
366
367
368 if (ancestorPDG ==
MC::POSITRON && numberOfChildren == 2 && NumOfEl == 0 && NumOfPos == 2)
return ElMagProc;
369
370
372
373
374
375 if (numberOfChildren == 2 && (NumOfEl == 1 || NumOfPos == 1) && !
MC::isElectron(ancestorPDG) && samePart)
return ElMagProc;
376
377 if ((ancestorPDG ==
MC::PI0 && numberOfChildren == 3 && NumOfPhot == 1 && NumOfEl == 1 && NumOfPos == 1) ||
378 (ancestorPDG ==
MC::PI0 && numberOfChildren == 4 && NumOfPhot == 0 && NumOfEl == 2 && NumOfPos == 2))
380
381
382 if (
MC::isSMQuark(ancestorPDG) && numOfParents == 1 && numberOfChildren == 3 && NumOfquark == 1 && NumOfElNeut == 1)
return QuarkWeakDec;
383
385
387
389
392 do {
395 }
while (
MC::isW(ptrPart) && prodVert);
396
401 }
403 }
406
407
409
413
414 bool isZboson = false;
415 bool isWboson = false;
416 bool skipnext = false;
417
418 for (
unsigned int ipOut = 0; ipOut + 1 < partProdVtx->
nOutgoingParticles(); ++ipOut) {
420 if (!aChild) continue;
422 for (
unsigned int ipOut1 = ipOut + 1; ipOut1 < partProdVtx->
nOutgoingParticles(); ipOut1++) {
424 if (theNextChild) break;
425 }
426 if (!theNextChild) continue;
427 if (skipnext) {
428 skipnext = false;
429 continue;
430 }
431
433
434 if (thePartToCheck == aChild || thePartToCheck == theNextChild) {
435 isZboson = true;
436 break;
437 }
438 skipnext = true;
440
441 if (thePartToCheck == aChild || thePartToCheck == theNextChild) {
442 isWboson = true;
443 break;
444 }
445 skipnext = true;
446 }
447 }
448 if (isWboson)
return WBoson;
449 if (isZboson)
return ZBoson;
450 }
451 if (numOfParents == 2) {
452
453 if ((numberOfChildren - NumOfquark - NumOfgluon) == 2 && NumOfEl == 1 && NumOfPos == 1)
return ZBoson;
454
455
456 if ((numberOfChildren - NumOfquark - NumOfgluon) == 2 && (NumOfEl == 1 || NumOfPos == 1) && NumOfElNeut == 1)
return WBoson;
457
460
461 if ((numberOfChildren - NumOfquark - NumOfgluon) == 4 &&
462 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 4) &&
464
465
466 if ((numberOfChildren - NumOfquark - NumOfgluon - NumOfPhot) == 6 &&
467 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 6) &&
469 }
470
471
472 if (partProdVtx == ancestorProdVtx) {
473 int NumOfEleLoop = 0;
474 int NumOfLepLoop = 0;
475 int NumOfEleNeuLoop = 0;
477 if (!pout) continue;
478 for (
const auto *
const pin: partProdVtx->
particles_in()) {
479 if (!pin) continue;
482 if (std::abs(
pout->pdgId()) ==
MC::NU_E) NumOfEleNeuLoop++;
484 break;
485 }
486 }
487 if (NumOfEleLoop == 2 && NumOfEleNeuLoop == 0)
return ZBoson;
488 if (NumOfEleLoop == 1 && NumOfEleNeuLoop == 1)
return WBoson;
489 if ((NumOfEleLoop == 4 && NumOfEleNeuLoop == 0) || (NumOfEleLoop == 3 && NumOfEleNeuLoop == 1) ||
490 (NumOfEleLoop == 2 && NumOfEleNeuLoop == 2))
return DiBoson;
491 if (NumOfLepLoop == 4)
return DiBoson;
492 }
493
494
495
497
499
501
507 }
508
516
520}
bool TruthLoopDetectionMethod1(const xAOD::TruthVertex *childOrigVtx, const xAOD::TruthParticle *parent) const
bool TruthLoopDetectionMethod2(const xAOD::TruthParticle *child, const xAOD::TruthParticle *parent) const
MCTruthPartClassifier::ParticleOrigin defOrigOfTau(const xAOD::TruthParticleContainer &xTruthParticleContainer, const xAOD::TruthParticle *, int motherPDG, MCTruthPartClassifier::Info &info) const
int pdgId() const
PDG ID code.
const TruthVertex_v1 * decayVtx() const
The decay vertex of this particle.
bool hasProdVtx() const
Check for a production vertex on this particle.
const TruthVertex_v1 * prodVtx() const
The production vertex of this particle.
const TruthParticle_v1 * outgoingParticle(size_t index) const
Get one of the outgoing particles.
const TruthParticle_v1 * incomingParticle(size_t index) const
Get one of the incoming particles.
std::vector< const TruthParticle * > particles_out() const
Get the outgoing particles.
size_t nOutgoingParticles() const
Get the number of outgoing particles.
size_t nIncomingParticles() const
Get the number of incoming particles.
std::vector< const TruthParticle * > particles_in() const
Get the incoming particles.
bool is_same_generator_particle(const T1 &p1, const T2 &p2)
Method to establish if two particles in the GenEvent actually represent the same generated particle.
bool is_same_particle(const T1 &p1, const T2 &p2)
Method to establish if two particles in the GenEvent actually represent the same particle.
ParticleOutCome defOutComeOfElectron(T thePart)
ParticleOrigin convHadronTypeToOrig(ParticleType pType, int motherPDG)
ParticleType defTypeOfTau(ParticleOrigin TauOrig)
ParticleType defTypeOfHadron(int pdg)
int isPrompt(const unsigned int classify, bool allow_prompt_tau_decays=true)
T findMatching(C TruthContainer, T p)
Function to find a particle in container.
bool isNeutrinoRH(const T &p)
PDG Rule 12: APID: Helper function for right-handed neutrino states These are generator defined PDG I...
bool isHardScatteringVertex(T pVert)
Function to classify the vertex as hard scattering vertex.
bool isSMLepton(const T &p)
APID: the fourth generation leptons are not standard model leptons.
bool isPhoton(const T &p)
static const int RH_NU_TAU
static const int WBOSON_LRSM
bool isElectron(const T &p)
static const int ELECTRON
bool isSMQuark(const T &p)
static const int POSITRON
bool isMSSMHiggs(const T &p)
APID: Additional Higgs bosons for MSSM (Used in MCTruthClassifier)
bool isDecayed(const T &p)
Identify if the particle decayed.
bool isQuark(const T &p)
PDG rule 2: Quarks and leptons are numbered consecutively starting from 1 and 11 respectively; to do ...
T findMother(T thePart)
Function to get a mother of particle. MCTruthClassifier legacy.
bool isHiggs(const T &p)
APID: HIGGS boson is only one particle.
static const int LEPTOQUARK
bool isNucleus(const T &p)
PDG rule 16 Nuclear codes are given as 10-digit numbers ±10LZZZAAAI.
static const int RH_NU_MU
bool isHeavyBoson(const T &p)
APID: Additional "Heavy"/"prime" versions of W and Z bosons (Used in MCTruthClassifier)
bool isLeptoQuark(const T &p)
PDG rule 11c: “One-of-a-kind” exotic particles are assigned numbers in the range 41–80.
static const int RH_NU_E
PDG Rule 12: Generator defined PDG ID values for right handed neutrinos and corresponding W+ boson fr...
bool isBSM(const T &p)
APID: graviton and all Higgs extensions are BSM.
pout(output, newline=True)
TruthVertex_v1 TruthVertex
Typedef to implementation.
TruthParticle_v1 TruthParticle
Typedef to implementation.