ATLAS Offline Software
McEventCollectionCnv_p3.cxx
Go to the documentation of this file.
1 
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 
28  Base_t( )
29 {}
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));
181  HepMC::suggest_barcode(vtx,persVtx.m_barcode);
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 ) {
210  createGenParticle( persEvt.m_genParticles[persVtx.m_particlesIn[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 {
232  HepMC::GenParticlePtr p = datapools.getGenParticle();
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 }
DataVector::reserve
void reserve(size_type n)
Attempt to preallocate enough memory for a specified number of elements.
HepMC::GenVertexPtr
HepMC::GenVertex * GenVertexPtr
Definition: GenVertex.h:59
GenEvent_p3
Definition: GenEvent_p3.h:23
McEventCollectionCnv_p3
Definition: McEventCollectionCnv_p3.h:47
GenEvent_p3::m_verticesBegin
unsigned int m_verticesBegin
Begin position in the vector of vertices composing this event.
Definition: GenEvent_p3.h:101
HepMC::suggest_barcode
bool suggest_barcode(T &p, int i)
Definition: GenEvent.h:548
GenParticle_p3::m_status
int m_status
Status of this particle, as defined for HEPEVT.
Definition: GenParticle_p3.h:83
GenParticle_p3::m_phiPolarization
float m_phiPolarization
phi polarization
Definition: GenParticle_p3.h:99
GenEvent_p3::m_alphaQCD
double m_alphaQCD
value of the QCD coupling.
Definition: GenEvent_p3.h:78
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
NSWL1::nVertices
int nVertices(const Polygon &p)
Definition: GeoUtils.cxx:35
Vtx
GenEvent_p3::m_signalProcessId
int m_signalProcessId
Id of the processus being generated.
Definition: GenEvent_p3.h:66
HepMC::DataPool
Definition: HepMcDataPool.h:81
McEventCollectionCnv_p3::persToTrans
virtual void persToTrans(const McEventCollection_p3 *persObj, McEventCollection *transObj, MsgStream &log)
Method creating the transient representation of McEventCollection from its persistent representation ...
Definition: McEventCollectionCnv_p3.cxx:52
SG::VIEW_ELEMENTS
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
Definition: OwnershipPolicy.h:18
GenParticle_p3::m_pz
float m_pz
z-component of the 4-momentum of this particle
Definition: GenParticle_p3.h:71
McEventCollectionCnv_p3::transToPers
virtual void transToPers(const McEventCollection *transObj, McEventCollection_p3 *persObj, MsgStream &log)
Method creating the persistent representation McEventCollection_p3 from its transient representation ...
Definition: McEventCollectionCnv_p3.cxx:152
McEventCollection_p3::m_genEvents
std::vector< GenEvent_p3 > m_genEvents
The vector of persistent representation of GenEvents.
Definition: McEventCollection_p3.h:51
GenParticle_p3::m_pdgId
int m_pdgId
identity of this particle, according to the Particle Data Group notation
Definition: GenParticle_p3.h:79
HepMC::GenParticlePtr
GenParticle * GenParticlePtr
Definition: GenParticle.h:37
GenEvent_p3::m_particlesEnd
unsigned int m_particlesEnd
End position in the vector of particles composing this event.
Definition: GenEvent_p3.h:113
TPConverterBase
Definition: TPConverter.h:738
McEventCollectionCnv_p3::createGenParticle
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.
Definition: McEventCollectionCnv_p3.cxx:228
GenVertex_p3
Definition: GenVertex_p3.h:24
HepMcDataPool.h
GenParticle_p3::m_thetaPolarization
float m_thetaPolarization
polarization
Definition: GenParticle_p3.h:95
GenVertex_p3::m_particlesOut
std::vector< int > m_particlesOut
collection of barcodes of out-going particles connected to this vertex
Definition: GenVertex_p3.h:72
GenParticle_p3::m_barcode
int m_barcode
barcode of this particles (uniquely identifying this particle within a given GenEvent)
Definition: GenParticle_p3.h:114
GenVertex_p3::m_weights
std::vector< float > m_weights
Weights for this vertex.
Definition: GenVertex_p3.h:80
GenEvent_p3::m_alphaQED
double m_alphaQED
value of the QED coupling.
Definition: GenEvent_p3.h:82
GenEvent_p3::m_eventScale
double m_eventScale
Energy scale.
Definition: GenEvent_p3.h:74
HepMC::DataPool::getGenParticle
HepMC::GenParticlePtr getGenParticle()
Definition: HepMcDataPool.h:160
McEventCollection_p3::m_genParticles
std::vector< GenParticle_p3 > m_genParticles
The vector of persistent representation of GenParticles.
Definition: McEventCollection_p3.h:59
GenEvent_p3::m_particlesBegin
unsigned int m_particlesBegin
Begin position in the vector of particles composing this event.
Definition: GenEvent_p3.h:109
GenVertex_p3::m_y
float m_y
y-coordinate of the vertex
Definition: GenVertex_p3.h:56
HepMC::set_signal_process_vertex
void set_signal_process_vertex(GenEvent *e, T v)
Definition: GenEvent.h:528
GenParticle_p3::m_flow
std::vector< std::pair< int, int > > m_flow
Flow for this particle.
Definition: GenParticle_p3.h:87
GenParticle_p3::m_px
float m_px
x-component of the 4-momentum of this particle
Definition: GenParticle_p3.h:63
HepMC::DataPool::evt
GenEvtPool_t evt
an arena of HepMC::GenEvent for efficient object instantiation
Definition: HepMcDataPool.h:140
lumiFormat.i
int i
Definition: lumiFormat.py:92
GenEvent_p3::m_eventNbr
int m_eventNbr
Event number.
Definition: GenEvent_p3.h:70
McEventCollectionCnv_p3::McEventCollectionCnv_p3
McEventCollectionCnv_p3()
Default constructor:
Definition: McEventCollectionCnv_p3.cxx:27
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
GenVertex_p3::m_x
float m_x
x-coordinate of the vertex
Definition: GenVertex_p3.h:52
test_pyathena.parent
parent
Definition: test_pyathena.py:15
HepMC::DataPool::vtx
GenVtxPool_t vtx
an arena of HepMC::GenVertex for efficient object instantiation
Definition: HepMcDataPool.h:144
McEventCollection
This defines the McEventCollection, which is really just an ObjectVector of McEvent objects.
Definition: McEventCollection.h:33
McEventCollectionCnv_p3::operator=
McEventCollectionCnv_p3 & operator=(const McEventCollectionCnv_p3 &rhs)
Assignement operator.
Definition: McEventCollectionCnv_p3.cxx:36
McEventCollectionCnv_p3.h
DataVector::clear
void clear()
Erase all the elements in the collection.
GenVertex_p3::m_z
float m_z
z-coordinate of the vertex
Definition: GenVertex_p3.h:60
GenParticle_p3::m_recoMethod
short m_recoMethod
switch to know which method to chose to better recover the original HepLorentzVector.
Definition: GenParticle_p3.h:124
GenEvent_p3::m_verticesEnd
unsigned int m_verticesEnd
End position in the vector of vertices composing this event.
Definition: GenEvent_p3.h:105
McEventCollectionCnv_p3::~McEventCollectionCnv_p3
virtual ~McEventCollectionCnv_p3()
Destructor.
McEventCollection_p3
Definition: McEventCollection_p3.h:27
GenVertex_p3::m_id
int m_id
Id of this vertex.
Definition: GenVertex_p3.h:76
GenEvent_p3::m_weights
std::vector< double > m_weights
Weights for this event.
Definition: GenEvent_p3.h:93
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
McEventCollectionCnv_p3::createGenVertex
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.
Definition: McEventCollectionCnv_p3.cxx:167
DEBUG
#define DEBUG
Definition: page_access.h:11
GenVertex_p3::m_barcode
int m_barcode
barcode of this vertex (uniquely identifying a vertex within an event)
Definition: GenVertex_p3.h:84
GenParticle_p3::m_endVtx
int m_endVtx
Barcode of the decay vertex of this particle.
Definition: GenParticle_p3.h:109
HepMC::DataPool::getGenEvent
HepMC::GenEvent * getGenEvent()
Definition: HepMcDataPool.h:150
HepMC::barcode_to_vertex
GenVertex * barcode_to_vertex(const GenEvent *e, int id)
Definition: GenEvent.h:505
GenParticle_p3
Definition: GenParticle_p3.h:22
McEventCollectionCnv_p3::ParticlesMap_t
std::unordered_map< HepMC::GenParticlePtr, int > ParticlesMap_t
Definition: McEventCollectionCnv_p3.h:92
GenVertex_p3::m_particlesIn
std::vector< int > m_particlesIn
collection of barcodes of in-going particles connected to this vertex
Definition: GenVertex_p3.h:68
GenEvent_p3::m_signalProcessVtx
int m_signalProcessVtx
Barcode of the GenVertex holding the signal process.
Definition: GenEvent_p3.h:88
GenParticle_p3::m_py
float m_py
y-component of the 4-momentum of this particle
Definition: GenParticle_p3.h:67
GenVertex_p3::m_t
float m_t
t-coordinate of the vertex
Definition: GenVertex_p3.h:64
HepMC::DataPool::getGenVertex
HepMC::GenVertexPtr getGenVertex()
Definition: HepMcDataPool.h:155
GenParticle_p3::m_m
float m_m
m-component of the 4-momentum of this particle
Definition: GenParticle_p3.h:75
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
McEventCollection_p3::m_genVertices
std::vector< GenVertex_p3 > m_genVertices
The vector of persistent representation of GenVertices.
Definition: McEventCollection_p3.h:55
GenEvent_p3::m_randomStates
std::vector< long int > m_randomStates
Container of random numbers for the generator states.
Definition: GenEvent_p3.h:97
HepMC::DataPool::part
GenPartPool_t part
an arena of HepMC::GenParticle for efficient object instantiation
Definition: HepMcDataPool.h:148