ATLAS Offline Software
Loading...
Searching...
No Matches
MC::HepMC Namespace Reference

Classes

class  Polarization
class  ShortEventAttribute
class  GenEventBarcodes
class  ShadowParticle
 Attribute for linking GenParticles between GenEvents. More...

Typedefs

typedef HepMC3::GenVertexPtr GenVertexPtr
typedef HepMC3::ConstGenVertexPtr ConstGenVertexPtr
typedef std::shared_ptr< HepMC3::VectorIntAttribute > Flow
typedef HepMC3::GenParticlePtr GenParticlePtr
typedef HepMC3::ConstGenParticlePtr ConstGenParticlePtr
typedef HepMC3::FourVector FourVector
using Print = HepMC3::Print
using GenHeavyIon = HepMC3::GenHeavyIon
using GenEvent = HepMC3::GenEvent

Functions

template<class T>
int barcode (const T *p)
int barcode (int p)
template<class T, std::enable_if_t< !std::is_pointer< T >::value &&!std::is_same< T, HepMC3::GenParticlePtr >::value &&!std::is_same< T, HepMC3::ConstGenParticlePtr >::value &&!std::is_same< T, HepMC3::GenVertexPtr >::value &&!std::is_same< T, HepMC3::ConstGenVertexPtr >::value &&!std::is_same< T, HepMC3::GenVertex >::value &&!std::is_same< T, HepMC3::GenParticle >::value &&!std::is_same< T, int >::value, bool > = true>
int barcode (const T &p)
template<class T, std::enable_if_t< std::is_same< T, HepMC3::GenParticlePtr >::value||std::is_same< T, HepMC3::ConstGenParticlePtr >::value||std::is_same< T, HepMC3::GenVertexPtr >::value||std::is_same< T, HepMC3::ConstGenVertexPtr >::value, bool > = true>
int barcode (const T &p)
template<class T, std::enable_if_t< std::is_same< T, HepMC3::GenParticle >::value||std::is_same< T, HepMC3::GenVertex >::value, bool > = true>
int barcode (const T &p)
GenVertexPtr newGenVertexPtr (const HepMC3::FourVector &pos=HepMC3::FourVector::ZERO_VECTOR(), const int i=0)
template<class T, std::enable_if_t< std::is_same< T, HepMC3::GenParticlePtr >::value||std::is_same< T, HepMC3::ConstGenParticlePtr >::value, bool > = true>
Polarization polarization (const T &a)
template<class T>
void set_polarization (T &a, const Polarization &b)
template<class T, std::enable_if_t< std::is_same< T, HepMC3::GenParticlePtr >::value||std::is_same< T, HepMC3::ConstGenParticlePtr >::value, bool > = true>
int flow (const T &p, int i)
template<class T, std::enable_if_t< std::is_same< T, HepMC3::GenParticlePtr >::value||std::is_same< T, HepMC3::ConstGenParticlePtr >::value, bool > = true>
Flow flow (const T &p)
template<class T>
void set_flow (T &a, Flow fl)
GenParticlePtr newGenParticlePtr (const HepMC3::FourVector &mom=HepMC3::FourVector::ZERO_VECTOR(), int pid=0, int status=0)
ConstGenParticlePtr newConstGenParticlePtr (const HepMC3::FourVector &mom=HepMC3::FourVector::ZERO_VECTOR(), int pid=0, int status=0)
bool set_ll_event_number (HepMC3::GenEvent *e, long long int num)
long long int get_ll_event_number (const HepMC3::GenEvent *e)
std::map< std::string, std::size_t > weights_map (const HepMC3::GenEvent *e)
std::vector< HepMC3::GenParticlePtr >::const_iterator begin (HepMC3::GenEvent &e)
std::vector< HepMC3::GenParticlePtr >::const_iterator end (HepMC3::GenEvent &e)
std::vector< HepMC3::ConstGenParticlePtr >::const_iterator begin (const HepMC3::GenEvent &e)
std::vector< HepMC3::ConstGenParticlePtr >::const_iterator end (const HepMC3::GenEvent &e)
GenEventnewGenEvent (const int signal_process_id, const int event_number)
GenEventcopyemptyGenEvent (const GenEvent *inEvt)
void fillBarcodesAttribute (GenEvent *e)
ConstGenVertexPtr barcode_to_vertex (const GenEvent *e, int id)
ConstGenParticlePtr barcode_to_particle (const GenEvent *e, int id)
GenVertexPtr barcode_to_vertex (GenEvent *e, int id)
GenParticlePtr barcode_to_particle (GenEvent *e, int id)
int mpi (const GenEvent &evt)
int mpi (const GenEvent *evt)
int signal_process_id (const GenEvent &evt)
int signal_process_id (const GenEvent *evt)
void set_signal_process_id (GenEvent *e, const int i=0)
void set_mpi (GenEvent *e, const int i=0)
void set_random_states (GenEvent *e, std::vector< long int > &a)
template<class T>
void set_signal_process_vertex (GenEvent *e, T &v)
ConstGenVertexPtr signal_process_vertex (const GenEvent *e)
GenVertexPtr signal_process_vertex (GenEvent *e)
bool valid_beam_particles (const GenEvent *e)
template<class T>
bool suggest_barcode (T &p, int i)

Typedef Documentation

◆ ConstGenParticlePtr

typedef HepMC3::ConstGenParticlePtr MC::HepMC::ConstGenParticlePtr

Definition at line 20 of file HepMCHelpers.h.

◆ ConstGenVertexPtr

typedef HepMC3::ConstGenVertexPtr MC::HepMC::ConstGenVertexPtr

Definition at line 24 of file HepMCHelpers.h.

◆ Flow

typedef std::shared_ptr<HepMC3::VectorIntAttribute> MC::HepMC::Flow

Definition at line 13 of file HepMCHelpers.h.

◆ FourVector

typedef HepMC3::FourVector MC::HepMC::FourVector

Definition at line 12 of file HepMCHelpers.h.

◆ GenEvent

using MC::HepMC::GenEvent = HepMC3::GenEvent

Definition at line 39 of file HepMCHelpers.h.

◆ GenHeavyIon

using MC::HepMC::GenHeavyIon = HepMC3::GenHeavyIon

Definition at line 38 of file HepMCHelpers.h.

◆ GenParticlePtr

typedef HepMC3::GenParticlePtr MC::HepMC::GenParticlePtr

Definition at line 19 of file HepMCHelpers.h.

◆ GenVertexPtr

typedef HepMC3::GenVertexPtr MC::HepMC::GenVertexPtr

Definition at line 23 of file HepMCHelpers.h.

◆ Print

using MC::HepMC::Print = HepMC3::Print

Definition at line 37 of file HepMCHelpers.h.

Function Documentation

◆ barcode() [1/5]

template<class T, std::enable_if_t< std::is_same< T, HepMC3::GenParticle >::value||std::is_same< T, HepMC3::GenVertex >::value, bool > = true>
int MC::HepMC::barcode ( const T & p)
inline

Definition at line 46 of file HepMCHelpers.h.

47
49 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
50
constexpr int SIM_STATUS_THRESHOLD
Constant definiting the status threshold for simulated particles, eg. can be used to separate generat...
int status(const T &p)
bool isFinalState(const T &p)
Identify if the particle is final state particle.

◆ barcode() [2/5]

template<class T, std::enable_if_t< std::is_same< T, HepMC3::GenParticlePtr >::value||std::is_same< T, HepMC3::ConstGenParticlePtr >::value||std::is_same< T, HepMC3::GenVertexPtr >::value||std::is_same< T, HepMC3::ConstGenVertexPtr >::value, bool > = true>
int MC::HepMC::barcode ( const T & p)
inline

Definition at line 34 of file HepMCHelpers.h.

35
37 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
38
40 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
bool isGeantino(const T &p)
bool isEMInteracting(const T &p)
bool isStrongInteracting(const T &p)
bool isMuon(const T &p)
bool isSUSY(const T &p)
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 isBeam(const T &p)
Identify if the particle is beam particle.

◆ barcode() [3/5]

template<class T, std::enable_if_t< !std::is_pointer< T >::value &&!std::is_same< T, HepMC3::GenParticlePtr >::value &&!std::is_same< T, HepMC3::ConstGenParticlePtr >::value &&!std::is_same< T, HepMC3::GenVertexPtr >::value &&!std::is_same< T, HepMC3::ConstGenVertexPtr >::value &&!std::is_same< T, HepMC3::GenVertex >::value &&!std::is_same< T, HepMC3::GenParticle >::value &&!std::is_same< T, int >::value, bool > = true>
int MC::HepMC::barcode ( const T & p)
inline

Definition at line 26 of file HepMCHelpers.h.

26{ return p->status() == 23;}

◆ barcode() [4/5]

template<class T>
int MC::HepMC::barcode ( const T * p)
inline

Definition at line 15 of file HepMCHelpers.h.

◆ barcode() [5/5]

int MC::HepMC::barcode ( int p)
inline

Definition at line 16 of file HepMCHelpers.h.

◆ barcode_to_particle() [1/2]

ConstGenParticlePtr MC::HepMC::barcode_to_particle ( const GenEvent * e,
int id )
inline

Definition at line 443 of file HepMCHelpers.h.

462{
463 namespace Pythia8
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
473#include "AtlasPID.h"
474
476 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
477
479 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
480
482 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
483
485 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
486
488 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
489
491 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
492
494 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
495
497 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
498
500 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
501
503 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
504
508 template <class T> inline bool isStableOrSimDecayed(const T& p) {
509 const auto vertex = p->end_vertex();
510 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
511 }
512
514 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
515
517 template <class T> inline bool isSpecialNonInteracting(const T& p) {
518 const int apid = std::abs(p->pdg_id());
519 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
520 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
521 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
522 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
523 return false;
524 }
525
527
528 template <class T> T findMother(T thePart) {
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;
537 T theMoth(nullptr);
538
539 size_t itr = 0;
540 do {
541 if (itr != 0) partOriVert = MothOriVert;
542 for ( const auto& p : partOriVert->particles_in() ) {
543 theMoth = p;
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 }
553 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
554 MothOriVert != partOriVert);
555 return theMoth;
556 }
557
559
560 template <class C, class T> T findMatching(C TruthContainer, T p) {
561 T ptrPart = nullptr;
562 if (!p) return ptrPart;
563 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
564 for (T truthParticle : *TruthContainer) {
565 if (HepMC::is_sim_descendant(p,truthParticle)) {
566 ptrPart = truthParticle;
567 break;
568 }
569 }
570 }
571 else {
572 for (T truthParticle : TruthContainer) {
573 if (HepMC::is_sim_descendant(p,truthParticle)) {
574 ptrPart = truthParticle;
575 break;
576 }
577 }
578 }
579 return ptrPart;
580 }
582
583 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
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);
589 findParticleAncestors(theMother, allancestors);
590 }
591 }
592
594
595 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
596 auto endVtx = thePart->end_vertex();
597 if (!endVtx) return;
598 for (const auto& theDaughter: endVtx->particles_out()) {
599 if (!theDaughter) continue;
600 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
601 allstabledescendants.insert(theDaughter);
602 }
603 findParticleStableDescendants(theDaughter, allstabledescendants);
604 }
605 }
606
610
611 template <class T> bool isHardScatteringVertex(T pVert) {
612 if (pVert == nullptr) return false;
613 T pV = pVert;
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) {
638 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
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 // should this really go into parton-level territory?
645 // probably depends where BSM particles are being decayed
646 fromBSM |= isBSM(parent);
647 if (!isPhysical(parent)) return false;
648 fromTau |= isTau(parent);
649 if (isHadron(parent)&&!isBeam(parent)) {
650 if (!hadron) hadron = parent; // assumes linear hadron parentage
651 return true;
652 }
653 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
654 }
655 return fromHad;
656 }
657
660
661 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
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;
672 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
673 // brem on generator level for tau
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); // pVert!=EndVert to prevent Sherpa loop
683 }
684 return EndVert;
685 }
686
688
689 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
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);
696 if (isStable(thePart)) continue;
697 V pVert = findSimulatedEndVertex(thePart);
698 if (pVert == theVert) break; // to prevent Sherpa loop
699 if (pVert != nullptr) {
700 auto vecPart = findFinalStateParticles<V>(pVert);
701 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
702 }
703 }
704 return finalStatePart;
705 }
706#if !defined(XAOD_ANALYSIS)
707#include "AtlasHepMC/GenEvent.h"
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
struct color C
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..
static const int NU_MU
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.
static const int NU_E
static const int NU_TAU
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 isTau(const T &p)
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).
unsigned long long T

◆ barcode_to_particle() [2/2]

GenParticlePtr MC::HepMC::barcode_to_particle ( GenEvent * e,
int id )
inline

Definition at line 523 of file HepMCHelpers.h.

542{
543 namespace Pythia8
544 {
546 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
547
548 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
549
550 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
551 }
552
553#include "AtlasPID.h"
554
556 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
557
559 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
560
562 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
563
565 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
566
568 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
569
571 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
572
574 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
575
577 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
578
580 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
581
583 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
584
588 template <class T> inline bool isStableOrSimDecayed(const T& p) {
589 const auto vertex = p->end_vertex();
590 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
591 }
592
594 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
595
597 template <class T> inline bool isSpecialNonInteracting(const T& p) {
598 const int apid = std::abs(p->pdg_id());
599 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
600 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
601 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
602 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
603 return false;
604 }
605
607
608 template <class T> T findMother(T thePart) {
609 auto partOriVert = thePart->production_vertex();
610 if (!partOriVert) return nullptr;
611
612 long partPDG = thePart->pdg_id();
613 long MotherPDG(0);
614
615 auto MothOriVert = partOriVert;
616 MothOriVert = nullptr;
617 T theMoth(nullptr);
618
619 size_t itr = 0;
620 do {
621 if (itr != 0) partOriVert = MothOriVert;
622 for ( const auto& p : partOriVert->particles_in() ) {
623 theMoth = p;
624 if (!theMoth) continue;
625 MotherPDG = theMoth->pdg_id();
626 MothOriVert = theMoth->production_vertex();
627 if (MotherPDG == partPDG) break;
628 }
629 itr++;
630 if (itr > 100) {
631 break;
632 }
633 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
634 MothOriVert != partOriVert);
635 return theMoth;
636 }
637
639
640 template <class C, class T> T findMatching(C TruthContainer, T p) {
641 T ptrPart = nullptr;
642 if (!p) return ptrPart;
643 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
644 for (T truthParticle : *TruthContainer) {
645 if (HepMC::is_sim_descendant(p,truthParticle)) {
646 ptrPart = truthParticle;
647 break;
648 }
649 }
650 }
651 else {
652 for (T truthParticle : TruthContainer) {
653 if (HepMC::is_sim_descendant(p,truthParticle)) {
654 ptrPart = truthParticle;
655 break;
656 }
657 }
658 }
659 return ptrPart;
660 }
662
663 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
664 auto prodVtx = thePart->production_vertex();
665 if (!prodVtx) return;
666 for (const auto& theMother: prodVtx->particles_in()) {
667 if (!theMother) continue;
668 allancestors.insert(theMother);
669 findParticleAncestors(theMother, allancestors);
670 }
671 }
672
674
675 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
676 auto endVtx = thePart->end_vertex();
677 if (!endVtx) return;
678 for (const auto& theDaughter: endVtx->particles_out()) {
679 if (!theDaughter) continue;
680 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
681 allstabledescendants.insert(theDaughter);
682 }
683 findParticleStableDescendants(theDaughter, allstabledescendants);
684 }
685 }
686
690
691 template <class T> bool isHardScatteringVertex(T pVert) {
692 if (pVert == nullptr) return false;
693 T pV = pVert;
694 int numOfPartIn(0);
695 int pdg(0);
696
697 do {
698 pVert = pV;
699 auto incoming = pVert->particles_in();
700 numOfPartIn = incoming.size();
701 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
702 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
703
704 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
705
706 if (numOfPartIn == 2) {
707 auto incoming = pVert->particles_in();
708 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;
709 }
710 return false;
711}
712
716
717 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
718 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
719 auto vtx = p->production_vertex();
720 if (!vtx) return false;
721 bool fromHad = false;
722 for ( const auto& parent : vtx->particles_in() ) {
723 if (!parent) continue;
724 // should this really go into parton-level territory?
725 // probably depends where BSM particles are being decayed
726 fromBSM |= isBSM(parent);
727 if (!isPhysical(parent)) return false;
728 fromTau |= isTau(parent);
729 if (isHadron(parent)&&!isBeam(parent)) {
730 if (!hadron) hadron = parent; // assumes linear hadron parentage
731 return true;
732 }
733 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
734 }
735 return fromHad;
736 }
737
740
741 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
742 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
743 decltype(thePart->end_vertex()) pVert(nullptr);
744 if (EndVert != nullptr) {
745 do {
746 bool samePart = false;
747 pVert = nullptr;
748 auto outgoing = EndVert->particles_out();
749 auto incoming = EndVert->particles_in();
750 for (const auto& itrDaug: outgoing) {
751 if (!itrDaug) continue;
752 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
753 // brem on generator level for tau
754 (outgoing.size() == 1 && incoming.size() == 1 &&
756 itrDaug->pdg_id() == thePart->pdg_id()) {
757 samePart = true;
758 pVert = itrDaug->end_vertex();
759 }
760 }
761 if (samePart) EndVert = pVert;
762 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
763 }
764 return EndVert;
765 }
766
768
769 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
770 if (!theVert) return {};
771 decltype(theVert->particles_out()) finalStatePart;
772 auto outgoing = theVert->particles_out();
773 for (const auto& thePart: outgoing) {
774 if (!thePart) continue;
775 finalStatePart.push_back(thePart);
776 if (isStable(thePart)) continue;
777 V pVert = findSimulatedEndVertex(thePart);
778 if (pVert == theVert) break; // to prevent Sherpa loop
779 if (pVert != nullptr) {
780 auto vecPart = findFinalStateParticles<V>(pVert);
781 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
782 }
783 }
784 return finalStatePart;
785 }
786#if !defined(XAOD_ANALYSIS)
787#include "AtlasHepMC/GenEvent.h"
788inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
789inline 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());} }
790
791#endif
792}
793#endif

◆ barcode_to_vertex() [1/2]

ConstGenVertexPtr MC::HepMC::barcode_to_vertex ( const GenEvent * e,
int id )
inline

Definition at line 403 of file HepMCHelpers.h.

