462{
464 {
466 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
467
468 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
469
470 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
471 }
472
474
477
480
483
486
489
492
495
498
501
504
509 const auto vertex =
p->end_vertex();
511 }
512
515
518 const int apid = std::abs(
p->pdg_id());
520 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true;
521 if (apid ==
GRAVITON || apid == 1000039 || apid == 5000039)
return true;
522 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true;
523 return false;
524 }
525
527
529 auto partOriVert = thePart->production_vertex();
530 if (!partOriVert) return nullptr;
531
532 long partPDG = thePart->pdg_id();
533 long MotherPDG(0);
534
535 auto MothOriVert = partOriVert;
536 MothOriVert = nullptr;
538
539 size_t itr = 0;
540 do {
541 if (itr != 0) partOriVert = MothOriVert;
542 for ( const auto& p : partOriVert->particles_in() ) {
544 if (!theMoth) continue;
545 MotherPDG = theMoth->pdg_id();
546 MothOriVert = theMoth->production_vertex();
547 if (MotherPDG == partPDG) break;
548 }
549 itr++;
550 if (itr > 100) {
551 break;
552 }
554 MothOriVert != partOriVert);
555 return theMoth;
556 }
557
559
560 template <
class C,
class T>
T findMatching(
C TruthContainer, T p) {
562 if (!p) return ptrPart;
564 for (T truthParticle : *TruthContainer) {
566 ptrPart = truthParticle;
567 break;
568 }
569 }
570 }
571 else {
572 for (T truthParticle : TruthContainer) {
574 ptrPart = truthParticle;
575 break;
576 }
577 }
578 }
579 return ptrPart;
580 }
582
584 auto prodVtx = thePart->production_vertex();
585 if (!prodVtx) return;
586 for (const auto& theMother: prodVtx->particles_in()) {
587 if (!theMother) continue;
588 allancestors.insert(theMother);
590 }
591 }
592
594
596 auto endVtx = thePart->end_vertex();
597 if (!endVtx) return;
598 for (const auto& theDaughter: endVtx->particles_out()) {
599 if (!theDaughter) continue;
601 allstabledescendants.insert(theDaughter);
602 }
604 }
605 }
606
610
612 if (pVert == nullptr) return false;
614 int numOfPartIn(0);
615 int pdg(0);
616
617 do {
618 pVert = pV;
619 auto incoming = pVert->particles_in();
620 numOfPartIn = incoming.size();
621 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
622 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
623
624 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
625
626 if (numOfPartIn == 2) {
627 auto incoming = pVert->particles_in();
628 if (incoming.at(0) && incoming.at(1) && (std::abs(incoming.at(0)->pdg_id()) < 7 || incoming.at(0)->pdg_id() == 21) && (std::abs(incoming.at(1)->pdg_id()) < 7 || incoming.at(1)->pdg_id() == 21)) return true;
629 }
630 return false;
631}
632
636
637 template <
class T,
class U>
bool isFromHadron(T p, U hadron,
bool &fromTau,
bool &fromBSM) {
639 auto vtx =
p->production_vertex();
640 if (!vtx) return false;
641 bool fromHad = false;
642 for ( const auto& parent : vtx->particles_in() ) {
643 if (!parent) continue;
644
645
646 fromBSM |=
isBSM(parent);
648 fromTau |=
isTau(parent);
651 return true;
652 }
653 fromHad |=
isFromHadron(parent, hadron, fromTau, fromBSM);
654 }
655 return fromHad;
656 }
657
660
662 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
663 decltype(thePart->end_vertex()) pVert(nullptr);
664 if (EndVert != nullptr) {
665 do {
666 bool samePart = false;
667 pVert = nullptr;
668 auto outgoing = EndVert->particles_out();
669 auto incoming = EndVert->particles_in();
670 for (const auto& itrDaug: outgoing) {
671 if (!itrDaug) continue;
673
674 (outgoing.size() == 1 && incoming.size() == 1 &&
676 itrDaug->pdg_id() == thePart->pdg_id()) {
677 samePart = true;
678 pVert = itrDaug->end_vertex();
679 }
680 }
681 if (samePart) EndVert = pVert;
682 } while (pVert != nullptr && pVert != EndVert);
683 }
684 return EndVert;
685 }
686
688
690 if (!theVert) return {};
691 decltype(theVert->particles_out()) finalStatePart;
692 auto outgoing = theVert->particles_out();
693 for (const auto& thePart: outgoing) {
694 if (!thePart) continue;
695 finalStatePart.push_back(thePart);
698 if (pVert == theVert) break;
699 if (pVert != nullptr) {
701 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
702 }
703 }
704 return finalStatePart;
705 }
706#if !defined(XAOD_ANALYSIS)
708inline void GeVToMeV(
HepMC::GenEvent* evt) {
for (
auto& p:
evt->particles()) {
p->set_momentum(
p->momentum()*1000);
p->set_generated_mass(1000*
p->generated_mass());}}
709inline void MeVToGeV(
HepMC::GenEvent* evt) {
for (
auto& p:
evt->particles()) {
p->set_momentum(
p->momentum()*1.0/1000);
p->set_generated_mass(1.0/1000*
p->generated_mass());} }
710
711#endif
712}
713#endif
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_simulation_vertex(const T &v)
Method to establish if the vertex was created during simulation (TODO migrate to be based on status).
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...
constexpr bool is_smart_ptr_v
bool is_sim_descendant(const T1 &p1, const T2 &p2)
Method to check if the first particle is a descendant of the second in the simulation,...
HepMC3::GenEvent GenEvent
T findMatching(C TruthContainer, T p)
Function to find a particle in container.
static const int GRAVITON
bool isZeroEnergyPhoton(const T &p)
Identify a photon with zero energy. Probably a workaround for a generator bug.
bool isHardScatteringVertex(T pVert)
Function to classify the vertex as hard scattering vertex.
void MeVToGeV(HepMC::GenEvent *evt)
bool isStableOrSimDecayed(const T &p)
Identify if particle is satble or decayed in simulation.
bool isPhoton(const T &p)
bool isSpecialNonInteracting(const T &p)
Identify a special non-interacting particles.
bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM)
Function to classify the particle.
bool isStable(const T &p)
Identify if the particle is stable, i.e. has not decayed.
bool isSimInteracting(const T &p)
Identify if the particle could interact with the detector during the simulation, e....
void GeVToMeV(HepMC::GenEvent *evt)
void findParticleAncestors(T thePart, std::set< T > &allancestors)
Function to find all ancestors of the particle.
bool isInteracting(const T &p)
Identify if the particle with given PDG ID would not interact with the detector, i....
auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out())
Function to find the stable particle descendants of the given vertex..
bool isDecayed(const T &p)
Identify if the particle decayed.
T findMother(T thePart)
Function to get a mother of particle. MCTruthClassifier legacy.
void findParticleStableDescendants(T thePart, std::set< T > &allstabledescendants)
Function to get the particle stable MC daughters.
bool isGenStable(const T &p)
Determine if the particle is stable at the generator (not det-sim) level,.
bool isHadron(const T &p)
bool isSimStable(const T &p)
Identify if the particle is considered stable at the post-detector-sim stage.
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.
Author: James Monk (jmonk@cern.ch).