719{
720inline
722 return std::ranges::subrange (p->particles_in_const_begin(),
723 p->particles_in_const_end());
724}
725}
726#endif
727
729{
730 template <class VTX>
731 auto particles_in (
const VTX* p) {
return p->particles_in(); }
732 template <class VTX>
733 auto particles_in (
const std::shared_ptr<VTX>& p) {
return p->particles_in(); }
734
736 {
738 template <
class T>
inline bool isConditionA(
const T& p) {
return p->status() == 62 ||
p->status() == 52 ||
p->status() == 21 ||
p->status() == 22;}
739
740 template <
class T>
inline bool isConditionB(
const T& p) {
return p->status() == 23;}
741
742 template <
class T>
inline bool isConditionC(
const T& p) {
return p->status() > 30 &&
p->status() < 40;}
743 }
744
746
749
752
755
758
761
764
767
770
773
776
781 const auto vertex =
p->end_vertex();
783 }
784
787
790 const int apid = std::abs(
p->pdg_id());
792 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true;
793 if (apid ==
GRAVITON || apid == 1000039 || apid == 5000039)
return true;
794 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true;
795 return false;
796 }
797
799
801 auto partOriVert = thePart->production_vertex();
802 if (!partOriVert) return nullptr;
803
804 long partPDG = thePart->pdg_id();
805 long MotherPDG(0);
806
807 auto MothOriVert = partOriVert;
808 MothOriVert = nullptr;
810
811 size_t itr = 0;
812 do {
813 if (itr != 0) partOriVert = MothOriVert;
816 if (!theMoth) continue;
817 MotherPDG = theMoth->pdg_id();
818 MothOriVert = theMoth->production_vertex();
819 if (MotherPDG == partPDG) break;
820 }
821 itr++;
822 if (itr > 100) {
823 break;
824 }
826 MothOriVert != partOriVert);
827 return theMoth;
828 }
829
831
832 template <
class C,
class T>
T findMatching(
C TruthContainer, T p) {
834 if (!p) return ptrPart;
836 for (T truthParticle : *TruthContainer) {
838 ptrPart = truthParticle;
839 break;
840 }
841 }
842 }
843 else {
844 for (T truthParticle : TruthContainer) {
846 ptrPart = truthParticle;
847 break;
848 }
849 }
850 }
851 return ptrPart;
852 }
854
856 auto prodVtx = thePart->production_vertex();
857 if (!prodVtx) return;
858 for (const auto& theMother: prodVtx->particles_in()) {
859 if (!theMother) continue;
860 allancestors.insert(theMother);
862 }
863 }
864
866
868 auto endVtx = thePart->end_vertex();
869 if (!endVtx) return;
870 for (const auto& theDaughter: endVtx->particles_out()) {
871 if (!theDaughter) continue;
873 allstabledescendants.insert(theDaughter);
874 }
876 }
877 }
878
882
884 if (pVert == nullptr) return false;
886 int numOfPartIn(0);
887 int pdg(0);
888
889 do {
890 pVert = pV;
891 auto incoming = pVert->particles_in();
892 numOfPartIn = incoming.size();
893 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
894 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
895
896 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
897
898 if (numOfPartIn == 2) {
899 auto incoming = pVert->particles_in();
900 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;
901 }
902 return false;
903}
904
908
909 template <class T, class U>
910 bool isFromHadron(T p, U hadron,
bool &fromTau,
bool &fromBSM) {
912 auto vtx =
p->production_vertex();
913 if (!vtx) return false;
914 bool fromHad = false;
916 if (!parent) continue;
917
918
919 fromBSM |=
isBSM(parent);
921 fromTau |=
isTau(parent);
924 return true;
925 }
926 fromHad |=
isFromHadron(parent, hadron, fromTau, fromBSM);
927 }
928 return fromHad;
929 }
930
933
935 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
936 decltype(thePart->end_vertex()) pVert(nullptr);
937 if (EndVert != nullptr) {
938 do {
939 bool samePart = false;
940 pVert = nullptr;
941 auto outgoing = EndVert->particles_out();
942 auto incoming = EndVert->particles_in();
943 for (const auto& itrDaug: outgoing) {
944 if (!itrDaug) continue;
946
947 (outgoing.size() == 1 && incoming.size() == 1 &&
949 itrDaug->pdg_id() == thePart->pdg_id()) {
950 samePart = true;
951 pVert = itrDaug->end_vertex();
952 }
953 }
954 if (samePart) EndVert = pVert;
955 } while (pVert != nullptr && pVert != EndVert);
956 }
957 return EndVert;
958 }
959
961
963 if (!theVert) return {};
964 decltype(theVert->particles_out()) finalStatePart;
965 auto outgoing = theVert->particles_out();
966 for (const auto& thePart: outgoing) {
967 if (!thePart) continue;
968 finalStatePart.push_back(thePart);
971 if (pVert == theVert) break;
972 if (pVert != nullptr) {
974 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
975 }
976 }
977 return finalStatePart;
978 }
979#if !defined(XAOD_ANALYSIS)
981#ifdef HEPMC3
982inline void GeVToMeV(HepMC::GenEvent* evt) {
for (
auto& p:
evt->particles()) {
p->set_momentum(
p->momentum()*1000);
p->set_generated_mass(1000*
p->generated_mass());}}
983inline 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());} }
984#else
985inline void GeVToMeV(HepMC::GenEvent* evt) {
986 for (HepMC::GenEvent::particle_iterator p =
evt->particles_begin(); p !=
evt->particles_end(); ++p) {
987 const HepMC::FourVector fv((*p)->momentum().px() * 1000,
988 (*p)->momentum().py() * 1000,
989 (*p)->momentum().pz() * 1000,
990 (*p)->momentum().e() * 1000);
991 (*p)->set_momentum(fv);
992 (*p)->set_generated_mass(1000 * (*p)->generated_mass());
993 }
994}
995inline void MeVToGeV(HepMC::GenEvent* evt) {
996 for (HepMC::GenEvent::particle_iterator p =
evt->particles_begin(); p !=
evt->particles_end(); ++p) {
997 const HepMC::FourVector fv((*p)->momentum().px() / 1000,
998 (*p)->momentum().py() / 1000,
999 (*p)->momentum().pz() / 1000,
1000 (*p)->momentum().e() / 1000);
1001 (*p)->set_momentum(fv);
1002 (*p)->set_generated_mass((*p)->generated_mass() / 1000);
1003 }
1004}
1005#endif
1006#endif
1007}
1008#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).
constexpr int SIM_STATUS_THRESHOLD
Constant definiting the status threshold for simulated particles, eg. can be used to separate generat...
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,...
bool isConditionB(const T &p)
bool isConditionA(const T &p)
To be understood.
bool isConditionC(const T &p)
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 isGeantino(const T &p)
bool isSimInteracting(const T &p)
Identify if the particle could interact with the detector during the simulation, e....
void GeVToMeV(HepMC::GenEvent *evt)
bool isEMInteracting(const T &p)
void findParticleAncestors(T thePart, std::set< T > &allancestors)
Function to find all ancestors of the particle.
bool isStrongInteracting(const T &p)
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 isChargedNonShowering(const T &p)
Identify if the particle with given PDG ID would produce ID tracks but not shower in the detector if ...
bool isDecayed(const T &p)
Identify if the particle decayed.
T findMother(T thePart)
Function to get a mother of particle. MCTruthClassifier legacy.
auto particles_in(const HepMC::GenVertex *p)
void findParticleStableDescendants(T thePart, std::set< T > &allstabledescendants)
Function to get the particle stable MC daughters.
bool isBeam(const T &p)
Identify if the particle is beam particle.
bool isFinalState(const T &p)
Identify if the particle is final state particle.
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.