20#include "GaudiKernel/SystemOfUnits.h"
26using Gaudi::Units::GeV;
31 const IInterface* p ) :
37 declareProperty (
"WritePartons",
41 declareProperty (
"WriteHadrons",
45 declareProperty (
"WriteBHadrons",
49 declareProperty (
"WriteCHadrons",
53 declareProperty (
"WriteGeant",
55 "Keep Geant particles?");
57 declareProperty (
"GeantPhotonPtThresh",
59 "Write Geant photons with Pt above this threshold. "
60 "Set to < 0 to not write any.");
62 declareProperty (
"WriteTauHad",
64 "Keep hadronic taus?");
66 declareProperty (
"PartonPtThresh",
68 "Write partons with Pt above this threshold.");
70 declareProperty (
"WriteBSM",
72 "Keep BSM particles?");
74 declareProperty (
"WriteBosons",
78 declareProperty (
"PhotonPtThresh",
80 "Photon pt cut with WriteBosons");
82 declareProperty (
"WriteBSMProducts",
84 "Keep BSM particle decay products?");
86 declareProperty (
"WriteBosonProducts",
88 "Keep boson decay products?");
90 declareProperty (
"WriteTopAndDecays",
92 "Keep top partons and immediate decay products?");
94 declareProperty(
"WriteEverything",
96 "Keep absolutely everything (overrides all other flags)");
98 declareProperty(
"WriteAllLeptons",
100 "Keep absolutely all leptons");
102 declareProperty(
"WriteLeptonsNotFromHadrons",
104 "Keep leptons not from hadron decays");
106 declareProperty(
"WriteAllStable",
108 "Keep all stable particles");
110 declareProperty(
"WriteNotPhysical",
112 "Save also non-physical particles");
114 declareProperty(
"WriteFirstN",
116 "Keep first N particles in record");
118 declareProperty(
"PreserveDescendants",
120 "Preserve descendants of retained particles");
122 declareProperty(
"PreserveGeneratorDescendants",
124 "Preserve descendants of retained particles excluding Geant particles");
126 declareProperty(
"PreserveAncestors",
128 "Preserve ancestors of retained particles");
130 declareProperty (
"PreserveParentsSiblingsChildren",
132 "Preserve the parents, siblings and children of retained particles");
134 declareProperty (
"PreserveHadronizationVertices",
136 "Preserve hadronization vertices with parents/children.");
138 declareProperty (
"WritettHFHadrons",
140 "Keep tt+HF hadrons?");
142 declareProperty (
"PDGIDsToKeep",
144 "List of PDG IDs to always keep");
146 declareProperty (
"LongLivedPDGIDs",
148 "List of PDG IDs of long lived particles so that one can store their children");
159 ATH_MSG_FATAL(
"You are asking to keep both all descendants, and only those from the event generator. Please check your job options.");
160 return StatusCode::FAILURE;
163 ATH_MSG_FATAL(
"You are asking to preserve only parents/children/siblings of retained states, and also more distant relatives. Please check your job options.");
164 return StatusCode::FAILURE;
172 return StatusCode::SUCCESS;
180 return StatusCode::SUCCESS;
190 m_totpart += importedTruthParticles->size();
202 std::vector<bool> particleMask, vertexMask;
203 int nTruthParticles = importedTruthParticles->size();
204 int nTruthVertices = importedTruthVertices->size();
205 particleMask.assign(nTruthParticles,
true);
206 vertexMask.assign(nTruthVertices,
false);
209 for (
int particleCounter = 0; particleCounter < nTruthParticles; ++particleCounter) {
214 particleMask[particleCounter] =
false;
226 std::unordered_set<int> encounteredUniqueIDs;
228 for (
int i=0; i<nTruthParticles; ++i) {
229 bool toKeep = particleMask[i];
230 if (!toKeep)
continue;
232 encounteredUniqueIDs.clear();
234 encounteredUniqueIDs.clear();
236 encounteredUniqueIDs.clear();
238 encounteredUniqueIDs.clear();
246 std::vector<bool> particleMaskCopy = particleMask;
247 for (
int i=0; i<nTruthParticles; ++i) {
248 bool toKeep = particleMask[i];
249 if (!toKeep)
continue;
254 particleMask = particleMaskCopy;
258 importedTruthParticles.
keep (particleMask);
259 importedTruthVertices.
keep (vertexMask);
261 return StatusCode::SUCCESS;
269 int pdg_id = p->absPdgId();
306 int motherPDGID = 999999999;
313 if (mother) motherPDGID = mother->
pdgId();
328 std::unordered_set<int> uniqueID_trace;
359 for(
unsigned int itr=0; itr<nIncoming; ++itr) {
361 if (!incomingParticle)
continue;
374 if (pdg_id==
id) ok=
true;
383 std::vector<int> hadrons = std::vector<int>{111};
384 std::vector<int>
taus = std::vector<int>{15,-15};
391 std::vector<int> quarks = std::vector<int>{1,6};
392 std::vector<int>
taus = std::vector<int>{15,-15};
401 int pdgId = part->pdgId();
403 if (!part->hasProdVtx())
return true;
407 unsigned int itrParent = 0;
410 if (prodVtx==part->decayVtx())
return false;
413 if(nIncoming == 0)
return true;
415 unsigned int nParents = 0;
416 while(nParents==0 && itrParent<nIncoming) {
420 if(incomingParticle->
pdgId() == pdgId) {
431 return (nParents==0);
435 std::vector<int> &intermediatePdgIds,
bool targetsAreRange)
const {
439 int pdgId = part->pdgId();
444 std::vector<int>::const_iterator itrPdgId, itrPdgIdEnd;
446 if (!part->hasProdVtx())
return false;
453 if (prodVtx==part->decayVtx())
return false;
455 unsigned int itrParent = 0;
456 while(!found && itrParent<nIncoming) {
459 if(!targetsAreRange) {
462 itrPdgId = targetPdgIds.begin();
463 itrPdgIdEnd = targetPdgIds.end();
464 for(;itrPdgId != itrPdgIdEnd; ++itrPdgId) {
465 if(incomingParticle->
pdgId() == (*itrPdgId))
return true;
469 int absPdgId = incomingParticle->
absPdgId();
472 if(targetPdgIds.size() == 1) {
473 if(absPdgId >= targetPdgIds.at(0))
return true;
475 else if(targetPdgIds.size() >= 2) {
476 if(absPdgId >= targetPdgIds.at(0) &&
477 absPdgId <= targetPdgIds.at(1))
return true;
482 if(incomingParticle->
pdgId() == pdgId) {
483 found =
matchGenParticle(incomingParticle, targetPdgIds, intermediatePdgIds, targetsAreRange);
487 itrPdgId = intermediatePdgIds.begin();
488 itrPdgIdEnd = intermediatePdgIds.end();
489 bool foundIntermediate =
false;
490 while(!foundIntermediate && itrPdgId != itrPdgIdEnd) {
491 if(incomingParticle->
pdgId() == (*itrPdgId)) foundIntermediate =
true;
494 if(foundIntermediate) {
495 found =
matchGenParticle(incomingParticle, targetPdgIds, intermediatePdgIds, targetsAreRange);
506 int pdg = part->pdgId();
511 if(!prod)
return false;
514 if (prod==part->decayVtx())
return false;
518 for(
unsigned int itr = 0; itr<nIncoming; ++itr){
521 ATH_MSG_DEBUG(
"Particle with pdgId = " << pdg <<
", matched to tau");
525 if(parentId == pdg) {
539 std::unordered_set<int>& uniqueID_trace)
const {
541 int pdg = part->pdgId();
544 if(!prod)
return false;
547 if (prod==part->decayVtx())
return false;
550 std::unordered_set<int>::const_iterator foundVtx = uniqueID_trace.find(
HepMC::uniqueID(prod) );
551 if( foundVtx != uniqueID_trace.end() ) {
552 ATH_MSG_DEBUG(
"Found a loop (a la Sherpa sample). Backing out." );
559 for (
unsigned int pitr = 0; pitr<nIncoming; ++pitr){
561 if (!itrParent)
continue;
567 bool has_fsr =
false;
570 for (
unsigned int citr = 0; citr<nChildren; ++citr) {
572 if (!itrChild)
continue;
579 if (has_fsr)
return false;
580 ATH_MSG_DEBUG(
"Particle with pdgId = " << pdg <<
", matched to tau");
585 if(
isFromTau(itrParent, uniqueID_trace)) {
597 int ttHFClassification=6;
601 ttHFClassification = TopHadronOriginFlagAcc(*part);
607 if (ttHFClassification < 6 )
615 int pdg = part->pdgId();
619 if(!prod)
return false;
621 if (prod==part->decayVtx())
return false;
624 for(
unsigned int pitr=0; pitr<nIncoming; ++pitr){
626 int parentId = itrParent->
pdgId();
633 if(parentId == pdg) {
644 for(
size_t parent_itr = 0; parent_itr < part->nParents(); parent_itr++){
645 if(!part->parent(parent_itr))
continue;
647 const int parent_abs_pdgid = abs(parent->pdgId());
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
Helper class to provide constant type-safe access to aux data.
Helpers for checking error return status codes and reporting errors.
ATLAS-specific HepMC functions.
Handle for requesting thinning for a data object.
Helper class to provide constant type-safe access to aux data.
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
void keep(size_t ndx)
Mark that index ndx in the container should be kept (not thinned away).
Handle for requesting thinning for a data object.
int pdgId() const
PDG ID code.
const TruthVertex_v1 * decayVtx() const
The decay vertex of this particle.
int absPdgId() const
Absolute PDG ID code (often useful).
bool hasDecayVtx() const
Check for a decay vertex on this particle.
virtual double pt() const override final
The transverse momentum ( ) of the particle.
const TruthParticle_v1 * outgoingParticle(size_t index) const
Get one of the outgoing particles.
const TruthParticle_v1 * incomingParticle(size_t index) const
Get one of the incoming particles.
size_t nOutgoingParticles() const
Get the number of outgoing particles.
size_t nIncomingParticles() const
Get the number of incoming particles.
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...
bool isCharmHadron(const T &p)
bool isSMLepton(const T &p)
APID: the fourth generation leptons are not standard model leptons.
bool isPhoton(const T &p)
bool isBottomHadron(const T &p)
bool isElectron(const T &p)
bool isStable(const T &p)
Identify if the particle is stable, i.e. has not decayed.
bool isHiggs(const T &p)
APID: HIGGS boson is only one particle.
bool isHadron(const T &p)
bool isLepton(const T &p)
APID: the fourth generation leptons are leptons.
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.
TruthVertex_v1 TruthVertex
Typedef to implementation.
TruthParticle_v1 TruthParticle
Typedef to implementation.
void descendants(const xAOD::TruthParticle *pHead, std::vector< int > &particleList, std::unordered_set< int > &encounteredUniqueIDs)
void ancestors(const xAOD::TruthParticle *pHead, std::vector< bool > &particleMask, std::vector< bool > &vertexMask, std::unordered_set< int > &encounteredUniqueIDs)
void immediateRelatives(const xAOD::TruthParticle *pHead, std::vector< bool > &particleMask, std::vector< bool > &vertexMask, bool keepHadVtx)