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)
int barcode_or_id (const ConstGenVertexPtr &p)
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)
int flow (const HepMC3::GenParticlePtr &p, int i)
int flow (const HepMC3::ConstGenParticlePtr &p, int i)
Flow flow (const HepMC3::GenParticlePtr &p)
Flow flow (const HepMC3::ConstGenParticlePtr &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)
int barcode_or_id (const ConstGenParticlePtr &p)
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 12 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.

49
51 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
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 isStable(const T &p)
Identify if the particle is stable, i.e. has not decayed.

◆ 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.

40
bool isGeantino(const T &p)
bool isEMInteracting(const T &p)
bool isStrongInteracting(const T &p)

◆ 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.

◆ 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_or_id() [1/2]

int MC::HepMC::barcode_or_id ( const ConstGenParticlePtr & p)
inline

Definition at line 27 of file HepMCHelpers.h.

27{

◆ barcode_or_id() [2/2]

int MC::HepMC::barcode_or_id ( const ConstGenVertexPtr & p)
inline

Definition at line 30 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 template <class VTX>
464 auto particles_in (const VTX* p) { return p->particles_in(); }
465 template <class VTX>
466 auto particles_in (const std::shared_ptr<VTX>& p) { return p->particles_in(); }
467
468 namespace Pythia8
469 {
471 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
472
473 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
474
475 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
476 }
477
478#include "AtlasPID.h"
479
481 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
482
484 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
485
487 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
488
490 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
491
493 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
494
496 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
497
499 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
500
502 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
503
505 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
506
508 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
509
513 template <class T> inline bool isStableOrSimDecayed(const T& p) {
514 const auto vertex = p->end_vertex();
515 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
516 }
517
519 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
520
522 template <class T> inline bool isSpecialNonInteracting(const T& p) {
523 const int apid = std::abs(p->pdg_id());
524 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
525 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
526 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
527 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
528 return false;
529 }
530
532
533 template <class T> T findMother(T thePart) {
534 auto partOriVert = thePart->production_vertex();
535 if (!partOriVert) return nullptr;
536
537 long partPDG = thePart->pdg_id();
538 long MotherPDG(0);
539
540 auto MothOriVert = partOriVert;
541 MothOriVert = nullptr;
542 T theMoth(nullptr);
543
544 size_t itr = 0;
545 do {
546 if (itr != 0) partOriVert = MothOriVert;
547 for ( const auto& p : particles_in(partOriVert) ) {
548 theMoth = p;
549 if (!theMoth) continue;
550 MotherPDG = theMoth->pdg_id();
551 MothOriVert = theMoth->production_vertex();
552 if (MotherPDG == partPDG) break;
553 }
554 itr++;
555 if (itr > 100) {
556 break;
557 }
558 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
559 MothOriVert != partOriVert);
560 return theMoth;
561 }
562
564
565 template <class C, class T> T findMatching(C TruthContainer, T p) {
566 T ptrPart = nullptr;
567 if (!p) return ptrPart;
568 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
569 for (T truthParticle : *TruthContainer) {
570 if (HepMC::is_sim_descendant(p,truthParticle)) {
571 ptrPart = truthParticle;
572 break;
573 }
574 }
575 }
576 else {
577 for (T truthParticle : TruthContainer) {
578 if (HepMC::is_sim_descendant(p,truthParticle)) {
579 ptrPart = truthParticle;
580 break;
581 }
582 }
583 }
584 return ptrPart;
585 }
587
588 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
589 auto prodVtx = thePart->production_vertex();
590 if (!prodVtx) return;
591 for (const auto& theMother: prodVtx->particles_in()) {
592 if (!theMother) continue;
593 allancestors.insert(theMother);
594 findParticleAncestors(theMother, allancestors);
595 }
596 }
597
599
600 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
601 auto endVtx = thePart->end_vertex();
602 if (!endVtx) return;
603 for (const auto& theDaughter: endVtx->particles_out()) {
604 if (!theDaughter) continue;
605 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
606 allstabledescendants.insert(theDaughter);
607 }
608 findParticleStableDescendants(theDaughter, allstabledescendants);
609 }
610 }
611
615
616 template <class T> bool isHardScatteringVertex(T pVert) {
617 if (pVert == nullptr) return false;
618 T pV = pVert;
619 int numOfPartIn(0);
620 int pdg(0);
621
622 do {
623 pVert = pV;
624 auto incoming = pVert->particles_in();
625 numOfPartIn = incoming.size();
626 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
627 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
628
629 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
630
631 if (numOfPartIn == 2) {
632 auto incoming = pVert->particles_in();
633 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;
634 }
635 return false;
636}
637
641
642 template <class T, class U>
643 bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
644 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
645 auto vtx = p->production_vertex();
646 if (!vtx) return false;
647 bool fromHad = false;
648 for ( const auto& parent : particles_in(vtx) ) {
649 if (!parent) continue;
650 // should this really go into parton-level territory?
651 // probably depends where BSM particles are being decayed
652 fromBSM |= isBSM(parent);
653 if (!isPhysical(parent)) return false;
654 fromTau |= isTau(parent);
655 if (isHadron(parent)&&!isBeam(parent)) {
656 if (!hadron) hadron = parent; // assumes linear hadron parentage
657 return true;
658 }
659 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
660 }
661 return fromHad;
662 }
663
666
667 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
668 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
669 decltype(thePart->end_vertex()) pVert(nullptr);
670 if (EndVert != nullptr) {
671 do {
672 bool samePart = false;
673 pVert = nullptr;
674 auto outgoing = EndVert->particles_out();
675 auto incoming = EndVert->particles_in();
676 for (const auto& itrDaug: outgoing) {
677 if (!itrDaug) continue;
678 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
679 // brem on generator level for tau
680 (outgoing.size() == 1 && incoming.size() == 1 &&
682 itrDaug->pdg_id() == thePart->pdg_id()) {
683 samePart = true;
684 pVert = itrDaug->end_vertex();
685 }
686 }
687 if (samePart) EndVert = pVert;
688 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
689 }
690 return EndVert;
691 }
692
694
695 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
696 if (!theVert) return {};
697 decltype(theVert->particles_out()) finalStatePart;
698 auto outgoing = theVert->particles_out();
699 for (const auto& thePart: outgoing) {
700 if (!thePart) continue;
701 finalStatePart.push_back(thePart);
702 if (isStable(thePart)) continue;
703 V pVert = findSimulatedEndVertex(thePart);
704 if (pVert == theVert) break; // to prevent Sherpa loop
705 if (pVert != nullptr) {
706 auto vecPart = findFinalStateParticles<V>(pVert);
707 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
708 }
709 }
710 return finalStatePart;
711 }
712#if !defined(XAOD_ANALYSIS)
713#include "AtlasHepMC/GenEvent.h"
714inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
715inline 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());} }
716
717#endif
718}
719#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
bool isConditionB(const T &p)
bool isConditionC(const T &p)
T findMatching(C TruthContainer, T p)
Function to find a particle in container.
static const int GRAVITON
auto particles_in(const VTX *p)
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 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....
bool isMuon(const T &p)
bool isSUSY(const T &p)
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 isChargedNonShowering(const T &p)
Identify if the particle with given PDG ID would produce ID tracks but not shower in the detector if ...
bool isDecayed(const T &p)
Identify if the particle decayed.
T findMother(T thePart)
Function to get a mother of particle. MCTruthClassifier legacy.
void findParticleStableDescendants(T thePart, std::set< T > &allstabledescendants)
Function to get the particle stable MC daughters.
static const int NU_E
bool isBeam(const T &p)
Identify if the particle is beam particle.
static const int NU_TAU
bool isFinalState(const T &p)
Identify if the particle is final state particle.
bool isGenStable(const T &p)
Determine if the particle is stable at the generator (not det-sim) level,.
bool isHadron(const T &p)
bool isSimStable(const T &p)
Identify if the particle is considered stable at the post-detector-sim stage.
auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex())
Function to find the end vertex of a particle.
bool 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 template <class VTX>
544 auto particles_in (const VTX* p) { return p->particles_in(); }
545 template <class VTX>
546 auto particles_in (const std::shared_ptr<VTX>& p) { return p->particles_in(); }
547
548 namespace Pythia8
549 {
551 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
552
553 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
554
555 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
556 }
557
558#include "AtlasPID.h"
559
561 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
562
564 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
565
567 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
568
570 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
571
573 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
574
576 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
577
579 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
580
582 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
583
585 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
586
588 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
589
593 template <class T> inline bool isStableOrSimDecayed(const T& p) {
594 const auto vertex = p->end_vertex();
595 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
596 }
597
599 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
600
602 template <class T> inline bool isSpecialNonInteracting(const T& p) {
603 const int apid = std::abs(p->pdg_id());
604 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
605 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
606 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
607 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
608 return false;
609 }
610
612
613 template <class T> T findMother(T thePart) {
614 auto partOriVert = thePart->production_vertex();
615 if (!partOriVert) return nullptr;
616
617 long partPDG = thePart->pdg_id();
618 long MotherPDG(0);
619
620 auto MothOriVert = partOriVert;
621 MothOriVert = nullptr;
622 T theMoth(nullptr);
623
624 size_t itr = 0;
625 do {
626 if (itr != 0) partOriVert = MothOriVert;
627 for ( const auto& p : particles_in(partOriVert) ) {
628 theMoth = p;
629 if (!theMoth) continue;
630 MotherPDG = theMoth->pdg_id();
631 MothOriVert = theMoth->production_vertex();
632 if (MotherPDG == partPDG) break;
633 }
634 itr++;
635 if (itr > 100) {
636 break;
637 }
638 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
639 MothOriVert != partOriVert);
640 return theMoth;
641 }
642
644
645 template <class C, class T> T findMatching(C TruthContainer, T p) {
646 T ptrPart = nullptr;
647 if (!p) return ptrPart;
648 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
649 for (T truthParticle : *TruthContainer) {
650 if (HepMC::is_sim_descendant(p,truthParticle)) {
651 ptrPart = truthParticle;
652 break;
653 }
654 }
655 }
656 else {
657 for (T truthParticle : TruthContainer) {
658 if (HepMC::is_sim_descendant(p,truthParticle)) {
659 ptrPart = truthParticle;
660 break;
661 }
662 }
663 }
664 return ptrPart;
665 }
667
668 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
669 auto prodVtx = thePart->production_vertex();
670 if (!prodVtx) return;
671 for (const auto& theMother: prodVtx->particles_in()) {
672 if (!theMother) continue;
673 allancestors.insert(theMother);
674 findParticleAncestors(theMother, allancestors);
675 }
676 }
677
679
680 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
681 auto endVtx = thePart->end_vertex();
682 if (!endVtx) return;
683 for (const auto& theDaughter: endVtx->particles_out()) {
684 if (!theDaughter) continue;
685 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
686 allstabledescendants.insert(theDaughter);
687 }
688 findParticleStableDescendants(theDaughter, allstabledescendants);
689 }
690 }
691
695
696 template <class T> bool isHardScatteringVertex(T pVert) {
697 if (pVert == nullptr) return false;
698 T pV = pVert;
699 int numOfPartIn(0);
700 int pdg(0);
701
702 do {
703 pVert = pV;
704 auto incoming = pVert->particles_in();
705 numOfPartIn = incoming.size();
706 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
707 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
708
709 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
710
711 if (numOfPartIn == 2) {
712 auto incoming = pVert->particles_in();
713 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;
714 }
715 return false;
716}
717
721
722 template <class T, class U>
723 bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
724 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
725 auto vtx = p->production_vertex();
726 if (!vtx) return false;
727 bool fromHad = false;
728 for ( const auto& parent : particles_in(vtx) ) {
729 if (!parent) continue;
730 // should this really go into parton-level territory?
731 // probably depends where BSM particles are being decayed
732 fromBSM |= isBSM(parent);
733 if (!isPhysical(parent)) return false;
734 fromTau |= isTau(parent);
735 if (isHadron(parent)&&!isBeam(parent)) {
736 if (!hadron) hadron = parent; // assumes linear hadron parentage
737 return true;
738 }
739 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
740 }
741 return fromHad;
742 }
743
746
747 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
748 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
749 decltype(thePart->end_vertex()) pVert(nullptr);
750 if (EndVert != nullptr) {
751 do {
752 bool samePart = false;
753 pVert = nullptr;
754 auto outgoing = EndVert->particles_out();
755 auto incoming = EndVert->particles_in();
756 for (const auto& itrDaug: outgoing) {
757 if (!itrDaug) continue;
758 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
759 // brem on generator level for tau
760 (outgoing.size() == 1 && incoming.size() == 1 &&
762 itrDaug->pdg_id() == thePart->pdg_id()) {
763 samePart = true;
764 pVert = itrDaug->end_vertex();
765 }
766 }
767 if (samePart) EndVert = pVert;
768 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
769 }
770 return EndVert;
771 }
772
774
775 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
776 if (!theVert) return {};
777 decltype(theVert->particles_out()) finalStatePart;
778 auto outgoing = theVert->particles_out();
779 for (const auto& thePart: outgoing) {
780 if (!thePart) continue;
781 finalStatePart.push_back(thePart);
782 if (isStable(thePart)) continue;
783 V pVert = findSimulatedEndVertex(thePart);
784 if (pVert == theVert) break; // to prevent Sherpa loop
785 if (pVert != nullptr) {
786 auto vecPart = findFinalStateParticles<V>(pVert);
787 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
788 }
789 }
790 return finalStatePart;
791 }
792#if !defined(XAOD_ANALYSIS)
793#include "AtlasHepMC/GenEvent.h"
794inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
795inline 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());} }
796
797#endif
798}
799#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 template <class VTX>
424 auto particles_in (const VTX* p) { return p->particles_in(); }
425 template <class VTX>
426 auto particles_in (const std::shared_ptr<VTX>& p) { return p->particles_in(); }
427
428 namespace Pythia8
429 {
431 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
432
433 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
434
435 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
436 }
437
438#include "AtlasPID.h"
439
441 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
442
444 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
445
447 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
448
450 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
451
453 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
454
456 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
457
459 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
460
462 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
463
465 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
466
468 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
469
473 template <class T> inline bool isStableOrSimDecayed(const T& p) {
474 const auto vertex = p->end_vertex();
475 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
476 }
477
479 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
480
482 template <class T> inline bool isSpecialNonInteracting(const T& p) {
483 const int apid = std::abs(p->pdg_id());
484 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
485 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
486 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
487 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
488 return false;
489 }
490
492
493 template <class T> T findMother(T thePart) {
494 auto partOriVert = thePart->production_vertex();
495 if (!partOriVert) return nullptr;
496
497 long partPDG = thePart->pdg_id();
498 long MotherPDG(0);
499
500 auto MothOriVert = partOriVert;
501 MothOriVert = nullptr;
502 T theMoth(nullptr);
503
504 size_t itr = 0;
505 do {
506 if (itr != 0) partOriVert = MothOriVert;
507 for ( const auto& p : particles_in(partOriVert) ) {
508 theMoth = p;
509 if (!theMoth) continue;
510 MotherPDG = theMoth->pdg_id();
511 MothOriVert = theMoth->production_vertex();
512 if (MotherPDG == partPDG) break;
513 }
514 itr++;
515 if (itr > 100) {
516 break;
517 }
518 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
519 MothOriVert != partOriVert);
520 return theMoth;
521 }
522
524
525 template <class C, class T> T findMatching(C TruthContainer, T p) {
526 T ptrPart = nullptr;
527 if (!p) return ptrPart;
528 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
529 for (T truthParticle : *TruthContainer) {
530 if (HepMC::is_sim_descendant(p,truthParticle)) {
531 ptrPart = truthParticle;
532 break;
533 }
534 }
535 }
536 else {
537 for (T truthParticle : TruthContainer) {
538 if (HepMC::is_sim_descendant(p,truthParticle)) {
539 ptrPart = truthParticle;
540 break;
541 }
542 }
543 }
544 return ptrPart;
545 }
547
548 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
549 auto prodVtx = thePart->production_vertex();
550 if (!prodVtx) return;
551 for (const auto& theMother: prodVtx->particles_in()) {
552 if (!theMother) continue;
553 allancestors.insert(theMother);
554 findParticleAncestors(theMother, allancestors);
555 }
556 }
557
559
560 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
561 auto endVtx = thePart->end_vertex();
562 if (!endVtx) return;
563 for (const auto& theDaughter: endVtx->particles_out()) {
564 if (!theDaughter) continue;
565 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
566 allstabledescendants.insert(theDaughter);
567 }
568 findParticleStableDescendants(theDaughter, allstabledescendants);
569 }
570 }
571
575
576 template <class T> bool isHardScatteringVertex(T pVert) {
577 if (pVert == nullptr) return false;
578 T pV = pVert;
579 int numOfPartIn(0);
580 int pdg(0);
581
582 do {
583 pVert = pV;
584 auto incoming = pVert->particles_in();
585 numOfPartIn = incoming.size();
586 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
587 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
588
589 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
590
591 if (numOfPartIn == 2) {
592 auto incoming = pVert->particles_in();
593 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;
594 }
595 return false;
596}
597
601
602 template <class T, class U>
603 bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
604 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
605 auto vtx = p->production_vertex();
606 if (!vtx) return false;
607 bool fromHad = false;
608 for ( const auto& parent : particles_in(vtx) ) {
609 if (!parent) continue;
610 // should this really go into parton-level territory?
611 // probably depends where BSM particles are being decayed
612 fromBSM |= isBSM(parent);
613 if (!isPhysical(parent)) return false;
614 fromTau |= isTau(parent);
615 if (isHadron(parent)&&!isBeam(parent)) {
616 if (!hadron) hadron = parent; // assumes linear hadron parentage
617 return true;
618 }
619 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
620 }
621 return fromHad;
622 }
623
626
627 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
628 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
629 decltype(thePart->end_vertex()) pVert(nullptr);
630 if (EndVert != nullptr) {
631 do {
632 bool samePart = false;
633 pVert = nullptr;
634 auto outgoing = EndVert->particles_out();
635 auto incoming = EndVert->particles_in();
636 for (const auto& itrDaug: outgoing) {
637 if (!itrDaug) continue;
638 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
639 // brem on generator level for tau
640 (outgoing.size() == 1 && incoming.size() == 1 &&
642 itrDaug->pdg_id() == thePart->pdg_id()) {
643 samePart = true;
644 pVert = itrDaug->end_vertex();
645 }
646 }
647 if (samePart) EndVert = pVert;
648 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
649 }
650 return EndVert;
651 }
652
654
655 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
656 if (!theVert) return {};
657 decltype(theVert->particles_out()) finalStatePart;
658 auto outgoing = theVert->particles_out();
659 for (const auto& thePart: outgoing) {
660 if (!thePart) continue;
661 finalStatePart.push_back(thePart);
662 if (isStable(thePart)) continue;
663 V pVert = findSimulatedEndVertex(thePart);
664 if (pVert == theVert) break; // to prevent Sherpa loop
665 if (pVert != nullptr) {
666 auto vecPart = findFinalStateParticles<V>(pVert);
667 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
668 }
669 }
670 return finalStatePart;
671 }
672#if !defined(XAOD_ANALYSIS)
673#include "AtlasHepMC/GenEvent.h"
674inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
675inline 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());} }
676
677#endif
678}
679#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 template <class VTX>
504 auto particles_in (const VTX* p) { return p->particles_in(); }
505 template <class VTX>
506 auto particles_in (const std::shared_ptr<VTX>& p) { return p->particles_in(); }
507
508 namespace Pythia8
509 {
511 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
512
513 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
514
515 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
516 }
517
518#include "AtlasPID.h"
519
521 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
522
524 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
525
527 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
528
530 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
531
533 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
534
536 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
537
539 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
540
542 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
543
545 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
546
548 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
549
553 template <class T> inline bool isStableOrSimDecayed(const T& p) {
554 const auto vertex = p->end_vertex();
555 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
556 }
557
559 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
560
562 template <class T> inline bool isSpecialNonInteracting(const T& p) {
563 const int apid = std::abs(p->pdg_id());
564 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
565 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
566 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
567 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
568 return false;
569 }
570
572
573 template <class T> T findMother(T thePart) {
574 auto partOriVert = thePart->production_vertex();
575 if (!partOriVert) return nullptr;
576
577 long partPDG = thePart->pdg_id();
578 long MotherPDG(0);
579
580 auto MothOriVert = partOriVert;
581 MothOriVert = nullptr;
582 T theMoth(nullptr);
583
584 size_t itr = 0;
585 do {
586 if (itr != 0) partOriVert = MothOriVert;
587 for ( const auto& p : particles_in(partOriVert) ) {
588 theMoth = p;
589 if (!theMoth) continue;
590 MotherPDG = theMoth->pdg_id();
591 MothOriVert = theMoth->production_vertex();
592 if (MotherPDG == partPDG) break;
593 }
594 itr++;
595 if (itr > 100) {
596 break;
597 }
598 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
599 MothOriVert != partOriVert);
600 return theMoth;
601 }
602
604
605 template <class C, class T> T findMatching(C TruthContainer, T p) {
606 T ptrPart = nullptr;
607 if (!p) return ptrPart;
608 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
609 for (T truthParticle : *TruthContainer) {
610 if (HepMC::is_sim_descendant(p,truthParticle)) {
611 ptrPart = truthParticle;
612 break;
613 }
614 }
615 }
616 else {
617 for (T truthParticle : TruthContainer) {
618 if (HepMC::is_sim_descendant(p,truthParticle)) {
619 ptrPart = truthParticle;
620 break;
621 }
622 }
623 }
624 return ptrPart;
625 }
627
628 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
629 auto prodVtx = thePart->production_vertex();
630 if (!prodVtx) return;
631 for (const auto& theMother: prodVtx->particles_in()) {
632 if (!theMother) continue;
633 allancestors.insert(theMother);
634 findParticleAncestors(theMother, allancestors);
635 }
636 }
637
639
640 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
641 auto endVtx = thePart->end_vertex();
642 if (!endVtx) return;
643 for (const auto& theDaughter: endVtx->particles_out()) {
644 if (!theDaughter) continue;
645 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
646 allstabledescendants.insert(theDaughter);
647 }
648 findParticleStableDescendants(theDaughter, allstabledescendants);
649 }
650 }
651
655
656 template <class T> bool isHardScatteringVertex(T pVert) {
657 if (pVert == nullptr) return false;
658 T pV = pVert;
659 int numOfPartIn(0);
660 int pdg(0);
661
662 do {
663 pVert = pV;
664 auto incoming = pVert->particles_in();
665 numOfPartIn = incoming.size();
666 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
667 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
668
669 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
670
671 if (numOfPartIn == 2) {
672 auto incoming = pVert->particles_in();
673 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;
674 }
675 return false;
676}
677
681
682 template <class T, class U>
683 bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
684 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
685 auto vtx = p->production_vertex();
686 if (!vtx) return false;
687 bool fromHad = false;
688 for ( const auto& parent : particles_in(vtx) ) {
689 if (!parent) continue;
690 // should this really go into parton-level territory?
691 // probably depends where BSM particles are being decayed
692 fromBSM |= isBSM(parent);
693 if (!isPhysical(parent)) return false;
694 fromTau |= isTau(parent);
695 if (isHadron(parent)&&!isBeam(parent)) {
696 if (!hadron) hadron = parent; // assumes linear hadron parentage
697 return true;
698 }
699 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
700 }
701 return fromHad;
702 }
703
706
707 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
708 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
709 decltype(thePart->end_vertex()) pVert(nullptr);
710 if (EndVert != nullptr) {
711 do {
712 bool samePart = false;
713 pVert = nullptr;
714 auto outgoing = EndVert->particles_out();
715 auto incoming = EndVert->particles_in();
716 for (const auto& itrDaug: outgoing) {
717 if (!itrDaug) continue;
718 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
719 // brem on generator level for tau
720 (outgoing.size() == 1 && incoming.size() == 1 &&
722 itrDaug->pdg_id() == thePart->pdg_id()) {
723 samePart = true;
724 pVert = itrDaug->end_vertex();
725 }
726 }
727 if (samePart) EndVert = pVert;
728 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
729 }
730 return EndVert;
731 }
732
734
735 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
736 if (!theVert) return {};
737 decltype(theVert->particles_out()) finalStatePart;
738 auto outgoing = theVert->particles_out();
739 for (const auto& thePart: outgoing) {
740 if (!thePart) continue;
741 finalStatePart.push_back(thePart);
742 if (isStable(thePart)) continue;
743 V pVert = findSimulatedEndVertex(thePart);
744 if (pVert == theVert) break; // to prevent Sherpa loop
745 if (pVert != nullptr) {
746 auto vecPart = findFinalStateParticles<V>(pVert);
747 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
748 }
749 }
750 return finalStatePart;
751 }
752#if !defined(XAOD_ANALYSIS)
753#include "AtlasHepMC/GenEvent.h"
754inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
755inline 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());} }
756
757#endif
758}
759#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 template <class VTX>
378 auto particles_in (const VTX* p) { return p->particles_in(); }
379 template <class VTX>
380 auto particles_in (const std::shared_ptr<VTX>& p) { return p->particles_in(); }
381
382 namespace Pythia8
383 {
385 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
386
387 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
388
389 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
390 }
391
392#include "AtlasPID.h"
393
395 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
396
398 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
399
401 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
402
404 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
405
407 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
408
410 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
411
413 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
414
416 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
417
419 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
420
422 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
423
427 template <class T> inline bool isStableOrSimDecayed(const T& p) {
428 const auto vertex = p->end_vertex();
429 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
430 }
431
433 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
434
436 template <class T> inline bool isSpecialNonInteracting(const T& p) {
437 const int apid = std::abs(p->pdg_id());
438 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
439 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
440 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
441 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
442 return false;
443 }
444
446
447 template <class T> T findMother(T thePart) {
448 auto partOriVert = thePart->production_vertex();
449 if (!partOriVert) return nullptr;
450
451 long partPDG = thePart->pdg_id();
452 long MotherPDG(0);
453
454 auto MothOriVert = partOriVert;
455 MothOriVert = nullptr;
456 T theMoth(nullptr);
457
458 size_t itr = 0;
459 do {
460 if (itr != 0) partOriVert = MothOriVert;
461 for ( const auto& p : particles_in(partOriVert) ) {
462 theMoth = p;
463 if (!theMoth) continue;
464 MotherPDG = theMoth->pdg_id();
465 MothOriVert = theMoth->production_vertex();
466 if (MotherPDG == partPDG) break;
467 }
468 itr++;
469 if (itr > 100) {
470 break;
471 }
472 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
473 MothOriVert != partOriVert);
474 return theMoth;
475 }
476
478
479 template <class C, class T> T findMatching(C TruthContainer, T p) {
480 T ptrPart = nullptr;
481 if (!p) return ptrPart;
482 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
483 for (T truthParticle : *TruthContainer) {
484 if (HepMC::is_sim_descendant(p,truthParticle)) {
485 ptrPart = truthParticle;
486 break;
487 }
488 }
489 }
490 else {
491 for (T truthParticle : TruthContainer) {
492 if (HepMC::is_sim_descendant(p,truthParticle)) {
493 ptrPart = truthParticle;
494 break;
495 }
496 }
497 }
498 return ptrPart;
499 }
501
502 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
503 auto prodVtx = thePart->production_vertex();
504 if (!prodVtx) return;
505 for (const auto& theMother: prodVtx->particles_in()) {
506 if (!theMother) continue;
507 allancestors.insert(theMother);
508 findParticleAncestors(theMother, allancestors);
509 }
510 }
511
513
514 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
515 auto endVtx = thePart->end_vertex();
516 if (!endVtx) return;
517 for (const auto& theDaughter: endVtx->particles_out()) {
518 if (!theDaughter) continue;
519 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
520 allstabledescendants.insert(theDaughter);
521 }
522 findParticleStableDescendants(theDaughter, allstabledescendants);
523 }
524 }
525
529
530 template <class T> bool isHardScatteringVertex(T pVert) {
531 if (pVert == nullptr) return false;
532 T pV = pVert;
533 int numOfPartIn(0);
534 int pdg(0);
535
536 do {
537 pVert = pV;
538 auto incoming = pVert->particles_in();
539 numOfPartIn = incoming.size();
540 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
541 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
542
543 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
544
545 if (numOfPartIn == 2) {
546 auto incoming = pVert->particles_in();
547 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;
548 }
549 return false;
550}
551
555
556 template <class T, class U>
557 bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
558 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
559 auto vtx = p->production_vertex();
560 if (!vtx) return false;
561 bool fromHad = false;
562 for ( const auto& parent : particles_in(vtx) ) {
563 if (!parent) continue;
564 // should this really go into parton-level territory?
565 // probably depends where BSM particles are being decayed
566 fromBSM |= isBSM(parent);
567 if (!isPhysical(parent)) return false;
568 fromTau |= isTau(parent);
569 if (isHadron(parent)&&!isBeam(parent)) {
570 if (!hadron) hadron = parent; // assumes linear hadron parentage
571 return true;
572 }
573 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
574 }
575 return fromHad;
576 }
577
580
581 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
582 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
583 decltype(thePart->end_vertex()) pVert(nullptr);
584 if (EndVert != nullptr) {
585 do {
586 bool samePart = false;
587 pVert = nullptr;
588 auto outgoing = EndVert->particles_out();
589 auto incoming = EndVert->particles_in();
590 for (const auto& itrDaug: outgoing) {
591 if (!itrDaug) continue;
592 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
593 // brem on generator level for tau
594 (outgoing.size() == 1 && incoming.size() == 1 &&
596 itrDaug->pdg_id() == thePart->pdg_id()) {
597 samePart = true;
598 pVert = itrDaug->end_vertex();
599 }
600 }
601 if (samePart) EndVert = pVert;
602 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
603 }
604 return EndVert;
605 }
606
608
609 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
610 if (!theVert) return {};
611 decltype(theVert->particles_out()) finalStatePart;
612 auto outgoing = theVert->particles_out();
613 for (const auto& thePart: outgoing) {
614 if (!thePart) continue;
615 finalStatePart.push_back(thePart);
616 if (isStable(thePart)) continue;
617 V pVert = findSimulatedEndVertex(thePart);
618 if (pVert == theVert) break; // to prevent Sherpa loop
619 if (pVert != nullptr) {
620 auto vecPart = findFinalStateParticles<V>(pVert);
621 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
622 }
623 }
624 return finalStatePart;
625 }
626#if !defined(XAOD_ANALYSIS)
627#include "AtlasHepMC/GenEvent.h"
628inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
629inline 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());} }
630
631#endif
632}
633#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 template <class VTX>
376 auto particles_in (const VTX* p) { return p->particles_in(); }
377 template <class VTX>
378 auto particles_in (const std::shared_ptr<VTX>& p) { return p->particles_in(); }
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 : particles_in(partOriVert) ) {
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>
555 bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
556 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
557 auto vtx = p->production_vertex();
558 if (!vtx) return false;
559 bool fromHad = false;
560 for ( const auto& parent : particles_in(vtx) ) {
561 if (!parent) continue;
562 // should this really go into parton-level territory?
563 // probably depends where BSM particles are being decayed
564 fromBSM |= isBSM(parent);
565 if (!isPhysical(parent)) return false;
566 fromTau |= isTau(parent);
567 if (isHadron(parent)&&!isBeam(parent)) {
568 if (!hadron) hadron = parent; // assumes linear hadron parentage
569 return true;
570 }
571 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
572 }
573 return fromHad;
574 }
575
578
579 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
580 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
581 decltype(thePart->end_vertex()) pVert(nullptr);
582 if (EndVert != nullptr) {
583 do {
584 bool samePart = false;
585 pVert = nullptr;
586 auto outgoing = EndVert->particles_out();
587 auto incoming = EndVert->particles_in();
588 for (const auto& itrDaug: outgoing) {
589 if (!itrDaug) continue;
590 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
591 // brem on generator level for tau
592 (outgoing.size() == 1 && incoming.size() == 1 &&
594 itrDaug->pdg_id() == thePart->pdg_id()) {
595 samePart = true;
596 pVert = itrDaug->end_vertex();
597 }
598 }
599 if (samePart) EndVert = pVert;
600 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
601 }
602 return EndVert;
603 }
604
606
607 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
608 if (!theVert) return {};
609 decltype(theVert->particles_out()) finalStatePart;
610 auto outgoing = theVert->particles_out();
611 for (const auto& thePart: outgoing) {
612 if (!thePart) continue;
613 finalStatePart.push_back(thePart);
614 if (isStable(thePart)) continue;
615 V pVert = findSimulatedEndVertex(thePart);
616 if (pVert == theVert) break; // to prevent Sherpa loop
617 if (pVert != nullptr) {
618 auto vecPart = findFinalStateParticles<V>(pVert);
619 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
620 }
621 }
622 return finalStatePart;
623 }
624#if !defined(XAOD_ANALYSIS)
625#include "AtlasHepMC/GenEvent.h"
626inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
627inline 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());} }
628
629#endif
630}
631#endif

◆ copyemptyGenEvent()

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

Definition at line 369 of file HepMCHelpers.h.

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

◆ fillBarcodesAttribute()

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

Definition at line 393 of file HepMCHelpers.h.

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

◆ flow() [1/4]

Flow MC::HepMC::flow ( const HepMC3::ConstGenParticlePtr & p)
inline

Definition at line 33 of file HepMCHelpers.h.

33 { return p->status() > 30 && p->status() < 40;}
34 }
35
36#include "AtlasPID.h"
37
39 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
40
42 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }

◆ flow() [2/4]

int MC::HepMC::flow ( const HepMC3::ConstGenParticlePtr & p,
int i )
inline

Definition at line 18 of file HepMCHelpers.h.

20{
21 template <class VTX>
22 auto particles_in (const VTX* p) { return p->particles_in(); }

◆ flow() [3/4]

Flow MC::HepMC::flow ( const HepMC3::GenParticlePtr & p)
inline

Definition at line 23 of file HepMCHelpers.h.

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

◆ flow() [4/4]

int MC::HepMC::flow ( const HepMC3::GenParticlePtr & p,
int i )
inline

Definition at line 13 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 template <class VTX>
362 auto particles_in (const VTX* p) { return p->particles_in(); }
363 template <class VTX>
364 auto particles_in (const std::shared_ptr<VTX>& p) { return p->particles_in(); }
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 : particles_in(partOriVert) ) {
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>
541 bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
542 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
543 auto vtx = p->production_vertex();
544 if (!vtx) return false;
545 bool fromHad = false;
546 for ( const auto& parent : particles_in(vtx) ) {
547 if (!parent) continue;
548 // should this really go into parton-level territory?
549 // probably depends where BSM particles are being decayed
550 fromBSM |= isBSM(parent);
551 if (!isPhysical(parent)) return false;
552 fromTau |= isTau(parent);
553 if (isHadron(parent)&&!isBeam(parent)) {
554 if (!hadron) hadron = parent; // assumes linear hadron parentage
555 return true;
556 }
557 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
558 }
559 return fromHad;
560 }
561
564
565 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
566 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
567 decltype(thePart->end_vertex()) pVert(nullptr);
568 if (EndVert != nullptr) {
569 do {
570 bool samePart = false;
571 pVert = nullptr;
572 auto outgoing = EndVert->particles_out();
573 auto incoming = EndVert->particles_in();
574 for (const auto& itrDaug: outgoing) {
575 if (!itrDaug) continue;
576 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
577 // brem on generator level for tau
578 (outgoing.size() == 1 && incoming.size() == 1 &&
580 itrDaug->pdg_id() == thePart->pdg_id()) {
581 samePart = true;
582 pVert = itrDaug->end_vertex();
583 }
584 }
585 if (samePart) EndVert = pVert;
586 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
587 }
588 return EndVert;
589 }
590
592
593 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
594 if (!theVert) return {};
595 decltype(theVert->particles_out()) finalStatePart;
596 auto outgoing = theVert->particles_out();
597 for (const auto& thePart: outgoing) {
598 if (!thePart) continue;
599 finalStatePart.push_back(thePart);
600 if (isStable(thePart)) continue;
601 V pVert = findSimulatedEndVertex(thePart);
602 if (pVert == theVert) break; // to prevent Sherpa loop
603 if (pVert != nullptr) {
604 auto vecPart = findFinalStateParticles<V>(pVert);
605 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
606 }
607 }
608 return finalStatePart;
609 }
610#if !defined(XAOD_ANALYSIS)
611#include "AtlasHepMC/GenEvent.h"
612inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
613inline 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());} }
614
615#endif
616}
617#endif