422{
423 namespace Pythia8
424 {
426 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
427
428 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
429
430 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
431 }
432
433#include "AtlasPID.h"
434
436 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
437
439 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
440
442 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
443
445 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
446
448 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
449
451 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
452
454 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
455
457 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
458
460 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
461
463 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
464
468 template <class T> inline bool isStableOrSimDecayed(const T& p) {
469 const auto vertex = p->end_vertex();
470 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
471 }
472
474 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
475
477 template <class T> inline bool isSpecialNonInteracting(const T& p) {
478 const int apid = std::abs(p->pdg_id());
479 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
480 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
481 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
482 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
483 return false;
484 }
485
487
488 template <class T> T findMother(T thePart) {
489 auto partOriVert = thePart->production_vertex();
490 if (!partOriVert) return nullptr;
491
492 long partPDG = thePart->pdg_id();
493 long MotherPDG(0);
494
495 auto MothOriVert = partOriVert;
496 MothOriVert = nullptr;
497 T theMoth(nullptr);
498
499 size_t itr = 0;
500 do {
501 if (itr != 0) partOriVert = MothOriVert;
502 for ( const auto& p : partOriVert->particles_in() ) {
503 theMoth = p;
504 if (!theMoth) continue;
505 MotherPDG = theMoth->pdg_id();
506 MothOriVert = theMoth->production_vertex();
507 if (MotherPDG == partPDG) break;
508 }
509 itr++;
510 if (itr > 100) {
511 break;
512 }
513 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
514 MothOriVert != partOriVert);
515 return theMoth;
516 }
517
519
520 template <class C, class T> T findMatching(C TruthContainer, T p) {
521 T ptrPart = nullptr;
522 if (!p) return ptrPart;
523 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
524 for (T truthParticle : *TruthContainer) {
525 if (HepMC::is_sim_descendant(p,truthParticle)) {
526 ptrPart = truthParticle;
527 break;
528 }
529 }
530 }
531 else {
532 for (T truthParticle : TruthContainer) {
533 if (HepMC::is_sim_descendant(p,truthParticle)) {
534 ptrPart = truthParticle;
535 break;
536 }
537 }
538 }
539 return ptrPart;
540 }
542
543 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
544 auto prodVtx = thePart->production_vertex();
545 if (!prodVtx) return;
546 for (const auto& theMother: prodVtx->particles_in()) {
547 if (!theMother) continue;
548 allancestors.insert(theMother);
549 findParticleAncestors(theMother, allancestors);
550 }
551 }
552
554
555 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
556 auto endVtx = thePart->end_vertex();
557 if (!endVtx) return;
558 for (const auto& theDaughter: endVtx->particles_out()) {
559 if (!theDaughter) continue;
560 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
561 allstabledescendants.insert(theDaughter);
562 }
563 findParticleStableDescendants(theDaughter, allstabledescendants);
564 }
565 }
566
570
571 template <class T> bool isHardScatteringVertex(T pVert) {
572 if (pVert == nullptr) return false;
573 T pV = pVert;
574 int numOfPartIn(0);
575 int pdg(0);
576
577 do {
578 pVert = pV;
579 auto incoming = pVert->particles_in();
580 numOfPartIn = incoming.size();
581 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
582 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
583
584 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
585
586 if (numOfPartIn == 2) {
587 auto incoming = pVert->particles_in();
588 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;
589 }
590 return false;
591}
592
596
597 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
598 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
599 auto vtx = p->production_vertex();
600 if (!vtx) return false;
601 bool fromHad = false;
602 for ( const auto& parent : vtx->particles_in() ) {
603 if (!parent) continue;
604 // should this really go into parton-level territory?
605 // probably depends where BSM particles are being decayed
606 fromBSM |= isBSM(parent);
607 if (!isPhysical(parent)) return false;
608 fromTau |= isTau(parent);
609 if (isHadron(parent)&&!isBeam(parent)) {
610 if (!hadron) hadron = parent; // assumes linear hadron parentage
611 return true;
612 }
613 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
614 }
615 return fromHad;
616 }
617
620
621 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
622 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
623 decltype(thePart->end_vertex()) pVert(nullptr);
624 if (EndVert != nullptr) {
625 do {
626 bool samePart = false;
627 pVert = nullptr;
628 auto outgoing = EndVert->particles_out();
629 auto incoming = EndVert->particles_in();
630 for (const auto& itrDaug: outgoing) {
631 if (!itrDaug) continue;
632 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
633 // brem on generator level for tau
634 (outgoing.size() == 1 && incoming.size() == 1 &&
636 itrDaug->pdg_id() == thePart->pdg_id()) {
637 samePart = true;
638 pVert = itrDaug->end_vertex();
639 }
640 }
641 if (samePart) EndVert = pVert;
642 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
643 }
644 return EndVert;
645 }
646
648
649 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
650 if (!theVert) return {};
651 decltype(theVert->particles_out()) finalStatePart;
652 auto outgoing = theVert->particles_out();
653 for (const auto& thePart: outgoing) {
654 if (!thePart) continue;
655 finalStatePart.push_back(thePart);
656 if (isStable(thePart)) continue;
657 V pVert = findSimulatedEndVertex(thePart);
658 if (pVert == theVert) break; // to prevent Sherpa loop
659 if (pVert != nullptr) {
660 auto vecPart = findFinalStateParticles<V>(pVert);
661 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
662 }
663 }
664 return finalStatePart;
665 }
666#if !defined(XAOD_ANALYSIS)
667#include "AtlasHepMC/GenEvent.h"
668inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
669inline 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());} }
670
671#endif
672}
673#endif

◆ barcode_to_vertex() [2/2]

GenVertexPtr MC::HepMC::barcode_to_vertex ( GenEvent * e,
int id )
inline

Definition at line 483 of file HepMCHelpers.h.

502{
503 namespace Pythia8
504 {
506 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
507
508 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
509
510 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
511 }
512
513#include "AtlasPID.h"
514
516 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
517
519 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
520
522 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
523
525 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
526
528 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
529
531 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
532
534 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
535
537 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
538
540 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
541
543 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
544
548 template <class T> inline bool isStableOrSimDecayed(const T& p) {
549 const auto vertex = p->end_vertex();
550 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
551 }
552
554 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
555
557 template <class T> inline bool isSpecialNonInteracting(const T& p) {
558 const int apid = std::abs(p->pdg_id());
559 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
560 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
561 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
562 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
563 return false;
564 }
565
567
568 template <class T> T findMother(T thePart) {
569 auto partOriVert = thePart->production_vertex();
570 if (!partOriVert) return nullptr;
571
572 long partPDG = thePart->pdg_id();
573 long MotherPDG(0);
574
575 auto MothOriVert = partOriVert;
576 MothOriVert = nullptr;
577 T theMoth(nullptr);
578
579 size_t itr = 0;
580 do {
581 if (itr != 0) partOriVert = MothOriVert;
582 for ( const auto& p : partOriVert->particles_in() ) {
583 theMoth = p;
584 if (!theMoth) continue;
585 MotherPDG = theMoth->pdg_id();
586 MothOriVert = theMoth->production_vertex();
587 if (MotherPDG == partPDG) break;
588 }
589 itr++;
590 if (itr > 100) {
591 break;
592 }
593 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
594 MothOriVert != partOriVert);
595 return theMoth;
596 }
597
599
600 template <class C, class T> T findMatching(C TruthContainer, T p) {
601 T ptrPart = nullptr;
602 if (!p) return ptrPart;
603 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
604 for (T truthParticle : *TruthContainer) {
605 if (HepMC::is_sim_descendant(p,truthParticle)) {
606 ptrPart = truthParticle;
607 break;
608 }
609 }
610 }
611 else {
612 for (T truthParticle : TruthContainer) {
613 if (HepMC::is_sim_descendant(p,truthParticle)) {
614 ptrPart = truthParticle;
615 break;
616 }
617 }
618 }
619 return ptrPart;
620 }
622
623 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
624 auto prodVtx = thePart->production_vertex();
625 if (!prodVtx) return;
626 for (const auto& theMother: prodVtx->particles_in()) {
627 if (!theMother) continue;
628 allancestors.insert(theMother);
629 findParticleAncestors(theMother, allancestors);
630 }
631 }
632
634
635 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
636 auto endVtx = thePart->end_vertex();
637 if (!endVtx) return;
638 for (const auto& theDaughter: endVtx->particles_out()) {
639 if (!theDaughter) continue;
640 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
641 allstabledescendants.insert(theDaughter);
642 }
643 findParticleStableDescendants(theDaughter, allstabledescendants);
644 }
645 }
646
650
651 template <class T> bool isHardScatteringVertex(T pVert) {
652 if (pVert == nullptr) return false;
653 T pV = pVert;
654 int numOfPartIn(0);
655 int pdg(0);
656
657 do {
658 pVert = pV;
659 auto incoming = pVert->particles_in();
660 numOfPartIn = incoming.size();
661 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
662 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
663
664 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
665
666 if (numOfPartIn == 2) {
667 auto incoming = pVert->particles_in();
668 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;
669 }
670 return false;
671}
672
676
677 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
678 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
679 auto vtx = p->production_vertex();
680 if (!vtx) return false;
681 bool fromHad = false;
682 for ( const auto& parent : vtx->particles_in() ) {
683 if (!parent) continue;
684 // should this really go into parton-level territory?
685 // probably depends where BSM particles are being decayed
686 fromBSM |= isBSM(parent);
687 if (!isPhysical(parent)) return false;
688 fromTau |= isTau(parent);
689 if (isHadron(parent)&&!isBeam(parent)) {
690 if (!hadron) hadron = parent; // assumes linear hadron parentage
691 return true;
692 }
693 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
694 }
695 return fromHad;
696 }
697
700
701 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
702 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
703 decltype(thePart->end_vertex()) pVert(nullptr);
704 if (EndVert != nullptr) {
705 do {
706 bool samePart = false;
707 pVert = nullptr;
708 auto outgoing = EndVert->particles_out();
709 auto incoming = EndVert->particles_in();
710 for (const auto& itrDaug: outgoing) {
711 if (!itrDaug) continue;
712 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
713 // brem on generator level for tau
714 (outgoing.size() == 1 && incoming.size() == 1 &&
716 itrDaug->pdg_id() == thePart->pdg_id()) {
717 samePart = true;
718 pVert = itrDaug->end_vertex();
719 }
720 }
721 if (samePart) EndVert = pVert;
722 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
723 }
724 return EndVert;
725 }
726
728
729 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
730 if (!theVert) return {};
731 decltype(theVert->particles_out()) finalStatePart;
732 auto outgoing = theVert->particles_out();
733 for (const auto& thePart: outgoing) {
734 if (!thePart) continue;
735 finalStatePart.push_back(thePart);
736 if (isStable(thePart)) continue;
737 V pVert = findSimulatedEndVertex(thePart);
738 if (pVert == theVert) break; // to prevent Sherpa loop
739 if (pVert != nullptr) {
740 auto vecPart = findFinalStateParticles<V>(pVert);
741 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
742 }
743 }
744 return finalStatePart;
745 }
746#if !defined(XAOD_ANALYSIS)
747#include "AtlasHepMC/GenEvent.h"
748inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
749inline 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());} }
750
751#endif
752}
753#endif

◆ begin() [1/2]

std::vector< HepMC3::ConstGenParticlePtr >::const_iterator MC::HepMC::begin ( const HepMC3::GenEvent & e)
inline

Definition at line 357 of file HepMCHelpers.h.

376{
377 namespace Pythia8
378 {
380 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
381
382 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
383
384 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
385 }
386
387#include "AtlasPID.h"
388
390 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
391
393 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
394
396 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
397
399 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
400
402 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
403
405 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
406
408 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
409
411 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
412
414 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
415
417 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
418
422 template <class T> inline bool isStableOrSimDecayed(const T& p) {
423 const auto vertex = p->end_vertex();
424 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
425 }
426
428 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
429
431 template <class T> inline bool isSpecialNonInteracting(const T& p) {
432 const int apid = std::abs(p->pdg_id());
433 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
434 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
435 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
436 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
437 return false;
438 }
439
441
442 template <class T> T findMother(T thePart) {
443 auto partOriVert = thePart->production_vertex();
444 if (!partOriVert) return nullptr;
445
446 long partPDG = thePart->pdg_id();
447 long MotherPDG(0);
448
449 auto MothOriVert = partOriVert;
450 MothOriVert = nullptr;
451 T theMoth(nullptr);
452
453 size_t itr = 0;
454 do {
455 if (itr != 0) partOriVert = MothOriVert;
456 for ( const auto& p : partOriVert->particles_in() ) {
457 theMoth = p;
458 if (!theMoth) continue;
459 MotherPDG = theMoth->pdg_id();
460 MothOriVert = theMoth->production_vertex();
461 if (MotherPDG == partPDG) break;
462 }
463 itr++;
464 if (itr > 100) {
465 break;
466 }
467 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
468 MothOriVert != partOriVert);
469 return theMoth;
470 }
471
473
474 template <class C, class T> T findMatching(C TruthContainer, T p) {
475 T ptrPart = nullptr;
476 if (!p) return ptrPart;
477 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
478 for (T truthParticle : *TruthContainer) {
479 if (HepMC::is_sim_descendant(p,truthParticle)) {
480 ptrPart = truthParticle;
481 break;
482 }
483 }
484 }
485 else {
486 for (T truthParticle : TruthContainer) {
487 if (HepMC::is_sim_descendant(p,truthParticle)) {
488 ptrPart = truthParticle;
489 break;
490 }
491 }
492 }
493 return ptrPart;
494 }
496
497 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
498 auto prodVtx = thePart->production_vertex();
499 if (!prodVtx) return;
500 for (const auto& theMother: prodVtx->particles_in()) {
501 if (!theMother) continue;
502 allancestors.insert(theMother);
503 findParticleAncestors(theMother, allancestors);
504 }
505 }
506
508
509 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
510 auto endVtx = thePart->end_vertex();
511 if (!endVtx) return;
512 for (const auto& theDaughter: endVtx->particles_out()) {
513 if (!theDaughter) continue;
514 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
515 allstabledescendants.insert(theDaughter);
516 }
517 findParticleStableDescendants(theDaughter, allstabledescendants);
518 }
519 }
520
524
525 template <class T> bool isHardScatteringVertex(T pVert) {
526 if (pVert == nullptr) return false;
527 T pV = pVert;
528 int numOfPartIn(0);
529 int pdg(0);
530
531 do {
532 pVert = pV;
533 auto incoming = pVert->particles_in();
534 numOfPartIn = incoming.size();
535 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
536 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
537
538 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
539
540 if (numOfPartIn == 2) {
541 auto incoming = pVert->particles_in();
542 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;
543 }
544 return false;
545}
546
550
551 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
552 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
553 auto vtx = p->production_vertex();
554 if (!vtx) return false;
555 bool fromHad = false;
556 for ( const auto& parent : vtx->particles_in() ) {
557 if (!parent) continue;
558 // should this really go into parton-level territory?
559 // probably depends where BSM particles are being decayed
560 fromBSM |= isBSM(parent);
561 if (!isPhysical(parent)) return false;
562 fromTau |= isTau(parent);
563 if (isHadron(parent)&&!isBeam(parent)) {
564 if (!hadron) hadron = parent; // assumes linear hadron parentage
565 return true;
566 }
567 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
568 }
569 return fromHad;
570 }
571
574
575 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
576 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
577 decltype(thePart->end_vertex()) pVert(nullptr);
578 if (EndVert != nullptr) {
579 do {
580 bool samePart = false;
581 pVert = nullptr;
582 auto outgoing = EndVert->particles_out();
583 auto incoming = EndVert->particles_in();
584 for (const auto& itrDaug: outgoing) {
585 if (!itrDaug) continue;
586 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
587 // brem on generator level for tau
588 (outgoing.size() == 1 && incoming.size() == 1 &&
590 itrDaug->pdg_id() == thePart->pdg_id()) {
591 samePart = true;
592 pVert = itrDaug->end_vertex();
593 }
594 }
595 if (samePart) EndVert = pVert;
596 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
597 }
598 return EndVert;
599 }
600
602
603 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
604 if (!theVert) return {};
605 decltype(theVert->particles_out()) finalStatePart;
606 auto outgoing = theVert->particles_out();
607 for (const auto& thePart: outgoing) {
608 if (!thePart) continue;
609 finalStatePart.push_back(thePart);
610 if (isStable(thePart)) continue;
611 V pVert = findSimulatedEndVertex(thePart);
612 if (pVert == theVert) break; // to prevent Sherpa loop
613 if (pVert != nullptr) {
614 auto vecPart = findFinalStateParticles<V>(pVert);
615 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
616 }
617 }
618 return finalStatePart;
619 }
620#if !defined(XAOD_ANALYSIS)
621#include "AtlasHepMC/GenEvent.h"
622inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
623inline 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());} }
624
625#endif
626}
627#endif

◆ begin() [2/2]

std::vector< HepMC3::GenParticlePtr >::const_iterator MC::HepMC::begin ( HepMC3::GenEvent & e)
inline

Definition at line 355 of file HepMCHelpers.h.

374{
375 namespace Pythia8
376 {
378 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
379
380 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
381
382 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
383 }
384
385#include "AtlasPID.h"
386
388 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
389
391 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
392
394 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
395
397 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
398
400 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
401
403 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
404
406 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
407
409 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
410
412 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
413
415 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
416
420 template <class T> inline bool isStableOrSimDecayed(const T& p) {
421 const auto vertex = p->end_vertex();
422 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
423 }
424
426 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
427
429 template <class T> inline bool isSpecialNonInteracting(const T& p) {
430 const int apid = std::abs(p->pdg_id());
431 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
432 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
433 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
434 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
435 return false;
436 }
437
439
440 template <class T> T findMother(T thePart) {
441 auto partOriVert = thePart->production_vertex();
442 if (!partOriVert) return nullptr;
443
444 long partPDG = thePart->pdg_id();
445 long MotherPDG(0);
446
447 auto MothOriVert = partOriVert;
448 MothOriVert = nullptr;
449 T theMoth(nullptr);
450
451 size_t itr = 0;
452 do {
453 if (itr != 0) partOriVert = MothOriVert;
454 for ( const auto& p : partOriVert->particles_in() ) {
455 theMoth = p;
456 if (!theMoth) continue;
457 MotherPDG = theMoth->pdg_id();
458 MothOriVert = theMoth->production_vertex();
459 if (MotherPDG == partPDG) break;
460 }
461 itr++;
462 if (itr > 100) {
463 break;
464 }
465 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
466 MothOriVert != partOriVert);
467 return theMoth;
468 }
469
471
472 template <class C, class T> T findMatching(C TruthContainer, T p) {
473 T ptrPart = nullptr;
474 if (!p) return ptrPart;
475 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
476 for (T truthParticle : *TruthContainer) {
477 if (HepMC::is_sim_descendant(p,truthParticle)) {
478 ptrPart = truthParticle;
479 break;
480 }
481 }
482 }
483 else {
484 for (T truthParticle : TruthContainer) {
485 if (HepMC::is_sim_descendant(p,truthParticle)) {
486 ptrPart = truthParticle;
487 break;
488 }
489 }
490 }
491 return ptrPart;
492 }
494
495 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
496 auto prodVtx = thePart->production_vertex();
497 if (!prodVtx) return;
498 for (const auto& theMother: prodVtx->particles_in()) {
499 if (!theMother) continue;
500 allancestors.insert(theMother);
501 findParticleAncestors(theMother, allancestors);
502 }
503 }
504
506
507 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
508 auto endVtx = thePart->end_vertex();
509 if (!endVtx) return;
510 for (const auto& theDaughter: endVtx->particles_out()) {
511 if (!theDaughter) continue;
512 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
513 allstabledescendants.insert(theDaughter);
514 }
515 findParticleStableDescendants(theDaughter, allstabledescendants);
516 }
517 }
518
522
523 template <class T> bool isHardScatteringVertex(T pVert) {
524 if (pVert == nullptr) return false;
525 T pV = pVert;
526 int numOfPartIn(0);
527 int pdg(0);
528
529 do {
530 pVert = pV;
531 auto incoming = pVert->particles_in();
532 numOfPartIn = incoming.size();
533 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
534 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
535
536 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
537
538 if (numOfPartIn == 2) {
539 auto incoming = pVert->particles_in();
540 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;
541 }
542 return false;
543}
544
548
549 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
550 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
551 auto vtx = p->production_vertex();
552 if (!vtx) return false;
553 bool fromHad = false;
554 for ( const auto& parent : vtx->particles_in() ) {
555 if (!parent) continue;
556 // should this really go into parton-level territory?
557 // probably depends where BSM particles are being decayed
558 fromBSM |= isBSM(parent);
559 if (!isPhysical(parent)) return false;
560 fromTau |= isTau(parent);
561 if (isHadron(parent)&&!isBeam(parent)) {
562 if (!hadron) hadron = parent; // assumes linear hadron parentage
563 return true;
564 }
565 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
566 }
567 return fromHad;
568 }
569
572
573 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
574 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
575 decltype(thePart->end_vertex()) pVert(nullptr);
576 if (EndVert != nullptr) {
577 do {
578 bool samePart = false;
579 pVert = nullptr;
580 auto outgoing = EndVert->particles_out();
581 auto incoming = EndVert->particles_in();
582 for (const auto& itrDaug: outgoing) {
583 if (!itrDaug) continue;
584 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
585 // brem on generator level for tau
586 (outgoing.size() == 1 && incoming.size() == 1 &&
588 itrDaug->pdg_id() == thePart->pdg_id()) {
589 samePart = true;
590 pVert = itrDaug->end_vertex();
591 }
592 }
593 if (samePart) EndVert = pVert;
594 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
595 }
596 return EndVert;
597 }
598
600
601 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
602 if (!theVert) return {};
603 decltype(theVert->particles_out()) finalStatePart;
604 auto outgoing = theVert->particles_out();
605 for (const auto& thePart: outgoing) {
606 if (!thePart) continue;
607 finalStatePart.push_back(thePart);
608 if (isStable(thePart)) continue;
609 V pVert = findSimulatedEndVertex(thePart);
610 if (pVert == theVert) break; // to prevent Sherpa loop
611 if (pVert != nullptr) {
612 auto vecPart = findFinalStateParticles<V>(pVert);
613 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
614 }
615 }
616 return finalStatePart;
617 }
618#if !defined(XAOD_ANALYSIS)
619#include "AtlasHepMC/GenEvent.h"
620inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
621inline 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());} }
622
623#endif
624}
625#endif

