Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
TruthDecayCollectionMaker.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // TruthDecayCollectionMaker.cxx
7 // Removes all truth particles/vertices which do not pass a user-defined cut
8 // Based on TruthCollectionMaker (but simpler)
9 
11 #include "StoreGate/ReadHandle.h"
12 #include "StoreGate/WriteHandle.h"
19 
21 
22 // STL includes
23 #include <vector>
24 #include <string>
25 // For a find in the vector
26 #include <algorithm>
27 
28 // Constructor
30  const std::string& n,
31  const IInterface* p)
32  : base_class(t,n,p)
33 {
34 }
35 
36 // Destructor
38 }
39 
40 // Athena initialize
42 {
43  ATH_MSG_VERBOSE("initialize() ...");
44 
45  // Input truth particles
46  ATH_CHECK( m_particlesKey.initialize() );
47  ATH_MSG_INFO("Using " << m_particlesKey.key() << " as the input truth container key");
48 
49  // Output particle/vertex containers
50  if (m_collectionName.empty()) {
51  ATH_MSG_FATAL("No base name provided for the new truth particle/vertex containers");
52  return StatusCode::FAILURE;
53  } else {ATH_MSG_INFO("Base name for new truth particle/vertex containers: " << m_collectionName );}
54  m_outputParticlesKey = m_collectionName + "Particles";
55  ATH_CHECK(m_outputParticlesKey.initialize());
56  ATH_MSG_INFO("New truth particles container key: " << m_outputParticlesKey.key() );
57  m_outputVerticesKey = m_collectionName + "Vertices";
58  ATH_CHECK(m_outputVerticesKey.initialize());
59  ATH_MSG_INFO("New truth vertices container key: " << m_outputVerticesKey.key() );
60 
61  if (m_pdgIdsToKeep.empty() && !m_keepBHadrons && !m_keepCHadrons && !m_keepBSM) {
62  ATH_MSG_FATAL("No PDG IDs provided, not keeping b- or c-hadrons or BSM particles -- what do you want?");
63  return StatusCode::FAILURE;
64  }
65 
66  // Decorators
67  m_originDecoratorKey = m_outputParticlesKey.key()+".classifierParticleOrigin";
68  ATH_CHECK(m_originDecoratorKey.initialize());
69  m_typeDecoratorKey = m_outputParticlesKey.key()+".classifierParticleType";
70  ATH_CHECK(m_typeDecoratorKey.initialize());
71  m_outcomeDecoratorKey = m_outputParticlesKey.key()+".classifierParticleOutCome";
72  ATH_CHECK(m_outcomeDecoratorKey.initialize());
73  m_classificationDecoratorKey = m_outputParticlesKey.key()+".Classification";
74  ATH_CHECK(m_classificationDecoratorKey.initialize());
75  m_motherIDDecoratorKey = m_outputParticlesKey.key()+".motherID";
76  ATH_CHECK(m_motherIDDecoratorKey.initialize());
77  m_daughterIDDecoratorKey = m_outputParticlesKey.key()+".daughterID";
78  ATH_CHECK(m_daughterIDDecoratorKey.initialize());
79 
80  return StatusCode::SUCCESS;
81 }
82 
83 
84 // Selection and collection creation
86 {
87  // Event context for AthenaMT
88  const EventContext& ctx = Gaudi::Hive::currentContext();
89 
90  // Retrieve truth collections
91  SG::ReadHandle<xAOD::TruthParticleContainer> truthParticles(m_particlesKey,ctx);
92  if (!truthParticles.isValid()) {
93  ATH_MSG_ERROR("Couldn't retrieve TruthParticle collection with name " << m_particlesKey);
94  return StatusCode::FAILURE;
95  }
96 
97  // Create the new particle containers and WriteHandles
98  SG::WriteHandle<xAOD::TruthParticleContainer> newParticlesWriteHandle(m_outputParticlesKey, ctx);
99  ATH_CHECK(newParticlesWriteHandle.record(std::make_unique<xAOD::TruthParticleContainer>(),
100  std::make_unique<xAOD::TruthParticleAuxContainer>()));
101  ATH_MSG_DEBUG( "Recorded new TruthParticleContainer with key: " << (m_outputParticlesKey.key()));
102  // Create the new vertex containers and WriteHandles
103  SG::WriteHandle<xAOD::TruthVertexContainer> newVerticesWriteHandle(m_outputVerticesKey, ctx);
104  ATH_CHECK(newVerticesWriteHandle.record(std::make_unique<xAOD::TruthVertexContainer>(),
105  std::make_unique<xAOD::TruthVertexAuxContainer>()));
106  ATH_MSG_DEBUG( "Recorded new TruthVertexContainer with key: " << (m_outputVerticesKey.key()));
107 
108  // List of unique IDs for particles in our collection already. Because of the way we recurse,
109  // adding more particles as we go, there should be no need to add (or help from adding) the
110  // unique IDs of particles that we are *not* going to keep
111  std::vector<int> seen_particles;
112  // Go through that list of particles!
113  for (const auto * part : *truthParticles){
114  // If this passes my cuts, keep it
115  if (id_ok(*part)){
116  addTruthParticle( ctx, *part, newParticlesWriteHandle.ptr(), newVerticesWriteHandle.ptr(), seen_particles , m_generations );
117  }
118  } // Loop over the initial truth particle collection
119  return StatusCode::SUCCESS;
120 }
121 
123  const xAOD::TruthParticle& old_part,
124  xAOD::TruthParticleContainer* part_cont,
125  xAOD::TruthVertexContainer* vert_cont,
126  std::vector<int>& seen_particles,
127  const int generations) const {
128  // See if we've seen it - note, could also do this with a unary function on the container itself
129  if (std::find(seen_particles.begin(),seen_particles.end(),HepMC::uniqueID(&old_part))!=seen_particles.end()){
130  for (size_t p=0;p<part_cont->size();++p){
131  // Was it a hit?
132  const xAOD::TruthParticle *theParticle = (*part_cont)[p];
133  if (HepMC::is_same_particle(theParticle,&old_part)) return p;
134  } // Look through the old container
135  } // Found it in the old container
136  // Now we have seen it
137  seen_particles.push_back(HepMC::uniqueID(&old_part));
138  // Set up decorators
139  SG::WriteDecorHandle<xAOD::TruthParticleContainer, unsigned int > originDecorator(m_originDecoratorKey, ctx);
140  SG::WriteDecorHandle<xAOD::TruthParticleContainer, unsigned int > typeDecorator(m_typeDecoratorKey, ctx);
141  SG::WriteDecorHandle<xAOD::TruthParticleContainer, unsigned int > outcomeDecorator(m_outcomeDecoratorKey, ctx);
142  SG::WriteDecorHandle<xAOD::TruthParticleContainer, unsigned int > classificationDecorator(m_classificationDecoratorKey, ctx);
143  SG::WriteDecorHandle< xAOD::TruthParticleContainer, int > motherIDDecorator(m_motherIDDecoratorKey, ctx);
144  SG::WriteDecorHandle< xAOD::TruthParticleContainer, int > daughterIDDecorator(m_daughterIDDecoratorKey, ctx);
145  // Make a truth particle and add it to the container
146  xAOD::TruthParticle* xTruthParticle = new xAOD::TruthParticle();
147  part_cont->push_back( xTruthParticle );
148  // Fill with numerical content
149  xTruthParticle->setPdgId(old_part.pdgId());
150  xTruthParticle->setBarcode(HepMC::barcode(&old_part)); // FIXME barcode-based
151  xTruthParticle->setStatus(old_part.status());
152  xTruthParticle->setM(old_part.m());
153  xTruthParticle->setPx(old_part.px());
154  xTruthParticle->setPy(old_part.py());
155  xTruthParticle->setPz(old_part.pz());
156  xTruthParticle->setE(old_part.e());
157  // Copy over the polarization information if it's there
158  if (old_part.polarization().valid()){
161  }
162  // Make a link to this particle
163  int my_index = part_cont->size()-1;
164  ElementLink<xAOD::TruthParticleContainer> eltp(*part_cont, my_index);
165  // Decay vertex information
166  if (old_part.hasDecayVtx()) {
167  int vert_index = addTruthVertex( ctx, *old_part.decayVtx(), part_cont, vert_cont, seen_particles, generations);
168  ElementLink<xAOD::TruthVertexContainer> eltv( *vert_cont, vert_index );
169  xTruthParticle->setDecayVtxLink( eltv );
170  (*vert_cont)[vert_index]->addIncomingParticleLink( eltp );
171  }
172  // Copy over the decorations if they are available
173  static const SG::ConstAccessor<unsigned int> classifierParticleTypeAcc("classifierParticleType");
174  static const SG::ConstAccessor<unsigned int> classifierParticleOriginAcc("classifierParticleOrigin");
175  static const SG::ConstAccessor<unsigned int> classifierParticleOutComeAcc("classifierParticleOutCome");
176  static const SG::ConstAccessor<unsigned int> ClassificationAcc("Classification");
177 
178  typeDecorator(*xTruthParticle) = classifierParticleTypeAcc.withDefault (old_part, 0);
179  originDecorator(*xTruthParticle) = classifierParticleOriginAcc.withDefault (old_part, 0);
180  outcomeDecorator(*xTruthParticle) = classifierParticleOutComeAcc.withDefault (old_part, 0);
181  classificationDecorator(*xTruthParticle) = ClassificationAcc.withDefault (old_part, 0);
182 
183  // Return a link to this particle
184  return my_index;
185 }
186 
188  const xAOD::TruthVertex& old_vert,
189  xAOD::TruthParticleContainer* part_cont,
190  xAOD::TruthVertexContainer* vert_cont,
191  std::vector<int>& seen_particles,
192  const int generations) const {
193  // Make a new vertex and add it to the container
194  xAOD::TruthVertex* xTruthVertex = new xAOD::TruthVertex();
195  vert_cont->push_back( xTruthVertex );
196  // Get a link to this vertex -- will be used to set production vertices on all the next particles
197  int my_index = vert_cont->size()-1;
198  ElementLink<xAOD::TruthVertexContainer> eltv(*vert_cont, my_index);
199  // Set properties
200  xTruthVertex->setId(HepMC::status(old_vert));
201  xTruthVertex->setBarcode(HepMC::barcode(&old_vert)); // FIXME barcode-based
202  xTruthVertex->setX(old_vert.x());
203  xTruthVertex->setY(old_vert.y());
204  xTruthVertex->setZ(old_vert.z());
205  xTruthVertex->setT(old_vert.t());
206  // If we are done, then stop here
207  if (generations==0) return my_index;
208  // Add all the outgoing particles
209  for (size_t n=0;n<old_vert.nOutgoingParticles();++n){
210  if (!old_vert.outgoingParticle(n)) continue; // Just in case we removed some truth particles, e.g. G4 decays
211  if (m_rejectHadronChildren && old_vert.outgoingParticle(n)->isHadron()) { // Option to skip hadrons outright{
212  continue;
213  }
214  // Continue on the next generation; note that we only decrement the generation if this particle doesn't also pass our cuts
215  int part_index = addTruthParticle( ctx, *old_vert.outgoingParticle(n), part_cont, vert_cont, seen_particles,
216  generations-1+(id_ok(*old_vert.outgoingParticle(n))?1:0) );
217  ElementLink<xAOD::TruthParticleContainer> eltp( *part_cont, part_index);
218  xTruthVertex->addOutgoingParticleLink( eltp );
219  (*part_cont)[part_index]->setProdVtxLink( eltv );
220  }
221  // Return a link to this vertex
222  return my_index;
223 }
224 
226 {
227  // Check list of PDG IDs to keep
228  for (int id : m_pdgIdsToKeep){
229  if (part.absPdgId()==id){
230  return true;
231  } // Found a particle of interest!
232  } // Loop over the PDG IDs we want to keep
233  // Also check functions for B/C/BSM
234  return (m_keepBHadrons && part.isBottomHadron()) ||
235 
236  (m_keepCHadrons && part.isCharmHadron()) ||
237 
238  (m_keepBSM && part.isBSM());
239 }
LArG4FSStartPointFilter.part
part
Definition: LArG4FSStartPointFilter.py:21
xAOD::TruthVertex_v1::nOutgoingParticles
size_t nOutgoingParticles() const
Get the number of outgoing particles.
xAOD::TruthParticle_v1::setStatus
void setStatus(int value)
Set status code.
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
xAOD::TruthParticle_v1::pz
float pz() const
The z component of the particle's momentum.
SG::ReadHandle< xAOD::TruthParticleContainer >
xAOD::TruthParticle_v1::setE
void setE(float value)
Set the energy of the particle.
Definition: TruthParticle_v1.cxx:235
xAOD::TruthParticle_v1::setBarcode
void setBarcode(int value)
Set barcode.
TruthVertexContainer.h
TruthParticleContainer.h
DerivationFramework::TruthDecayCollectionMaker::TruthDecayCollectionMaker
TruthDecayCollectionMaker(const std::string &t, const std::string &n, const IInterface *p)
Definition: TruthDecayCollectionMaker.cxx:29
xAOD::TruthParticle_v1::setPolarizationParameter
bool setPolarizationParameter(float value, PolParam parameter)
Set method for polarization parameter values.
Definition: TruthParticle_v1.cxx:353
xAOD::TruthParticle_v1::Polarization::valid
bool valid() const
Check if the stored values are valid.
Definition: TruthParticle_v1.h:379
xAOD::TruthParticle_v1::polarization
Polarization polarization() const
Retrieve a full Polarization with a single call.
Definition: TruthParticle_v1.cxx:385
xAOD::TruthParticle_v1::px
float px() const
The x component of the particle's momentum.
DerivationFramework::TruthDecayCollectionMaker::initialize
StatusCode initialize()
Definition: TruthDecayCollectionMaker.cxx:41
xAOD::TruthVertex_v1::setT
void setT(float value)
Set the vertex time.
xAOD::TruthParticle_v1::setPx
void setPx(float value)
Set the x component of the particle's momentum.
xAOD::TruthParticle_v1::py
float py() const
The y component of the particle's momentum.
SG::ConstAccessor< unsigned int >
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
xAOD::TruthVertex_v1::addOutgoingParticleLink
void addOutgoingParticleLink(const TPLink_t &link)
Add one outgoing particle.
Definition: TruthVertex_v1.cxx:137
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
xAOD::TruthVertex_v1::setY
void setY(float value)
Set the y displacement of the vertex.
HepMC::is_same_particle
bool is_same_particle(const T1 &p1, const T2 &p2)
Method to establish if two particles in the GenEvent actually represent the same particle.
Definition: MagicNumbers.h:367
xAOD::TruthVertex_v1::y
float y() const
Vertex y displacement.
HepMC::BarcodeBased::generations
int generations(const T &p)
Method to return how many interactions a particle has undergone during simulation (only to be used in...
Definition: MagicNumbers.h:212
xAOD::TruthVertex_v1::t
float t() const
Vertex time.
TruthParticleAuxContainer.h
WriteHandle.h
Handle class for recording to StoreGate.
xAOD::TruthParticle_v1::hasDecayVtx
bool hasDecayVtx() const
Check for a decay vertex on this particle.
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
xAOD::TruthParticle_v1::setM
void setM(float value)
Also store the mass.
Definition: TruthParticle_v1.cxx:241
TruthDecayCollectionMaker.h
DerivationFramework::TruthDecayCollectionMaker::addTruthVertex
int addTruthVertex(const EventContext &, const xAOD::TruthVertex &old_vert, xAOD::TruthParticleContainer *part_cont, xAOD::TruthVertexContainer *vert_cont, std::vector< int > &seen_particles, const int generations=-1) const
Definition: TruthDecayCollectionMaker.cxx:187
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
xAOD::TruthParticle_v1::e
virtual double e() const override final
The total energy of the particle.
DerivationFramework::TruthDecayCollectionMaker::addTruthParticle
int addTruthParticle(const EventContext &ctx, const xAOD::TruthParticle &old_part, xAOD::TruthParticleContainer *part_cont, xAOD::TruthVertexContainer *vert_cont, std::vector< int > &seen_particles, const int generations=-1) const
Definition: TruthDecayCollectionMaker.cxx:122
beamspotman.n
n
Definition: beamspotman.py:731
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
SG::WriteHandle::ptr
pointer_type ptr()
Dereference the pointer.
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
HepMC::barcode
int barcode(const T *p)
Definition: Barcode.h:16
xAOD::TruthParticle_v1
Class describing a truth particle in the MC record.
Definition: TruthParticle_v1.h:37
SG::WriteDecorHandle
Handle class for adding a decoration to an object.
Definition: StoreGate/StoreGate/WriteDecorHandle.h:100
WriteDecorHandle.h
Handle class for adding a decoration to an object.
xAOD::TruthParticle
TruthParticle_v1 TruthParticle
Typedef to implementation.
Definition: Event/xAOD/xAODTruth/xAODTruth/TruthParticle.h:15
HepMC::uniqueID
int uniqueID(const T &p)
Definition: MagicNumbers.h:116
xAOD::TruthParticle_v1::setPy
void setPy(float value)
Set the y component of the particle's momentum.
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
xAOD::TruthVertex
TruthVertex_v1 TruthVertex
Typedef to implementation.
Definition: TruthVertex.h:15
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
TruthVertexAuxContainer.h
xAOD::TruthParticle_v1::decayVtx
const TruthVertex_v1 * decayVtx() const
The decay vertex of this particle.
xAOD::TruthVertex_v1
Class describing a truth vertex in the MC record.
Definition: TruthVertex_v1.h:37
xAOD::TruthParticle_v1::setPdgId
void setPdgId(int pid)
Set PDG ID code.
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
DerivationFramework::TruthDecayCollectionMaker::id_ok
bool id_ok(const xAOD::TruthParticle &part) const
Definition: TruthDecayCollectionMaker.cxx:225
xAOD::TruthVertex_v1::setId
void setId(int value)
Obsolete function Set vertex ID code HepMC2 id == HepMC3 status, i.e.
xAOD::TruthParticle_v1::polarizationParameter
bool polarizationParameter(float &value, PolParam parameter) const
Accessor for polarization parameters.
Definition: TruthParticle_v1.cxx:330
xAOD::TruthVertex_v1::x
float x() const
Vertex x displacement.
xAOD::TruthVertex_v1::setZ
void setZ(float value)
Set the vertex's longitudinal distance from the origin.
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:73
xAOD::TruthParticle_v1::status
int status() const
Status code.
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
xAOD::TruthVertex_v1::setBarcode
void setBarcode(int value)
Set barcode.
xAOD::TruthParticle_v1::polarizationTheta
@ polarizationTheta
Polarization in ( )
Definition: TruthParticle_v1.h:323
xAOD::TruthParticle_v1::polarizationPhi
@ polarizationPhi
Polarization in ( )
Definition: TruthParticle_v1.h:322
xAOD::TruthVertex_v1::z
float z() const
Vertex longitudinal distance along the beam line form the origin.
xAOD::TruthParticle_v1::setPz
void setPz(float value)
Set the z component of the particle's momentum.
DerivationFramework::TruthDecayCollectionMaker::~TruthDecayCollectionMaker
~TruthDecayCollectionMaker()
Definition: TruthDecayCollectionMaker.cxx:37
xAOD::TruthParticle_v1::setDecayVtxLink
void setDecayVtxLink(const ElementLink< TruthVertexContainer > &link)
Set the decay vertex of the particle.
ConstAccessor.h
Helper class to provide constant type-safe access to aux data.
ReadHandle.h
Handle class for reading from StoreGate.
HepMC::status
int status(const T &p)
Definition: MagicNumbers.h:138
xAOD::TruthParticle_v1::pdgId
int pdgId() const
PDG ID code.
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
xAOD::TruthVertex_v1::outgoingParticle
const TruthParticle_v1 * outgoingParticle(size_t index) const
Get one of the outgoing particles.
Definition: TruthVertex_v1.cxx:119
xAOD::TruthParticle_v1::m
virtual double m() const override final
The mass of the particle.
HepMCHelpers.h
xAOD::TruthParticle_v1::isHadron
bool isHadron() const
Whether the particle is a hadron.
xAOD::TruthVertex_v1::setX
void setX(float value)
Set the x displacement of the vertex.
SG::ConstAccessor::withDefault
const_reference_type withDefault(const ELT &e, const T &deflt) const
Fetch the variable for one element, as a const reference, with a default.
DerivationFramework::TruthDecayCollectionMaker::addBranches
virtual StatusCode addBranches() const
Definition: TruthDecayCollectionMaker.cxx:85