ATLAS Offline Software
Loading...
Searching...
No Matches
TruthResetAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "TruthResetAlg.h"
6//
12
15
16#include "CLHEP/Vector/LorentzVector.h"
17#include "CLHEP/Units/SystemOfUnits.h"
18//
19#include "CLHEP/Geometry/Point3D.h"
21#include <climits>
22
23TruthResetAlg::TruthResetAlg(const std::string& name, ISvcLocator* pSvcLocator):
24 AthAlgorithm(name, pSvcLocator)
25{
26 declareProperty("InputMcEventCollection" , m_inputMcEventCollection = "TruthEvent");
27 declareProperty("OutputMcEventCollection" , m_outputMcEventCollection = "NewTruthEvent");
28}
29
30
31//----------------------------------------------------
33//----------------------------------------------------
34
37 return StatusCode::SUCCESS;
38
39}
40
41//-------------------------------------------------
43//-------------------------------------------------
44
45 ATH_MSG_DEBUG( " execute..... " );
47 if (!inputMcEventCollection.isValid()) {
48 ATH_MSG_ERROR("Could not find input McEventCollection called " << inputMcEventCollection.name() << " in store " << inputMcEventCollection.store() << ".");
49 return StatusCode::FAILURE;
50 }
51 const HepMC::GenEvent& inputEvent(**(inputMcEventCollection->begin()));
52
53 //Sanity check
54 bool inputProblem(false);
55 for (const auto& particle: inputEvent) {
56 if (MC::isStable(particle)) {
57 if (!particle->production_vertex()) {
58 ATH_MSG_ERROR("Stable particle without a production vertex!! " << particle);
59 inputProblem = true;
60 }
61 }
62 else if (MC::isDecayed(particle)) {
63 if (!particle->production_vertex()) {
64 ATH_MSG_ERROR("Decyed particle without a production vertex!! " << particle);
65 inputProblem = true;
66 }
67 if (!particle->end_vertex()) {
68 ATH_MSG_ERROR("Decyed particle without an end vertex!! " << particle);
69 inputProblem = true;
70 }
71 }
72 }
73 if (inputProblem) {
74 ATH_MSG_FATAL("Problems in input GenEvent - bailing out.");
75 return StatusCode::FAILURE;
76 }
77#ifdef HEPMC3
80 std::unique_ptr<HepMC::GenEvent> outputEvent = std::make_unique<HepMC::GenEvent>(inputEvent);
81 if (inputEvent.run_info()) outputEvent->set_run_info(std::make_shared<HepMC3::GenRunInfo>(*(inputEvent.run_info().get())));
82 for (;;) {
83 std::vector<HepMC::GenParticlePtr> p_to_remove;
84 std::vector<HepMC::GenVertexPtr> v_to_remove;
85 for (auto& particle: outputEvent->particles()) {
86 if (HepMC::is_simulation_particle(particle)) {
87 p_to_remove.push_back(particle);
88 }
89 }
90 for (auto& particle: p_to_remove) outputEvent->remove_particle(particle);
91 for (auto& vertex: outputEvent->vertices()) {
92 if (HepMC::is_simulation_vertex(vertex) || vertex->particles_out().empty() ) {
93 v_to_remove.push_back(vertex);
94 }
95 }
96 for (auto& vertex: v_to_remove) outputEvent->remove_vertex(vertex);
97 if (p_to_remove.empty() && v_to_remove.empty()) break;
98 }
99#else
100
101 std::unique_ptr<HepMC::GenEvent> outputEvent = std::make_unique<HepMC::GenEvent>(inputEvent.signal_process_id(),
102 inputEvent.event_number());
103
104 outputEvent->set_mpi ( inputEvent.mpi() );
105 outputEvent->set_event_scale ( inputEvent.event_scale() );
106 outputEvent->set_alphaQCD ( inputEvent.alphaQCD() );
107 outputEvent->set_alphaQED ( inputEvent.alphaQED() );
108 if ( inputEvent.cross_section() ) {
109 outputEvent->set_cross_section ( *inputEvent.cross_section());
110 }
111 if (inputEvent.heavy_ion()) {
112 outputEvent->set_heavy_ion(*(inputEvent.heavy_ion()));
113 }
114 if (inputEvent.pdf_info()) {
115 outputEvent->set_pdf_info(*(inputEvent.pdf_info()));
116 }
117 outputEvent->define_units( inputEvent.momentum_unit(), inputEvent.length_unit() );
118
119 // 1. create a NEW copy of all vertices from inputEvent
120 // taking care to map new vertices onto the vertices being copied
121 // and add these new vertices to this event.
122 // We do not use GenVertex::operator= because that would copy
123 // the attached particles as well.
124 std::map<const HepMC::GenVertex*,HepMC::GenVertex*> inputEvtVtxToOutputEvtVtx;
125 HepMC::GenEvent::vertex_const_iterator currentVertexIter(inputEvent.vertices_begin());
126 const HepMC::GenEvent::vertex_const_iterator endOfCurrentListOfVertices(inputEvent.vertices_end());
127 ATH_MSG_VERBOSE( "Starting a vertex loop ... " );
128 for (; currentVertexIter != endOfCurrentListOfVertices; ++currentVertexIter) {
129 const HepMC::GenVertex *pCurrentVertex(*currentVertexIter);
130 if (HepMC::is_simulation_vertex(pCurrentVertex)) {
131 continue; // skip vertices created by the simulation
132 }
133 std::unique_ptr<HepMC::GenVertex> copyOfGenVertex =std::make_unique<HepMC::GenVertex>(pCurrentVertex->position(), pCurrentVertex->id(), pCurrentVertex->weights() );
134 copyOfGenVertex->suggest_barcode( HepMC::barcode(pCurrentVertex) );
135 inputEvtVtxToOutputEvtVtx[pCurrentVertex] = copyOfGenVertex.get();
136 outputEvent->add_vertex( copyOfGenVertex.release() );
137 } //vertex loop
138
139 // 2. copy the signal process vertex info.
140 if ( inputEvent.signal_process_vertex() ) {
141 outputEvent->set_signal_process_vertex( inputEvtVtxToOutputEvtVtx[inputEvent.signal_process_vertex()] );
142 }
143 else {
144 outputEvent->set_signal_process_vertex( nullptr );
145 }
146 //
147 // 3. create a NEW copy of all particles from inputEvent
148 // taking care to attach them to the appropriate vertex
149 HepMC::GenParticle* beam1{};
150 HepMC::GenParticle* beam2{};
151 for ( HepMC::GenEvent::particle_const_iterator particleIter = inputEvent.particles_begin();
152 particleIter != inputEvent.particles_end(); ++particleIter ) {
153 const HepMC::GenParticle* currentParticle = *particleIter;
154 if (HepMC::is_simulation_particle(currentParticle)) {
155 continue; // skip particles created by simulation
156 }
157 std::unique_ptr<HepMC::GenParticle> copyOfGenParticle = std::make_unique<HepMC::GenParticle>(*currentParticle);
158 const bool isBeamParticle1(currentParticle == inputEvent.beam_particles().first);
159 const bool isBeamParticle2(currentParticle == inputEvent.beam_particles().second);
160 // There may (will) be particles which had end vertices added by
161 // the simulation (inputEvent). Those vertices will not be copied
162 // to the outputEvent, so we should not try to use them here.
163 const bool shouldAddProdVertex(currentParticle->production_vertex() && inputEvtVtxToOutputEvtVtx[ currentParticle->production_vertex() ]);
164 const bool shouldAddEndVertex(currentParticle->end_vertex() && inputEvtVtxToOutputEvtVtx[ currentParticle->end_vertex() ]);
165 if ( isBeamParticle1 || isBeamParticle2 || shouldAddProdVertex || shouldAddEndVertex ) {
166 HepMC::GenParticle* particleCopy = copyOfGenParticle.release();
167 if ( isBeamParticle1 ) {
168 beam1 = particleCopy;
169 }
170 if ( isBeamParticle2 ) {
171 beam2 = particleCopy;
172 }
173 if ( shouldAddProdVertex || shouldAddEndVertex ) {
174 if ( shouldAddEndVertex ) {
175 inputEvtVtxToOutputEvtVtx[ currentParticle->end_vertex() ]->
176 add_particle_in(particleCopy);
177 }
178 if ( shouldAddProdVertex ) {
179 inputEvtVtxToOutputEvtVtx[ currentParticle->production_vertex() ]->
180 add_particle_out(particleCopy);
181 }
182 }
183 else {
184 ATH_MSG_WARNING ( "Found GenParticle with no production or end vertex! \n" << *currentParticle);
185 }
186 }
187 }
188 outputEvent->set_beam_particles( beam1, beam2 );
189 //
190 // 4. now that vtx/particles are copied, copy weights and random states
191 outputEvent->set_random_states( inputEvent.random_states() );
192 outputEvent->weights() = inputEvent.weights();
193#endif
194
195 //Sanity check
196 bool outputProblem(false);
197 for (const auto& particle: *(outputEvent.get())) {
198 if (MC::isStable(particle)) {
199 if (!particle->production_vertex()) {
200 ATH_MSG_ERROR("Stable particle without a production vertex!! " << particle);
201 outputProblem = true;
202 }
203 if (particle->end_vertex()) {
204 ATH_MSG_ERROR("Stable particle with an end vertex!! " << particle);
205 outputProblem = true;
206 }
207 }
208 else if (MC::isDecayed(particle)) {
209 if (!particle->production_vertex()) {
210 ATH_MSG_ERROR("Decayed particle without a production vertex!! " << particle);
211 outputProblem = true;
212 }
213 if (!particle->end_vertex()) {
214 ATH_MSG_ERROR("Decayed particle without an end vertex!! " << particle);
215 outputProblem = true;
216 }
217 }
218 }
219 if (outputProblem) {
220 ATH_MSG_FATAL("Problems in output GenEvent - bailing out.");
221 return StatusCode::FAILURE;
222 }
223
225 ATH_CHECK(outputMcEventCollection.record(std::make_unique<McEventCollection>()));
226 outputMcEventCollection->push_back(outputEvent.release());
227 if (!outputMcEventCollection.isValid()) {
228 ATH_MSG_ERROR("Could not record output McEventCollection called " << outputMcEventCollection.name() << " in store " << outputMcEventCollection.store() << ".");
229 return StatusCode::FAILURE;
230 }
231
232 ATH_MSG_DEBUG( "succeded TruthResetAlg ..... " );
233
234 return StatusCode::SUCCESS;
235
236}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
ATLAS-specific HepMC functions.
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
virtual bool isValid() override final
Can the handle be successfully dereferenced?
std::string store() const
Return the name of the store holding the object we are proxying.
const std::string & name() const
Return the StoreGate ID for the referenced object.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
virtual StatusCode initialize() override final
SG::WriteHandleKey< McEventCollection > m_outputMcEventCollection
SG::ReadHandleKey< McEventCollection > m_inputMcEventCollection
virtual StatusCode execute() override final
TruthResetAlg(const std::string &name, ISvcLocator *pSvcLocator)
bool is_simulation_vertex(const T &v)
Method to establish if the vertex was created during simulation (TODO migrate to be based on status).
int barcode(const T *p)
Definition Barcode.h:16
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 isStable(const T &p)
Identify if the particle is stable, i.e. has not decayed.
bool isDecayed(const T &p)
Identify if the particle decayed.