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