ATLAS Offline Software
Loading...
Searching...
No Matches
McEventCollectionCnv_p4.cxx
Go to the documentation of this file.
1
2
3/*
4 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
5*/
6
7// McEventCollectionCnv_p4.cxx
8// Implementation file for class McEventCollectionCnv_p4
9// Author: S.Binet<binet@cern.ch>
11
12
13// STL includes
14#include <utility>
15#include <cmath>
16#include <cfloat> // for DBL_EPSILON
17
18// GeneratorObjectsTPCnv includes
20#include "HepMcDataPool.h"
21#include "HepMC3AccessStrings.h"
22
24
26#include "GaudiKernel/ThreadLocalContext.h"
28using namespace GeneratorObjectsTPCnv;
29
31// Constructors
33
34
36 Base_t( ),
37 m_isPileup(false),m_hepMCWeightSvc("HepMCWeightSvc","McEventCollectionCnv_p4")
38{}
39
41 Base_t( rhs ),
42 m_isPileup(false),m_hepMCWeightSvc("HepMCWeightSvc","McEventCollectionCnv_p4")
43{}
44
47{
48 if ( this != &rhs ) {
49 Base_t::operator=( rhs );
52 }
53 return *this;
54}
55
56// Destructor
58
60= default;
61
63// Const methods:
65
67 McEventCollection* transObj,
68 MsgStream& msg )
69{
70 const EventContext& ctx = Gaudi::Hive::currentContext();
71
72 msg << MSG::DEBUG << "Loading McEventCollection from persistent state..."
73 << endmsg;
74
75 // elements are managed by DataPool
76 if (!m_isPileup)
77 {
78 transObj->clear(SG::VIEW_ELEMENTS);
79 }
80 HepMC::DataPool datapools;
81 const unsigned int nVertices = persObj->m_genVertices.size();
82 datapools.vtx.prepareToAdd(nVertices);
83 const unsigned int nParts = persObj->m_genParticles.size();
84 datapools.part.prepareToAdd(nParts);
85 const unsigned int nEvts = persObj->m_genEvents.size();
86 datapools.evt.prepareToAdd(nEvts);
87
88 transObj->reserve( nEvts );
89 for ( std::vector<GenEvent_p4>::const_iterator
90 itr = persObj->m_genEvents.begin(),
91 itrEnd = persObj->m_genEvents.end();
92 itr != itrEnd;
93 ++itr )
94 {
95 const GenEvent_p4& persEvt = *itr;
96 HepMC::GenEvent * genEvt(nullptr);
97 if(m_isPileup)
98 {
99 genEvt = new HepMC::GenEvent();
100 }
101 else
102 {
103 genEvt = datapools.getGenEvent();
104 }
105#ifdef HEPMC3
106 genEvt->add_attribute (barcodesStr, std::make_shared<HepMC::GenEventBarcodes>());
107 genEvt->add_attribute(signalProcessIdStr, std::make_shared<HepMC3::IntAttribute>(persEvt.m_signalProcessId));
108 genEvt->set_event_number(persEvt.m_eventNbr);
109 genEvt->add_attribute(eventScaleStr, std::make_shared<HepMC3::DoubleAttribute>(persEvt.m_eventScale));
110 genEvt->add_attribute(alphaQcdStr, std::make_shared<HepMC3::DoubleAttribute>(persEvt.m_alphaQCD));
111 genEvt->add_attribute(alphaQedStr, std::make_shared<HepMC3::DoubleAttribute>(persEvt.m_alphaQED));
112 genEvt->weights() = persEvt.m_weights;
113 genEvt->add_attribute(randomStatesStr, std::make_shared<HepMC3::VectorLongIntAttribute>(persEvt.m_randomStates));
114 //restore weight names from the dedicated svc (which was keeping them in metadata for efficiency)
115 if(!genEvt->run_info()) genEvt->set_run_info(std::make_shared<HepMC3::GenRunInfo>());
116 if(genEvt->run_info()) genEvt->run_info()->set_weight_names(m_hepMCWeightSvc->weightNameVec(ctx));
117
118
119 // pdfinfo restore
120 if (!persEvt.m_pdfinfo.empty())
121 {
122 const std::vector<double>& pdf = persEvt.m_pdfinfo;
123 HepMC3::GenPdfInfoPtr pi = std::make_shared<HepMC3::GenPdfInfo>();
124 pi->set(
125 static_cast<int>(pdf[6]), // id1
126 static_cast<int>(pdf[5]), // id2
127 pdf[4], // x1
128 pdf[3], // x2
129 pdf[2], // scalePDF
130 pdf[1], // pdf1
131 pdf[0] ); // pdf2
132 genEvt->set_pdf_info(std::move(pi));
133 }
134
135 transObj->push_back( genEvt );
136
137 // create a temporary map associating the barcode of an end-vtx to its
138 // particle.
139 // As not all particles are stable (d'oh!) we take 50% of the number of
140 // particles as an initial size of the hash-map (to prevent re-hash)
141 ParticlesMap_t partToEndVtx( (persEvt.m_particlesEnd-persEvt.m_particlesBegin)/2 );
142 // This is faster than the HepMC::barcode_to_vertex
143 std::map<int, HepMC::GenVertexPtr> brc_to_vertex;
144 // create the vertices
145 const unsigned int endVtx = persEvt.m_verticesEnd;
146 for ( unsigned int iVtx= persEvt.m_verticesBegin; iVtx != endVtx; ++iVtx )
147 {
148 auto vtx = createGenVertex( *persObj, persObj->m_genVertices[iVtx], partToEndVtx, datapools, genEvt );
149 brc_to_vertex[persObj->m_genVertices[iVtx].m_barcode] = std::move(vtx);
150 } //> end loop over vertices
151
152 // set the signal process vertex
153 const int sigProcVtx = persEvt.m_signalProcessVtx;
154 if ( sigProcVtx != 0 && brc_to_vertex.count(sigProcVtx) ) {
155 HepMC::set_signal_process_vertex(genEvt, brc_to_vertex[sigProcVtx] );
156 }
157
158 // connect particles to their end vertices
159 for (auto & p : partToEndVtx) {
160 if ( brc_to_vertex.count(p.second) ) {
161 auto decayVtx = brc_to_vertex[p.second];
162 decayVtx->add_particle_in( p.first );
163 } else {
164 msg << MSG::ERROR << "GenParticle points to null end vertex !!" << endmsg;
165 }
166 }
167#else
168 genEvt->m_signal_process_id = persEvt.m_signalProcessId;
169 genEvt->m_event_number = persEvt.m_eventNbr;
170 genEvt->m_event_scale = persEvt.m_eventScale;
171 genEvt->m_alphaQCD = persEvt.m_alphaQCD;
172 genEvt->m_alphaQED = persEvt.m_alphaQED;
173 genEvt->m_signal_process_vertex = 0;
174 genEvt->m_weights = persEvt.m_weights;
175 genEvt->m_random_states = persEvt.m_randomStates;
176 genEvt->m_vertex_barcodes.clear();
177 genEvt->m_particle_barcodes.clear();
178 //restore weight names from the dedicated svc (which was keeping them in metadata for efficiency)
179 genEvt->m_weights.m_names = m_hepMCWeightSvc->weightNames(ctx);
180
181 // pdfinfo restore
182 delete genEvt->m_pdf_info; genEvt->m_pdf_info = 0;
183 if (!persEvt.m_pdfinfo.empty())
184 {
185 const std::vector<double>& pdf = persEvt.m_pdfinfo;
186 genEvt->m_pdf_info = new HepMC::PdfInfo
187 ( static_cast<int>(pdf[6]), // id1
188 static_cast<int>(pdf[5]), // id2
189 pdf[4], // x1
190 pdf[3], // x2
191 pdf[2], // scalePDF
192 pdf[1], // pdf1
193 pdf[0] ); // pdf2
194 }
195
196
197 transObj->push_back( genEvt );
198
199 // create a temporary map associating the barcode of an end-vtx to its
200 // particle.
201 // As not all particles are stable (d'oh!) we take 50% of the number of
202 // particles as an initial size of the hash-map (to prevent re-hash)
203 ParticlesMap_t partToEndVtx( (persEvt.m_particlesEnd-
204 persEvt.m_particlesBegin)/2 );
205
206 // create the vertices
207 const unsigned int endVtx = persEvt.m_verticesEnd;
208 for ( unsigned int iVtx= persEvt.m_verticesBegin; iVtx != endVtx; ++iVtx )
209 {
210 genEvt->add_vertex( createGenVertex( *persObj,
211 persObj->m_genVertices[iVtx],
212 partToEndVtx,
213 datapools ) );
214 } //> end loop over vertices
215
216 // set the signal process vertex
217 const int sigProcVtx = persEvt.m_signalProcessVtx;
218 if ( sigProcVtx != 0 )
219 {
221 }
222
223
224 // connect particles to their end vertices
225 for ( ParticlesMap_t::iterator
226 p = partToEndVtx.begin(),
227 endItr = partToEndVtx.end();
228 p != endItr;
229 ++p )
230 {
231 auto decayVtx= HepMC::barcode_to_vertex(genEvt, p->second );
232 if ( decayVtx )
233 {
234 decayVtx->add_particle_in( p->first );
235 }
236 else
237 {
238 msg << MSG::ERROR
239 << "GenParticle points to null end vertex !!"
240 << endmsg;
241 }
242 }
243#endif
244
245 } //> end loop over m_genEvents
246
247 msg << MSG::DEBUG << "Loaded McEventCollection from persistent state [OK]"
248 << endmsg;
249}
250
252 McEventCollection_p4* persObj,
253 MsgStream& msg )
254{
255 const EventContext& ctx = Gaudi::Hive::currentContext();
256
257 msg << MSG::DEBUG << "Creating persistent state of McEventCollection..."
258 << endmsg;
259 persObj->m_genEvents.reserve( transObj->size() );
260
261 const std::pair<unsigned int,unsigned int> stats = nbrParticlesAndVertices( transObj );
262 persObj->m_genParticles.reserve( stats.first );
263 persObj->m_genVertices.reserve ( stats.second );
264
265 const McEventCollection::const_iterator itrEnd = transObj->end();
266 for ( McEventCollection::const_iterator itr = transObj->begin();
267 itr != itrEnd;
268 ++itr )
269 {
270#ifdef HEPMC3
271 const unsigned int nPersVtx = persObj->m_genVertices.size();
272 const unsigned int nPersParts = persObj->m_genParticles.size();
273 const HepMC::GenEvent* genEvt = *itr;
274 //save the weight names to metadata via the HepMCWeightSvc
275 if (genEvt->run_info()) {
276 if (!genEvt->run_info()->weight_names().empty()) {
277 m_hepMCWeightSvc->setWeightNames( names_to_name_index_map(genEvt->weight_names()), ctx ).ignore();
278 } else {
279 //AV : This to be decided if one would like to have default names.
280 //std::vector<std::string> names{"0"};
281 //m_hepMCWeightSvc->setWeightNames( names_to_name_index_map(names), ctx );
282 }
283 }
284 auto A_signal_process_id=genEvt->attribute<HepMC3::IntAttribute>(signalProcessIdStr);
285 auto A_event_scale=genEvt->attribute<HepMC3::DoubleAttribute>(eventScaleStr);
286 auto A_alphaQCD=genEvt->attribute<HepMC3::DoubleAttribute>(alphaQcdStr);
287 auto A_alphaQED=genEvt->attribute<HepMC3::DoubleAttribute>(alphaQedStr);
288 auto signal_process_vertex = HepMC::signal_process_vertex(genEvt);
289 auto A_random_states=genEvt->attribute<HepMC3::VectorLongIntAttribute>(randomStatesStr);
290
291 persObj->m_genEvents.
292 emplace_back( A_signal_process_id?(A_signal_process_id->value()):0,
293 genEvt->event_number(),
294 A_event_scale?(A_event_scale->value()):0.0,
295 A_alphaQCD?(A_alphaQCD->value()):0.0,
296 A_alphaQED?(A_alphaQED->value()):0.0,
297 signal_process_vertex?HepMC::barcode(signal_process_vertex):0,
298 genEvt->weights(),
299 std::vector<double>(),//No idea why it is empty
300 A_random_states?(A_random_states->value()):std::vector<long>(),
301 nPersVtx,
302 nPersVtx + genEvt->vertices().size(),
303 nPersParts,
304 nPersParts + genEvt->particles().size() );
305
306 //PdfInfo encoding
307 if (genEvt->pdf_info())
308 {
309 auto pi=genEvt->pdf_info();
310 GenEvent_p4& persEvt = persObj->m_genEvents.back();
311 std::vector<double>& pdfinfo = persEvt.m_pdfinfo;
312 pdfinfo.resize(7);
313 pdfinfo[6] = static_cast<double>(pi->parton_id[0]);
314 pdfinfo[5] = static_cast<double>(pi->parton_id[1]);
315 pdfinfo[4] = pi->x[0];
316 pdfinfo[3] = pi->x[1];
317 pdfinfo[2] = pi->scale;
318 pdfinfo[1] = pi->xf[0];
319 pdfinfo[0] = pi->xf[1];
320 }
321 // create vertices
322 for ( const auto& v: genEvt->vertices())
323 {
324 writeGenVertex( v, *persObj );
325 }
326
327#else
328 const unsigned int nPersVtx = persObj->m_genVertices.size();
329 const unsigned int nPersParts = persObj->m_genParticles.size();
330 const HepMC::GenEvent* genEvt = *itr;
331 const int signalProcessVtx = genEvt->m_signal_process_vertex
332 ? genEvt->m_signal_process_vertex->barcode()
333 : 0;
334 //save the weight names to metadata via the HepMCWeightSvc
335 m_hepMCWeightSvc->setWeightNames( genEvt->m_weights.m_names, ctx ).ignore();
336 persObj->m_genEvents.
337 push_back( GenEvent_p4( genEvt->m_signal_process_id,
338 genEvt->m_event_number,
339 genEvt->m_event_scale,
340 genEvt->m_alphaQCD,
341 genEvt->m_alphaQED,
342 signalProcessVtx,
343 genEvt->m_weights.m_weights,
344 std::vector<double>(),
345 genEvt->m_random_states,
346 nPersVtx,
347 nPersVtx + genEvt->vertices_size(),
348 nPersParts,
349 nPersParts + genEvt->particles_size() ) );
350 //PdfInfo encoding
351 if (genEvt->m_pdf_info)
352 {
353 GenEvent_p4& persEvt = persObj->m_genEvents.back();
354 std::vector<double>& pdfinfo = persEvt.m_pdfinfo;
355 pdfinfo.resize(7);
356 pdfinfo[6] = static_cast<double>(genEvt->m_pdf_info->m_id1);
357 pdfinfo[5] = static_cast<double>(genEvt->m_pdf_info->m_id2);
358 pdfinfo[4] = genEvt->m_pdf_info->m_x1;
359 pdfinfo[3] = genEvt->m_pdf_info->m_x2;
360 pdfinfo[2] = genEvt->m_pdf_info->m_scalePDF;
361 pdfinfo[1] = genEvt->m_pdf_info->m_pdf1;
362 pdfinfo[0] = genEvt->m_pdf_info->m_pdf2;
363 }
364
365 // create vertices
366 const HepMC::GenEvent::vertex_const_iterator endVtx=genEvt->vertices_end();
367 for ( HepMC::GenEvent::vertex_const_iterator i = genEvt->vertices_begin();
368 i != endVtx;
369 ++i )
370 {
371 writeGenVertex( **i, *persObj );
372 }
373#endif
374
375 } //> end loop over GenEvents
376
377 msg << MSG::DEBUG << "Created persistent state of HepMC::GenEvent [OK]"
378 << endmsg;
379}
380
381
384 const GenVertex_p4& persVtx,
385 ParticlesMap_t& partToEndVtx,
386 HepMC::DataPool& datapools, HepMC::GenEvent* parent ) const
387{
388 HepMC::GenVertexPtr vtx(nullptr);
389 if(m_isPileup)
390 {
392 }
393 else
394 {
395 vtx = datapools.getGenVertex();
396 }
397 if (parent) parent->add_vertex(vtx);
398#ifdef HEPMC3
399 vtx->set_position(HepMC::FourVector( persVtx.m_x , persVtx.m_y , persVtx.m_z ,persVtx.m_t ));
400 vtx->set_status(HepMC::new_vertex_status_from_old(persVtx.m_id, persVtx.m_barcode)); // UPDATED STATUS VALUE TO NEW SCHEME
401 // cast from std::vector<float> to std::vector<double>
402 std::vector<double> weights( persVtx.m_weights.begin(), persVtx.m_weights.end() );
403 vtx->add_attribute("weights",std::make_shared<HepMC3::VectorDoubleAttribute>(weights));
405
406 // handle the in-going (orphans) particles
407 //Is this needed in HepMC3?
408 const unsigned int nPartsIn = persVtx.m_particlesIn.size();
409 for ( unsigned int i = 0; i != nPartsIn; ++i )
410 {
411 createGenParticle( persEvt.m_genParticles[persVtx.m_particlesIn[i]], partToEndVtx, datapools, vtx, false );
412 }
413
414 // now handle the out-going particles
415 const unsigned int nPartsOut = persVtx.m_particlesOut.size();
416 for ( unsigned int i = 0; i != nPartsOut; ++i )
417 {
418 createGenParticle( persEvt.m_genParticles[persVtx.m_particlesOut[i]], partToEndVtx, datapools, vtx );
419 }
420#else
421 vtx->m_position.setX( persVtx.m_x );
422 vtx->m_position.setY( persVtx.m_y );
423 vtx->m_position.setZ( persVtx.m_z );
424 vtx->m_position.setT( persVtx.m_t );
425 vtx->m_particles_in.clear();
426 vtx->m_particles_out.clear();
427 vtx->m_id = HepMC::new_vertex_status_from_old(persVtx.m_id, persVtx.m_barcode); // UPDATED STATUS VALUE TO NEW SCHEME
428 vtx->m_weights.m_weights.reserve( persVtx.m_weights.size() );
429 vtx->m_weights.m_weights.assign ( persVtx.m_weights.begin(),
430 persVtx.m_weights.end() );
431 vtx->m_event = 0;
432 vtx->m_barcode = persVtx.m_barcode;
433
434 // handle the in-going (orphans) particles
435 const unsigned int nPartsIn = persVtx.m_particlesIn.size();
436 for ( unsigned int i = 0; i != nPartsIn; ++i )
437 {
439 partToEndVtx,
440 datapools );
441 }
442
443 // now handle the out-going particles
444 const unsigned int nPartsOut = persVtx.m_particlesOut.size();
445 for ( unsigned int i = 0; i != nPartsOut; ++i )
446 {
447 vtx->add_particle_out( createGenParticle( persEvt.m_genParticles[persVtx.m_particlesOut[i]],
448 partToEndVtx,
449 datapools ) );
450 }
451#endif
452
453 return vtx;
454}
455
458 ParticlesMap_t& partToEndVtx,
459 HepMC::DataPool& datapools, const HepMC::GenVertexPtr& parent, bool add_to_output ) const
460{
461 HepMC::GenParticlePtr p(nullptr);
462 if (m_isPileup)
463 {
465 }
466 else
467 {
468 p = datapools.getGenParticle();
469 }
470 if (parent) add_to_output?parent->add_particle_out(p):parent->add_particle_in(p);
471#ifdef HEPMC3
472 p->set_pdg_id( persPart.m_pdgId);
473 p->set_status(HepMC::new_particle_status_from_old(persPart.m_status, persPart.m_barcode)); // UPDATED STATUS VALUE TO NEW SCHEME
474 p->add_attribute("phi",std::make_shared<HepMC3::DoubleAttribute>(persPart.m_phiPolarization));
475 p->add_attribute("theta",std::make_shared<HepMC3::DoubleAttribute>(persPart.m_thetaPolarization));
477
478 // Note: do the E calculation in extended (long double) precision.
479 // That happens implicitly on x86 with optimization on; saying it
480 // explicitly ensures that we get the same results with and without
481 // optimization. (If this is a performance issue for platforms
482 // other than x86, one could change to double for those platforms.)
483 if ( 0 == persPart.m_recoMethod )
484 {
485 double temp_e = std::sqrt( (long double)(persPart.m_px)*persPart.m_px +
486 (long double)(persPart.m_py)*persPart.m_py +
487 (long double)(persPart.m_pz)*persPart.m_pz +
488 (long double)(persPart.m_m) *persPart.m_m );
489 p->set_momentum( HepMC::FourVector(persPart.m_px,persPart.m_py,persPart.m_pz,temp_e));
490 }
491 else
492 {
493 const int signM2 = ( persPart.m_m >= 0. ? 1 : -1 );
494 const double persPart_ene =
495 std::sqrt( std::abs((long double)(persPart.m_px)*persPart.m_px +
496 (long double)(persPart.m_py)*persPart.m_py +
497 (long double)(persPart.m_pz)*persPart.m_pz +
498 signM2* (long double)(persPart.m_m)* persPart.m_m));
499 const int signEne = ( persPart.m_recoMethod == 1 ? 1 : -1 );
500 p->set_momentum( HepMC::FourVector( persPart.m_px,
501 persPart.m_py,
502 persPart.m_pz,
503 signEne * persPart_ene ));
504 }
505
506 // setup flow
507 std::vector<int> flows;
508 const unsigned int nFlow = persPart.m_flow.size();
509 for ( unsigned int iFlow= 0; iFlow != nFlow; ++iFlow ) {
510 flows.push_back(persPart.m_flow[iFlow].second );
511 }
512 //We construct it here as vector w/o gaps.
513 p->add_attribute("flows", std::make_shared<HepMC3::VectorIntAttribute>(flows));
514#else
515 p->m_pdg_id = persPart.m_pdgId;
516 p->m_status = HepMC::new_particle_status_from_old(persPart.m_status, persPart.m_barcode); // UPDATED STATUS VALUE TO NEW SCHEME
517 p->m_polarization.m_theta= static_cast<double>(persPart.m_thetaPolarization);
518 p->m_polarization.m_phi = static_cast<double>(persPart.m_phiPolarization );
519 p->m_production_vertex = 0;
520 p->m_end_vertex = 0;
521 p->m_barcode = persPart.m_barcode;
522
523 // Note: do the E calculation in extended (long double) precision.
524 // That happens implicitly on x86 with optimization on; saying it
525 // explicitly ensures that we get the same results with and without
526 // optimization. (If this is a performance issue for platforms
527 // other than x86, one could change to double for those platforms.)
528 if ( 0 == persPart.m_recoMethod )
529 {
530
531 p->m_momentum.setPx( persPart.m_px);
532 p->m_momentum.setPy( persPart.m_py);
533 p->m_momentum.setPz( persPart.m_pz);
534 double temp_e = std::sqrt( (long double)(persPart.m_px)*persPart.m_px +
535 (long double)(persPart.m_py)*persPart.m_py +
536 (long double)(persPart.m_pz)*persPart.m_pz +
537 (long double)(persPart.m_m) *persPart.m_m );
538 p->m_momentum.setE( temp_e);
539 }
540 else
541 {
542 const int signM2 = ( persPart.m_m >= 0. ? 1 : -1 );
543 const double persPart_ene =
544 std::sqrt( std::abs((long double)(persPart.m_px)*persPart.m_px +
545 (long double)(persPart.m_py)*persPart.m_py +
546 (long double)(persPart.m_pz)*persPart.m_pz +
547 signM2* (long double)(persPart.m_m)* persPart.m_m));
548 const int signEne = ( persPart.m_recoMethod == 1 ? 1 : -1 );
549 p->m_momentum.set( persPart.m_px,
550 persPart.m_py,
551 persPart.m_pz,
552 signEne * persPart_ene );
553 }
554
555 // setup flow
556 const unsigned int nFlow = persPart.m_flow.size();
557 p->m_flow.clear();
558 for ( unsigned int iFlow= 0; iFlow != nFlow; ++iFlow )
559 {
560 p->m_flow.set_icode( persPart.m_flow[iFlow].first,
561 persPart.m_flow[iFlow].second );
562 }
563#endif
564
565 if ( persPart.m_endVtx != 0 )
566 {
567 partToEndVtx[p] = persPart.m_endVtx;
568 }
569
570 return p;
571}
572
573#ifdef HEPMC3
575 McEventCollection_p4& persEvt )
576{
577 const HepMC::FourVector& position = vtx->position();
578 auto A_weights=vtx->attribute<HepMC3::VectorDoubleAttribute>("weights");
579 auto A_barcode=vtx->attribute<HepMC3::IntAttribute>("barcode");
580 std::vector<float> weights;
581 if (A_weights) {
582 auto weights_d = A_weights->value();
583 for (auto& w: weights_d) weights.push_back(w);
584 }
585 persEvt.m_genVertices.emplace_back( position.x(),
586 position.y(),
587 position.z(),
588 position.t(),
589 HepMC::old_vertex_status_from_new(vtx->status()), // REVERTED STATUS VALUE TO OLD SCHEME
590 weights.begin(),
591 weights.end(),
592 A_barcode?(A_barcode->value()):vtx->id()
593 );
594 GenVertex_p4& persVtx = persEvt.m_genVertices.back();
595 // we write only the orphans in-coming particles and beams
596 persVtx.m_particlesIn.reserve(vtx->particles_in().size());
597 for ( const auto& p: vtx->particles_in())
598 {
599 if ( !p->production_vertex() || p->production_vertex()->id() == 0 )
600 {
601 persVtx.m_particlesIn.push_back( writeGenParticle(p, persEvt ));
602 }
603 }
604 persVtx.m_particlesOut.reserve(vtx->particles_out().size());
605 for ( const auto& p: vtx->particles_out())
606 {
607 persVtx.m_particlesOut.push_back( writeGenParticle(p, persEvt ) );
608 }
609 }
610#else
611void McEventCollectionCnv_p4::writeGenVertex( const HepMC::GenVertex& vtx,
612 McEventCollection_p4& persEvt ) const
613{
614 const HepMC::FourVector& position = vtx.m_position;
615 persEvt.m_genVertices.push_back(
616 GenVertex_p4( position.x(),
617 position.y(),
618 position.z(),
619 position.t(),
620 HepMC::old_vertex_status_from_new(vtx.m_id), // REVERTED STATUS VALUE TO OLD SCHEME
621 vtx.m_weights.m_weights.begin(),
622 vtx.m_weights.m_weights.end(),
623 vtx.m_barcode ) );
624 GenVertex_p4& persVtx = persEvt.m_genVertices.back();
625
626 // we write only the orphans in-coming particles
627 const std::vector<HepMC::GenParticlePtr>::const_iterator endInVtx = vtx.m_particles_in.end();
628 persVtx.m_particlesIn.reserve(vtx.m_particles_in.size());
629 for ( std::vector<HepMC::GenParticlePtr>::const_iterator p = vtx.m_particles_in.begin();
630 p != endInVtx;
631 ++p )
632 {
633 if ( 0 == (*p)->production_vertex() )
634 {
635 persVtx.m_particlesIn.push_back( writeGenParticle( **p, persEvt ) );
636 }
637 }
638
639 const std::vector<HepMC::GenParticlePtr>::const_iterator endOutVtx = vtx.m_particles_out.end();
640 persVtx.m_particlesOut.reserve(vtx.m_particles_out.size());
641 for ( std::vector<HepMC::GenParticlePtr>::const_iterator p = vtx.m_particles_out.begin();
642 p != endOutVtx;
643 ++p )
644 {
645 persVtx.m_particlesOut.push_back( writeGenParticle( **p, persEvt ) );
646 }
647
648 return;
649}
650#endif
651
652#ifdef HEPMC3
654 McEventCollection_p4& persEvt )
655{
656 const HepMC::FourVector& mom = p->momentum();
657 const double ene = mom.e();
658 const double m2 = mom.m2();
659
660 // Definitions of Bool isTimeLilike, isSpacelike and isLightlike according to HepLorentzVector definition
661 const bool useP2M2 = !(m2 > 0) && // !isTimelike
662 (m2 < 0) && // isSpacelike
663 !(std::abs(m2) < 2.0*DBL_EPSILON*ene*ene); // !isLightlike
664
665 const short recoMethod = ( !useP2M2 ? 0: ( ene >= 0. ? 1 : 2 ) );
666 auto A_theta=p->attribute<HepMC3::DoubleAttribute>("theta");
667 auto A_phi=p->attribute<HepMC3::DoubleAttribute>("phi");
668 auto A_flows=p->attribute<HepMC3::VectorIntAttribute>("flows");
669
670
671 persEvt.m_genParticles.emplace_back( mom.px(),
672 mom.py(),
673 mom.pz(),
674 mom.m(),
675 p->pdg_id(),
676 HepMC::old_particle_status_from_new(p->status()), // REVERTED STATUS VALUE TO OLD SCHEME
677 A_flows?(A_flows->value().size()):0,
678 A_theta?(A_theta->value()):0.0,
679 A_phi?(A_phi->value()):0.0,
680 p->production_vertex()?(HepMC::barcode(p->production_vertex())):0,
681 p->end_vertex()?(HepMC::barcode(p->end_vertex())):0,
683 recoMethod );
684
685 std::vector< std::pair<int,int> > flow_hepmc2;
686 if(A_flows) flow_hepmc2=vector_to_vector_int_int(A_flows->value());
687 persEvt.m_genParticles.back().m_flow.assign( flow_hepmc2.begin(),flow_hepmc2.end() );
688 // we return the index of the particle in the big vector of particles
689 // (contained by the persistent GenEvent)
690 return (persEvt.m_genParticles.size() - 1);
691}
692#else
693int McEventCollectionCnv_p4::writeGenParticle( const HepMC::GenParticle& p,
694 McEventCollection_p4& persEvt ) const
695{
696 const HepMC::FourVector& mom = p.m_momentum;
697 const double ene = mom.e();
698 const double m2 = mom.m2();
699
700 // Definitions of Bool isTimeLilike, isSpacelike and isLightlike according to HepLorentzVector definition
701 const bool useP2M2 = !(m2 > 0) && // !isTimelike
702 (m2 < 0) && // isSpacelike
703 !(std::abs(m2) < 2.0*DBL_EPSILON*ene*ene); // !isLightlike
704
705 const short recoMethod = ( !useP2M2
706 ? 0
707 : ( ene >= 0. //*GeV
708 ? 1
709 : 2 ) );
710
711 persEvt.m_genParticles.
712 push_back( GenParticle_p4( mom.px(),
713 mom.py(),
714 mom.pz(),
715 mom.m(),
716 p.m_pdg_id,
717 HepMC::old_particle_status_from_new(p.m_status), // REVERTED STATUS VALUE TO OLD SCHEME
718 p.m_flow.size(),
719 p.m_polarization.theta(),
720 p.m_polarization.phi(),
721 p.m_production_vertex
722 ? p.m_production_vertex->barcode()
723 : 0,
724 p.m_end_vertex
725 ? p.m_end_vertex->barcode()
726 : 0,
727 p.m_barcode,
728 recoMethod ) );
729 persEvt.m_genParticles.back().m_flow.assign( p.m_flow.begin(),
730 p.m_flow.end() );
731
732 // we return the index of the particle in the big vector of particles
733 // (contained by the persistent GenEvent)
734 return (persEvt.m_genParticles.size() - 1);
735}
736#endif
737
#define endmsg
#define pi
void prepareToAdd(unsigned int size)
Prepare to add cached elements.
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
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.
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
void clear()
Erase all the elements in the collection.
double m_alphaQED
value of the QED coupling.
Definition GenEvent_p4.h:83
double m_alphaQCD
value of the QCD coupling.
Definition GenEvent_p4.h:79
double m_eventScale
Energy scale.
Definition GenEvent_p4.h:75
std::vector< double > m_weights
Weights for this event.
Definition GenEvent_p4.h:94
int m_signalProcessId
Id of the processus being generated.
Definition GenEvent_p4.h:67
int m_eventNbr
Event number.
Definition GenEvent_p4.h:71
std::vector< double > m_pdfinfo
Container of HepMC::PdfInfo object translated to vector<double> for simplicity.
Definition GenEvent_p4.h:99
unsigned int m_verticesEnd
End position in the vector of vertices composing this event.
unsigned int m_particlesEnd
End position in the vector of particles composing this event.
unsigned int m_verticesBegin
Begin position in the vector of vertices composing this event.
unsigned int m_particlesBegin
Begin position in the vector of particles composing this event.
int m_signalProcessVtx
Barcode of the GenVertex holding the signal process.
Definition GenEvent_p4.h:89
std::vector< long int > m_randomStates
Container of random numbers for the generator states.
float m_px
x-component of the 4-momentum of this particle
float m_m
m-component of the 4-momentum of this particle
float m_py
y-component of the 4-momentum of this particle
short m_recoMethod
switch to know which method to chose to better recover the original HepLorentzVector.
int m_pdgId
identity of this particle, according to the Particle Data Group notation
std::vector< std::pair< int, int > > m_flow
Flow for this particle.
float m_phiPolarization
phi polarization
float m_pz
z-component of the 4-momentum of this particle
float m_thetaPolarization
polarization
int m_endVtx
Barcode of the decay vertex of this particle.
int m_status
Status of this particle, as defined for HEPEVT.
int m_barcode
barcode of this particles (uniquely identifying this particle within a given GenEvent)
float m_x
x-coordinate of the vertex
float m_t
t-coordinate of the vertex
std::vector< int > m_particlesIn
collection of barcodes of in-going particles connected to this vertex
float m_y
y-coordinate of the vertex
std::vector< float > m_weights
Weights for this vertex.
float m_z
z-coordinate of the vertex
int m_barcode
barcode of this vertex (uniquely identifying a vertex within an event)
std::vector< int > m_particlesOut
collection of barcodes of out-going particles connected to this vertex
int m_id
Id of this vertex.
void writeGenVertex(const HepMC::GenVertex &vtx, McEventCollection_p4 &persEvt) const
Method to write a persistent GenVertex object.
virtual void persToTrans(const McEventCollection_p4 *persObj, McEventCollection *transObj, MsgStream &log)
Method creating the transient representation of McEventCollection from its persistent representation ...
HepMC::GenParticlePtr createGenParticle(const GenParticle_p4 &p, ParticlesMap_t &partToEndVtx, HepMC::DataPool &datapools, const HepMC::GenVertexPtr &parent=nullptr, bool add_to_output=true) const
Create a transient GenParticle from a persistent one (vers.1) It returns the new GenParticle.
McEventCollectionCnv_p4 & operator=(const McEventCollectionCnv_p4 &rhs)
Assignement operator.
virtual ~McEventCollectionCnv_p4()
Destructor.
McEventCollectionCnv_p4()
Default constructor:
int writeGenParticle(const HepMC::GenParticle &p, McEventCollection_p4 &persEvt) const
Method to write a persistent GenParticle object It returns the index of the persistent GenParticle in...
virtual void transToPers(const McEventCollection *transObj, McEventCollection_p4 *persObj, MsgStream &log)
Method creating the persistent representation McEventCollection_p4 from its transient representation ...
T_AthenaPoolTPCnvBase< McEventCollection, McEventCollection_p4 > Base_t
std::unordered_map< HepMC::GenParticlePtr, int > ParticlesMap_t
HepMC::GenVertexPtr createGenVertex(const McEventCollection_p4 &persEvts, const GenVertex_p4 &vtx, ParticlesMap_t &bcToPart, HepMC::DataPool &datapools, HepMC::GenEvent *parent=nullptr) const
Create a transient GenVertex from a persistent one (version 1) It returns the new GenVertex.
ServiceHandle< IHepMCWeightSvc > m_hepMCWeightSvc
std::vector< GenParticle_p4 > m_genParticles
The vector of persistent representation of GenParticles.
std::vector< GenVertex_p4 > m_genVertices
The vector of persistent representation of GenVertices.
std::vector< GenEvent_p4 > m_genEvents
The vector of persistent representation of GenEvents.
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:670
int barcode(const T *p)
Definition Barcode.h:16
GenVertex * barcode_to_vertex(const GenEvent *e, int id)
Definition GenEvent.h:647
HepMC::GenVertex * GenVertexPtr
Definition GenVertex.h:59
bool suggest_barcode(T &p, int i)
Definition GenEvent.h:690
GenVertexPtr newGenVertexPtr(const HepMC::FourVector &pos=HepMC::FourVector(0.0, 0.0, 0.0, 0.0), const int i=0)
Definition GenVertex.h:64
int new_vertex_status_from_old(const int oldStatus, const int barcode)
Get vertex status in the new scheme from the barcode and status in the old scheme.
int old_vertex_status_from_new(const int newStatus)
Get vertex status in the old scheme from the status in the new scheme.
GenParticlePtr newGenParticlePtr(const HepMC::FourVector &mom=HepMC::FourVector(0.0, 0.0, 0.0, 0.0), int pid=0, int status=0)
Definition GenParticle.h:39
int new_particle_status_from_old(const int oldStatus, const int barcode)
Get particle status in the new scheme from the barcode and status in the old scheme.
int old_particle_status_from_new(const int newStatus)
Get particle status in the old scheme from the status in the new scheme.
GenParticle * GenParticlePtr
Definition GenParticle.h:37
const GenParticle * ConstGenParticlePtr
Definition GenParticle.h:38
GenVertex * signal_process_vertex(const GenEvent *e)
Definition GenEvent.h:645
const HepMC::GenVertex * ConstGenVertexPtr
Definition GenVertex.h:60
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
const Amg::Vector3D & position() const
Method to retrieve the position of the Intersection.
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