ATLAS Offline Software
Loading...
Searching...
No Matches
McEventCollectionCnv_p3.cxx
Go to the documentation of this file.
1
2
3/*
4 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
5*/
6
7// McEventCollectionCnv_p3.cxx
8// Implementation file for class McEventCollectionCnv_p3
9// Author: S.Binet<binet@cern.ch>
11
12
13// STL includes
14#include <utility>
15#include <cmath>
16
17// GeneratorObjectsTPCnv includes
19#include "HepMcDataPool.h"
20
21
23// Constructors
25
26
30
32
33= default;
34
37{
38 if ( this != &rhs ) {
39 Base_t::operator=( rhs );
40 }
41 return *this;
42}
43
45// Destructor
47
49= default;
50
51
53 McEventCollection* transObj,
54 MsgStream& msg )
55{
56 msg << MSG::DEBUG << "Loading McEventCollection from persistent state..."
57 << endmsg;
58
59 // elements are managed by DataPool
60 transObj->clear(SG::VIEW_ELEMENTS);
61 HepMC::DataPool datapools;
62 const unsigned int nVertices = persObj->m_genVertices.size();
63 datapools.vtx.prepareToAdd(nVertices);
64 const unsigned int nParts = persObj->m_genParticles.size();
65 datapools.part.prepareToAdd(nParts);
66 const unsigned int nEvts = persObj->m_genEvents.size();
67 datapools.evt.prepareToAdd(nEvts);
68
69 transObj->reserve( nEvts );
70 for ( std::vector<GenEvent_p3>::const_iterator
71 itr = persObj->m_genEvents.begin(),
72 itrEnd = persObj->m_genEvents.end();
73 itr != itrEnd;
74 ++itr ) {
75 const GenEvent_p3& persEvt = *itr;
76
77 HepMC::GenEvent * genEvt = datapools.getGenEvent();
78#ifdef HEPMC3
79 genEvt->add_attribute ("barcodes", std::make_shared<HepMC::GenEventBarcodes>());
80 genEvt->add_attribute("signal_process_id",std::make_shared<HepMC3::IntAttribute>(persEvt.m_signalProcessId));
81 genEvt->set_event_number(persEvt.m_eventNbr);
82 genEvt->add_attribute("event_scale",std::make_shared<HepMC3::DoubleAttribute>(persEvt.m_eventScale));
83 genEvt->add_attribute("alphaQCD",std::make_shared<HepMC3::DoubleAttribute>(persEvt.m_alphaQCD));
84 genEvt->add_attribute("alphaQED",std::make_shared<HepMC3::DoubleAttribute>(persEvt.m_alphaQED));
85 genEvt->weights()= persEvt.m_weights;
86 genEvt->add_attribute("random_states",std::make_shared<HepMC3::VectorLongIntAttribute>(persEvt.m_randomStates));
87 transObj->push_back( genEvt );
88
89 ParticlesMap_t partToEndVtx( (persEvt.m_particlesEnd- persEvt.m_particlesBegin)/2 );
90
91 // create the vertices
92 const unsigned int endVtx = persEvt.m_verticesEnd;
93 for ( unsigned int iVtx= persEvt.m_verticesBegin; iVtx != endVtx; ++iVtx ) {
94 createGenVertex( *persObj, persObj->m_genVertices[iVtx],partToEndVtx, datapools, genEvt );
95 }
96#else
97 genEvt->m_signal_process_id = persEvt.m_signalProcessId;
98 genEvt->m_event_number = persEvt.m_eventNbr;
99 genEvt->m_event_scale = persEvt.m_eventScale;
100 genEvt->m_alphaQCD = persEvt.m_alphaQCD;
101 genEvt->m_alphaQED = persEvt.m_alphaQED;
102 genEvt->m_signal_process_vertex = 0;
103 genEvt->m_weights = persEvt.m_weights;
104 genEvt->m_random_states = persEvt.m_randomStates;
105 genEvt->m_vertex_barcodes.clear();
106 genEvt->m_particle_barcodes.clear();
107 genEvt->m_pdf_info = 0; //> not available at that time...
108
109 transObj->push_back( genEvt );
110
111 // create a temporary map associating the barcode of an end-vtx to its
112 // particle.
113 // As not all particles are stable (d'oh!) we take 50% of the number of
114 // particles as an initial size of the hash-map (to prevent re-hash)
115 ParticlesMap_t partToEndVtx( (persEvt.m_particlesEnd-
116 persEvt.m_particlesBegin)/2 );
117
118 // create the vertices
119 const unsigned int endVtx = persEvt.m_verticesEnd;
120 for ( unsigned int iVtx= persEvt.m_verticesBegin; iVtx != endVtx; ++iVtx ) {
121 genEvt->add_vertex( createGenVertex( *persObj,
122 persObj->m_genVertices[iVtx],
123 partToEndVtx,
124 datapools ) );
125 } //> end loop over vertices
126#endif
127
128 // set the signal process vertex
129 const int sigProcVtx = persEvt.m_signalProcessVtx;
130 if ( sigProcVtx != 0 ) {
131 auto Vtx=HepMC::barcode_to_vertex(genEvt, sigProcVtx );
133 }
134
135 // connect particles to their end vertices
136 for (auto & p : partToEndVtx) {
137 auto decayVtx=HepMC::barcode_to_vertex(genEvt, p.second );
138 if ( decayVtx ) {
139 decayVtx->add_particle_in( p.first );
140 } else {
141 msg << MSG::ERROR
142 << "GenParticle points to null end vertex !!"
143 << endmsg;
144 }
145 }
146 } //> end loop over m_genEvents
147
148 msg << MSG::DEBUG << "Loaded McEventCollection from persistent state [OK]"
149 << endmsg;
150}
151
153 McEventCollection_p3* /*persObj*/,
154 MsgStream& msg )
155{
156 msg << MSG::ERROR
157 << "This transient-to-persistent converter method has been RETIRED !!"
158 << endmsg
159 << "You are not supposed to end-up here ! Go away !"
160 << endmsg;
161
162 throw std::runtime_error( "Retired McEventCollectionCnv_p3::transToPers() !!" );
163}
164
165
168 const GenVertex_p3& persVtx,
169 ParticlesMap_t& partToEndVtx,
170 HepMC::DataPool& datapools, HepMC::GenEvent* parent )
171{
172 HepMC::GenVertexPtr vtx = datapools.getGenVertex();
173 if (parent) parent->add_vertex(vtx);
174
175#ifdef HEPMC3
176 vtx->set_position( HepMC::FourVector(persVtx.m_x,persVtx.m_y,persVtx.m_z,persVtx.m_t) );
177 vtx->set_status(persVtx.m_id);
178 // cast from std::vector<float> to std::vector<double>
179 std::vector<double> weights( persVtx.m_weights.begin(), persVtx.m_weights.end() );
180 vtx->add_attribute("weights",std::make_shared<HepMC3::VectorDoubleAttribute>(weights));
182 // handle the in-going (orphans) particles
183 //Is this needed for HEPMC3?
184 const unsigned int nPartsIn = persVtx.m_particlesIn.size();
185 for ( unsigned int i = 0; i != nPartsIn; ++i ) {
186 createGenParticle( persEvt.m_genParticles[persVtx.m_particlesIn[i]], partToEndVtx, datapools, vtx, false );
187 }
188 // now handle the out-going particles
189 const unsigned int nPartsOut = persVtx.m_particlesOut.size();
190 for ( unsigned int i = 0; i != nPartsOut; ++i ) {
191 createGenParticle( persEvt.m_genParticles[persVtx.m_particlesOut[i]], partToEndVtx, datapools, vtx );
192 }
193#else
194 vtx->m_position.setX( persVtx.m_x );
195 vtx->m_position.setY( persVtx.m_y );
196 vtx->m_position.setZ( persVtx.m_z );
197 vtx->m_position.setT( persVtx.m_t );
198 vtx->m_particles_in.clear();
199 vtx->m_particles_out.clear();
200 vtx->m_id = persVtx.m_id;
201 vtx->m_weights.m_weights.reserve( persVtx.m_weights.size() );
202 vtx->m_weights.m_weights.assign ( persVtx.m_weights.begin(),
203 persVtx.m_weights.end() );
204 vtx->m_event = 0;
205 vtx->m_barcode = persVtx.m_barcode;
206
207 // handle the in-going (orphans) particles
208 const unsigned int nPartsIn = persVtx.m_particlesIn.size();
209 for ( unsigned int i = 0; i != nPartsIn; ++i ) {
211 partToEndVtx,
212 datapools );
213 }
214
215 // now handle the out-going particles
216 const unsigned int nPartsOut = persVtx.m_particlesOut.size();
217 for ( unsigned int i = 0; i != nPartsOut; ++i ) {
218 vtx->add_particle_out( createGenParticle( persEvt.m_genParticles[persVtx.m_particlesOut[i]],
219 partToEndVtx,
220 datapools ) );
221 }
222#endif
223
224 return vtx;
225}
226
229 ParticlesMap_t& partToEndVtx,
230 HepMC::DataPool& datapools, const HepMC::GenVertexPtr& parent, bool add_to_output )
231{
233 if (parent) add_to_output?parent->add_particle_out(p):parent->add_particle_in(p);
234
235#ifdef HEPMC3
236 p->set_pdg_id(persPart.m_pdgId);
237 p->set_status(persPart.m_status);
238 // Note: do the E calculation in extended (long double) precision.
239 // That happens implicitly on x86 with optimization on; saying it
240 // explicitly ensures that we get the same results with and without
241 // optimization. (If this is a performance issue for platforms
242 // other than x86, one could change to double for those platforms.)
243 double temp_e=0.0;
244 if ( 0 == persPart.m_recoMethod ) {
245 temp_e = std::sqrt( (long double)(persPart.m_px)*persPart.m_px +
246 (long double)(persPart.m_py)*persPart.m_py +
247 (long double)(persPart.m_pz)*persPart.m_pz +
248 (long double)(persPart.m_m) *persPart.m_m );
249 } else {
250 const int signM2 = ( persPart.m_m >= 0. ? 1 : -1 );
251 const double persPart_ene =
252 std::sqrt( std::abs((long double)(persPart.m_px)*persPart.m_px +
253 (long double)(persPart.m_py)*persPart.m_py +
254 (long double)(persPart.m_pz)*persPart.m_pz +
255 signM2* (long double)(persPart.m_m)* persPart.m_m));
256 const int signEne = ( persPart.m_recoMethod == 1 ? 1 : -1 );
257 temp_e=signEne * persPart_ene;
258 }
259 p->set_momentum(HepMC::FourVector(persPart.m_px,persPart.m_py,persPart.m_pz,temp_e));
260 // setup flow
261 // fillin' the flow
262 std::vector<int> flows;
263 const unsigned int nFlow = persPart.m_flow.size();
264 for ( unsigned int iFlow= 0; iFlow != nFlow; ++iFlow ) {
265 flows.push_back(persPart.m_flow[iFlow].second );
266 }
267 //We construct it here as vector w/o gaps.
268 p->add_attribute("flows", std::make_shared<HepMC3::VectorIntAttribute>(flows));
270#else
271 p->m_pdg_id = persPart.m_pdgId;
272 p->m_status = persPart.m_status;
273 p->m_polarization.m_theta= static_cast<double>(persPart.m_thetaPolarization);
274 p->m_polarization.m_phi = static_cast<double>(persPart.m_phiPolarization );
275 p->m_production_vertex = 0;
276 p->m_end_vertex = 0;
277 p->m_barcode = persPart.m_barcode;
278
279 // Note: do the E calculation in extended (long double) precision.
280 // That happens implicitly on x86 with optimization on; saying it
281 // explicitly ensures that we get the same results with and without
282 // optimization. (If this is a performance issue for platforms
283 // other than x86, one could change to double for those platforms.)
284 if ( 0 == persPart.m_recoMethod ) {
285 p->m_momentum.setPx( persPart.m_px );
286 p->m_momentum.setPy( persPart.m_py );
287 p->m_momentum.setPz( persPart.m_pz );
288 double temp_e = std::sqrt( (long double)(persPart.m_px)*persPart.m_px +
289 (long double)(persPart.m_py)*persPart.m_py +
290 (long double)(persPart.m_pz)*persPart.m_pz +
291 (long double)(persPart.m_m) *persPart.m_m );
292 p->m_momentum.setE( temp_e );
293 } else {
294 const int signM2 = ( persPart.m_m >= 0. ? 1 : -1 );
295 const double persPart_ene =
296 std::sqrt( std::abs((long double)(persPart.m_px)*persPart.m_px +
297 (long double)(persPart.m_py)*persPart.m_py +
298 (long double)(persPart.m_pz)*persPart.m_pz +
299 signM2* (long double)(persPart.m_m)* persPart.m_m));
300 const int signEne = ( persPart.m_recoMethod == 1 ? 1 : -1 );
301 p->m_momentum.set( persPart.m_px,
302 persPart.m_py,
303 persPart.m_pz,
304 signEne * persPart_ene );
305 }
306
307 // setup flow
308 const unsigned int nFlow = persPart.m_flow.size();
309 p->m_flow.clear();
310 for ( unsigned int iFlow= 0; iFlow != nFlow; ++iFlow ) {
311 p->m_flow.set_icode( persPart.m_flow[iFlow].first,
312 persPart.m_flow[iFlow].second );
313 }
314#endif
315
316 if ( persPart.m_endVtx != 0 ) {
317 partToEndVtx[p] = persPart.m_endVtx;
318 }
319
320 return p;
321}
#define endmsg
void prepareToAdd(unsigned int size)
Prepare to add cached elements.
void reserve(size_type n)
Attempt to preallocate enough memory for a specified number of elements.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
void clear()
Erase all the elements in the collection.
std::vector< long int > m_randomStates
Container of random numbers for the generator states.
Definition GenEvent_p3.h:97
double m_eventScale
Energy scale.
Definition GenEvent_p3.h:74
int m_signalProcessVtx
Barcode of the GenVertex holding the signal process.
Definition GenEvent_p3.h:88
unsigned int m_verticesEnd
End position in the vector of vertices composing this event.
double m_alphaQED
value of the QED coupling.
Definition GenEvent_p3.h:82
unsigned int m_particlesEnd
End position in the vector of particles composing this event.
int m_signalProcessId
Id of the processus being generated.
Definition GenEvent_p3.h:66
std::vector< double > m_weights
Weights for this event.
Definition GenEvent_p3.h:93
unsigned int m_particlesBegin
Begin position in the vector of particles composing this event.
double m_alphaQCD
value of the QCD coupling.
Definition GenEvent_p3.h:78
int m_eventNbr
Event number.
Definition GenEvent_p3.h:70
unsigned int m_verticesBegin
Begin position in the vector of vertices composing this event.
float m_pz
z-component of the 4-momentum of this particle
int m_status
Status of this particle, as defined for HEPEVT.
float m_phiPolarization
phi polarization
short m_recoMethod
switch to know which method to chose to better recover the original HepLorentzVector.
int m_barcode
barcode of this particles (uniquely identifying this particle within a given GenEvent)
float m_m
m-component of the 4-momentum of this particle
float m_px
x-component of the 4-momentum of this particle
std::vector< std::pair< int, int > > m_flow
Flow for this particle.
float m_py
y-component of the 4-momentum of this particle
int m_endVtx
Barcode of the decay vertex of this particle.
int m_pdgId
identity of this particle, according to the Particle Data Group notation
float m_thetaPolarization
polarization
std::vector< float > m_weights
Weights for this vertex.
std::vector< int > m_particlesOut
collection of barcodes of out-going particles connected to this vertex
int m_barcode
barcode of this vertex (uniquely identifying a vertex within an event)
float m_z
z-coordinate of the vertex
std::vector< int > m_particlesIn
collection of barcodes of in-going particles connected to this vertex
float m_x
x-coordinate of the vertex
float m_y
y-coordinate of the vertex
int m_id
Id of this vertex.
float m_t
t-coordinate of the vertex
virtual void transToPers(const McEventCollection *transObj, McEventCollection_p3 *persObj, MsgStream &log)
Method creating the persistent representation McEventCollection_p3 from its transient representation ...
McEventCollectionCnv_p3 & operator=(const McEventCollectionCnv_p3 &rhs)
Assignement operator.
static HepMC::GenVertexPtr createGenVertex(const McEventCollection_p3 &persEvts, const GenVertex_p3 &vtx, ParticlesMap_t &bcToPart, HepMC::DataPool &datapools, HepMC::GenEvent *parent=nullptr)
Create a transient GenVertex from a persistent one (version 1) It returns the new GenVertex.
McEventCollectionCnv_p3()
Default constructor:
static HepMC::GenParticlePtr createGenParticle(const GenParticle_p3 &p, ParticlesMap_t &partToEndVtx, HepMC::DataPool &datapools, const HepMC::GenVertexPtr &parent=nullptr, bool add_to_output=true)
Create a transient GenParticle from a persistent one (vers.1) It returns the new GenParticle.
virtual void persToTrans(const McEventCollection_p3 *persObj, McEventCollection *transObj, MsgStream &log)
Method creating the transient representation of McEventCollection from its persistent representation ...
std::unordered_map< HepMC::GenParticlePtr, int > ParticlesMap_t
T_AthenaPoolTPCnvBase< McEventCollection, McEventCollection_p3 > Base_t
virtual ~McEventCollectionCnv_p3()
Destructor.
std::vector< GenParticle_p3 > m_genParticles
The vector of persistent representation of GenParticles.
std::vector< GenEvent_p3 > m_genEvents
The vector of persistent representation of GenEvents.
std::vector< GenVertex_p3 > m_genVertices
The vector of persistent representation of GenVertices.
This defines the McEventCollection, which is really just an ObjectVector of McEvent objectsFile: Gene...
void set_signal_process_vertex(GenEvent *e, T v)
Definition GenEvent.h:652
GenVertex * barcode_to_vertex(const GenEvent *e, int id)
Definition GenEvent.h:629
HepMC::GenVertex * GenVertexPtr
Definition GenVertex.h:59
bool suggest_barcode(T &p, int i)
Definition GenEvent.h:672
GenParticle * GenParticlePtr
Definition GenParticle.h:37
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
A namespace for all vertexing packages and related stuff.
HepMC::GenParticlePtr getGenParticle()
GenPartPool_t part
an arena of HepMC::GenParticle for efficient object instantiation
HepMC::GenEvent * getGenEvent()
HepMC::GenVertexPtr getGenVertex()
GenVtxPool_t vtx
an arena of HepMC::GenVertex for efficient object instantiation
GenEvtPool_t evt
an arena of HepMC::GenEvent for efficient object instantiation
MsgStream & msg
Definition testRead.cxx:32