◆ copyemptyGenEvent()

GenEvent * MC::HepMC::copyemptyGenEvent ( const GenEvent * inEvt)
inline

Definition at line 369 of file HepMCHelpers.h.

388{
389 namespace Pythia8
390 {
392 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
393
394 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
395
396 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
397 }
398
399#include "AtlasPID.h"
400
402 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
403
405 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
406
408 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
409
411 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
412
414 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
415
417 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
418
420 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
421
423 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
424
426 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
427
429 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
430
434 template <class T> inline bool isStableOrSimDecayed(const T& p) {
435 const auto vertex = p->end_vertex();
436 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
437 }
438
440 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
441
443 template <class T> inline bool isSpecialNonInteracting(const T& p) {
444 const int apid = std::abs(p->pdg_id());
445 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
446 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
447 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
448 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
449 return false;
450 }
451
453
454 template <class T> T findMother(T thePart) {
455 auto partOriVert = thePart->production_vertex();
456 if (!partOriVert) return nullptr;
457
458 long partPDG = thePart->pdg_id();
459 long MotherPDG(0);
460
461 auto MothOriVert = partOriVert;
462 MothOriVert = nullptr;
463 T theMoth(nullptr);
464
465 size_t itr = 0;
466 do {
467 if (itr != 0) partOriVert = MothOriVert;
468 for ( const auto& p : partOriVert->particles_in() ) {
469 theMoth = p;
470 if (!theMoth) continue;
471 MotherPDG = theMoth->pdg_id();
472 MothOriVert = theMoth->production_vertex();
473 if (MotherPDG == partPDG) break;
474 }
475 itr++;
476 if (itr > 100) {
477 break;
478 }
479 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
480 MothOriVert != partOriVert);
481 return theMoth;
482 }
483
485
486 template <class C, class T> T findMatching(C TruthContainer, T p) {
487 T ptrPart = nullptr;
488 if (!p) return ptrPart;
489 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
490 for (T truthParticle : *TruthContainer) {
491 if (HepMC::is_sim_descendant(p,truthParticle)) {
492 ptrPart = truthParticle;
493 break;
494 }
495 }
496 }
497 else {
498 for (T truthParticle : TruthContainer) {
499 if (HepMC::is_sim_descendant(p,truthParticle)) {
500 ptrPart = truthParticle;
501 break;
502 }
503 }
504 }
505 return ptrPart;
506 }
508
509 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
510 auto prodVtx = thePart->production_vertex();
511 if (!prodVtx) return;
512 for (const auto& theMother: prodVtx->particles_in()) {
513 if (!theMother) continue;
514 allancestors.insert(theMother);
515 findParticleAncestors(theMother, allancestors);
516 }
517 }
518
520
521 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
522 auto endVtx = thePart->end_vertex();
523 if (!endVtx) return;
524 for (const auto& theDaughter: endVtx->particles_out()) {
525 if (!theDaughter) continue;
526 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
527 allstabledescendants.insert(theDaughter);
528 }
529 findParticleStableDescendants(theDaughter, allstabledescendants);
530 }
531 }
532
536
537 template <class T> bool isHardScatteringVertex(T pVert) {
538 if (pVert == nullptr) return false;
539 T pV = pVert;
540 int numOfPartIn(0);
541 int pdg(0);
542
543 do {
544 pVert = pV;
545 auto incoming = pVert->particles_in();
546 numOfPartIn = incoming.size();
547 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
548 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
549
550 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
551
552 if (numOfPartIn == 2) {
553 auto incoming = pVert->particles_in();
554 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;
555 }
556 return false;
557}
558
562
563 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
564 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
565 auto vtx = p->production_vertex();
566 if (!vtx) return false;
567 bool fromHad = false;
568 for ( const auto& parent : vtx->particles_in() ) {
569 if (!parent) continue;
570 // should this really go into parton-level territory?
571 // probably depends where BSM particles are being decayed
572 fromBSM |= isBSM(parent);
573 if (!isPhysical(parent)) return false;
574 fromTau |= isTau(parent);
575 if (isHadron(parent)&&!isBeam(parent)) {
576 if (!hadron) hadron = parent; // assumes linear hadron parentage
577 return true;
578 }
579 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
580 }
581 return fromHad;
582 }
583
586
587 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
588 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
589 decltype(thePart->end_vertex()) pVert(nullptr);
590 if (EndVert != nullptr) {
591 do {
592 bool samePart = false;
593 pVert = nullptr;
594 auto outgoing = EndVert->particles_out();
595 auto incoming = EndVert->particles_in();
596 for (const auto& itrDaug: outgoing) {
597 if (!itrDaug) continue;
598 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
599 // brem on generator level for tau
600 (outgoing.size() == 1 && incoming.size() == 1 &&
602 itrDaug->pdg_id() == thePart->pdg_id()) {
603 samePart = true;
604 pVert = itrDaug->end_vertex();
605 }
606 }
607 if (samePart) EndVert = pVert;
608 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
609 }
610 return EndVert;
611 }
612
614
615 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
616 if (!theVert) return {};
617 decltype(theVert->particles_out()) finalStatePart;
618 auto outgoing = theVert->particles_out();
619 for (const auto& thePart: outgoing) {
620 if (!thePart) continue;
621 finalStatePart.push_back(thePart);
622 if (isStable(thePart)) continue;
623 V pVert = findSimulatedEndVertex(thePart);
624 if (pVert == theVert) break; // to prevent Sherpa loop
625 if (pVert != nullptr) {
626 auto vecPart = findFinalStateParticles<V>(pVert);
627 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
628 }
629 }
630 return finalStatePart;
631 }
632#if !defined(XAOD_ANALYSIS)
633#include "AtlasHepMC/GenEvent.h"
634inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
635inline 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());} }
636
637#endif
638}
639#endif

◆ end() [1/2]

std::vector< HepMC3::ConstGenParticlePtr >::const_iterator MC::HepMC::end ( const HepMC3::GenEvent & e)
inline

Definition at line 358 of file HepMCHelpers.h.

377{
378 namespace Pythia8
379 {
381 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
382
383 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
384
385 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
386 }
387
388#include "AtlasPID.h"
389
391 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
392
394 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
395
397 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
398
400 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
401
403 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
404
406 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
407
409 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
410
412 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
413
415 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
416
418 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
419
423 template <class T> inline bool isStableOrSimDecayed(const T& p) {
424 const auto vertex = p->end_vertex();
425 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
426 }
427
429 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
430
432 template <class T> inline bool isSpecialNonInteracting(const T& p) {
433 const int apid = std::abs(p->pdg_id());
434 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
435 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
436 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
437 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
438 return false;
439 }
440
442
443 template <class T> T findMother(T thePart) {
444 auto partOriVert = thePart->production_vertex();
445 if (!partOriVert) return nullptr;
446
447 long partPDG = thePart->pdg_id();
448 long MotherPDG(0);
449
450 auto MothOriVert = partOriVert;
451 MothOriVert = nullptr;
452 T theMoth(nullptr);
453
454 size_t itr = 0;
455 do {
456 if (itr != 0) partOriVert = MothOriVert;
457 for ( const auto& p : partOriVert->particles_in() ) {
458 theMoth = p;
459 if (!theMoth) continue;
460 MotherPDG = theMoth->pdg_id();
461 MothOriVert = theMoth->production_vertex();
462 if (MotherPDG == partPDG) break;
463 }
464 itr++;
465 if (itr > 100) {
466 break;
467 }
468 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
469 MothOriVert != partOriVert);
470 return theMoth;
471 }
472
474
475 template <class C, class T> T findMatching(C TruthContainer, T p) {
476 T ptrPart = nullptr;
477 if (!p) return ptrPart;
478 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
479 for (T truthParticle : *TruthContainer) {
480 if (HepMC::is_sim_descendant(p,truthParticle)) {
481 ptrPart = truthParticle;
482 break;
483 }
484 }
485 }
486 else {
487 for (T truthParticle : TruthContainer) {
488 if (HepMC::is_sim_descendant(p,truthParticle)) {
489 ptrPart = truthParticle;
490 break;
491 }
492 }
493 }
494 return ptrPart;
495 }
497
498 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
499 auto prodVtx = thePart->production_vertex();
500 if (!prodVtx) return;
501 for (const auto& theMother: prodVtx->particles_in()) {
502 if (!theMother) continue;
503 allancestors.insert(theMother);
504 findParticleAncestors(theMother, allancestors);
505 }
506 }
507
509
510 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
511 auto endVtx = thePart->end_vertex();
512 if (!endVtx) return;
513 for (const auto& theDaughter: endVtx->particles_out()) {
514 if (!theDaughter) continue;
515 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
516 allstabledescendants.insert(theDaughter);
517 }
518 findParticleStableDescendants(theDaughter, allstabledescendants);
519 }
520 }
521
525
526 template <class T> bool isHardScatteringVertex(T pVert) {
527 if (pVert == nullptr) return false;
528 T pV = pVert;
529 int numOfPartIn(0);
530 int pdg(0);
531
532 do {
533 pVert = pV;
534 auto incoming = pVert->particles_in();
535 numOfPartIn = incoming.size();
536 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
537 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
538
539 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
540
541 if (numOfPartIn == 2) {
542 auto incoming = pVert->particles_in();
543 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;
544 }
545 return false;
546}
547
551
552 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
553 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
554 auto vtx = p->production_vertex();
555 if (!vtx) return false;
556 bool fromHad = false;
557 for ( const auto& parent : vtx->particles_in() ) {
558 if (!parent) continue;
559 // should this really go into parton-level territory?
560 // probably depends where BSM particles are being decayed
561 fromBSM |= isBSM(parent);
562 if (!isPhysical(parent)) return false;
563 fromTau |= isTau(parent);
564 if (isHadron(parent)&&!isBeam(parent)) {
565 if (!hadron) hadron = parent; // assumes linear hadron parentage
566 return true;
567 }
568 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
569 }
570 return fromHad;
571 }
572
575
576 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
577 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
578 decltype(thePart->end_vertex()) pVert(nullptr);
579 if (EndVert != nullptr) {
580 do {
581 bool samePart = false;
582 pVert = nullptr;
583 auto outgoing = EndVert->particles_out();
584 auto incoming = EndVert->particles_in();
585 for (const auto& itrDaug: outgoing) {
586 if (!itrDaug) continue;
587 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
588 // brem on generator level for tau
589 (outgoing.size() == 1 && incoming.size() == 1 &&
591 itrDaug->pdg_id() == thePart->pdg_id()) {
592 samePart = true;
593 pVert = itrDaug->end_vertex();
594 }
595 }
596 if (samePart) EndVert = pVert;
597 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
598 }
599 return EndVert;
600 }
601
603
604 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
605 if (!theVert) return {};
606 decltype(theVert->particles_out()) finalStatePart;
607 auto outgoing = theVert->particles_out();
608 for (const auto& thePart: outgoing) {
609 if (!thePart) continue;
610 finalStatePart.push_back(thePart);
611 if (isStable(thePart)) continue;
612 V pVert = findSimulatedEndVertex(thePart);
613 if (pVert == theVert) break; // to prevent Sherpa loop
614 if (pVert != nullptr) {
615 auto vecPart = findFinalStateParticles<V>(pVert);
616 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
617 }
618 }
619 return finalStatePart;
620 }
621#if !defined(XAOD_ANALYSIS)
622#include "AtlasHepMC/GenEvent.h"
623inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
624inline 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());} }
625
626#endif
627}
628#endif

◆ end() [2/2]

std::vector< HepMC3::GenParticlePtr >::const_iterator MC::HepMC::end ( HepMC3::GenEvent & e)
inline

Definition at line 356 of file HepMCHelpers.h.

375{
376 namespace Pythia8
377 {
379 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
380
381 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
382
383 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
384 }
385
386#include "AtlasPID.h"
387
389 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
390
392 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
393
395 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
396
398 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
399
401 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
402
404 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
405
407 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
408
410 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
411
413 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
414
416 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
417
421 template <class T> inline bool isStableOrSimDecayed(const T& p) {
422 const auto vertex = p->end_vertex();
423 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
424 }
425
427 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
428
430 template <class T> inline bool isSpecialNonInteracting(const T& p) {
431 const int apid = std::abs(p->pdg_id());
432 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
433 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
434 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
435 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
436 return false;
437 }
438
440
441 template <class T> T findMother(T thePart) {
442 auto partOriVert = thePart->production_vertex();
443 if (!partOriVert) return nullptr;
444
445 long partPDG = thePart->pdg_id();
446 long MotherPDG(0);
447
448 auto MothOriVert = partOriVert;
449 MothOriVert = nullptr;
450 T theMoth(nullptr);
451
452 size_t itr = 0;
453 do {
454 if (itr != 0) partOriVert = MothOriVert;
455 for ( const auto& p : partOriVert->particles_in() ) {
456 theMoth = p;
457 if (!theMoth) continue;
458 MotherPDG = theMoth->pdg_id();
459 MothOriVert = theMoth->production_vertex();
460 if (MotherPDG == partPDG) break;
461 }
462 itr++;
463 if (itr > 100) {
464 break;
465 }
466 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
467 MothOriVert != partOriVert);
468 return theMoth;
469 }
470
472
473 template <class C, class T> T findMatching(C TruthContainer, T p) {
474 T ptrPart = nullptr;
475 if (!p) return ptrPart;
476 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
477 for (T truthParticle : *TruthContainer) {
478 if (HepMC::is_sim_descendant(p,truthParticle)) {
479 ptrPart = truthParticle;
480 break;
481 }
482 }
483 }
484 else {
485 for (T truthParticle : TruthContainer) {
486 if (HepMC::is_sim_descendant(p,truthParticle)) {
487 ptrPart = truthParticle;
488 break;
489 }
490 }
491 }
492 return ptrPart;
493 }
495
496 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
497 auto prodVtx = thePart->production_vertex();
498 if (!prodVtx) return;
499 for (const auto& theMother: prodVtx->particles_in()) {
500 if (!theMother) continue;
501 allancestors.insert(theMother);
502 findParticleAncestors(theMother, allancestors);
503 }
504 }
505
507
508 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
509 auto endVtx = thePart->end_vertex();
510 if (!endVtx) return;
511 for (const auto& theDaughter: endVtx->particles_out()) {
512 if (!theDaughter) continue;
513 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
514 allstabledescendants.insert(theDaughter);
515 }
516 findParticleStableDescendants(theDaughter, allstabledescendants);
517 }
518 }
519
523
524 template <class T> bool isHardScatteringVertex(T pVert) {
525 if (pVert == nullptr) return false;
526 T pV = pVert;
527 int numOfPartIn(0);
528 int pdg(0);
529
530 do {
531 pVert = pV;
532 auto incoming = pVert->particles_in();
533 numOfPartIn = incoming.size();
534 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
535 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
536
537 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
538
539 if (numOfPartIn == 2) {
540 auto incoming = pVert->particles_in();
541 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;
542 }
543 return false;
544}
545
549
550 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
551 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
552 auto vtx = p->production_vertex();
553 if (!vtx) return false;
554 bool fromHad = false;
555 for ( const auto& parent : vtx->particles_in() ) {
556 if (!parent) continue;
557 // should this really go into parton-level territory?
558 // probably depends where BSM particles are being decayed
559 fromBSM |= isBSM(parent);
560 if (!isPhysical(parent)) return false;
561 fromTau |= isTau(parent);
562 if (isHadron(parent)&&!isBeam(parent)) {
563 if (!hadron) hadron = parent; // assumes linear hadron parentage
564 return true;
565 }
566 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
567 }
568 return fromHad;
569 }
570
573
574 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
575 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
576 decltype(thePart->end_vertex()) pVert(nullptr);
577 if (EndVert != nullptr) {
578 do {
579 bool samePart = false;
580 pVert = nullptr;
581 auto outgoing = EndVert->particles_out();
582 auto incoming = EndVert->particles_in();
583 for (const auto& itrDaug: outgoing) {
584 if (!itrDaug) continue;
585 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
586 // brem on generator level for tau
587 (outgoing.size() == 1 && incoming.size() == 1 &&
589 itrDaug->pdg_id() == thePart->pdg_id()) {
590 samePart = true;
591 pVert = itrDaug->end_vertex();
592 }
593 }
594 if (samePart) EndVert = pVert;
595 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
596 }
597 return EndVert;
598 }
599
601
602 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
603 if (!theVert) return {};
604 decltype(theVert->particles_out()) finalStatePart;
605 auto outgoing = theVert->particles_out();
606 for (const auto& thePart: outgoing) {
607 if (!thePart) continue;
608 finalStatePart.push_back(thePart);
609 if (isStable(thePart)) continue;
610 V pVert = findSimulatedEndVertex(thePart);
611 if (pVert == theVert) break; // to prevent Sherpa loop
612 if (pVert != nullptr) {
613 auto vecPart = findFinalStateParticles<V>(pVert);
614 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
615 }
616 }
617 return finalStatePart;
618 }
619#if !defined(XAOD_ANALYSIS)
620#include "AtlasHepMC/GenEvent.h"
621inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
622inline 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());} }
623
624#endif
625}
626#endif

◆ fillBarcodesAttribute()

void MC::HepMC::fillBarcodesAttribute ( GenEvent * e)
inline

Definition at line 393 of file HepMCHelpers.h.

412{
413 namespace Pythia8
414 {
416 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
417
418 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
419
420 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
421 }
422
423#include "AtlasPID.h"
424
426 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
427
429 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
430
432 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
433
435 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
436
438 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
439
441 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
442
444 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
445
447 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
448
450 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
451
453 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
454
458 template <class T> inline bool isStableOrSimDecayed(const T& p) {
459 const auto vertex = p->end_vertex();
460 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
461 }
462
464 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
465
467 template <class T> inline bool isSpecialNonInteracting(const T& p) {
468 const int apid = std::abs(p->pdg_id());
469 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
470 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
471 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
472 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
473 return false;
474 }
475
477
478 template <class T> T findMother(T thePart) {
479 auto partOriVert = thePart->production_vertex();
480 if (!partOriVert) return nullptr;
481
482 long partPDG = thePart->pdg_id();
483 long MotherPDG(0);
484
485 auto MothOriVert = partOriVert;
486 MothOriVert = nullptr;
487 T theMoth(nullptr);
488
489 size_t itr = 0;
490 do {
491 if (itr != 0) partOriVert = MothOriVert;
492 for ( const auto& p : partOriVert->particles_in() ) {
493 theMoth = p;
494 if (!theMoth) continue;
495 MotherPDG = theMoth->pdg_id();
496 MothOriVert = theMoth->production_vertex();
497 if (MotherPDG == partPDG) break;
498 }
499 itr++;
500 if (itr > 100) {
501 break;
502 }
503 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
504 MothOriVert != partOriVert);
505 return theMoth;
506 }
507
509
510 template <class C, class T> T findMatching(C TruthContainer, T p) {
511 T ptrPart = nullptr;
512 if (!p) return ptrPart;
513 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
514 for (T truthParticle : *TruthContainer) {
515 if (HepMC::is_sim_descendant(p,truthParticle)) {
516 ptrPart = truthParticle;
517 break;
518 }
519 }
520 }
521 else {
522 for (T truthParticle : TruthContainer) {
523 if (HepMC::is_sim_descendant(p,truthParticle)) {
524 ptrPart = truthParticle;
525 break;
526 }
527 }
528 }
529 return ptrPart;
530 }
532
533 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
534 auto prodVtx = thePart->production_vertex();
535 if (!prodVtx) return;
536 for (const auto& theMother: prodVtx->particles_in()) {
537 if (!theMother) continue;
538 allancestors.insert(theMother);
539 findParticleAncestors(theMother, allancestors);
540 }
541 }
542
544
545 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
546 auto endVtx = thePart->end_vertex();
547 if (!endVtx) return;
548 for (const auto& theDaughter: endVtx->particles_out()) {
549 if (!theDaughter) continue;
550 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
551 allstabledescendants.insert(theDaughter);
552 }
553 findParticleStableDescendants(theDaughter, allstabledescendants);
554 }
555 }
556
560
561 template <class T> bool isHardScatteringVertex(T pVert) {
562 if (pVert == nullptr) return false;
563 T pV = pVert;
564 int numOfPartIn(0);
565 int pdg(0);
566
567 do {
568 pVert = pV;
569 auto incoming = pVert->particles_in();
570 numOfPartIn = incoming.size();
571 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
572 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
573
574 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
575
576 if (numOfPartIn == 2) {
577 auto incoming = pVert->particles_in();
578 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;
579 }
580 return false;
581}
582
586
587 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
588 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
589 auto vtx = p->production_vertex();
590 if (!vtx) return false;
591 bool fromHad = false;
592 for ( const auto& parent : vtx->particles_in() ) {
593 if (!parent) continue;
594 // should this really go into parton-level territory?
595 // probably depends where BSM particles are being decayed
596 fromBSM |= isBSM(parent);
597 if (!isPhysical(parent)) return false;
598 fromTau |= isTau(parent);
599 if (isHadron(parent)&&!isBeam(parent)) {
600 if (!hadron) hadron = parent; // assumes linear hadron parentage
601 return true;
602 }
603 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
604 }
605 return fromHad;
606 }
607
610
611 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
612 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
613 decltype(thePart->end_vertex()) pVert(nullptr);
614 if (EndVert != nullptr) {
615 do {
616 bool samePart = false;
617 pVert = nullptr;
618 auto outgoing = EndVert->particles_out();
619 auto incoming = EndVert->particles_in();
620 for (const auto& itrDaug: outgoing) {
621 if (!itrDaug) continue;
622 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
623 // brem on generator level for tau
624 (outgoing.size() == 1 && incoming.size() == 1 &&
626 itrDaug->pdg_id() == thePart->pdg_id()) {
627 samePart = true;
628 pVert = itrDaug->end_vertex();
629 }
630 }
631 if (samePart) EndVert = pVert;
632 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
633 }
634 return EndVert;
635 }
636
638
639 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
640 if (!theVert) return {};
641 decltype(theVert->particles_out()) finalStatePart;
642 auto outgoing = theVert->particles_out();
643 for (const auto& thePart: outgoing) {
644 if (!thePart) continue;
645 finalStatePart.push_back(thePart);
646 if (isStable(thePart)) continue;
647 V pVert = findSimulatedEndVertex(thePart);
648 if (pVert == theVert) break; // to prevent Sherpa loop
649 if (pVert != nullptr) {
650 auto vecPart = findFinalStateParticles<V>(pVert);
651 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
652 }
653 }
654 return finalStatePart;
655 }
656#if !defined(XAOD_ANALYSIS)
657#include "AtlasHepMC/GenEvent.h"
658inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
659inline 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());} }
660
661#endif
662}
663#endif

◆ flow() [1/2]

template<class T, std::enable_if_t< std::is_same< T, HepMC3::GenParticlePtr >::value||std::is_same< T, HepMC3::ConstGenParticlePtr >::value, bool > = true>
Flow MC::HepMC::flow ( const T & p)
inline

Definition at line 21 of file HepMCHelpers.h.

22 {
24 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
25
26 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
27
28 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
29 }
30

◆ flow() [2/2]

template<class T, std::enable_if_t< std::is_same< T, HepMC3::GenParticlePtr >::value||std::is_same< T, HepMC3::ConstGenParticlePtr >::value, bool > = true>
int MC::HepMC::flow ( const T & p,
int i )
inline

Definition at line 15 of file HepMCHelpers.h.

◆ get_ll_event_number()

long long int MC::HepMC::get_ll_event_number ( const HepMC3::GenEvent * e)
inline

Definition at line 341 of file HepMCHelpers.h.

360{
361 namespace Pythia8
362 {
364 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
365
366 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
367
368 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
369 }
370
371#include "AtlasPID.h"
372
374 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
375
377 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
378
380 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
381
383 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
384
386 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
387
389 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
390
392 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
393
395 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
396
398 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
399
401 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
402
406 template <class T> inline bool isStableOrSimDecayed(const T& p) {
407 const auto vertex = p->end_vertex();
408 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
409 }
410
412 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
413
415 template <class T> inline bool isSpecialNonInteracting(const T& p) {
416 const int apid = std::abs(p->pdg_id());
417 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
418 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
419 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
420 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
421 return false;
422 }
423
425
426 template <class T> T findMother(T thePart) {
427 auto partOriVert = thePart->production_vertex();
428 if (!partOriVert) return nullptr;
429
430 long partPDG = thePart->pdg_id();
431 long MotherPDG(0);
432
433 auto MothOriVert = partOriVert;
434 MothOriVert = nullptr;
435 T theMoth(nullptr);
436
437 size_t itr = 0;
438 do {
439 if (itr != 0) partOriVert = MothOriVert;
440 for ( const auto& p : partOriVert->particles_in() ) {
441 theMoth = p;
442 if (!theMoth) continue;
443 MotherPDG = theMoth->pdg_id();
444 MothOriVert = theMoth->production_vertex();
445 if (MotherPDG == partPDG) break;
446 }
447 itr++;
448 if (itr > 100) {
449 break;
450 }
451 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
452 MothOriVert != partOriVert);
453 return theMoth;
454 }
455
457
458 template <class C, class T> T findMatching(C TruthContainer, T p) {
459 T ptrPart = nullptr;
460 if (!p) return ptrPart;
461 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
462 for (T truthParticle : *TruthContainer) {
463 if (HepMC::is_sim_descendant(p,truthParticle)) {
464 ptrPart = truthParticle;
465 break;
466 }
467 }
468 }
469 else {
470 for (T truthParticle : TruthContainer) {
471 if (HepMC::is_sim_descendant(p,truthParticle)) {
472 ptrPart = truthParticle;
473 break;
474 }
475 }
476 }
477 return ptrPart;
478 }
480
481 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
482 auto prodVtx = thePart->production_vertex();
483 if (!prodVtx) return;
484 for (const auto& theMother: prodVtx->particles_in()) {
485 if (!theMother) continue;
486 allancestors.insert(theMother);
487 findParticleAncestors(theMother, allancestors);
488 }
489 }
490
492
493 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
494 auto endVtx = thePart->end_vertex();
495 if (!endVtx) return;
496 for (const auto& theDaughter: endVtx->particles_out()) {
497 if (!theDaughter) continue;
498 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
499 allstabledescendants.insert(theDaughter);
500 }
501 findParticleStableDescendants(theDaughter, allstabledescendants);
502 }
503 }
504
508
509 template <class T> bool isHardScatteringVertex(T pVert) {
510 if (pVert == nullptr) return false;
511 T pV = pVert;
512 int numOfPartIn(0);
513 int pdg(0);
514
515 do {
516 pVert = pV;
517 auto incoming = pVert->particles_in();
518 numOfPartIn = incoming.size();
519 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
520 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
521
522 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
523
524 if (numOfPartIn == 2) {
525 auto incoming = pVert->particles_in();
526 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;
527 }
528 return false;
529}
530
534
535 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
536 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
537 auto vtx = p->production_vertex();
538 if (!vtx) return false;
539 bool fromHad = false;
540 for ( const auto& parent : vtx->particles_in() ) {
541 if (!parent) continue;
542 // should this really go into parton-level territory?
543 // probably depends where BSM particles are being decayed
544 fromBSM |= isBSM(parent);
545 if (!isPhysical(parent)) return false;
546 fromTau |= isTau(parent);
547 if (isHadron(parent)&&!isBeam(parent)) {
548 if (!hadron) hadron = parent; // assumes linear hadron parentage
549 return true;
550 }
551 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
552 }
553 return fromHad;
554 }
555
558
559 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
560 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
561 decltype(thePart->end_vertex()) pVert(nullptr);
562 if (EndVert != nullptr) {
563 do {
564 bool samePart = false;
565 pVert = nullptr;
566 auto outgoing = EndVert->particles_out();
567 auto incoming = EndVert->particles_in();
568 for (const auto& itrDaug: outgoing) {
569 if (!itrDaug) continue;
570 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
571 // brem on generator level for tau
572 (outgoing.size() == 1 && incoming.size() == 1 &&
574 itrDaug->pdg_id() == thePart->pdg_id()) {
575 samePart = true;
576 pVert = itrDaug->end_vertex();
577 }
578 }
579 if (samePart) EndVert = pVert;
580 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
581 }
582 return EndVert;
583 }
584
586
587 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
588 if (!theVert) return {};
589 decltype(theVert->particles_out()) finalStatePart;
590 auto outgoing = theVert->particles_out();
591 for (const auto& thePart: outgoing) {
592 if (!thePart) continue;
593 finalStatePart.push_back(thePart);
594 if (isStable(thePart)) continue;
595 V pVert = findSimulatedEndVertex(thePart);
596 if (pVert == theVert) break; // to prevent Sherpa loop
597 if (pVert != nullptr) {
598 auto vecPart = findFinalStateParticles<V>(pVert);
599 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
600 }
601 }
602 return finalStatePart;
603 }
604#if !defined(XAOD_ANALYSIS)
605#include "AtlasHepMC/GenEvent.h"
606inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
607inline 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());} }
608
609#endif
610}
611#endif

◆ mpi() [1/2]

int MC::HepMC::mpi ( const GenEvent & evt)
inline

Definition at line 563 of file HepMCHelpers.h.

582{
583 namespace Pythia8
584 {
586 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
587
588 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
589
590 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
591 }
592
593#include "AtlasPID.h"
594
596 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
597
599 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
600
602 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
603
605 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
606
608 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
609
611 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
612
614 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
615
617 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
618
620 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
621
623 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
624
628 template <class T> inline bool isStableOrSimDecayed(const T& p) {
629 const auto vertex = p->end_vertex();
630 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
631 }
632
634 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
635
637 template <class T> inline bool isSpecialNonInteracting(const T& p) {
638 const int apid = std::abs(p->pdg_id());
639 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
640 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
641 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
642 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
643 return false;
644 }
645
647
648 template <class T> T findMother(T thePart) {
649 auto partOriVert = thePart->production_vertex();
650 if (!partOriVert) return nullptr;
651
652 long partPDG = thePart->pdg_id();
653 long MotherPDG(0);
654
655 auto MothOriVert = partOriVert;
656 MothOriVert = nullptr;
657 T theMoth(nullptr);
658
659 size_t itr = 0;
660 do {
661 if (itr != 0) partOriVert = MothOriVert;
662 for ( const auto& p : partOriVert->particles_in() ) {
663 theMoth = p;
664 if (!theMoth) continue;
665 MotherPDG = theMoth->pdg_id();
666 MothOriVert = theMoth->production_vertex();
667 if (MotherPDG == partPDG) break;
668 }
669 itr++;
670 if (itr > 100) {
671 break;
672 }
673 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
674 MothOriVert != partOriVert);
675 return theMoth;
676 }
677
679
680 template <class C, class T> T findMatching(C TruthContainer, T p) {
681 T ptrPart = nullptr;
682 if (!p) return ptrPart;
683 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
684 for (T truthParticle : *TruthContainer) {
685 if (HepMC::is_sim_descendant(p,truthParticle)) {
686 ptrPart = truthParticle;
687 break;
688 }
689 }
690 }
691 else {
692 for (T truthParticle : TruthContainer) {
693 if (HepMC::is_sim_descendant(p,truthParticle)) {
694 ptrPart = truthParticle;
695 break;
696 }
697 }
698 }
699 return ptrPart;
700 }
702
703 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
704 auto prodVtx = thePart->production_vertex();
705 if (!prodVtx) return;
706 for (const auto& theMother: prodVtx->particles_in()) {
707 if (!theMother) continue;
708 allancestors.insert(theMother);
709 findParticleAncestors(theMother, allancestors);
710 }
711 }
712
714
715 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
716 auto endVtx = thePart->end_vertex();
717 if (!endVtx) return;
718 for (const auto& theDaughter: endVtx->particles_out()) {
719 if (!theDaughter) continue;
720 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
721 allstabledescendants.insert(theDaughter);
722 }
723 findParticleStableDescendants(theDaughter, allstabledescendants);
724 }
725 }
726
730
731 template <class T> bool isHardScatteringVertex(T pVert) {
732 if (pVert == nullptr) return false;
733 T pV = pVert;
734 int numOfPartIn(0);
735 int pdg(0);
736
737 do {
738 pVert = pV;
739 auto incoming = pVert->particles_in();
740 numOfPartIn = incoming.size();
741 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
742 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
743
744 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
745
746 if (numOfPartIn == 2) {
747 auto incoming = pVert->particles_in();
748 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;
749 }
750 return false;
751}
752
756
757 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
758 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
759 auto vtx = p->production_vertex();
760 if (!vtx) return false;
761 bool fromHad = false;
762 for ( const auto& parent : vtx->particles_in() ) {
763 if (!parent) continue;
764 // should this really go into parton-level territory?
765 // probably depends where BSM particles are being decayed
766 fromBSM |= isBSM(parent);
767 if (!isPhysical(parent)) return false;
768 fromTau |= isTau(parent);
769 if (isHadron(parent)&&!isBeam(parent)) {
770 if (!hadron) hadron = parent; // assumes linear hadron parentage
771 return true;
772 }
773 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
774 }
775 return fromHad;
776 }
777
780
781 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
782 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
783 decltype(thePart->end_vertex()) pVert(nullptr);
784 if (EndVert != nullptr) {
785 do {
786 bool samePart = false;
787 pVert = nullptr;
788 auto outgoing = EndVert->particles_out();
789 auto incoming = EndVert->particles_in();
790 for (const auto& itrDaug: outgoing) {
791 if (!itrDaug) continue;
792 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
793 // brem on generator level for tau
794 (outgoing.size() == 1 && incoming.size() == 1 &&
796 itrDaug->pdg_id() == thePart->pdg_id()) {
797 samePart = true;
798 pVert = itrDaug->end_vertex();
799 }
800 }
801 if (samePart) EndVert = pVert;
802 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
803 }
804 return EndVert;
805 }
806
808
809 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
810 if (!theVert) return {};
811 decltype(theVert->particles_out()) finalStatePart;
812 auto outgoing = theVert->particles_out();
813 for (const auto& thePart: outgoing) {
814 if (!thePart) continue;
815 finalStatePart.push_back(thePart);
816 if (isStable(thePart)) continue;
817 V pVert = findSimulatedEndVertex(thePart);
818 if (pVert == theVert) break; // to prevent Sherpa loop
819 if (pVert != nullptr) {
820 auto vecPart = findFinalStateParticles<V>(pVert);
821 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
822 }
823 }
824 return finalStatePart;
825 }
826#if !defined(XAOD_ANALYSIS)
827#include "AtlasHepMC/GenEvent.h"
828inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
829inline 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());} }
830
831#endif
832}
833#endif

◆ mpi() [2/2]

int MC::HepMC::mpi ( const GenEvent * evt)
inline

Definition at line 567 of file HepMCHelpers.h.