◆ mpi() [1/2]

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

Definition at line 563 of file HepMCHelpers.h.

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

◆ mpi() [2/2]

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

Definition at line 567 of file HepMCHelpers.h.

586{
587 template <class VTX>
588 auto particles_in (const VTX* p) { return p->particles_in(); }
589 template <class VTX>
590 auto particles_in (const std::shared_ptr<VTX>& p) { return p->particles_in(); }
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 : particles_in(partOriVert) ) {
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>
767 bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
768 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
769 auto vtx = p->production_vertex();
770 if (!vtx) return false;
771 bool fromHad = false;
772 for ( const auto& parent : particles_in(vtx) ) {
773 if (!parent) continue;
774 // should this really go into parton-level territory?
775 // probably depends where BSM particles are being decayed
776 fromBSM |= isBSM(parent);
777 if (!isPhysical(parent)) return false;
778 fromTau |= isTau(parent);
779 if (isHadron(parent)&&!isBeam(parent)) {
780 if (!hadron) hadron = parent; // assumes linear hadron parentage
781 return true;
782 }
783 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
784 }
785 return fromHad;
786 }
787
790
791 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
792 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
793 decltype(thePart->end_vertex()) pVert(nullptr);
794 if (EndVert != nullptr) {
795 do {
796 bool samePart = false;
797 pVert = nullptr;
798 auto outgoing = EndVert->particles_out();
799 auto incoming = EndVert->particles_in();
800 for (const auto& itrDaug: outgoing) {
801 if (!itrDaug) continue;
802 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
803 // brem on generator level for tau
804 (outgoing.size() == 1 && incoming.size() == 1 &&
806 itrDaug->pdg_id() == thePart->pdg_id()) {
807 samePart = true;
808 pVert = itrDaug->end_vertex();
809 }
810 }
811 if (samePart) EndVert = pVert;
812 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
813 }
814 return EndVert;
815 }
816
818
819 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
820 if (!theVert) return {};
821 decltype(theVert->particles_out()) finalStatePart;
822 auto outgoing = theVert->particles_out();
823 for (const auto& thePart: outgoing) {
824 if (!thePart) continue;
825 finalStatePart.push_back(thePart);
826 if (isStable(thePart)) continue;
827 V pVert = findSimulatedEndVertex(thePart);
828 if (pVert == theVert) break; // to prevent Sherpa loop
829 if (pVert != nullptr) {
830 auto vecPart = findFinalStateParticles<V>(pVert);
831 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
832 }
833 }
834 return finalStatePart;
835 }
836#if !defined(XAOD_ANALYSIS)
837#include "AtlasHepMC/GenEvent.h"
838inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
839inline 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());} }
840
841#endif
842}
843#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->particles_in(); }
25
26 namespace Pythia8

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

◆ 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.

27 {
29 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}

◆ 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.

29 { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
30
31 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
32
33 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
34 }
35

◆ set_flow()

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

Definition at line 43 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 template <class VTX>
358 auto particles_in (const VTX* p) { return p->particles_in(); }
359 template <class VTX>
360 auto particles_in (const std::shared_ptr<VTX>& p) { return p->particles_in(); }
361
362 namespace Pythia8
363 {
365 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
366
367 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
368
369 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
370 }
371
372#include "AtlasPID.h"
373
375 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
376
378 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
379
381 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
382
384 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
385
387 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
388
390 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
391
393 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
394
396 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
397
399 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
400
402 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
403
407 template <class T> inline bool isStableOrSimDecayed(const T& p) {
408 const auto vertex = p->end_vertex();
409 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
410 }
411
413 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
414
416 template <class T> inline bool isSpecialNonInteracting(const T& p) {
417 const int apid = std::abs(p->pdg_id());
418 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
419 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
420 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
421 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
422 return false;
423 }
424
426
427 template <class T> T findMother(T thePart) {
428 auto partOriVert = thePart->production_vertex();
429 if (!partOriVert) return nullptr;
430
431 long partPDG = thePart->pdg_id();
432 long MotherPDG(0);
433
434 auto MothOriVert = partOriVert;
435 MothOriVert = nullptr;
436 T theMoth(nullptr);
437
438 size_t itr = 0;
439 do {
440 if (itr != 0) partOriVert = MothOriVert;
441 for ( const auto& p : particles_in(partOriVert) ) {
442 theMoth = p;
443 if (!theMoth) continue;
444 MotherPDG = theMoth->pdg_id();
445 MothOriVert = theMoth->production_vertex();
446 if (MotherPDG == partPDG) break;
447 }
448 itr++;
449 if (itr > 100) {
450 break;
451 }
452 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
453 MothOriVert != partOriVert);
454 return theMoth;
455 }
456
458
459 template <class C, class T> T findMatching(C TruthContainer, T p) {
460 T ptrPart = nullptr;
461 if (!p) return ptrPart;
462 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
463 for (T truthParticle : *TruthContainer) {
464 if (HepMC::is_sim_descendant(p,truthParticle)) {
465 ptrPart = truthParticle;
466 break;
467 }
468 }
469 }
470 else {
471 for (T truthParticle : TruthContainer) {
472 if (HepMC::is_sim_descendant(p,truthParticle)) {
473 ptrPart = truthParticle;
474 break;
475 }
476 }
477 }
478 return ptrPart;
479 }
481
482 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
483 auto prodVtx = thePart->production_vertex();
484 if (!prodVtx) return;
485 for (const auto& theMother: prodVtx->particles_in()) {
486 if (!theMother) continue;
487 allancestors.insert(theMother);
488 findParticleAncestors(theMother, allancestors);
489 }
490 }
491
493
494 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
495 auto endVtx = thePart->end_vertex();
496 if (!endVtx) return;
497 for (const auto& theDaughter: endVtx->particles_out()) {
498 if (!theDaughter) continue;
499 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
500 allstabledescendants.insert(theDaughter);
501 }
502 findParticleStableDescendants(theDaughter, allstabledescendants);
503 }
504 }
505
509
510 template <class T> bool isHardScatteringVertex(T pVert) {
511 if (pVert == nullptr) return false;
512 T pV = pVert;
513 int numOfPartIn(0);
514 int pdg(0);
515
516 do {
517 pVert = pV;
518 auto incoming = pVert->particles_in();
519 numOfPartIn = incoming.size();
520 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
521 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
522
523 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
524
525 if (numOfPartIn == 2) {
526 auto incoming = pVert->particles_in();
527 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;
528 }
529 return false;
530}
531
535
536 template <class T, class U>
537 bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
538 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
539 auto vtx = p->production_vertex();
540 if (!vtx) return false;
541 bool fromHad = false;
542 for ( const auto& parent : particles_in(vtx) ) {
543 if (!parent) continue;
544 // should this really go into parton-level territory?
545 // probably depends where BSM particles are being decayed
546 fromBSM |= isBSM(parent);
547 if (!isPhysical(parent)) return false;
548 fromTau |= isTau(parent);
549 if (isHadron(parent)&&!isBeam(parent)) {
550 if (!hadron) hadron = parent; // assumes linear hadron parentage
551 return true;
552 }
553 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
554 }
555 return fromHad;
556 }
557
560
561 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
562 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
563 decltype(thePart->end_vertex()) pVert(nullptr);
564 if (EndVert != nullptr) {
565 do {
566 bool samePart = false;
567 pVert = nullptr;
568 auto outgoing = EndVert->particles_out();
569 auto incoming = EndVert->particles_in();
570 for (const auto& itrDaug: outgoing) {
571 if (!itrDaug) continue;
572 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
573 // brem on generator level for tau
574 (outgoing.size() == 1 && incoming.size() == 1 &&
576 itrDaug->pdg_id() == thePart->pdg_id()) {
577 samePart = true;
578 pVert = itrDaug->end_vertex();
579 }
580 }
581 if (samePart) EndVert = pVert;
582 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
583 }
584 return EndVert;
585 }
586
588
589 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
590 if (!theVert) return {};
591 decltype(theVert->particles_out()) finalStatePart;
592 auto outgoing = theVert->particles_out();
593 for (const auto& thePart: outgoing) {
594 if (!thePart) continue;
595 finalStatePart.push_back(thePart);
596 if (isStable(thePart)) continue;
597 V pVert = findSimulatedEndVertex(thePart);
598 if (pVert == theVert) break; // to prevent Sherpa loop
599 if (pVert != nullptr) {
600 auto vecPart = findFinalStateParticles<V>(pVert);
601 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
602 }
603 }
604 return finalStatePart;
605 }
606#if !defined(XAOD_ANALYSIS)
607#include "AtlasHepMC/GenEvent.h"
608inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
609inline 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());} }
610
611#endif
612}
613#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 template <class VTX>
605 auto particles_in (const VTX* p) { return p->particles_in(); }
606 template <class VTX>
607 auto particles_in (const std::shared_ptr<VTX>& p) { return p->particles_in(); }
608
609 namespace Pythia8
610 {
612 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
613
614 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
615
616 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
617 }
618
619#include "AtlasPID.h"
620
622 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
623
625 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
626
628 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
629
631 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
632
634 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
635
637 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
638
640 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
641
643 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
644
646 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
647
649 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
650
654 template <class T> inline bool isStableOrSimDecayed(const T& p) {
655 const auto vertex = p->end_vertex();
656 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
657 }
658
660 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
661
663 template <class T> inline bool isSpecialNonInteracting(const T& p) {
664 const int apid = std::abs(p->pdg_id());
665 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
666 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
667 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
668 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
669 return false;
670 }
671
673
674 template <class T> T findMother(T thePart) {
675 auto partOriVert = thePart->production_vertex();
676 if (!partOriVert) return nullptr;
677
678 long partPDG = thePart->pdg_id();
679 long MotherPDG(0);
680
681 auto MothOriVert = partOriVert;
682 MothOriVert = nullptr;
683 T theMoth(nullptr);
684
685 size_t itr = 0;
686 do {
687 if (itr != 0) partOriVert = MothOriVert;
688 for ( const auto& p : particles_in(partOriVert) ) {
689 theMoth = p;
690 if (!theMoth) continue;
691 MotherPDG = theMoth->pdg_id();
692 MothOriVert = theMoth->production_vertex();
693 if (MotherPDG == partPDG) break;
694 }
695 itr++;
696 if (itr > 100) {
697 break;
698 }
699 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
700 MothOriVert != partOriVert);
701 return theMoth;
702 }
703
705
706 template <class C, class T> T findMatching(C TruthContainer, T p) {
707 T ptrPart = nullptr;
708 if (!p) return ptrPart;
709 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
710 for (T truthParticle : *TruthContainer) {
711 if (HepMC::is_sim_descendant(p,truthParticle)) {
712 ptrPart = truthParticle;
713 break;
714 }
715 }
716 }
717 else {
718 for (T truthParticle : TruthContainer) {
719 if (HepMC::is_sim_descendant(p,truthParticle)) {
720 ptrPart = truthParticle;
721 break;
722 }
723 }
724 }
725 return ptrPart;
726 }
728
729 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
730 auto prodVtx = thePart->production_vertex();
731 if (!prodVtx) return;
732 for (const auto& theMother: prodVtx->particles_in()) {
733 if (!theMother) continue;
734 allancestors.insert(theMother);
735 findParticleAncestors(theMother, allancestors);
736 }
737 }
738
740
741 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
742 auto endVtx = thePart->end_vertex();
743 if (!endVtx) return;
744 for (const auto& theDaughter: endVtx->particles_out()) {
745 if (!theDaughter) continue;
746 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
747 allstabledescendants.insert(theDaughter);
748 }
749 findParticleStableDescendants(theDaughter, allstabledescendants);
750 }
751 }
752
756
757 template <class T> bool isHardScatteringVertex(T pVert) {
758 if (pVert == nullptr) return false;
759 T pV = pVert;
760 int numOfPartIn(0);
761 int pdg(0);
762
763 do {
764 pVert = pV;
765 auto incoming = pVert->particles_in();
766 numOfPartIn = incoming.size();
767 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
768 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
769
770 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
771
772 if (numOfPartIn == 2) {
773 auto incoming = pVert->particles_in();
774 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;
775 }
776 return false;
777}
778
782
783 template <class T, class U>
784 bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
785 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
786 auto vtx = p->production_vertex();
787 if (!vtx) return false;
788 bool fromHad = false;
789 for ( const auto& parent : particles_in(vtx) ) {
790 if (!parent) continue;
791 // should this really go into parton-level territory?
792 // probably depends where BSM particles are being decayed
793 fromBSM |= isBSM(parent);
794 if (!isPhysical(parent)) return false;
795 fromTau |= isTau(parent);
796 if (isHadron(parent)&&!isBeam(parent)) {
797 if (!hadron) hadron = parent; // assumes linear hadron parentage
798 return true;
799 }
800 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
801 }
802 return fromHad;
803 }
804
807
808 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
809 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
810 decltype(thePart->end_vertex()) pVert(nullptr);
811 if (EndVert != nullptr) {
812 do {
813 bool samePart = false;
814 pVert = nullptr;
815 auto outgoing = EndVert->particles_out();
816 auto incoming = EndVert->particles_in();
817 for (const auto& itrDaug: outgoing) {
818 if (!itrDaug) continue;
819 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
820 // brem on generator level for tau
821 (outgoing.size() == 1 && incoming.size() == 1 &&
823 itrDaug->pdg_id() == thePart->pdg_id()) {
824 samePart = true;
825 pVert = itrDaug->end_vertex();
826 }
827 }
828 if (samePart) EndVert = pVert;
829 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
830 }
831 return EndVert;
832 }
833
835
836 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
837 if (!theVert) return {};
838 decltype(theVert->particles_out()) finalStatePart;
839 auto outgoing = theVert->particles_out();
840 for (const auto& thePart: outgoing) {
841 if (!thePart) continue;
842 finalStatePart.push_back(thePart);
843 if (isStable(thePart)) continue;
844 V pVert = findSimulatedEndVertex(thePart);
845 if (pVert == theVert) break; // to prevent Sherpa loop
846 if (pVert != nullptr) {
847 auto vecPart = findFinalStateParticles<V>(pVert);
848 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
849 }
850 }
851 return finalStatePart;
852 }
853#if !defined(XAOD_ANALYSIS)
854#include "AtlasHepMC/GenEvent.h"
855inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
856inline 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());} }
857
858#endif
859}
860#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.

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

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

Definition at line 572 of file HepMCHelpers.h.

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

◆ valid_beam_particles()

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

Definition at line 599 of file HepMCHelpers.h.

618{
619 template <class VTX>
620 auto particles_in (const VTX* p) { return p->particles_in(); }
621 template <class VTX>
622 auto particles_in (const std::shared_ptr<VTX>& p) { return p->particles_in(); }
623
624 namespace Pythia8
625 {
627 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
628
629 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
630
631 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
632 }
633
634#include "AtlasPID.h"
635
637 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
638
640 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
641
643 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
644
646 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
647
649 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
650
652 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
653
655 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
656
658 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
659
661 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
662
664 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
665
669 template <class T> inline bool isStableOrSimDecayed(const T& p) {
670 const auto vertex = p->end_vertex();
671 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
672 }
673
675 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
676
678 template <class T> inline bool isSpecialNonInteracting(const T& p) {
679 const int apid = std::abs(p->pdg_id());
680 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
681 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
682 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
683 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
684 return false;
685 }
686
688
689 template <class T> T findMother(T thePart) {
690 auto partOriVert = thePart->production_vertex();
691 if (!partOriVert) return nullptr;
692
693 long partPDG = thePart->pdg_id();
694 long MotherPDG(0);
695
696 auto MothOriVert = partOriVert;
697 MothOriVert = nullptr;
698 T theMoth(nullptr);
699
700 size_t itr = 0;
701 do {
702 if (itr != 0) partOriVert = MothOriVert;
703 for ( const auto& p : particles_in(partOriVert) ) {
704 theMoth = p;
705 if (!theMoth) continue;
706 MotherPDG = theMoth->pdg_id();
707 MothOriVert = theMoth->production_vertex();
708 if (MotherPDG == partPDG) break;
709 }
710 itr++;
711 if (itr > 100) {
712 break;
713 }
714 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
715 MothOriVert != partOriVert);
716 return theMoth;
717 }
718
720
721 template <class C, class T> T findMatching(C TruthContainer, T p) {
722 T ptrPart = nullptr;
723 if (!p) return ptrPart;
724 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
725 for (T truthParticle : *TruthContainer) {
726 if (HepMC::is_sim_descendant(p,truthParticle)) {
727 ptrPart = truthParticle;
728 break;
729 }
730 }
731 }
732 else {
733 for (T truthParticle : TruthContainer) {
734 if (HepMC::is_sim_descendant(p,truthParticle)) {
735 ptrPart = truthParticle;
736 break;
737 }
738 }
739 }
740 return ptrPart;
741 }
743
744 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
745 auto prodVtx = thePart->production_vertex();
746 if (!prodVtx) return;
747 for (const auto& theMother: prodVtx->particles_in()) {
748 if (!theMother) continue;
749 allancestors.insert(theMother);
750 findParticleAncestors(theMother, allancestors);
751 }
752 }
753
755
756 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
757 auto endVtx = thePart->end_vertex();
758 if (!endVtx) return;
759 for (const auto& theDaughter: endVtx->particles_out()) {
760 if (!theDaughter) continue;
761 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
762 allstabledescendants.insert(theDaughter);
763 }
764 findParticleStableDescendants(theDaughter, allstabledescendants);
765 }
766 }
767
771
772 template <class T> bool isHardScatteringVertex(T pVert) {
773 if (pVert == nullptr) return false;
774 T pV = pVert;
775 int numOfPartIn(0);
776 int pdg(0);
777
778 do {
779 pVert = pV;
780 auto incoming = pVert->particles_in();
781 numOfPartIn = incoming.size();
782 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
783 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
784
785 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
786
787 if (numOfPartIn == 2) {
788 auto incoming = pVert->particles_in();
789 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;
790 }
791 return false;
792}
793
797
798 template <class T, class U>
799 bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
800 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
801 auto vtx = p->production_vertex();
802 if (!vtx) return false;
803 bool fromHad = false;
804 for ( const auto& parent : particles_in(vtx) ) {
805 if (!parent) continue;
806 // should this really go into parton-level territory?
807 // probably depends where BSM particles are being decayed
808 fromBSM |= isBSM(parent);
809 if (!isPhysical(parent)) return false;
810 fromTau |= isTau(parent);
811 if (isHadron(parent)&&!isBeam(parent)) {
812 if (!hadron) hadron = parent; // assumes linear hadron parentage
813 return true;
814 }
815 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
816 }
817 return fromHad;
818 }
819
822
823 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
824 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
825 decltype(thePart->end_vertex()) pVert(nullptr);
826 if (EndVert != nullptr) {
827 do {
828 bool samePart = false;
829 pVert = nullptr;
830 auto outgoing = EndVert->particles_out();
831 auto incoming = EndVert->particles_in();
832 for (const auto& itrDaug: outgoing) {
833 if (!itrDaug) continue;
834 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
835 // brem on generator level for tau
836 (outgoing.size() == 1 && incoming.size() == 1 &&
838 itrDaug->pdg_id() == thePart->pdg_id()) {
839 samePart = true;
840 pVert = itrDaug->end_vertex();
841 }
842 }
843 if (samePart) EndVert = pVert;
844 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
845 }
846 return EndVert;
847 }
848
850
851 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
852 if (!theVert) return {};
853 decltype(theVert->particles_out()) finalStatePart;
854 auto outgoing = theVert->particles_out();
855 for (const auto& thePart: outgoing) {
856 if (!thePart) continue;
857 finalStatePart.push_back(thePart);
858 if (isStable(thePart)) continue;
859 V pVert = findSimulatedEndVertex(thePart);
860 if (pVert == theVert) break; // to prevent Sherpa loop
861 if (pVert != nullptr) {
862 auto vecPart = findFinalStateParticles<V>(pVert);
863 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
864 }
865 }
866 return finalStatePart;
867 }
868#if !defined(XAOD_ANALYSIS)
869#include "AtlasHepMC/GenEvent.h"
870inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
871inline 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());} }
872
873#endif
874}
875#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 template <class VTX>
367 auto particles_in (const VTX* p) { return p->particles_in(); }
368 template <class VTX>
369 auto particles_in (const std::shared_ptr<VTX>& p) { return p->particles_in(); }
370
371 namespace Pythia8
372 {
374 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
375
376 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
377
378 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
379 }
380
381#include "AtlasPID.h"
382
384 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
385
387 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
388
390 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
391
393 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
394
396 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
397
399 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
400
402 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
403
405 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
406
408 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
409
411 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
412
416 template <class T> inline bool isStableOrSimDecayed(const T& p) {
417 const auto vertex = p->end_vertex();
418 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
419 }
420
422 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
423
425 template <class T> inline bool isSpecialNonInteracting(const T& p) {
426 const int apid = std::abs(p->pdg_id());
427 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
428 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
429 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
430 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
431 return false;
432 }
433
435
436 template <class T> T findMother(T thePart) {
437 auto partOriVert = thePart->production_vertex();
438 if (!partOriVert) return nullptr;
439
440 long partPDG = thePart->pdg_id();
441 long MotherPDG(0);
442
443 auto MothOriVert = partOriVert;
444 MothOriVert = nullptr;
445 T theMoth(nullptr);
446
447 size_t itr = 0;
448 do {
449 if (itr != 0) partOriVert = MothOriVert;
450 for ( const auto& p : particles_in(partOriVert) ) {
451 theMoth = p;
452 if (!theMoth) continue;
453 MotherPDG = theMoth->pdg_id();
454 MothOriVert = theMoth->production_vertex();
455 if (MotherPDG == partPDG) break;
456 }
457 itr++;
458 if (itr > 100) {
459 break;
460 }
461 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
462 MothOriVert != partOriVert);
463 return theMoth;
464 }
465
467
468 template <class C, class T> T findMatching(C TruthContainer, T p) {
469 T ptrPart = nullptr;
470 if (!p) return ptrPart;
471 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
472 for (T truthParticle : *TruthContainer) {
473 if (HepMC::is_sim_descendant(p,truthParticle)) {
474 ptrPart = truthParticle;
475 break;
476 }
477 }
478 }
479 else {
480 for (T truthParticle : TruthContainer) {
481 if (HepMC::is_sim_descendant(p,truthParticle)) {
482 ptrPart = truthParticle;
483 break;
484 }
485 }
486 }
487 return ptrPart;
488 }
490
491 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
492 auto prodVtx = thePart->production_vertex();
493 if (!prodVtx) return;
494 for (const auto& theMother: prodVtx->particles_in()) {
495 if (!theMother) continue;
496 allancestors.insert(theMother);
497 findParticleAncestors(theMother, allancestors);
498 }
499 }
500
502
503 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
504 auto endVtx = thePart->end_vertex();
505 if (!endVtx) return;
506 for (const auto& theDaughter: endVtx->particles_out()) {
507 if (!theDaughter) continue;
508 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
509 allstabledescendants.insert(theDaughter);
510 }
511 findParticleStableDescendants(theDaughter, allstabledescendants);
512 }
513 }
514
518
519 template <class T> bool isHardScatteringVertex(T pVert) {
520 if (pVert == nullptr) return false;
521 T pV = pVert;
522 int numOfPartIn(0);
523 int pdg(0);
524
525 do {
526 pVert = pV;
527 auto incoming = pVert->particles_in();
528 numOfPartIn = incoming.size();
529 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
530 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
531
532 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
533
534 if (numOfPartIn == 2) {
535 auto incoming = pVert->particles_in();
536 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;
537 }
538 return false;
539}
540
544
545 template <class T, class U>
546 bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
547 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
548 auto vtx = p->production_vertex();
549 if (!vtx) return false;
550 bool fromHad = false;
551 for ( const auto& parent : particles_in(vtx) ) {
552 if (!parent) continue;
553 // should this really go into parton-level territory?
554 // probably depends where BSM particles are being decayed
555 fromBSM |= isBSM(parent);
556 if (!isPhysical(parent)) return false;
557 fromTau |= isTau(parent);
558 if (isHadron(parent)&&!isBeam(parent)) {
559 if (!hadron) hadron = parent; // assumes linear hadron parentage
560 return true;
561 }
562 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
563 }
564 return fromHad;
565 }
566
569
570 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
571 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
572 decltype(thePart->end_vertex()) pVert(nullptr);
573 if (EndVert != nullptr) {
574 do {
575 bool samePart = false;
576 pVert = nullptr;
577 auto outgoing = EndVert->particles_out();
578 auto incoming = EndVert->particles_in();
579 for (const auto& itrDaug: outgoing) {
580 if (!itrDaug) continue;
581 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
582 // brem on generator level for tau
583 (outgoing.size() == 1 && incoming.size() == 1 &&
585 itrDaug->pdg_id() == thePart->pdg_id()) {
586 samePart = true;
587 pVert = itrDaug->end_vertex();
588 }
589 }
590 if (samePart) EndVert = pVert;
591 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
592 }
593 return EndVert;
594 }
595
597
598 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
599 if (!theVert) return {};
600 decltype(theVert->particles_out()) finalStatePart;
601 auto outgoing = theVert->particles_out();
602 for (const auto& thePart: outgoing) {
603 if (!thePart) continue;
604 finalStatePart.push_back(thePart);
605 if (isStable(thePart)) continue;
606 V pVert = findSimulatedEndVertex(thePart);
607 if (pVert == theVert) break; // to prevent Sherpa loop
608 if (pVert != nullptr) {
609 auto vecPart = findFinalStateParticles<V>(pVert);
610 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
611 }
612 }
613 return finalStatePart;
614 }
615#if !defined(XAOD_ANALYSIS)
616#include "AtlasHepMC/GenEvent.h"
617inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
618inline 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());} }
619
620#endif
621}
622#endif