258{
260
261
265
266
268
271
273
275 info.setMotherProperties(ancestor);
277
278
279 bool samePart = TruthLoopDetectionMethod1(partProdVtx, ancestor);
280
281
282
284 int pPDG(0);
286 do {
287 pPDG = 0;
289
290
291 if (ancestor == ancestorParent) { break; }
292 if (TruthLoopDetectionMethod2(ancestor,ancestorParent)) {
293 ancestorParent = ancestor;
294 break;
295 }
296
297
298 if (ancestorParent) {
299 pPDG = ancestorParent->
pdgId();
301 ancestor = ancestorParent;
302 }
303 }
305
310 ancestor = ancestorParent;
311 }
312 }
313
314 info.setMotherProperties(ancestor);
315 const int ancestorPDG = ancestor->
pdgId();
320
321
322 auto DP = DecayProducts(partProdVtx);
327 const int NumOfgluon = DP.apd(
MC::GLUON);
328 const int NumOfElNeut = DP.apd(
MC::NU_E);
330 const int NumOfMuPl = DP.pd(-
MC::MUON);
331 const int NumOfMuMin = DP.pd(
MC::MUON);
332 const int NumOfMuNeut = DP.apd(
MC::NU_MU);
333 const int NumOfTau = DP.apd(
MC::TAU);
335
336 samePart = false;
337 int NumOfNucFr(0);
340 if (!aChild) continue;
341 const int childPDG = aChild->pdgId();
343 if (possibleNuclearFragment &&
346 NumOfNucFr++;
347 }
348
349
352 for (
const auto& photonParent: ancestorProdVtx->
particles_in()) {
353 if (!photonParent) continue;
354 info.photonMother = photonParent;
355 }
356 }
357
358 if ((
MC::isPhoton(ancestorPDG) && numberOfChildren == 2 && NumOfEl == 1 && NumOfPos == 1) || (
MC::isPhoton(ancestorPDG) && numberOfChildren == 1 && (NumOfEl == 1 || NumOfPos == 1)))
return PhotonConv;
359
360
362
363 if (numOfParents == 1 && std::abs(ancestorPDG) ==
MC::PIPLUS && numberOfChildren > 2 && NumOfNucFr != 0)
return ElMagProc;
364
365
367
368
370
371
372 if (ancestorPDG ==
MC::ELECTRON && numberOfChildren == 2 && NumOfEl == 2 && NumOfPos == 0)
return ElMagProc;
373
374
375 if (ancestorPDG ==
MC::POSITRON && numberOfChildren == 2 && NumOfEl == 0 && NumOfPos == 2)
return ElMagProc;
376
377
379
380
381
382 if (numberOfChildren == 2 && (NumOfEl == 1 || NumOfPos == 1) && !
MC::isElectron(ancestorPDG) && samePart)
return ElMagProc;
383
384 if ((ancestorPDG ==
MC::PI0 && numberOfChildren == 3 && NumOfPhot == 1 && NumOfEl == 1 && NumOfPos == 1) ||
385 (ancestorPDG ==
MC::PI0 && numberOfChildren == 4 && NumOfPhot == 0 && NumOfEl == 2 && NumOfPos == 2))
387
388
389 if (
MC::isSMQuark(ancestorPDG) && numOfParents == 1 && numberOfChildren == 3 && NumOfquark == 1 && NumOfElNeut == 1)
return QuarkWeakDec;
390
392
394
396
399 do {
402 }
while (
MC::isW(ptrPart) && prodVert);
403
408 }
410 }
413
414
416
420
421 bool isZboson = false;
422 bool isWboson = false;
423 bool skipnext = false;
424
425 for (
unsigned int ipOut = 0; ipOut + 1 < partProdVtx->
nOutgoingParticles(); ++ipOut) {
427 if (!aChild) continue;
429 for (
unsigned int ipOut1 = ipOut + 1; ipOut1 < partProdVtx->
nOutgoingParticles(); ipOut1++) {
431 if (theNextChild) break;
432 }
433 if (!theNextChild) continue;
434 if (skipnext) {
435 skipnext = false;
436 continue;
437 }
438
440
441 if (thePartToCheck == aChild || thePartToCheck == theNextChild) {
442 isZboson = true;
443 break;
444 }
445 skipnext = true;
447
448 if (thePartToCheck == aChild || thePartToCheck == theNextChild) {
449 isWboson = true;
450 break;
451 }
452 skipnext = true;
453 }
454 }
455 if (isWboson)
return WBoson;
456 if (isZboson)
return ZBoson;
457 }
458 if (numOfParents == 2) {
459
460 if ((numberOfChildren - NumOfquark - NumOfgluon) == 2 && NumOfEl == 1 && NumOfPos == 1)
return ZBoson;
461
462
463 if ((numberOfChildren - NumOfquark - NumOfgluon) == 2 && (NumOfEl == 1 || NumOfPos == 1) && NumOfElNeut == 1)
return WBoson;
464
467
468 if ((numberOfChildren - NumOfquark - NumOfgluon) == 4 &&
469 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 4) &&
471
472
473 if ((numberOfChildren - NumOfquark - NumOfgluon - NumOfPhot) == 6 &&
474 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 6) &&
476
477
478 if ((numberOfChildren - NumOfquark - NumOfgluon) == 8 &&
479 (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 8) &&
483 }
484
485
486 if ((numberOfChildren - NumOfquark - NumOfgluon) >= 3 && NumOfPhot >= 1 && NumOfEl == 1 && NumOfPos == 1) {
489 }
490 if ((numberOfChildren - NumOfquark - NumOfgluon) >= 3 && NumOfPhot >= 1 && (NumOfEl == 1 || NumOfPos == 1) && NumOfElNeut == 1) {
493 }
494 }
495
496
497 if (partProdVtx == ancestorProdVtx) {
498 int NumOfEleLoop = 0;
499 int NumOfLepLoop = 0;
500 int NumOfEleNeuLoop = 0;
502 if (!pout) continue;
503 for (
const auto *
const pin: partProdVtx->
particles_in()) {
504 if (!pin) continue;
507 if (std::abs(
pout->pdgId()) ==
MC::NU_E) NumOfEleNeuLoop++;
509 break;
510 }
511 }
512 if (NumOfEleLoop == 2 && NumOfEleNeuLoop == 0)
return ZBoson;
513 if (NumOfEleLoop == 1 && NumOfEleNeuLoop == 1)
return WBoson;
514 if ((NumOfEleLoop == 4 && NumOfEleNeuLoop == 0) || (NumOfEleLoop == 3 && NumOfEleNeuLoop == 1) ||
515 (NumOfEleLoop == 2 && NumOfEleNeuLoop == 2))
return DiBoson;
516 if (NumOfLepLoop == 4)
return DiBoson;
517 }
518
519
520
522
524
526
532 }
533
541
545}
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_VERBOSE(x,...)
MCTruthPartClassifier::ParticleOrigin defOrigOfTau(const xAOD::TruthParticleContainer &xTruthParticleContainer, const xAOD::TruthParticle *, int motherPDG, IMCTruthClassifier::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)
Determine the outcome of a simulated electron from its end vertex (NonInteract, ElectrMagInter,...
ParticleOrigin convHadronTypeToOrig(ParticleType pType, int motherPDG)
Convert a hadron ParticleType to a ParticleOrigin (JPsi if a c-cbar meson has a J/psi mother).
ParticleType defTypeOfTau(ParticleOrigin TauOrig)
Classify a tau (Unknown/Iso/NonIso/Bkg) from its origin.
ParticleType defTypeOfHadron(int pdg)
Classify a hadron by PDG ID into a ParticleType (Unknown if none applies).
int isPrompt(const unsigned int classify, bool allow_prompt_tau_decays=true)
Tell whether a particle is prompt, from the word returned by defOrigOfParticle().
T findMatching(C TruthContainer, T p)
Function to find in the container the particle that p descends from in the simulation (see HepMC::is_...
bool isNeutrinoRH(const T &p)
PDG rule 12: Occasionally program authors add their own states.
static const int DQUARK
PDG Rule 1: Particles are given positive numbers, antiparticles negative numbers.
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: Occasionally program authors add their own states.
bool isBSM(const T &p)
APID: graviton and all Higgs extensions are BSM.
TruthVertex_v1 TruthVertex
Typedef to implementation.
TruthParticle_v1 TruthParticle
Typedef to implementation.