586{
587 namespace Pythia8
588 {
590 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
591
592 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
593
594 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
595 }
596
597#include "AtlasPID.h"
598
600 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
601
603 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
604
606 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
607
609 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
610
612 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
613
615 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
616
618 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
619
621 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
622
624 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
625
627 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
628
632 template <class T> inline bool isStableOrSimDecayed(const T& p) {
633 const auto vertex = p->end_vertex();
634 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
635 }
636
638 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
639
641 template <class T> inline bool isSpecialNonInteracting(const T& p) {
642 const int apid = std::abs(p->pdg_id());
643 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
644 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
645 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
646 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
647 return false;
648 }
649
651
652 template <class T> T findMother(T thePart) {
653 auto partOriVert = thePart->production_vertex();
654 if (!partOriVert) return nullptr;
655
656 long partPDG = thePart->pdg_id();
657 long MotherPDG(0);
658
659 auto MothOriVert = partOriVert;
660 MothOriVert = nullptr;
661 T theMoth(nullptr);
662
663 size_t itr = 0;
664 do {
665 if (itr != 0) partOriVert = MothOriVert;
666 for ( const auto& p : partOriVert->particles_in() ) {
667 theMoth = p;
668 if (!theMoth) continue;
669 MotherPDG = theMoth->pdg_id();
670 MothOriVert = theMoth->production_vertex();
671 if (MotherPDG == partPDG) break;
672 }
673 itr++;
674 if (itr > 100) {
675 break;
676 }
677 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
678 MothOriVert != partOriVert);
679 return theMoth;
680 }
681
683
684 template <class C, class T> T findMatching(C TruthContainer, T p) {
685 T ptrPart = nullptr;
686 if (!p) return ptrPart;
687 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
688 for (T truthParticle : *TruthContainer) {
689 if (HepMC::is_sim_descendant(p,truthParticle)) {
690 ptrPart = truthParticle;
691 break;
692 }
693 }
694 }
695 else {
696 for (T truthParticle : TruthContainer) {
697 if (HepMC::is_sim_descendant(p,truthParticle)) {
698 ptrPart = truthParticle;
699 break;
700 }
701 }
702 }
703 return ptrPart;
704 }
706
707 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
708 auto prodVtx = thePart->production_vertex();
709 if (!prodVtx) return;
710 for (const auto& theMother: prodVtx->particles_in()) {
711 if (!theMother) continue;
712 allancestors.insert(theMother);
713 findParticleAncestors(theMother, allancestors);
714 }
715 }
716
718
719 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
720 auto endVtx = thePart->end_vertex();
721 if (!endVtx) return;
722 for (const auto& theDaughter: endVtx->particles_out()) {
723 if (!theDaughter) continue;
724 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
725 allstabledescendants.insert(theDaughter);
726 }
727 findParticleStableDescendants(theDaughter, allstabledescendants);
728 }
729 }
730
734
735 template <class T> bool isHardScatteringVertex(T pVert) {
736 if (pVert == nullptr) return false;
737 T pV = pVert;
738 int numOfPartIn(0);
739 int pdg(0);
740
741 do {
742 pVert = pV;
743 auto incoming = pVert->particles_in();
744 numOfPartIn = incoming.size();
745 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
746 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
747
748 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
749
750 if (numOfPartIn == 2) {
751 auto incoming = pVert->particles_in();
752 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;
753 }
754 return false;
755}
756
760
761 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
762 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
763 auto vtx = p->production_vertex();
764 if (!vtx) return false;
765 bool fromHad = false;
766 for ( const auto& parent : vtx->particles_in() ) {
767 if (!parent) continue;
768 // should this really go into parton-level territory?
769 // probably depends where BSM particles are being decayed
770 fromBSM |= isBSM(parent);
771 if (!isPhysical(parent)) return false;
772 fromTau |= isTau(parent);
773 if (isHadron(parent)&&!isBeam(parent)) {
774 if (!hadron) hadron = parent; // assumes linear hadron parentage
775 return true;
776 }
777 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
778 }
779 return fromHad;
780 }
781
784
785 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
786 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
787 decltype(thePart->end_vertex()) pVert(nullptr);
788 if (EndVert != nullptr) {
789 do {
790 bool samePart = false;
791 pVert = nullptr;
792 auto outgoing = EndVert->particles_out();
793 auto incoming = EndVert->particles_in();
794 for (const auto& itrDaug: outgoing) {
795 if (!itrDaug) continue;
796 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
797 // brem on generator level for tau
798 (outgoing.size() == 1 && incoming.size() == 1 &&
800 itrDaug->pdg_id() == thePart->pdg_id()) {
801 samePart = true;
802 pVert = itrDaug->end_vertex();
803 }
804 }
805 if (samePart) EndVert = pVert;
806 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
807 }
808 return EndVert;
809 }
810
812
813 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
814 if (!theVert) return {};
815 decltype(theVert->particles_out()) finalStatePart;
816 auto outgoing = theVert->particles_out();
817 for (const auto& thePart: outgoing) {
818 if (!thePart) continue;
819 finalStatePart.push_back(thePart);
820 if (isStable(thePart)) continue;
821 V pVert = findSimulatedEndVertex(thePart);
822 if (pVert == theVert) break; // to prevent Sherpa loop
823 if (pVert != nullptr) {
824 auto vecPart = findFinalStateParticles<V>(pVert);
825 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
826 }
827 }
828 return finalStatePart;
829 }
830#if !defined(XAOD_ANALYSIS)
831#include "AtlasHepMC/GenEvent.h"
832inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
833inline 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());} }
834
835#endif
836}
837#endif

◆ newConstGenParticlePtr()

ConstGenParticlePtr MC::HepMC::newConstGenParticlePtr ( const HepMC3::FourVector & mom = HepMC3::FourVector::ZERO_VECTOR(),
int pid = 0,
int status = 0 )
inline

Definition at line 24 of file HepMCHelpers.h.

24 { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
25
26 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}

◆ newGenEvent()

GenEvent * MC::HepMC::newGenEvent ( const int signal_process_id,
const int event_number )
inline

Definition at line 360 of file HepMCHelpers.h.

379{
380 namespace Pythia8
381 {
383 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
384
385 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
386
387 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
388 }
389
390#include "AtlasPID.h"
391
393 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
394
396 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
397
399 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
400
402 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
403
405 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
406
408 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
409
411 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
412
414 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
415
417 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
418
420 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
421
425 template <class T> inline bool isStableOrSimDecayed(const T& p) {
426 const auto vertex = p->end_vertex();
427 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
428 }
429
431 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
432
434 template <class T> inline bool isSpecialNonInteracting(const T& p) {
435 const int apid = std::abs(p->pdg_id());
436 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
437 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
438 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
439 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
440 return false;
441 }
442
444
445 template <class T> T findMother(T thePart) {
446 auto partOriVert = thePart->production_vertex();
447 if (!partOriVert) return nullptr;
448
449 long partPDG = thePart->pdg_id();
450 long MotherPDG(0);
451
452 auto MothOriVert = partOriVert;
453 MothOriVert = nullptr;
454 T theMoth(nullptr);
455
456 size_t itr = 0;
457 do {
458 if (itr != 0) partOriVert = MothOriVert;
459 for ( const auto& p : partOriVert->particles_in() ) {
460 theMoth = p;
461 if (!theMoth) continue;
462 MotherPDG = theMoth->pdg_id();
463 MothOriVert = theMoth->production_vertex();
464 if (MotherPDG == partPDG) break;
465 }
466 itr++;
467 if (itr > 100) {
468 break;
469 }
470 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
471 MothOriVert != partOriVert);
472 return theMoth;
473 }
474
476
477 template <class C, class T> T findMatching(C TruthContainer, T p) {
478 T ptrPart = nullptr;
479 if (!p) return ptrPart;
480 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
481 for (T truthParticle : *TruthContainer) {
482 if (HepMC::is_sim_descendant(p,truthParticle)) {
483 ptrPart = truthParticle;
484 break;
485 }
486 }
487 }
488 else {
489 for (T truthParticle : TruthContainer) {
490 if (HepMC::is_sim_descendant(p,truthParticle)) {
491 ptrPart = truthParticle;
492 break;
493 }
494 }
495 }
496 return ptrPart;
497 }
499
500 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
501 auto prodVtx = thePart->production_vertex();
502 if (!prodVtx) return;
503 for (const auto& theMother: prodVtx->particles_in()) {
504 if (!theMother) continue;
505 allancestors.insert(theMother);
506 findParticleAncestors(theMother, allancestors);
507 }
508 }
509
511
512 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
513 auto endVtx = thePart->end_vertex();
514 if (!endVtx) return;
515 for (const auto& theDaughter: endVtx->particles_out()) {
516 if (!theDaughter) continue;
517 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
518 allstabledescendants.insert(theDaughter);
519 }
520 findParticleStableDescendants(theDaughter, allstabledescendants);
521 }
522 }
523
527
528 template <class T> bool isHardScatteringVertex(T pVert) {
529 if (pVert == nullptr) return false;
530 T pV = pVert;
531 int numOfPartIn(0);
532 int pdg(0);
533
534 do {
535 pVert = pV;
536 auto incoming = pVert->particles_in();
537 numOfPartIn = incoming.size();
538 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
539 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
540
541 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
542
543 if (numOfPartIn == 2) {
544 auto incoming = pVert->particles_in();
545 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;
546 }
547 return false;
548}
549
553
554 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
555 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
556 auto vtx = p->production_vertex();
557 if (!vtx) return false;
558 bool fromHad = false;
559 for ( const auto& parent : vtx->particles_in() ) {
560 if (!parent) continue;
561 // should this really go into parton-level territory?
562 // probably depends where BSM particles are being decayed
563 fromBSM |= isBSM(parent);
564 if (!isPhysical(parent)) return false;
565 fromTau |= isTau(parent);
566 if (isHadron(parent)&&!isBeam(parent)) {
567 if (!hadron) hadron = parent; // assumes linear hadron parentage
568 return true;
569 }
570 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
571 }
572 return fromHad;
573 }
574
577
578 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
579 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
580 decltype(thePart->end_vertex()) pVert(nullptr);
581 if (EndVert != nullptr) {
582 do {
583 bool samePart = false;
584 pVert = nullptr;
585 auto outgoing = EndVert->particles_out();
586 auto incoming = EndVert->particles_in();
587 for (const auto& itrDaug: outgoing) {
588 if (!itrDaug) continue;
589 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
590 // brem on generator level for tau
591 (outgoing.size() == 1 && incoming.size() == 1 &&
593 itrDaug->pdg_id() == thePart->pdg_id()) {
594 samePart = true;
595 pVert = itrDaug->end_vertex();
596 }
597 }
598 if (samePart) EndVert = pVert;
599 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
600 }
601 return EndVert;
602 }
603
605
606 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
607 if (!theVert) return {};
608 decltype(theVert->particles_out()) finalStatePart;
609 auto outgoing = theVert->particles_out();
610 for (const auto& thePart: outgoing) {
611 if (!thePart) continue;
612 finalStatePart.push_back(thePart);
613 if (isStable(thePart)) continue;
614 V pVert = findSimulatedEndVertex(thePart);
615 if (pVert == theVert) break; // to prevent Sherpa loop
616 if (pVert != nullptr) {
617 auto vecPart = findFinalStateParticles<V>(pVert);
618 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
619 }
620 }
621 return finalStatePart;
622 }
623#if !defined(XAOD_ANALYSIS)
624#include "AtlasHepMC/GenEvent.h"
625inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
626inline 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());} }
627
628#endif
629}
630#endif

◆ newGenParticlePtr()

GenParticlePtr MC::HepMC::newGenParticlePtr ( const HepMC3::FourVector & mom = HepMC3::FourVector::ZERO_VECTOR(),
int pid = 0,
int status = 0 )
inline

Definition at line 21 of file HepMCHelpers.h.

22 {

◆ newGenVertexPtr()

GenVertexPtr MC::HepMC::newGenVertexPtr ( const HepMC3::FourVector & pos = HepMC3::FourVector::ZERO_VECTOR(),
const int i = 0 )
inline

Definition at line 25 of file HepMCHelpers.h.

26 { return p->status() == 23;}
27
28 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
29 }

◆ polarization()

template<class T, std::enable_if_t< std::is_same< T, HepMC3::GenParticlePtr >::value||std::is_same< T, HepMC3::ConstGenParticlePtr >::value, bool > = true>
Polarization MC::HepMC::polarization ( const T & a)
inline

Definition at line 28 of file HepMCHelpers.h.

28 { return p->status() > 30 && p->status() < 40;}
29 }
30
31#include "AtlasPID.h"
32
34 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
35

◆ set_flow()

template<class T>
void MC::HepMC::set_flow ( T & a,
Flow fl )

Definition at line 31 of file HepMCHelpers.h.

◆ set_ll_event_number()

bool MC::HepMC::set_ll_event_number ( HepMC3::GenEvent * e,
long long int num )
inline

Definition at line 337 of file HepMCHelpers.h.

356{
357 namespace Pythia8
358 {
360 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
361
362 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
363
364 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
365 }
366
367#include "AtlasPID.h"
368
370 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
371
373 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
374
376 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
377
379 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
380
382 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
383
385 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
386
388 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
389
391 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
392
394 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
395
397 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
398
402 template <class T> inline bool isStableOrSimDecayed(const T& p) {
403 const auto vertex = p->end_vertex();
404 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
405 }
406
408 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
409
411 template <class T> inline bool isSpecialNonInteracting(const T& p) {
412 const int apid = std::abs(p->pdg_id());
413 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
414 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
415 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
416 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
417 return false;
418 }
419
421
422 template <class T> T findMother(T thePart) {
423 auto partOriVert = thePart->production_vertex();
424 if (!partOriVert) return nullptr;
425
426 long partPDG = thePart->pdg_id();
427 long MotherPDG(0);
428
429 auto MothOriVert = partOriVert;
430 MothOriVert = nullptr;
431 T theMoth(nullptr);
432
433 size_t itr = 0;
434 do {
435 if (itr != 0) partOriVert = MothOriVert;
436 for ( const auto& p : partOriVert->particles_in() ) {
437 theMoth = p;
438 if (!theMoth) continue;
439 MotherPDG = theMoth->pdg_id();
440 MothOriVert = theMoth->production_vertex();
441 if (MotherPDG == partPDG) break;
442 }
443 itr++;
444 if (itr > 100) {
445 break;
446 }
447 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
448 MothOriVert != partOriVert);
449 return theMoth;
450 }
451
453
454 template <class C, class T> T findMatching(C TruthContainer, T p) {
455 T ptrPart = nullptr;
456 if (!p) return ptrPart;
457 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
458 for (T truthParticle : *TruthContainer) {
459 if (HepMC::is_sim_descendant(p,truthParticle)) {
460 ptrPart = truthParticle;
461 break;
462 }
463 }
464 }
465 else {
466 for (T truthParticle : TruthContainer) {
467 if (HepMC::is_sim_descendant(p,truthParticle)) {
468 ptrPart = truthParticle;
469 break;
470 }
471 }
472 }
473 return ptrPart;
474 }
476
477 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
478 auto prodVtx = thePart->production_vertex();
479 if (!prodVtx) return;
480 for (const auto& theMother: prodVtx->particles_in()) {
481 if (!theMother) continue;
482 allancestors.insert(theMother);
483 findParticleAncestors(theMother, allancestors);
484 }
485 }
486
488
489 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
490 auto endVtx = thePart->end_vertex();
491 if (!endVtx) return;
492 for (const auto& theDaughter: endVtx->particles_out()) {
493 if (!theDaughter) continue;
494 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
495 allstabledescendants.insert(theDaughter);
496 }
497 findParticleStableDescendants(theDaughter, allstabledescendants);
498 }
499 }
500
504
505 template <class T> bool isHardScatteringVertex(T pVert) {
506 if (pVert == nullptr) return false;
507 T pV = pVert;
508 int numOfPartIn(0);
509 int pdg(0);
510
511 do {
512 pVert = pV;
513 auto incoming = pVert->particles_in();
514 numOfPartIn = incoming.size();
515 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
516 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
517
518 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
519
520 if (numOfPartIn == 2) {
521 auto incoming = pVert->particles_in();
522 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;
523 }
524 return false;
525}
526
530
531 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
532 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
533 auto vtx = p->production_vertex();
534 if (!vtx) return false;
535 bool fromHad = false;
536 for ( const auto& parent : vtx->particles_in() ) {
537 if (!parent) continue;
538 // should this really go into parton-level territory?
539 // probably depends where BSM particles are being decayed
540 fromBSM |= isBSM(parent);
541 if (!isPhysical(parent)) return false;
542 fromTau |= isTau(parent);
543 if (isHadron(parent)&&!isBeam(parent)) {
544 if (!hadron) hadron = parent; // assumes linear hadron parentage
545 return true;
546 }
547 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
548 }
549 return fromHad;
550 }
551
554
555 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
556 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
557 decltype(thePart->end_vertex()) pVert(nullptr);
558 if (EndVert != nullptr) {
559 do {
560 bool samePart = false;
561 pVert = nullptr;
562 auto outgoing = EndVert->particles_out();
563 auto incoming = EndVert->particles_in();
564 for (const auto& itrDaug: outgoing) {
565 if (!itrDaug) continue;
566 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
567 // brem on generator level for tau
568 (outgoing.size() == 1 && incoming.size() == 1 &&
570 itrDaug->pdg_id() == thePart->pdg_id()) {
571 samePart = true;
572 pVert = itrDaug->end_vertex();
573 }
574 }
575 if (samePart) EndVert = pVert;
576 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
577 }
578 return EndVert;
579 }
580
582
583 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
584 if (!theVert) return {};
585 decltype(theVert->particles_out()) finalStatePart;
586 auto outgoing = theVert->particles_out();
587 for (const auto& thePart: outgoing) {
588 if (!thePart) continue;
589 finalStatePart.push_back(thePart);
590 if (isStable(thePart)) continue;
591 V pVert = findSimulatedEndVertex(thePart);
592 if (pVert == theVert) break; // to prevent Sherpa loop
593 if (pVert != nullptr) {
594 auto vecPart = findFinalStateParticles<V>(pVert);
595 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
596 }
597 }
598 return finalStatePart;
599 }
600#if !defined(XAOD_ANALYSIS)
601#include "AtlasHepMC/GenEvent.h"
602inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
603inline 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());} }
604
605#endif
606}
607#endif

◆ set_mpi()

void MC::HepMC::set_mpi ( GenEvent * e,
const int i = 0 )
inline

Definition at line 584 of file HepMCHelpers.h.

603{
604 namespace Pythia8
605 {
607 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
608
609 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
610
611 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
612 }
613
614#include "AtlasPID.h"
615
617 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
618
620 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
621
623 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
624
626 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
627
629 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
630
632 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
633
635 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
636
638 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
639
641 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
642
644 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
645
649 template <class T> inline bool isStableOrSimDecayed(const T& p) {
650 const auto vertex = p->end_vertex();
651 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
652 }
653
655 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
656
658 template <class T> inline bool isSpecialNonInteracting(const T& p) {
659 const int apid = std::abs(p->pdg_id());
660 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
661 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
662 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
663 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
664 return false;
665 }
666
668
669 template <class T> T findMother(T thePart) {
670 auto partOriVert = thePart->production_vertex();
671 if (!partOriVert) return nullptr;
672
673 long partPDG = thePart->pdg_id();
674 long MotherPDG(0);
675
676 auto MothOriVert = partOriVert;
677 MothOriVert = nullptr;
678 T theMoth(nullptr);
679
680 size_t itr = 0;
681 do {
682 if (itr != 0) partOriVert = MothOriVert;
683 for ( const auto& p : partOriVert->particles_in() ) {
684 theMoth = p;
685 if (!theMoth) continue;
686 MotherPDG = theMoth->pdg_id();
687 MothOriVert = theMoth->production_vertex();
688 if (MotherPDG == partPDG) break;
689 }
690 itr++;
691 if (itr > 100) {
692 break;
693 }
694 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
695 MothOriVert != partOriVert);
696 return theMoth;
697 }
698
700
701 template <class C, class T> T findMatching(C TruthContainer, T p) {
702 T ptrPart = nullptr;
703 if (!p) return ptrPart;
704 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
705 for (T truthParticle : *TruthContainer) {
706 if (HepMC::is_sim_descendant(p,truthParticle)) {
707 ptrPart = truthParticle;
708 break;
709 }
710 }
711 }
712 else {
713 for (T truthParticle : TruthContainer) {
714 if (HepMC::is_sim_descendant(p,truthParticle)) {
715 ptrPart = truthParticle;
716 break;
717 }
718 }
719 }
720 return ptrPart;
721 }
723
724 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
725 auto prodVtx = thePart->production_vertex();
726 if (!prodVtx) return;
727 for (const auto& theMother: prodVtx->particles_in()) {
728 if (!theMother) continue;
729 allancestors.insert(theMother);
730 findParticleAncestors(theMother, allancestors);
731 }
732 }
733
735
736 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
737 auto endVtx = thePart->end_vertex();
738 if (!endVtx) return;
739 for (const auto& theDaughter: endVtx->particles_out()) {
740 if (!theDaughter) continue;
741 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
742 allstabledescendants.insert(theDaughter);
743 }
744 findParticleStableDescendants(theDaughter, allstabledescendants);
745 }
746 }
747
751
752 template <class T> bool isHardScatteringVertex(T pVert) {
753 if (pVert == nullptr) return false;
754 T pV = pVert;
755 int numOfPartIn(0);
756 int pdg(0);
757
758 do {
759 pVert = pV;
760 auto incoming = pVert->particles_in();
761 numOfPartIn = incoming.size();
762 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
763 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
764
765 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
766
767 if (numOfPartIn == 2) {
768 auto incoming = pVert->particles_in();
769 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;
770 }
771 return false;
772}
773
777
778 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
779 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
780 auto vtx = p->production_vertex();
781 if (!vtx) return false;
782 bool fromHad = false;
783 for ( const auto& parent : vtx->particles_in() ) {
784 if (!parent) continue;
785 // should this really go into parton-level territory?
786 // probably depends where BSM particles are being decayed
787 fromBSM |= isBSM(parent);
788 if (!isPhysical(parent)) return false;
789 fromTau |= isTau(parent);
790 if (isHadron(parent)&&!isBeam(parent)) {
791 if (!hadron) hadron = parent; // assumes linear hadron parentage
792 return true;
793 }
794 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
795 }
796 return fromHad;
797 }
798
801
802 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
803 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
804 decltype(thePart->end_vertex()) pVert(nullptr);
805 if (EndVert != nullptr) {
806 do {
807 bool samePart = false;
808 pVert = nullptr;
809 auto outgoing = EndVert->particles_out();
810 auto incoming = EndVert->particles_in();
811 for (const auto& itrDaug: outgoing) {
812 if (!itrDaug) continue;
813 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
814 // brem on generator level for tau
815 (outgoing.size() == 1 && incoming.size() == 1 &&
817 itrDaug->pdg_id() == thePart->pdg_id()) {
818 samePart = true;
819 pVert = itrDaug->end_vertex();
820 }
821 }
822 if (samePart) EndVert = pVert;
823 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
824 }
825 return EndVert;
826 }
827
829
830 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
831 if (!theVert) return {};
832 decltype(theVert->particles_out()) finalStatePart;
833 auto outgoing = theVert->particles_out();
834 for (const auto& thePart: outgoing) {
835 if (!thePart) continue;
836 finalStatePart.push_back(thePart);
837 if (isStable(thePart)) continue;
838 V pVert = findSimulatedEndVertex(thePart);
839 if (pVert == theVert) break; // to prevent Sherpa loop
840 if (pVert != nullptr) {
841 auto vecPart = findFinalStateParticles<V>(pVert);
842 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
843 }
844 }
845 return finalStatePart;
846 }
847#if !defined(XAOD_ANALYSIS)
848#include "AtlasHepMC/GenEvent.h"
849inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
850inline 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());} }
851
852#endif
853}
854#endif

