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

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: