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

Attribute for linking GenParticles between GenEvents. More...

#include <HepMCHelpers.h>

Inheritance diagram for MC::HepMC::ShadowParticle:
Collaboration diagram for MC::HepMC::ShadowParticle:

Public Member Functions

 ShadowParticle ()
 Default constructor.
 ShadowParticle (ConstGenParticlePtr p)
 Constructor initializing attribute value.
virtual bool from_string (const std::string &) override
 Implementation of Attribute::from_string.
virtual bool to_string (std::string &att) const override
 Implementation of Attribute::to_string.
ConstGenParticlePtr value () const
 get a pointer to the shadow particle.

Private Attributes

ConstGenParticlePtr m_shadow
 The shadow particle.

Detailed Description

Attribute for linking GenParticles between GenEvents.

Variation of the AssociatedParticle Attribute, which allows GenParticles to be linked between GenEvents. For transient use only as the from_string(...) method is not defined

Definition at line 308 of file HepMCHelpers.h.

Constructor & Destructor Documentation

◆ ShadowParticle() [1/2]

MC::HepMC::ShadowParticle::ShadowParticle ( )
inline

Default constructor.

Definition at line 312 of file HepMCHelpers.h.

331{
332 template <class VTX>
333 auto particles_in (const VTX* p) { return p->particles_in(); }
334 template <class VTX>
335 auto particles_in (const std::shared_ptr<VTX>& p) { return p->particles_in(); }
336
337 namespace Pythia8
338 {
340 template <class T> inline bool isConditionA(const T& p) { return p->status() == 62 || p->status() == 52 || p->status() == 21 || p->status() == 22;}
341
342 template <class T> inline bool isConditionB(const T& p) { return p->status() == 23;}
343
344 template <class T> inline bool isConditionC(const T& p) { return p->status() > 30 && p->status() < 40;}
345 }
346
347#include "AtlasPID.h"
348
350 template <class T> inline bool isInteracting(const T& p) { return isStrongInteracting<T>(p) || isEMInteracting<T>(p) || isGeantino<T>(p); }
351
353 template <class T> inline bool isChargedNonShowering(const T& p) { return (isMuon<T>(p) || isSUSY<T>(p)); }
354
356 template <class T> inline bool isBeam(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 4;}
357
359 template <class T> inline bool isDecayed(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 2;}
360
362 template <class T> inline bool isStable(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1;}
363
365 template <class T> inline bool isFinalState(const T& p) { return HepMC::status(p)%HepMC::SIM_STATUS_THRESHOLD == 1 && !p->end_vertex();}
366
368 template <class T> inline bool isPhysical(const T& p) { return isStable<T>(p) || isDecayed<T>(p); }
369
371 template <class T> inline bool isGenStable(const T& p) { return isStable<T>(p) && !HepMC::is_simulation_particle<T>(p);}
372
374 template <class T> inline bool isSimStable(const T& p) { return isStable<T>(p) && !p->end_vertex() && HepMC::is_simulation_particle<T>(p);}
375
377 template <class T> inline bool isSimInteracting(const T& p) { return isGenStable<T>(p) && isInteracting<T>(p);}
378
382 template <class T> inline bool isStableOrSimDecayed(const T& p) {
383 const auto vertex = p->end_vertex();
384 return ( isStable<T>(p) || (isDecayed<T>(p) && (!vertex || HepMC::is_simulation_vertex(vertex))));
385 }
386
388 template <class T> inline bool isZeroEnergyPhoton(const T& p) { return isPhoton<T>(p) && p->e() == 0;}
389
391 template <class T> inline bool isSpecialNonInteracting(const T& p) {
392 const int apid = std::abs(p->pdg_id());
393 if (apid == NU_E || apid == NU_MU || apid == NU_TAU) return true; //< neutrinos
394 if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners
395 if (apid == GRAVITON || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK
396 if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model
397 return false;
398 }
399
401
402 template <class T> T findMother(T thePart) {
403 auto partOriVert = thePart->production_vertex();
404 if (!partOriVert) return nullptr;
405
406 long partPDG = thePart->pdg_id();
407 long MotherPDG(0);
408
409 auto MothOriVert = partOriVert;
410 MothOriVert = nullptr;
411 T theMoth(nullptr);
412
413 size_t itr = 0;
414 do {
415 if (itr != 0) partOriVert = MothOriVert;
416 for ( const auto& p : particles_in(partOriVert) ) {
417 theMoth = p;
418 if (!theMoth) continue;
419 MotherPDG = theMoth->pdg_id();
420 MothOriVert = theMoth->production_vertex();
421 if (MotherPDG == partPDG) break;
422 }
423 itr++;
424 if (itr > 100) {
425 break;
426 }
427 } while (MothOriVert != nullptr && MotherPDG == partPDG && !HepMC::is_simulation_particle(thePart) &&
428 MothOriVert != partOriVert);
429 return theMoth;
430 }
431
433
434 template <class C, class T> T findMatching(C TruthContainer, T p) {
435 T ptrPart = nullptr;
436 if (!p) return ptrPart;
437 if constexpr (std::is_pointer_v<C> || HepMC::is_smart_ptr_v<C>){ //C is ptr
438 for (T truthParticle : *TruthContainer) {
439 if (HepMC::is_sim_descendant(p,truthParticle)) {
440 ptrPart = truthParticle;
441 break;
442 }
443 }
444 }
445 else {
446 for (T truthParticle : TruthContainer) {
447 if (HepMC::is_sim_descendant(p,truthParticle)) {
448 ptrPart = truthParticle;
449 break;
450 }
451 }
452 }
453 return ptrPart;
454 }
456
457 template <class T> void findParticleAncestors(T thePart, std::set<T>& allancestors) {
458 auto prodVtx = thePart->production_vertex();
459 if (!prodVtx) return;
460 for (const auto& theMother: prodVtx->particles_in()) {
461 if (!theMother) continue;
462 allancestors.insert(theMother);
463 findParticleAncestors(theMother, allancestors);
464 }
465 }
466
468
469 template <class T> void findParticleStableDescendants(T thePart, std::set<T>& allstabledescendants) {
470 auto endVtx = thePart->end_vertex();
471 if (!endVtx) return;
472 for (const auto& theDaughter: endVtx->particles_out()) {
473 if (!theDaughter) continue;
474 if (isStable(theDaughter) && !HepMC::is_simulation_particle(theDaughter)) {
475 allstabledescendants.insert(theDaughter);
476 }
477 findParticleStableDescendants(theDaughter, allstabledescendants);
478 }
479 }
480
484
485 template <class T> bool isHardScatteringVertex(T pVert) {
486 if (pVert == nullptr) return false;
487 T pV = pVert;
488 int numOfPartIn(0);
489 int pdg(0);
490
491 do {
492 pVert = pV;
493 auto incoming = pVert->particles_in();
494 numOfPartIn = incoming.size();
495 pdg = numOfPartIn && incoming.front() != nullptr ? incoming.front()->pdg_id() : 0;
496 pV = numOfPartIn && incoming.front() != nullptr ? incoming.front()->production_vertex() : nullptr;
497
498 } while (numOfPartIn == 1 && (std::abs(pdg) < 81 || std::abs(pdg) > 100) && pV != nullptr);
499
500 if (numOfPartIn == 2) {
501 auto incoming = pVert->particles_in();
502 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;
503 }
504 return false;
505}
506
510
511 template <class T, class U>
512 bool isFromHadron(T p, U hadron, bool &fromTau, bool &fromBSM) {
513 if (isHadron(p)&&!isBeam(p)) return true; // trivial case
514 auto vtx = p->production_vertex();
515 if (!vtx) return false;
516 bool fromHad = false;
517 for ( const auto& parent : particles_in(vtx) ) {
518 if (!parent) continue;
519 // should this really go into parton-level territory?
520 // probably depends where BSM particles are being decayed
521 fromBSM |= isBSM(parent);
522 if (!isPhysical(parent)) return false;
523 fromTau |= isTau(parent);
524 if (isHadron(parent)&&!isBeam(parent)) {
525 if (!hadron) hadron = parent; // assumes linear hadron parentage
526 return true;
527 }
528 fromHad |= isFromHadron(parent, hadron, fromTau, fromBSM);
529 }
530 return fromHad;
531 }
532
535
536 template <class T> auto findSimulatedEndVertex(T thePart) -> decltype(thePart->end_vertex()) {
537 decltype(thePart->end_vertex()) EndVert = thePart->end_vertex();
538 decltype(thePart->end_vertex()) pVert(nullptr);
539 if (EndVert != nullptr) {
540 do {
541 bool samePart = false;
542 pVert = nullptr;
543 auto outgoing = EndVert->particles_out();
544 auto incoming = EndVert->particles_in();
545 for (const auto& itrDaug: outgoing) {
546 if (!itrDaug) continue;
547 if ((( HepMC::is_same_generator_particle(itrDaug,thePart)) ||
548 // brem on generator level for tau
549 (outgoing.size() == 1 && incoming.size() == 1 &&
551 itrDaug->pdg_id() == thePart->pdg_id()) {
552 samePart = true;
553 pVert = itrDaug->end_vertex();
554 }
555 }
556 if (samePart) EndVert = pVert;
557 } while (pVert != nullptr && pVert != EndVert); // pVert!=EndVert to prevent Sherpa loop
558 }
559 return EndVert;
560 }
561
563
564 template <class V> auto findFinalStateParticles(V theVert) -> decltype(theVert->particles_out()) {
565 if (!theVert) return {};
566 decltype(theVert->particles_out()) finalStatePart;
567 auto outgoing = theVert->particles_out();
568 for (const auto& thePart: outgoing) {
569 if (!thePart) continue;
570 finalStatePart.push_back(thePart);
571 if (isStable(thePart)) continue;
572 V pVert = findSimulatedEndVertex(thePart);
573 if (pVert == theVert) break; // to prevent Sherpa loop
574 if (pVert != nullptr) {
575 auto vecPart = findFinalStateParticles<V>(pVert);
576 finalStatePart.insert(finalStatePart.end(),vecPart.begin(),vecPart.end());
577 }
578 }
579 return finalStatePart;
580 }
581#if !defined(XAOD_ANALYSIS)
582#include "AtlasHepMC/GenEvent.h"
583inline void GeVToMeV(HepMC::GenEvent* evt) { for (auto& p: evt->particles()) { p->set_momentum(p->momentum()*1000); p->set_generated_mass(1000* p->generated_mass());}}
584inline 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());} }
585
586#endif
587}
588#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).
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 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 isConditionA(const T &p)
To be understood.
bool isConditionC(const T &p)
T findMatching(C TruthContainer, T p)
Function to find a particle in container.
static const int GRAVITON
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 isStable(const T &p)
Identify if the particle is stable, i.e. has not decayed.
bool isGeantino(const T &p)
bool isSimInteracting(const T &p)
Identify if the particle could interact with the detector during the simulation, e....
void GeVToMeV(HepMC::GenEvent *evt)
bool isEMInteracting(const T &p)
void findParticleAncestors(T thePart, std::set< T > &allancestors)
Function to find all ancestors of the particle.
bool isStrongInteracting(const T &p)
bool isInteracting(const T &p)
Identify if the particle with given PDG ID would not interact with the detector, i....
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.
unsigned long long T

◆ ShadowParticle() [2/2]

MC::HepMC::ShadowParticle::ShadowParticle ( ConstGenParticlePtr p)
inline

Constructor initializing attribute value.

Definition at line 315 of file HepMCHelpers.h.

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

Member Function Documentation

◆ from_string()

virtual bool MC::HepMC::ShadowParticle::from_string ( const std::string & )
inlineoverridevirtual

Implementation of Attribute::from_string.

Definition at line 319 of file HepMCHelpers.h.

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

◆ to_string()

virtual bool MC::HepMC::ShadowParticle::to_string ( std::string & att) const
inlineoverridevirtual

Implementation of Attribute::to_string.

Definition at line 322 of file HepMCHelpers.h.

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

◆ value()

ConstGenParticlePtr MC::HepMC::ShadowParticle::value ( ) const
inline

get a pointer to the shadow particle.

Definition at line 328 of file HepMCHelpers.h.

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

Member Data Documentation

◆ m_shadow

ConstGenParticlePtr MC::HepMC::ShadowParticle::m_shadow
private

The shadow particle.

Definition at line 334 of file HepMCHelpers.h.


The documentation for this class was generated from the following file: