ATLAS Offline Software
Loading...
Searching...
No Matches
GenericTruthThinning.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6// GenericTruthThinning.cxx, (c) ATLAS Detector software
8// Author: James Catmore (James.Catmore@cern.ch)
9// Removes all truth particles/vertices which do not pass a user-defined cut
10
16#include "GaudiKernel/ThreadLocalContext.h"
17
19
20#include <vector>
21#include <string>
22
23// Constructor
25 const std::string& n,
26 const IInterface* p ) :
27base_class(t,n,p),
28m_ntotvtx(0),
29m_ntotpart(0),
30m_npassvtx(0),
32m_partString(""),
33//m_vtxString(""),
37m_tauHandling(true)
38{
39 declareProperty("ParticleSelectionString", m_partString);
40 //declareProperty("VertexSelectionString", m_vtxString);
41 declareProperty("PreserveDescendants", m_preserveDescendants);
42 declareProperty("PreserveGeneratorDescendants", m_preserveGeneratorDescendants);
43 declareProperty("PreserveAncestors", m_preserveAncestors);
44 declareProperty("TauHandling", m_tauHandling);
45}
46
47// Destructor
50
51// Athena initialize and finalize
53{
54 ATH_MSG_VERBOSE("initialize() ...");
56 ATH_CHECK( m_verticesKey.initialize (m_streamName) );
57 ATH_MSG_INFO("Using " << m_particlesKey.key() << " and "<< m_verticesKey.key() << " as the source collections for truth thinning");
58
59 if (m_partString.empty()/* && m_vtxString==""*/) {
60 ATH_MSG_FATAL("No selection string provided either for vertices or particles!");
61 return StatusCode::FAILURE;
62 } else {ATH_MSG_INFO("Truth thinning selection strings: " << m_partString /*<< " " << m_vtxString*/);}
63
65 ATH_MSG_FATAL("You are asking to keep both all descendants, and only those from the event generator. Please check your job options.");
66 return StatusCode::FAILURE;
67 }
68 // Set up the text-parsing machinery for thinning the truth directly according to user cuts
69 if (!m_partString.empty()) {
70 ATH_CHECK( initializeParser(m_partString) );
71 }
72 return StatusCode::SUCCESS;
73}
74
76{
77 ATH_MSG_VERBOSE("finalize() ...");
78 ATH_MSG_INFO("Processed "<< m_ntotvtx <<" truth vertices, "<< m_npassvtx << " were retained ");
79 ATH_MSG_INFO("Processed "<< m_ntotpart <<" truth particles, "<< m_npasspart << " were retained ");
80 ATH_CHECK(finalizeParser());
81 return StatusCode::SUCCESS;
82}
83
84// The thinning itself
86{
87 const EventContext& ctx = Gaudi::Hive::currentContext();
88
89 // Retrieve truth collections
91 (m_particlesKey, ctx);
93 (m_verticesKey, ctx);
94
95 // Set up a mask with the same entries as the full collections
96 unsigned int nParticles = importedTruthParticles->size();
97 unsigned int nVertices = importedTruthVertices->size();
98 std::vector<bool> partMask, vertMask;
99 partMask.assign(nParticles,false); // default: don't keep any truth items
100 vertMask.assign(nVertices,false);
101 m_ntotvtx += nVertices; m_ntotpart += nParticles;
102
103 // Execute the text parsers and update the mask
104 if (!m_partString.empty()) {
105 std::vector<int> entries = m_parser->evaluateAsVector();
106 unsigned int nEntries = entries.size();
107 // check the sizes are compatible
108 if (nParticles != nEntries ) {
109 ATH_MSG_ERROR("Sizes incompatible! Are you sure your selection string used TruthParticles?");
110 return StatusCode::FAILURE;
111 } else {
112 // set mask
113 for (unsigned int i=0; i<nParticles; ++i) if (entries[i]==1) partMask[i]=true;
114 }
115 }
116
117 // Special treatment of taus such that only the last one in the chain is kept
118 // Needs another run over the particle collection
119 if (m_tauHandling) {
121 for (unsigned int i=0; i<nParticles; ++i) {
122 const xAOD::TruthParticle* particle = (*importedTruthParticles)[i];
123 if ( MC::isTau(particle) ) { // This is a tau
124 bool last(true);
125 std::vector<int> tauDecayProducts; // all decay products of the tau
126 std::unordered_set<int> tauDecayEncounteredUniqueIDs; // loop checking
127 tauDecayHelper.descendants(particle,tauDecayProducts,tauDecayEncounteredUniqueIDs); // recursive
128 for (unsigned int tauDecIt=0; tauDecIt<tauDecayProducts.size(); ++tauDecIt) {
129 if (std::abs(tauDecayProducts[tauDecIt])==15) { // any taus in the decay products?
130 last = false;
131 break;
132 }
133 }
134 if (!last) partMask[i]=false;
135 } // end of code for tau
136 } // end of loop over particles for tau checking
137 } // end of tau handling option
138
139 // If user requested preservation of descendants/ancestors:
140 // - loop over the masks and work out which particles need to be descended/ascended from
141 // - do the recursive loop
142 // - update the masks including the descendants/ancestors
143 // To ensure graph completeness, this over-rides anything set by the special treatment
144 // of taus in the section above
146 std::unordered_set<int> encounteredUniqueIDs; // to enable loop handling
148 for (unsigned int i=0; i<nParticles; ++i) {
149 bool toKeep = partMask[i];
150 if (!toKeep) continue;
151 const xAOD::TruthParticle* particle = (*importedTruthParticles)[i];
152 encounteredUniqueIDs.clear();
153 if (m_preserveDescendants) decayHelper.descendants(particle,partMask,vertMask,encounteredUniqueIDs,true);
154 encounteredUniqueIDs.clear();
155 if (m_preserveGeneratorDescendants) decayHelper.descendants(particle,partMask,vertMask,encounteredUniqueIDs,false);
156 encounteredUniqueIDs.clear();
157 if (m_preserveAncestors) decayHelper.ancestors(particle,partMask,vertMask,encounteredUniqueIDs);
158 encounteredUniqueIDs.clear();
159 }
160 }
161 //for (unsigned int i=0; i<nVertices; ++i) {
162 // bool toKeep = vertMask[i];
163 // if (!toKeep) continue;
164 // const xAOD::TruthVertex* vertex = (*importedTruthVertices)[i];
165 // decayHelper.descend(vertex,partMask,vertMask);
166 //}
167
168 // Count the masks
169 m_npasspart += std::count (partMask.begin(), partMask.end(), true);
170 m_npassvtx += std::count (vertMask.begin(), vertMask.end(), true);
171
172 // Execute the thinning service based on the mask. Finish.
173 importedTruthParticles.keep (partMask);
174 importedTruthVertices.keep (vertMask);
175
176 return StatusCode::SUCCESS;
177}
178
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
ATLAS-specific HepMC functions.
Handle for requesting thinning for a data object.
SG::ThinningHandleKey< xAOD::TruthVertexContainer > m_verticesKey
SG::ThinningHandleKey< xAOD::TruthParticleContainer > m_particlesKey
virtual StatusCode doThinning() const override
GenericTruthThinning(const std::string &t, const std::string &n, const IInterface *p)
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.
double entries
Definition listroot.cxx:49
bool isTau(const T &p)
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)