◆ set_polarization()

template<class T>
void MC::HepMC::set_polarization ( T & a,
const Polarization & b )
inline

Definition at line 36 of file HepMCHelpers.h.

37 { return (isMuon<T>(p) || isSUSY<T>(p)); }
38

◆ set_random_states()

void MC::HepMC::set_random_states ( GenEvent * e,
std::vector< long int > & a )
inline

Definition at line 588 of file HepMCHelpers.h.

607{
608 namespace Pythia8
609 {
611 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
612
613 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
614
615 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
616 }
617
618#include "AtlasPID.h"
619
621 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
622
624 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
625
627 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
628
630 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
631
633 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
634
636 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
637
639 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
640
642 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
643
645 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
646
648 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
649
653 template <class T> inline bool isStableOrSimDecayed(const T& p) {
654 const auto vertex = p->end_vertex();
655 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
656 }
657
659 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
660
662 template <class T> inline bool isSpecialNonInteracting(const T& p) {
663 const int apid = std::abs(p->pdg_id());
664 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
665 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
666 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
667 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
668 return false;
669 }
670
672
673 template <class T> T findMother(T thePart) {
674 auto partOriVert = thePart->production_vertex();
675 if (!partOriVert) return nullptr;
676
677 long partPDG = thePart->pdg_id();
678 long MotherPDG(0);
679
680 auto MothOriVert = partOriVert;
681 MothOriVert = nullptr;
682 T theMoth(nullptr);
683
684 size_t itr = 0;
685 do {
686 if (itr != 0) partOriVert = MothOriVert;
687 for ( const auto& p : partOriVert->particles_in() ) {
688 theMoth = p;
689 if (!theMoth) continue;
690 MotherPDG = theMoth->pdg_id();
691 MothOriVert = theMoth->production_vertex();
692 if (MotherPDG == partPDG) break;
693 }
694 itr++;
695 if (itr > 100) {
696 break;
697 }
698 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
699 MothOriVert != partOriVert);
700 return theMoth;
701 }
702
704
705 template <class C, class T> T findMatching(C TruthContainer, T p) {
706 T ptrPart = nullptr;
707 if (!p) return ptrPart;
708 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
709 for (T truthParticle : *TruthContainer) {
710 if (HepMC::is_sim_descendant(p,truthParticle)) {
711 ptrPart = truthParticle;
712 break;
713 }
714 }
715 }
716 else {
717 for (T truthParticle : TruthContainer) {
718 if (HepMC::is_sim_descendant(p,truthParticle)) {
719 ptrPart = truthParticle;
720 break;
721 }
722 }
723 }
724 return ptrPart;
725 }
727
728 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
729 auto prodVtx = thePart->production_vertex();
730 if (!prodVtx) return;
731 for (const auto& theMother: prodVtx->particles_in()) {
732 if (!theMother) continue;
733 allancestors.insert(theMother);
734 findParticleAncestors(theMother, allancestors);
735 }
736 }
737
739
740 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
741 auto endVtx = thePart->end_vertex();
742 if (!endVtx) return;
743 for (const auto& theDaughter: endVtx->particles_out()) {
744 if (!theDaughter) continue;
745 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
746 allstabledescendants.insert(theDaughter);
747 }
748 findParticleStableDescendants(theDaughter, allstabledescendants);
749 }
750 }
751
755
756 template <class T> bool isHardScatteringVertex(T pVert) {
757 if (pVert == nullptr) return false;
758 T pV = pVert;
759 int numOfPartIn(0);
760 int pdg(0);
761
762 do {
763 pVert = pV;
764 auto incoming = pVert->particles_in();
765 numOfPartIn = incoming.size();
766 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
767 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
768
769 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
770
771 if (numOfPartIn == 2) {
772 auto incoming = pVert->particles_in();
773 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;
774 }
775 return false;
776}
777
781
782 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
783 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
784 auto vtx = p->production_vertex();
785 if (!vtx) return false;
786 bool fromHad = false;
787 for ( const auto& parent : vtx->particles_in() ) {
788 if (!parent) continue;
789 // should this really go into parton-level territory?
790 // probably depends where BSM particles are being decayed
791 fromBSM |= isBSM(parent);
792 if (!isPhysical(parent)) return false;
793 fromTau |= isTau(parent);
794 if (isHadron(parent)&&!isBeam(parent)) {
795 if (!hadron) hadron = parent; // assumes linear hadron parentage
796 return true;
797 }
798 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
799 }
800 return fromHad;
801 }
802
805
806 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
807 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
808 decltype(thePart->end_vertex()) pVert(nullptr);
809 if (EndVert != nullptr) {
810 do {
811 bool samePart = false;
812 pVert = nullptr;
813 auto outgoing = EndVert->particles_out();
814 auto incoming = EndVert->particles_in();
815 for (const auto& itrDaug: outgoing) {
816 if (!itrDaug) continue;
817 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
818 // brem on generator level for tau
819 (outgoing.size() == 1 && incoming.size() == 1 &&
821 itrDaug->pdg_id() == thePart->pdg_id()) {
822 samePart = true;
823 pVert = itrDaug->end_vertex();
824 }
825 }
826 if (samePart) EndVert = pVert;
827 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
828 }
829 return EndVert;
830 }
831
833
834 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
835 if (!theVert) return {};
836 decltype(theVert->particles_out()) finalStatePart;
837 auto outgoing = theVert->particles_out();
838 for (const auto& thePart: outgoing) {
839 if (!thePart) continue;
840 finalStatePart.push_back(thePart);
841 if (isStable(thePart)) continue;
842 V pVert = findSimulatedEndVertex(thePart);
843 if (pVert == theVert) break; // to prevent Sherpa loop
844 if (pVert != nullptr) {
845 auto vecPart = findFinalStateParticles<V>(pVert);
846 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
847 }
848 }
849 return finalStatePart;
850 }
851#if !defined(XAOD_ANALYSIS)
852#include "AtlasHepMC/GenEvent.h"
853inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
854inline 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());} }
855
856#endif
857}
858#endif

◆ set_signal_process_id()

void MC::HepMC::set_signal_process_id ( GenEvent * e,
const int i = 0 )
inline

Definition at line 580 of file HepMCHelpers.h.

599{
600 namespace Pythia8
601 {
603 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
604
605 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
606
607 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
608 }
609
610#include "AtlasPID.h"
611
613 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
614
616 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
617
619 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
620
622 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
623
625 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
626
628 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
629
631 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
632
634 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
635
637 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
638
640 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
641
645 template <class T> inline bool isStableOrSimDecayed(const T& p) {
646 const auto vertex = p->end_vertex();
647 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
648 }
649
651 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
652
654 template <class T> inline bool isSpecialNonInteracting(const T& p) {
655 const int apid = std::abs(p->pdg_id());
656 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
657 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
658 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
659 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
660 return false;
661 }
662
664
665 template <class T> T findMother(T thePart) {
666 auto partOriVert = thePart->production_vertex();
667 if (!partOriVert) return nullptr;
668
669 long partPDG = thePart->pdg_id();
670 long MotherPDG(0);
671
672 auto MothOriVert = partOriVert;
673 MothOriVert = nullptr;
674 T theMoth(nullptr);
675
676 size_t itr = 0;
677 do {
678 if (itr != 0) partOriVert = MothOriVert;
679 for ( const auto& p : partOriVert->particles_in() ) {
680 theMoth = p;
681 if (!theMoth) continue;
682 MotherPDG = theMoth->pdg_id();
683 MothOriVert = theMoth->production_vertex();
684 if (MotherPDG == partPDG) break;
685 }
686 itr++;
687 if (itr > 100) {
688 break;
689 }
690 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
691 MothOriVert != partOriVert);
692 return theMoth;
693 }
694
696
697 template <class C, class T> T findMatching(C TruthContainer, T p) {
698 T ptrPart = nullptr;
699 if (!p) return ptrPart;
700 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
701 for (T truthParticle : *TruthContainer) {
702 if (HepMC::is_sim_descendant(p,truthParticle)) {
703 ptrPart = truthParticle;
704 break;
705 }
706 }
707 }
708 else {
709 for (T truthParticle : TruthContainer) {
710 if (HepMC::is_sim_descendant(p,truthParticle)) {
711 ptrPart = truthParticle;
712 break;
713 }
714 }
715 }
716 return ptrPart;
717 }
719
720 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
721 auto prodVtx = thePart->production_vertex();
722 if (!prodVtx) return;
723 for (const auto& theMother: prodVtx->particles_in()) {
724 if (!theMother) continue;
725 allancestors.insert(theMother);
726 findParticleAncestors(theMother, allancestors);
727 }
728 }
729
731
732 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
733 auto endVtx = thePart->end_vertex();
734 if (!endVtx) return;
735 for (const auto& theDaughter: endVtx->particles_out()) {
736 if (!theDaughter) continue;
737 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
738 allstabledescendants.insert(theDaughter);
739 }
740 findParticleStableDescendants(theDaughter, allstabledescendants);
741 }
742 }
743
747
748 template <class T> bool isHardScatteringVertex(T pVert) {
749 if (pVert == nullptr) return false;
750 T pV = pVert;
751 int numOfPartIn(0);
752 int pdg(0);
753
754 do {
755 pVert = pV;
756 auto incoming = pVert->particles_in();
757 numOfPartIn = incoming.size();
758 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
759 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
760
761 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
762
763 if (numOfPartIn == 2) {
764 auto incoming = pVert->particles_in();
765 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;
766 }
767 return false;
768}
769
773
774 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
775 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
776 auto vtx = p->production_vertex();
777 if (!vtx) return false;
778 bool fromHad = false;
779 for ( const auto& parent : vtx->particles_in() ) {
780 if (!parent) continue;
781 // should this really go into parton-level territory?
782 // probably depends where BSM particles are being decayed
783 fromBSM |= isBSM(parent);
784 if (!isPhysical(parent)) return false;
785 fromTau |= isTau(parent);
786 if (isHadron(parent)&&!isBeam(parent)) {
787 if (!hadron) hadron = parent; // assumes linear hadron parentage
788 return true;
789 }
790 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
791 }
792 return fromHad;
793 }
794
797
798 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
799 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
800 decltype(thePart->end_vertex()) pVert(nullptr);
801 if (EndVert != nullptr) {
802 do {
803 bool samePart = false;
804 pVert = nullptr;
805 auto outgoing = EndVert->particles_out();
806 auto incoming = EndVert->particles_in();
807 for (const auto& itrDaug: outgoing) {
808 if (!itrDaug) continue;
809 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
810 // brem on generator level for tau
811 (outgoing.size() == 1 && incoming.size() == 1 &&
813 itrDaug->pdg_id() == thePart->pdg_id()) {
814 samePart = true;
815 pVert = itrDaug->end_vertex();
816 }
817 }
818 if (samePart) EndVert = pVert;
819 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
820 }
821 return EndVert;
822 }
823
825
826 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
827 if (!theVert) return {};
828 decltype(theVert->particles_out()) finalStatePart;
829 auto outgoing = theVert->particles_out();
830 for (const auto& thePart: outgoing) {
831 if (!thePart) continue;
832 finalStatePart.push_back(thePart);
833 if (isStable(thePart)) continue;
834 V pVert = findSimulatedEndVertex(thePart);
835 if (pVert == theVert) break; // to prevent Sherpa loop
836 if (pVert != nullptr) {
837 auto vecPart = findFinalStateParticles<V>(pVert);
838 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
839 }
840 }
841 return finalStatePart;
842 }
843#if !defined(XAOD_ANALYSIS)
844#include "AtlasHepMC/GenEvent.h"
845inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
846inline 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());} }
847
848#endif
849}
850#endif

◆ set_signal_process_vertex()

template<class T>
void MC::HepMC::set_signal_process_vertex ( GenEvent * e,
T & v )

Definition at line 591 of file HepMCHelpers.h.

610{
611 namespace Pythia8
612 {
614 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
615
616 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
617
618 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
619 }
620
621#include "AtlasPID.h"
622
624 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
625
627 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
628
630 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
631
633 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
634
636 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
637
639 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
640
642 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
643
645 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
646
648 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
649
651 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
652
656 template <class T> inline bool isStableOrSimDecayed(const T& p) {
657 const auto vertex = p->end_vertex();
658 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
659 }
660
662 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
663
665 template <class T> inline bool isSpecialNonInteracting(const T& p) {
666 const int apid = std::abs(p->pdg_id());
667 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
668 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
669 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
670 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
671 return false;
672 }
673
675
676 template <class T> T findMother(T thePart) {
677 auto partOriVert = thePart->production_vertex();
678 if (!partOriVert) return nullptr;
679
680 long partPDG = thePart->pdg_id();
681 long MotherPDG(0);
682
683 auto MothOriVert = partOriVert;
684 MothOriVert = nullptr;
685 T theMoth(nullptr);
686
687 size_t itr = 0;
688 do {
689 if (itr != 0) partOriVert = MothOriVert;
690 for ( const auto& p : partOriVert->particles_in() ) {
691 theMoth = p;
692 if (!theMoth) continue;
693 MotherPDG = theMoth->pdg_id();
694 MothOriVert = theMoth->production_vertex();
695 if (MotherPDG == partPDG) break;
696 }
697 itr++;
698 if (itr > 100) {
699 break;
700 }
701 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
702 MothOriVert != partOriVert);
703 return theMoth;
704 }
705
707
708 template <class C, class T> T findMatching(C TruthContainer, T p) {
709 T ptrPart = nullptr;
710 if (!p) return ptrPart;
711 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
712 for (T truthParticle : *TruthContainer) {
713 if (HepMC::is_sim_descendant(p,truthParticle)) {
714 ptrPart = truthParticle;
715 break;
716 }
717 }
718 }
719 else {
720 for (T truthParticle : TruthContainer) {
721 if (HepMC::is_sim_descendant(p,truthParticle)) {
722 ptrPart = truthParticle;
723 break;
724 }
725 }
726 }
727 return ptrPart;
728 }
730
731 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
732 auto prodVtx = thePart->production_vertex();
733 if (!prodVtx) return;
734 for (const auto& theMother: prodVtx->particles_in()) {
735 if (!theMother) continue;
736 allancestors.insert(theMother);
737 findParticleAncestors(theMother, allancestors);
738 }
739 }
740
742
743 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
744 auto endVtx = thePart->end_vertex();
745 if (!endVtx) return;
746 for (const auto& theDaughter: endVtx->particles_out()) {
747 if (!theDaughter) continue;
748 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
749 allstabledescendants.insert(theDaughter);
750 }
751 findParticleStableDescendants(theDaughter, allstabledescendants);
752 }
753 }
754
758
759 template <class T> bool isHardScatteringVertex(T pVert) {
760 if (pVert == nullptr) return false;
761 T pV = pVert;
762 int numOfPartIn(0);
763 int pdg(0);
764
765 do {
766 pVert = pV;
767 auto incoming = pVert->particles_in();
768 numOfPartIn = incoming.size();
769 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
770 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
771
772 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
773
774 if (numOfPartIn == 2) {
775 auto incoming = pVert->particles_in();
776 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;
777 }
778 return false;
779}
780
784
785 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
786 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
787 auto vtx = p->production_vertex();
788 if (!vtx) return false;
789 bool fromHad = false;
790 for ( const auto& parent : vtx->particles_in() ) {
791 if (!parent) continue;
792 // should this really go into parton-level territory?
793 // probably depends where BSM particles are being decayed
794 fromBSM |= isBSM(parent);
795 if (!isPhysical(parent)) return false;
796 fromTau |= isTau(parent);
797 if (isHadron(parent)&&!isBeam(parent)) {
798 if (!hadron) hadron = parent; // assumes linear hadron parentage
799 return true;
800 }
801 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
802 }
803 return fromHad;
804 }
805
808
809 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
810 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
811 decltype(thePart->end_vertex()) pVert(nullptr);
812 if (EndVert != nullptr) {
813 do {
814 bool samePart = false;
815 pVert = nullptr;
816 auto outgoing = EndVert->particles_out();
817 auto incoming = EndVert->particles_in();
818 for (const auto& itrDaug: outgoing) {
819 if (!itrDaug) continue;
820 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
821 // brem on generator level for tau
822 (outgoing.size() == 1 && incoming.size() == 1 &&
824 itrDaug->pdg_id() == thePart->pdg_id()) {
825 samePart = true;
826 pVert = itrDaug->end_vertex();
827 }
828 }
829 if (samePart) EndVert = pVert;
830 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
831 }
832 return EndVert;
833 }
834
836
837 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
838 if (!theVert) return {};
839 decltype(theVert->particles_out()) finalStatePart;
840 auto outgoing = theVert->particles_out();
841 for (const auto& thePart: outgoing) {
842 if (!thePart) continue;
843 finalStatePart.push_back(thePart);
844 if (isStable(thePart)) continue;
845 V pVert = findSimulatedEndVertex(thePart);
846 if (pVert == theVert) break; // to prevent Sherpa loop
847 if (pVert != nullptr) {
848 auto vecPart = findFinalStateParticles<V>(pVert);
849 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
850 }
851 }
852 return finalStatePart;
853 }
854#if !defined(XAOD_ANALYSIS)
855#include "AtlasHepMC/GenEvent.h"
856inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
857inline 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());} }
858
859#endif
860}
861#endif

◆ signal_process_id() [1/2]

int MC::HepMC::signal_process_id ( const GenEvent & evt)
inline

Definition at line 572 of file HepMCHelpers.h.

591{
592 namespace Pythia8
593 {
595 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
596
597 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
598
599 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
600 }
601
602#include "AtlasPID.h"
603
605 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
606
608 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
609
611 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
612
614 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
615
617 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
618
620 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
621
623 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
624
626 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
627
629 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
630
632 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
633
637 template <class T> inline bool isStableOrSimDecayed(const T& p) {
638 const auto vertex = p->end_vertex();
639 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
640 }
641
643 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
644
646 template <class T> inline bool isSpecialNonInteracting(const T& p) {
647 const int apid = std::abs(p->pdg_id());
648 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
649 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
650 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
651 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
652 return false;
653 }
654
656
657 template <class T> T findMother(T thePart) {
658 auto partOriVert = thePart->production_vertex();
659 if (!partOriVert) return nullptr;
660
661 long partPDG = thePart->pdg_id();
662 long MotherPDG(0);
663
664 auto MothOriVert = partOriVert;
665 MothOriVert = nullptr;
666 T theMoth(nullptr);
667
668 size_t itr = 0;
669 do {
670 if (itr != 0) partOriVert = MothOriVert;
671 for ( const auto& p : partOriVert->particles_in() ) {
672 theMoth = p;
673 if (!theMoth) continue;
674 MotherPDG = theMoth->pdg_id();
675 MothOriVert = theMoth->production_vertex();
676 if (MotherPDG == partPDG) break;
677 }
678 itr++;
679 if (itr > 100) {
680 break;
681 }
682 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
683 MothOriVert != partOriVert);
684 return theMoth;
685 }
686
688
689 template <class C, class T> T findMatching(C TruthContainer, T p) {
690 T ptrPart = nullptr;
691 if (!p) return ptrPart;
692 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
693 for (T truthParticle : *TruthContainer) {
694 if (HepMC::is_sim_descendant(p,truthParticle)) {
695 ptrPart = truthParticle;
696 break;
697 }
698 }
699 }
700 else {
701 for (T truthParticle : TruthContainer) {
702 if (HepMC::is_sim_descendant(p,truthParticle)) {
703 ptrPart = truthParticle;
704 break;
705 }
706 }
707 }
708 return ptrPart;
709 }
711
712 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
713 auto prodVtx = thePart->production_vertex();
714 if (!prodVtx) return;
715 for (const auto& theMother: prodVtx->particles_in()) {
716 if (!theMother) continue;
717 allancestors.insert(theMother);
718 findParticleAncestors(theMother, allancestors);
719 }
720 }
721
723
724 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
725 auto endVtx = thePart->end_vertex();
726 if (!endVtx) return;
727 for (const auto& theDaughter: endVtx->particles_out()) {
728 if (!theDaughter) continue;
729 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
730 allstabledescendants.insert(theDaughter);
731 }
732 findParticleStableDescendants(theDaughter, allstabledescendants);
733 }
734 }
735
739
740 template <class T> bool isHardScatteringVertex(T pVert) {
741 if (pVert == nullptr) return false;
742 T pV = pVert;
743 int numOfPartIn(0);
744 int pdg(0);
745
746 do {
747 pVert = pV;
748 auto incoming = pVert->particles_in();
749 numOfPartIn = incoming.size();
750 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
751 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
752
753 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
754
755 if (numOfPartIn == 2) {
756 auto incoming = pVert->particles_in();
757 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;
758 }
759 return false;
760}
761
765
766 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
767 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
768 auto vtx = p->production_vertex();
769 if (!vtx) return false;
770 bool fromHad = false;
771 for ( const auto& parent : vtx->particles_in() ) {
772 if (!parent) continue;
773 // should this really go into parton-level territory?
774 // probably depends where BSM particles are being decayed
775 fromBSM |= isBSM(parent);
776 if (!isPhysical(parent)) return false;
777 fromTau |= isTau(parent);
778 if (isHadron(parent)&&!isBeam(parent)) {
779 if (!hadron) hadron = parent; // assumes linear hadron parentage
780 return true;
781 }
782 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
783 }
784 return fromHad;
785 }
786
789
790 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
791 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
792 decltype(thePart->end_vertex()) pVert(nullptr);
793 if (EndVert != nullptr) {
794 do {
795 bool samePart = false;
796 pVert = nullptr;
797 auto outgoing = EndVert->particles_out();
798 auto incoming = EndVert->particles_in();
799 for (const auto& itrDaug: outgoing) {
800 if (!itrDaug) continue;
801 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
802 // brem on generator level for tau
803 (outgoing.size() == 1 && incoming.size() == 1 &&
805 itrDaug->pdg_id() == thePart->pdg_id()) {
806 samePart = true;
807 pVert = itrDaug->end_vertex();
808 }
809 }
810 if (samePart) EndVert = pVert;
811 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
812 }
813 return EndVert;
814 }
815
817
818 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
819 if (!theVert) return {};
820 decltype(theVert->particles_out()) finalStatePart;
821 auto outgoing = theVert->particles_out();
822 for (const auto& thePart: outgoing) {
823 if (!thePart) continue;
824 finalStatePart.push_back(thePart);
825 if (isStable(thePart)) continue;
826 V pVert = findSimulatedEndVertex(thePart);
827 if (pVert == theVert) break; // to prevent Sherpa loop
828 if (pVert != nullptr) {
829 auto vecPart = findFinalStateParticles<V>(pVert);
830 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
831 }
832 }
833 return finalStatePart;
834 }
835#if !defined(XAOD_ANALYSIS)
836#include "AtlasHepMC/GenEvent.h"
837inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
838inline 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());} }
839
840#endif
841}
842#endif

◆ signal_process_id() [2/2]

int MC::HepMC::signal_process_id ( const GenEvent * evt)
inline

Definition at line 576 of file HepMCHelpers.h.

595{
596 namespace Pythia8
597 {
599 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
600
601 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
602
603 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
604 }
605
606#include "AtlasPID.h"
607
609 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
610
612 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
613
615 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
616
618 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
619
621 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
622
624 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
625
627 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
628
630 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
631
633 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
634
636 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
637
641 template <class T> inline bool isStableOrSimDecayed(const T& p) {
642 const auto vertex = p->end_vertex();
643 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
644 }
645
647 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
648
650 template <class T> inline bool isSpecialNonInteracting(const T& p) {
651 const int apid = std::abs(p->pdg_id());
652 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
653 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
654 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
655 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
656 return false;
657 }
658
660
661 template <class T> T findMother(T thePart) {
662 auto partOriVert = thePart->production_vertex();
663 if (!partOriVert) return nullptr;
664
665 long partPDG = thePart->pdg_id();
666 long MotherPDG(0);
667
668 auto MothOriVert = partOriVert;
669 MothOriVert = nullptr;
670 T theMoth(nullptr);
671
672 size_t itr = 0;
673 do {
674 if (itr != 0) partOriVert = MothOriVert;
675 for ( const auto& p : partOriVert->particles_in() ) {
676 theMoth = p;
677 if (!theMoth) continue;
678 MotherPDG = theMoth->pdg_id();
679 MothOriVert = theMoth->production_vertex();
680 if (MotherPDG == partPDG) break;
681 }
682 itr++;
683 if (itr > 100) {
684 break;
685 }
686 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
687 MothOriVert != partOriVert);
688 return theMoth;
689 }
690
692
693 template <class C, class T> T findMatching(C TruthContainer, T p) {
694 T ptrPart = nullptr;
695 if (!p) return ptrPart;
696 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
697 for (T truthParticle : *TruthContainer) {
698 if (HepMC::is_sim_descendant(p,truthParticle)) {
699 ptrPart = truthParticle;
700 break;
701 }
702 }
703 }
704 else {
705 for (T truthParticle : TruthContainer) {
706 if (HepMC::is_sim_descendant(p,truthParticle)) {
707 ptrPart = truthParticle;
708 break;
709 }
710 }
711 }
712 return ptrPart;
713 }
715
716 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
717 auto prodVtx = thePart->production_vertex();
718 if (!prodVtx) return;
719 for (const auto& theMother: prodVtx->particles_in()) {
720 if (!theMother) continue;
721 allancestors.insert(theMother);
722 findParticleAncestors(theMother, allancestors);
723 }
724 }
725
727
728 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
729 auto endVtx = thePart->end_vertex();
730 if (!endVtx) return;
731 for (const auto& theDaughter: endVtx->particles_out()) {
732 if (!theDaughter) continue;
733 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
734 allstabledescendants.insert(theDaughter);
735 }
736 findParticleStableDescendants(theDaughter, allstabledescendants);
737 }
738 }
739
743
744 template <class T> bool isHardScatteringVertex(T pVert) {
745 if (pVert == nullptr) return false;
746 T pV = pVert;
747 int numOfPartIn(0);
748 int pdg(0);
749
750 do {
751 pVert = pV;
752 auto incoming = pVert->particles_in();
753 numOfPartIn = incoming.size();
754 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
755 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
756
757 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
758
759 if (numOfPartIn == 2) {
760 auto incoming = pVert->particles_in();
761 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;
762 }
763 return false;
764}
765
769
770 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
771 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
772 auto vtx = p->production_vertex();
773 if (!vtx) return false;
774 bool fromHad = false;
775 for ( const auto& parent : vtx->particles_in() ) {
776 if (!parent) continue;
777 // should this really go into parton-level territory?
778 // probably depends where BSM particles are being decayed
779 fromBSM |= isBSM(parent);
780 if (!isPhysical(parent)) return false;
781 fromTau |= isTau(parent);
782 if (isHadron(parent)&&!isBeam(parent)) {
783 if (!hadron) hadron = parent; // assumes linear hadron parentage
784 return true;
785 }
786 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
787 }
788 return fromHad;
789 }
790
793
794 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
795 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
796 decltype(thePart->end_vertex()) pVert(nullptr);
797 if (EndVert != nullptr) {
798 do {
799 bool samePart = false;
800 pVert = nullptr;
801 auto outgoing = EndVert->particles_out();
802 auto incoming = EndVert->particles_in();
803 for (const auto& itrDaug: outgoing) {
804 if (!itrDaug) continue;
805 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
806 // brem on generator level for tau
807 (outgoing.size() == 1 && incoming.size() == 1 &&
809 itrDaug->pdg_id() == thePart->pdg_id()) {
810 samePart = true;
811 pVert = itrDaug->end_vertex();
812 }
813 }
814 if (samePart) EndVert = pVert;
815 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
816 }
817 return EndVert;
818 }
819
821
822 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
823 if (!theVert) return {};
824 decltype(theVert->particles_out()) finalStatePart;
825 auto outgoing = theVert->particles_out();
826 for (const auto& thePart: outgoing) {
827 if (!thePart) continue;
828 finalStatePart.push_back(thePart);
829 if (isStable(thePart)) continue;
830 V pVert = findSimulatedEndVertex(thePart);
831 if (pVert == theVert) break; // to prevent Sherpa loop
832 if (pVert != nullptr) {
833 auto vecPart = findFinalStateParticles<V>(pVert);
834 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
835 }
836 }
837 return finalStatePart;
838 }
839#if !defined(XAOD_ANALYSIS)
840#include "AtlasHepMC/GenEvent.h"
841inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
842inline 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());} }
843
844#endif
845}
846#endif

◆ signal_process_vertex() [1/2]

ConstGenVertexPtr MC::HepMC::signal_process_vertex ( const GenEvent * e)
inline

Definition at line 597 of file HepMCHelpers.h.

616{
617 namespace Pythia8
618 {
620 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
621
622 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
623
624 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
625 }
626
627#include "AtlasPID.h"
628
630 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
631
633 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
634
636 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
637
639 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
640
642 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
643
645 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
646
648 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
649
651 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
652
654 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
655
657 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
658
662 template <class T> inline bool isStableOrSimDecayed(const T& p) {
663 const auto vertex = p->end_vertex();
664 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
665 }
666
668 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
669
671 template <class T> inline bool isSpecialNonInteracting(const T& p) {
672 const int apid = std::abs(p->pdg_id());
673 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
674 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
675 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
676 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
677 return false;
678 }
679
681
682 template <class T> T findMother(T thePart) {
683 auto partOriVert = thePart->production_vertex();
684 if (!partOriVert) return nullptr;
685
686 long partPDG = thePart->pdg_id();
687 long MotherPDG(0);
688
689 auto MothOriVert = partOriVert;
690 MothOriVert = nullptr;
691 T theMoth(nullptr);
692
693 size_t itr = 0;
694 do {
695 if (itr != 0) partOriVert = MothOriVert;
696 for ( const auto& p : partOriVert->particles_in() ) {
697 theMoth = p;
698 if (!theMoth) continue;
699 MotherPDG = theMoth->pdg_id();
700 MothOriVert = theMoth->production_vertex();
701 if (MotherPDG == partPDG) break;
702 }
703 itr++;
704 if (itr > 100) {
705 break;
706 }
707 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
708 MothOriVert != partOriVert);
709 return theMoth;
710 }
711
713
714 template <class C, class T> T findMatching(C TruthContainer, T p) {
715 T ptrPart = nullptr;
716 if (!p) return ptrPart;
717 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
718 for (T truthParticle : *TruthContainer) {
719 if (HepMC::is_sim_descendant(p,truthParticle)) {
720 ptrPart = truthParticle;
721 break;
722 }
723 }
724 }
725 else {
726 for (T truthParticle : TruthContainer) {
727 if (HepMC::is_sim_descendant(p,truthParticle)) {
728 ptrPart = truthParticle;
729 break;
730 }
731 }
732 }
733 return ptrPart;
734 }
736
737 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
738 auto prodVtx = thePart->production_vertex();
739 if (!prodVtx) return;
740 for (const auto& theMother: prodVtx->particles_in()) {
741 if (!theMother) continue;
742 allancestors.insert(theMother);
743 findParticleAncestors(theMother, allancestors);
744 }
745 }
746
748
749 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
750 auto endVtx = thePart->end_vertex();
751 if (!endVtx) return;
752 for (const auto& theDaughter: endVtx->particles_out()) {
753 if (!theDaughter) continue;
754 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
755 allstabledescendants.insert(theDaughter);
756 }
757 findParticleStableDescendants(theDaughter, allstabledescendants);
758 }
759 }
760
764
765 template <class T> bool isHardScatteringVertex(T pVert) {
766 if (pVert == nullptr) return false;
767 T pV = pVert;
768 int numOfPartIn(0);
769 int pdg(0);
770
771 do {
772 pVert = pV;
773 auto incoming = pVert->particles_in();
774 numOfPartIn = incoming.size();
775 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
776 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
777
778 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
779
780 if (numOfPartIn == 2) {
781 auto incoming = pVert->particles_in();
782 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;
783 }
784 return false;
785}
786
790
791 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
792 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
793 auto vtx = p->production_vertex();
794 if (!vtx) return false;
795 bool fromHad = false;
796 for ( const auto& parent : vtx->particles_in() ) {
797 if (!parent) continue;
798 // should this really go into parton-level territory?
799 // probably depends where BSM particles are being decayed
800 fromBSM |= isBSM(parent);
801 if (!isPhysical(parent)) return false;
802 fromTau |= isTau(parent);
803 if (isHadron(parent)&&!isBeam(parent)) {
804 if (!hadron) hadron = parent; // assumes linear hadron parentage
805 return true;
806 }
807 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
808 }
809 return fromHad;
810 }
811
814
815 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
816 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
817 decltype(thePart->end_vertex()) pVert(nullptr);
818 if (EndVert != nullptr) {
819 do {
820 bool samePart = false;
821 pVert = nullptr;
822 auto outgoing = EndVert->particles_out();
823 auto incoming = EndVert->particles_in();
824 for (const auto& itrDaug: outgoing) {
825 if (!itrDaug) continue;
826 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
827 // brem on generator level for tau
828 (outgoing.size() == 1 && incoming.size() == 1 &&
830 itrDaug->pdg_id() == thePart->pdg_id()) {
831 samePart = true;
832 pVert = itrDaug->end_vertex();
833 }
834 }
835 if (samePart) EndVert = pVert;
836 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
837 }
838 return EndVert;
839 }
840
842
843 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
844 if (!theVert) return {};
845 decltype(theVert->particles_out()) finalStatePart;
846 auto outgoing = theVert->particles_out();
847 for (const auto& thePart: outgoing) {
848 if (!thePart) continue;
849 finalStatePart.push_back(thePart);
850 if (isStable(thePart)) continue;
851 V pVert = findSimulatedEndVertex(thePart);
852 if (pVert == theVert) break; // to prevent Sherpa loop
853 if (pVert != nullptr) {
854 auto vecPart = findFinalStateParticles<V>(pVert);
855 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
856 }
857 }
858 return finalStatePart;
859 }
860#if !defined(XAOD_ANALYSIS)
861#include "AtlasHepMC/GenEvent.h"
862inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
863inline 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());} }
864
865#endif
866}
867#endif

◆ signal_process_vertex() [2/2]

GenVertexPtr MC::HepMC::signal_process_vertex ( GenEvent * e)
inline

Definition at line 598 of file HepMCHelpers.h.

617{
618 namespace Pythia8
619 {
621 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
622
623 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
624
625 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
626 }
627
628#include "AtlasPID.h"
629
631 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
632
634 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
635
637 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
638
640 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
641
643 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
644
646 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
647
649 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
650
652 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
653
655 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
656
658 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
659
663 template <class T> inline bool isStableOrSimDecayed(const T& p) {
664 const auto vertex = p->end_vertex();
665 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
666 }
667
669 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
670
672 template <class T> inline bool isSpecialNonInteracting(const T& p) {
673 const int apid = std::abs(p->pdg_id());
674 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
675 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
676 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
677 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
678 return false;
679 }
680
682
683 template <class T> T findMother(T thePart) {
684 auto partOriVert = thePart->production_vertex();
685 if (!partOriVert) return nullptr;
686
687 long partPDG = thePart->pdg_id();
688 long MotherPDG(0);
689
690 auto MothOriVert = partOriVert;
691 MothOriVert = nullptr;
692 T theMoth(nullptr);
693
694 size_t itr = 0;
695 do {
696 if (itr != 0) partOriVert = MothOriVert;
697 for ( const auto& p : partOriVert->particles_in() ) {
698 theMoth = p;
699 if (!theMoth) continue;
700 MotherPDG = theMoth->pdg_id();
701 MothOriVert = theMoth->production_vertex();
702 if (MotherPDG == partPDG) break;
703 }
704 itr++;
705 if (itr > 100) {
706 break;
707 }
708 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
709 MothOriVert != partOriVert);
710 return theMoth;
711 }
712
714
715 template <class C, class T> T findMatching(C TruthContainer, T p) {
716 T ptrPart = nullptr;
717 if (!p) return ptrPart;
718 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
719 for (T truthParticle : *TruthContainer) {
720 if (HepMC::is_sim_descendant(p,truthParticle)) {
721 ptrPart = truthParticle;
722 break;
723 }
724 }
725 }
726 else {
727 for (T truthParticle : TruthContainer) {
728 if (HepMC::is_sim_descendant(p,truthParticle)) {
729 ptrPart = truthParticle;
730 break;
731 }
732 }
733 }
734 return ptrPart;
735 }
737
738 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
739 auto prodVtx = thePart->production_vertex();
740 if (!prodVtx) return;
741 for (const auto& theMother: prodVtx->particles_in()) {
742 if (!theMother) continue;
743 allancestors.insert(theMother);
744 findParticleAncestors(theMother, allancestors);
745 }
746 }
747
749
750 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
751 auto endVtx = thePart->end_vertex();
752 if (!endVtx) return;
753 for (const auto& theDaughter: endVtx->particles_out()) {
754 if (!theDaughter) continue;
755 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
756 allstabledescendants.insert(theDaughter);
757 }
758 findParticleStableDescendants(theDaughter, allstabledescendants);
759 }
760 }
761
765
766 template <class T> bool isHardScatteringVertex(T pVert) {
767 if (pVert == nullptr) return false;
768 T pV = pVert;
769 int numOfPartIn(0);
770 int pdg(0);
771
772 do {
773 pVert = pV;
774 auto incoming = pVert->particles_in();
775 numOfPartIn = incoming.size();
776 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
777 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
778
779 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
780
781 if (numOfPartIn == 2) {
782 auto incoming = pVert->particles_in();
783 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;
784 }
785 return false;
786}
787
791
792 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
793 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
794 auto vtx = p->production_vertex();
795 if (!vtx) return false;
796 bool fromHad = false;
797 for ( const auto& parent : vtx->particles_in() ) {
798 if (!parent) continue;
799 // should this really go into parton-level territory?
800 // probably depends where BSM particles are being decayed
801 fromBSM |= isBSM(parent);
802 if (!isPhysical(parent)) return false;
803 fromTau |= isTau(parent);
804 if (isHadron(parent)&&!isBeam(parent)) {
805 if (!hadron) hadron = parent; // assumes linear hadron parentage
806 return true;
807 }
808 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
809 }
810 return fromHad;
811 }
812
815
816 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
817 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
818 decltype(thePart->end_vertex()) pVert(nullptr);
819 if (EndVert != nullptr) {
820 do {
821 bool samePart = false;
822 pVert = nullptr;
823 auto outgoing = EndVert->particles_out();
824 auto incoming = EndVert->particles_in();
825 for (const auto& itrDaug: outgoing) {
826 if (!itrDaug) continue;
827 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
828 // brem on generator level for tau
829 (outgoing.size() == 1 && incoming.size() == 1 &&
831 itrDaug->pdg_id() == thePart->pdg_id()) {
832 samePart = true;
833 pVert = itrDaug->end_vertex();
834 }
835 }
836 if (samePart) EndVert = pVert;
837 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
838 }
839 return EndVert;
840 }
841
843
844 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
845 if (!theVert) return {};
846 decltype(theVert->particles_out()) finalStatePart;
847 auto outgoing = theVert->particles_out();
848 for (const auto& thePart: outgoing) {
849 if (!thePart) continue;
850 finalStatePart.push_back(thePart);
851 if (isStable(thePart)) continue;
852 V pVert = findSimulatedEndVertex(thePart);
853 if (pVert == theVert) break; // to prevent Sherpa loop
854 if (pVert != nullptr) {
855 auto vecPart = findFinalStateParticles<V>(pVert);
856 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
857 }
858 }
859 return finalStatePart;
860 }
861#if !defined(XAOD_ANALYSIS)
862#include "AtlasHepMC/GenEvent.h"
863inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
864inline 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());} }
865
866#endif
867}
868#endif

◆ suggest_barcode()

template<class T>
bool MC::HepMC::suggest_barcode ( T & p,
int i )

Definition at line 607 of file HepMCHelpers.h.

626{
627 namespace Pythia8
628 {
630 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
631
632 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
633
634 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
635 }
636
637#include "AtlasPID.h"
638
640 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
641
643 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
644
646 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
647
649 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
650
652 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
653
655 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
656
658 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
659
661 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
662
664 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
665
667 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
668
672 template <class T> inline bool isStableOrSimDecayed(const T& p) {
673 const auto vertex = p->end_vertex();
674 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
675 }
676
678 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
679
681 template <class T> inline bool isSpecialNonInteracting(const T& p) {
682 const int apid = std::abs(p->pdg_id());
683 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
684 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
685 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
686 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
687 return false;
688 }
689
691
692 template <class T> T findMother(T thePart) {
693 auto partOriVert = thePart->production_vertex();
694 if (!partOriVert) return nullptr;
695
696 long partPDG = thePart->pdg_id();
697 long MotherPDG(0);
698
699 auto MothOriVert = partOriVert;
700 MothOriVert = nullptr;
701 T theMoth(nullptr);
702
703 size_t itr = 0;
704 do {
705 if (itr != 0) partOriVert = MothOriVert;
706 for ( const auto& p : partOriVert->particles_in() ) {
707 theMoth = p;
708 if (!theMoth) continue;
709 MotherPDG = theMoth->pdg_id();
710 MothOriVert = theMoth->production_vertex();
711 if (MotherPDG == partPDG) break;
712 }
713 itr++;
714 if (itr > 100) {
715 break;
716 }
717 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
718 MothOriVert != partOriVert);
719 return theMoth;
720 }
721
723
724 template <class C, class T> T findMatching(C TruthContainer, T p) {
725 T ptrPart = nullptr;
726 if (!p) return ptrPart;
727 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
728 for (T truthParticle : *TruthContainer) {
729 if (HepMC::is_sim_descendant(p,truthParticle)) {
730 ptrPart = truthParticle;
731 break;
732 }
733 }
734 }
735 else {
736 for (T truthParticle : TruthContainer) {
737 if (HepMC::is_sim_descendant(p,truthParticle)) {
738 ptrPart = truthParticle;
739 break;
740 }
741 }
742 }
743 return ptrPart;
744 }
746
747 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
748 auto prodVtx = thePart->production_vertex();
749 if (!prodVtx) return;
750 for (const auto& theMother: prodVtx->particles_in()) {
751 if (!theMother) continue;
752 allancestors.insert(theMother);
753 findParticleAncestors(theMother, allancestors);
754 }
755 }
756
758
759 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
760 auto endVtx = thePart->end_vertex();
761 if (!endVtx) return;
762 for (const auto& theDaughter: endVtx->particles_out()) {
763 if (!theDaughter) continue;
764 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
765 allstabledescendants.insert(theDaughter);
766 }
767 findParticleStableDescendants(theDaughter, allstabledescendants);
768 }
769 }
770
774
775 template <class T> bool isHardScatteringVertex(T pVert) {
776 if (pVert == nullptr) return false;
777 T pV = pVert;
778 int numOfPartIn(0);
779 int pdg(0);
780
781 do {
782 pVert = pV;
783 auto incoming = pVert->particles_in();
784 numOfPartIn = incoming.size();
785 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
786 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
787
788 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
789
790 if (numOfPartIn == 2) {
791 auto incoming = pVert->particles_in();
792 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;
793 }
794 return false;
795}
796
800
801 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
802 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
803 auto vtx = p->production_vertex();
804 if (!vtx) return false;
805 bool fromHad = false;
806 for ( const auto& parent : vtx->particles_in() ) {
807 if (!parent) continue;
808 // should this really go into parton-level territory?
809 // probably depends where BSM particles are being decayed
810 fromBSM |= isBSM(parent);
811 if (!isPhysical(parent)) return false;
812 fromTau |= isTau(parent);
813 if (isHadron(parent)&&!isBeam(parent)) {
814 if (!hadron) hadron = parent; // assumes linear hadron parentage
815 return true;
816 }
817 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
818 }
819 return fromHad;
820 }
821
824
825 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
826 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
827 decltype(thePart->end_vertex()) pVert(nullptr);
828 if (EndVert != nullptr) {
829 do {
830 bool samePart = false;
831 pVert = nullptr;
832 auto outgoing = EndVert->particles_out();
833 auto incoming = EndVert->particles_in();
834 for (const auto& itrDaug: outgoing) {
835 if (!itrDaug) continue;
836 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
837 // brem on generator level for tau
838 (outgoing.size() == 1 && incoming.size() == 1 &&
840 itrDaug->pdg_id() == thePart->pdg_id()) {
841 samePart = true;
842 pVert = itrDaug->end_vertex();
843 }
844 }
845 if (samePart) EndVert = pVert;
846 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
847 }
848 return EndVert;
849 }
850
852
853 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
854 if (!theVert) return {};
855 decltype(theVert->particles_out()) finalStatePart;
856 auto outgoing = theVert->particles_out();
857 for (const auto& thePart: outgoing) {
858 if (!thePart) continue;
859 finalStatePart.push_back(thePart);
860 if (isStable(thePart)) continue;
861 V pVert = findSimulatedEndVertex(thePart);
862 if (pVert == theVert) break; // to prevent Sherpa loop
863 if (pVert != nullptr) {
864 auto vecPart = findFinalStateParticles<V>(pVert);
865 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
866 }
867 }
868 return finalStatePart;
869 }
870#if !defined(XAOD_ANALYSIS)
871#include "AtlasHepMC/GenEvent.h"
872inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
873inline 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());} }
874
875#endif
876}
877#endif

◆ valid_beam_particles()

bool MC::HepMC::valid_beam_particles ( const GenEvent * e)
inline

Definition at line 599 of file HepMCHelpers.h.

618{
619 namespace Pythia8
620 {
622 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
623
624 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
625
626 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
627 }
628
629#include "AtlasPID.h"
630
632 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
633
635 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
636
638 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
639
641 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
642
644 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
645
647 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
648
650 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
651
653 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
654
656 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
657
659 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
660
664 template <class T> inline bool isStableOrSimDecayed(const T& p) {
665 const auto vertex = p->end_vertex();
666 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
667 }
668
670 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
671
673 template <class T> inline bool isSpecialNonInteracting(const T& p) {
674 const int apid = std::abs(p->pdg_id());
675 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
676 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
677 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
678 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
679 return false;
680 }
681
683
684 template <class T> T findMother(T thePart) {
685 auto partOriVert = thePart->production_vertex();
686 if (!partOriVert) return nullptr;
687
688 long partPDG = thePart->pdg_id();
689 long MotherPDG(0);
690
691 auto MothOriVert = partOriVert;
692 MothOriVert = nullptr;
693 T theMoth(nullptr);
694
695 size_t itr = 0;
696 do {
697 if (itr != 0) partOriVert = MothOriVert;
698 for ( const auto& p : partOriVert->particles_in() ) {
699 theMoth = p;
700 if (!theMoth) continue;
701 MotherPDG = theMoth->pdg_id();
702 MothOriVert = theMoth->production_vertex();
703 if (MotherPDG == partPDG) break;
704 }
705 itr++;
706 if (itr > 100) {
707 break;
708 }
709 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
710 MothOriVert != partOriVert);
711 return theMoth;
712 }
713
715
716 template <class C, class T> T findMatching(C TruthContainer, T p) {
717 T ptrPart = nullptr;
718 if (!p) return ptrPart;
719 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
720 for (T truthParticle : *TruthContainer) {
721 if (HepMC::is_sim_descendant(p,truthParticle)) {
722 ptrPart = truthParticle;
723 break;
724 }
725 }
726 }
727 else {
728 for (T truthParticle : TruthContainer) {
729 if (HepMC::is_sim_descendant(p,truthParticle)) {
730 ptrPart = truthParticle;
731 break;
732 }
733 }
734 }
735 return ptrPart;
736 }
738
739 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
740 auto prodVtx = thePart->production_vertex();
741 if (!prodVtx) return;
742 for (const auto& theMother: prodVtx->particles_in()) {
743 if (!theMother) continue;
744 allancestors.insert(theMother);
745 findParticleAncestors(theMother, allancestors);
746 }
747 }
748
750
751 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
752 auto endVtx = thePart->end_vertex();
753 if (!endVtx) return;
754 for (const auto& theDaughter: endVtx->particles_out()) {
755 if (!theDaughter) continue;
756 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
757 allstabledescendants.insert(theDaughter);
758 }
759 findParticleStableDescendants(theDaughter, allstabledescendants);
760 }
761 }
762
766
767 template <class T> bool isHardScatteringVertex(T pVert) {
768 if (pVert == nullptr) return false;
769 T pV = pVert;
770 int numOfPartIn(0);
771 int pdg(0);
772
773 do {
774 pVert = pV;
775 auto incoming = pVert->particles_in();
776 numOfPartIn = incoming.size();
777 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
778 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
779
780 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
781
782 if (numOfPartIn == 2) {
783 auto incoming = pVert->particles_in();
784 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;
785 }
786 return false;
787}
788
792
793 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
794 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
795 auto vtx = p->production_vertex();
796 if (!vtx) return false;
797 bool fromHad = false;
798 for ( const auto& parent : vtx->particles_in() ) {
799 if (!parent) continue;
800 // should this really go into parton-level territory?
801 // probably depends where BSM particles are being decayed
802 fromBSM |= isBSM(parent);
803 if (!isPhysical(parent)) return false;
804 fromTau |= isTau(parent);
805 if (isHadron(parent)&&!isBeam(parent)) {
806 if (!hadron) hadron = parent; // assumes linear hadron parentage
807 return true;
808 }
809 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
810 }
811 return fromHad;
812 }
813
816
817 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
818 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
819 decltype(thePart->end_vertex()) pVert(nullptr);
820 if (EndVert != nullptr) {
821 do {
822 bool samePart = false;
823 pVert = nullptr;
824 auto outgoing = EndVert->particles_out();
825 auto incoming = EndVert->particles_in();
826 for (const auto& itrDaug: outgoing) {
827 if (!itrDaug) continue;
828 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
829 // brem on generator level for tau
830 (outgoing.size() == 1 && incoming.size() == 1 &&
832 itrDaug->pdg_id() == thePart->pdg_id()) {
833 samePart = true;
834 pVert = itrDaug->end_vertex();
835 }
836 }
837 if (samePart) EndVert = pVert;
838 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
839 }
840 return EndVert;
841 }
842
844
845 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
846 if (!theVert) return {};
847 decltype(theVert->particles_out()) finalStatePart;
848 auto outgoing = theVert->particles_out();
849 for (const auto& thePart: outgoing) {
850 if (!thePart) continue;
851 finalStatePart.push_back(thePart);
852 if (isStable(thePart)) continue;
853 V pVert = findSimulatedEndVertex(thePart);
854 if (pVert == theVert) break; // to prevent Sherpa loop
855 if (pVert != nullptr) {
856 auto vecPart = findFinalStateParticles<V>(pVert);
857 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
858 }
859 }
860 return finalStatePart;
861 }
862#if !defined(XAOD_ANALYSIS)
863#include "AtlasHepMC/GenEvent.h"
864inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
865inline 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());} }
866
867#endif
868}
869#endif

◆ weights_map()

std::map< std::string, std::size_t > MC::HepMC::weights_map ( const HepMC3::GenEvent * e)
inline

Definition at line 346 of file HepMCHelpers.h.

365{
366 namespace Pythia8
367 {
369 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
370
371 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
372
373 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
374 }
375
376#include "AtlasPID.h"
377
379 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
380
382 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
383
385 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
386
388 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
389
391 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
392
394 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
395
397 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
398
400 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
401
403 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
404
406 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
407
411 template <class T> inline bool isStableOrSimDecayed(const T& p) {
412 const auto vertex = p->end_vertex();
413 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
414 }
415
417 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
418
420 template <class T> inline bool isSpecialNonInteracting(const T& p) {
421 const int apid = std::abs(p->pdg_id());
422 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
423 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
424 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
425 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
426 return false;
427 }
428
430
431 template <class T> T findMother(T thePart) {
432 auto partOriVert = thePart->production_vertex();
433 if (!partOriVert) return nullptr;
434
435 long partPDG = thePart->pdg_id();
436 long MotherPDG(0);
437
438 auto MothOriVert = partOriVert;
439 MothOriVert = nullptr;
440 T theMoth(nullptr);
441
442 size_t itr = 0;
443 do {
444 if (itr != 0) partOriVert = MothOriVert;
445 for ( const auto& p : partOriVert->particles_in() ) {
446 theMoth = p;
447 if (!theMoth) continue;
448 MotherPDG = theMoth->pdg_id();
449 MothOriVert = theMoth->production_vertex();
450 if (MotherPDG == partPDG) break;
451 }
452 itr++;
453 if (itr > 100) {
454 break;
455 }
456 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
457 MothOriVert != partOriVert);
458 return theMoth;
459 }
460
462
463 template <class C, class T> T findMatching(C TruthContainer, T p) {
464 T ptrPart = nullptr;
465 if (!p) return ptrPart;
466 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
467 for (T truthParticle : *TruthContainer) {
468 if (HepMC::is_sim_descendant(p,truthParticle)) {
469 ptrPart = truthParticle;
470 break;
471 }
472 }
473 }
474 else {
475 for (T truthParticle : TruthContainer) {
476 if (HepMC::is_sim_descendant(p,truthParticle)) {
477 ptrPart = truthParticle;
478 break;
479 }
480 }
481 }
482 return ptrPart;
483 }
485
486 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
487 auto prodVtx = thePart->production_vertex();
488 if (!prodVtx) return;
489 for (const auto& theMother: prodVtx->particles_in()) {
490 if (!theMother) continue;
491 allancestors.insert(theMother);
492 findParticleAncestors(theMother, allancestors);
493 }
494 }
495
497
498 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
499 auto endVtx = thePart->end_vertex();
500 if (!endVtx) return;
501 for (const auto& theDaughter: endVtx->particles_out()) {
502 if (!theDaughter) continue;
503 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
504 allstabledescendants.insert(theDaughter);
505 }
506 findParticleStableDescendants(theDaughter, allstabledescendants);
507 }
508 }
509
513
514 template <class T> bool isHardScatteringVertex(T pVert) {
515 if (pVert == nullptr) return false;
516 T pV = pVert;
517 int numOfPartIn(0);
518 int pdg(0);
519
520 do {
521 pVert = pV;
522 auto incoming = pVert->particles_in();
523 numOfPartIn = incoming.size();
524 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
525 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
526
527 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
528
529 if (numOfPartIn == 2) {
530 auto incoming = pVert->particles_in();
531 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;
532 }
533 return false;
534}
535
539
540 template <class T, class U> bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
541 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
542 auto vtx = p->production_vertex();
543 if (!vtx) return false;
544 bool fromHad = false;
545 for ( const auto& parent : vtx->particles_in() ) {
546 if (!parent) continue;
547 // should this really go into parton-level territory?
548 // probably depends where BSM particles are being decayed
549 fromBSM |= isBSM(parent);
550 if (!isPhysical(parent)) return false;
551 fromTau |= isTau(parent);
552 if (isHadron(parent)&&!isBeam(parent)) {
553 if (!hadron) hadron = parent; // assumes linear hadron parentage
554 return true;
555 }
556 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
557 }
558 return fromHad;
559 }
560
563
564 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
565 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
566 decltype(thePart->end_vertex()) pVert(nullptr);
567 if (EndVert != nullptr) {
568 do {
569 bool samePart = false;
570 pVert = nullptr;
571 auto outgoing = EndVert->particles_out();
572 auto incoming = EndVert->particles_in();
573 for (const auto& itrDaug: outgoing) {
574 if (!itrDaug) continue;
575 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
576 // brem on generator level for tau
577 (outgoing.size() == 1 && incoming.size() == 1 &&
579 itrDaug->pdg_id() == thePart->pdg_id()) {
580 samePart = true;
581 pVert = itrDaug->end_vertex();
582 }
583 }
584 if (samePart) EndVert = pVert;
585 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
586 }
587 return EndVert;
588 }
589
591
592 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
593 if (!theVert) return {};
594 decltype(theVert->particles_out()) finalStatePart;
595 auto outgoing = theVert->particles_out();
596 for (const auto& thePart: outgoing) {
597 if (!thePart) continue;
598 finalStatePart.push_back(thePart);
599 if (isStable(thePart)) continue;
600 V pVert = findSimulatedEndVertex(thePart);
601 if (pVert == theVert) break; // to prevent Sherpa loop
602 if (pVert != nullptr) {
603 auto vecPart = findFinalStateParticles<V>(pVert);
604 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
605 }
606 }
607 return finalStatePart;
608 }
609#if !defined(XAOD_ANALYSIS)
610#include "AtlasHepMC/GenEvent.h"
611inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
612inline 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());} }
613
614#endif
615}
616#endif