6 #ifndef ATLASHEPMC_GENEVENT_H
7 #define ATLASHEPMC_GENEVENT_H
11 #include "HepMC3/GenEvent.h"
12 #include "HepMC3/GenHeavyIon.h"
13 #include "HepMC3/GenPdfInfo.h"
14 #include "HepMC3/PrintStreams.h"
20 #include <unordered_map>
23 inline std::vector<HepMC3::GenParticlePtr>::const_iterator
begin(HepMC3::GenEvent&
e) {
return e.particles().begin(); }
24 inline std::vector<HepMC3::GenParticlePtr>::const_iterator
end(HepMC3::GenEvent&
e) {
return e.particles().end(); }
25 inline std::vector<HepMC3::ConstGenParticlePtr>::const_iterator
begin(
const HepMC3::GenEvent&
e) {
return e.particles().begin(); }
26 inline std::vector<HepMC3::ConstGenParticlePtr>::const_iterator
end(
const HepMC3::GenEvent&
e) {
return e.particles().end(); }
31 using GenHeavyIon=HepMC3::GenHeavyIon;
32 using GenEvent=HepMC3::GenEvent;
34 class ShortEventAttribute :
public HepMC3::Attribute {
36 ShortEventAttribute():HepMC3::Attribute(){}
37 ShortEventAttribute(
const HepMC3::GenEvent*
e):HepMC3::Attribute(){ from_event(
e); }
39 bool from_event(
const HepMC3::GenEvent*
e){
40 NUP=
e->particles().size();
42 XWGTUP =
e->weights().size() ?
e->weights()[0] : 1.0;
43 auto A_signal_process_id=
e->attribute<HepMC3::IntAttribute>(
"signal_process_id");
44 IDPRUP = A_signal_process_id?A_signal_process_id->value() : 0;
45 auto A_event_scale=
e->attribute<HepMC3::DoubleAttribute>(
"event_scale");
46 SCALUP = A_event_scale? A_event_scale->value():0;
47 auto A_alphaQCD=
e->attribute<HepMC3::DoubleAttribute>(
"alphaQCD");
48 AQCDUP = A_alphaQCD? A_alphaQCD->value():0;
49 auto A_alphaQED=
e->attribute<HepMC3::DoubleAttribute>(
"alphaQED");
50 AQEDUP = A_alphaQED? A_alphaQED->value():0;
52 for (
int i = 0;
i < NUP; ++
i ){
53 PUP[
i][0] =
e->particles().at(
i)->momentum().px();
54 PUP[
i][1] =
e->particles().at(
i)->momentum().py();
55 PUP[
i][2] =
e->particles().at(
i)->momentum().pz();
56 PUP[
i][3] =
e->particles().at(
i)->momentum().e();
57 PUP[
i][4] =
e->particles().at(
i)->momentum().m();
58 IDUP[
i] =
e->particles().at(
i)->pdg_id();
59 auto pv =
e->particles().at(
i)->production_vertex();
60 auto ev =
e->particles().at(
i)->end_vertex();
61 if (
pv &&
ev ) ISTUP[
i] = 2;
62 if (
pv && !
ev ) ISTUP[
i] = 1;
63 if (
e->particles().at(
i)->status() == 4 || !
pv ) ISTUP[
i] = -1;
64 auto flow1 =
e->particles().at(
i)->attribute<HepMC3::IntAttribute>(
"flow1");
65 auto flow2 =
e->particles().at(
i)->attribute<HepMC3::IntAttribute>(
"flow2");
66 ICOLUP[
i].first = flow1 ? flow1->value() : 0;
67 ICOLUP[
i].second = flow2 ? flow2->value() : 0;
76 bool from_string(
const std::string &att)
override {
77 std::istringstream iss(att);
86 for (
int i = 0;
i < NUP; ++
i ){
89 iss >> MOTHUP[
i].first;
90 iss >> MOTHUP[
i].second;
91 iss >> ICOLUP[
i].first;
92 iss >> ICOLUP[
i].second;
105 bool to_string(std::string &fl)
const override {
106 std::ostringstream
file;
107 file <<
" " << std::setw(4) << NUP
108 <<
" " << std::setw(6) << IDPRUP
109 <<
" " << std::setw(14) << XWGTUP
110 <<
" " << std::setw(14) << SCALUP
111 <<
" " << std::setw(14) << AQEDUP
112 <<
" " << std::setw(14) << AQCDUP <<
"\n";
113 for (
int i = 0;
i < NUP; ++
i )
114 file <<
" " << std::setw(8) << IDUP[
i]
115 <<
" " << std::setw(2) << ISTUP[
i]
116 <<
" " << std::setw(4) << MOTHUP[
i].first
117 <<
" " << std::setw(4) << MOTHUP[
i].second
118 <<
" " << std::setw(4) << ICOLUP[
i].first
119 <<
" " << std::setw(4) << ICOLUP[
i].second
120 <<
" " << std::setw(14) << PUP[
i][0]
121 <<
" " << std::setw(14) << PUP[
i][1]
122 <<
" " << std::setw(14) << PUP[
i][2]
123 <<
" " << std::setw(14) << PUP[
i][3]
124 <<
" " << std::setw(14) << PUP[
i][4]
125 <<
" " << std::setw(1) << VTIMUP[
i]
126 <<
" " << std::setw(1) << SPINUP[
i] << std::endl;
136 PUP.resize(NUP, std::vector<double>(5));
147 std::vector<long> IDUP{};
148 std::vector<int> ISTUP{};
149 std::vector< std::pair<int,int> > MOTHUP{};
150 std::vector< std::pair<int,int> > ICOLUP{};
151 std::vector< std::vector<double> > PUP{};
152 std::vector<double> VTIMUP{};
153 std::vector<double> SPINUP{};
157 class GenEventBarcodes :
public HepMC3::Attribute
160 virtual bool from_string(
const std::string & )
override {
return false; }
161 virtual bool to_string(std::string &att)
const override
163 att =
"GenEventBarcodes";
167 auto it = m_vertexBC.find (
id);
168 if (
it != m_vertexBC.end())
return it->second;
172 auto it = m_vertexBC.find (
id);
173 if (
it != m_vertexBC.end())
return it->second;
177 auto it = m_particleBC.find (
id);
178 if (
it != m_particleBC.end())
return it->second;
182 auto it = m_particleBC.find (
id);
183 if (
it != m_particleBC.end())
return it->second;
189 auto barcode =
p->attribute<HepMC3::IntAttribute>(
"barcode");
191 m_vertexBC[
barcode->value()] = std::move(
p);
197 auto barcode =
p->attribute<HepMC3::IntAttribute>(
"barcode");
199 auto it = m_vertexBC.find (
barcode->value());
200 if (
it != m_vertexBC.end()) {
201 m_vertexBC.erase (
it);
208 auto barcode =
p->attribute<HepMC3::IntAttribute>(
"barcode");
210 m_particleBC[
barcode->value()] = std::move(
p);
216 auto barcode =
p->attribute<HepMC3::IntAttribute>(
"barcode");
218 auto it = m_particleBC.find (
barcode->value());
219 if (
it != m_particleBC.end()) {
220 m_particleBC.erase (
it);
225 std::map<int, ConstGenVertexPtr> barcode_to_vertex_map()
const {
226 std::map<int, ConstGenVertexPtr> ret;
227 for (
const auto &bcvertpair: m_vertexBC)
228 ret.insert({bcvertpair.first,std::const_pointer_cast<const HepMC3::GenVertex>(bcvertpair.second)});
231 std::map<int, ConstGenParticlePtr> barcode_to_particle_map()
const {
232 std::map<int, ConstGenParticlePtr> ret;
233 for (
const auto &bcpartpair: m_particleBC)
234 ret.insert({bcpartpair.first,std::const_pointer_cast<const HepMC3::GenParticle>(bcpartpair.second)});
237 std::map<int,int> id_to_barcode_map()
const {
238 std::map<int, int> ret;
239 for (
const auto &bcvertpair: m_vertexBC) ret.insert({bcvertpair.second->id(),bcvertpair.first});
240 for (
const auto &bcpartpair: m_particleBC) ret.insert({bcpartpair.second->id(),bcpartpair.first});
245 void fillAttribute(GenEvent*
e) {
246 const auto eventAttributes =
e->attributes();
247 const auto barcodeAttributeIt = eventAttributes.find(
"barcode");
248 const bool hasBarcodeAttribute = barcodeAttributeIt != eventAttributes.end();
252 if (hasBarcodeAttribute && barcodeAttributeIt->second.count(
i) > 0) {
253 const auto &
ptr = barcodeAttributeIt->second.at(
i);
254 if (
ptr->is_parsed()) {
255 m_particleBC[
static_cast<HepMC3::IntAttribute*
>(
ptr.get())->
value()] =
ptr->particle();
258 m_particleBC[
std::atoi(
ptr->unparsed_string().c_str())] =
ptr->particle();
264 const auto &vertices =
e->vertices();
265 for (
size_t i = 1;
i <= vertices.size();
i++) {
266 if (hasBarcodeAttribute && barcodeAttributeIt->second.count(-
i) > 0) {
267 const auto &
ptr = barcodeAttributeIt->second.at(-
i);
268 if (
ptr->is_parsed()) {
269 m_vertexBC[
static_cast<HepMC3::IntAttribute*
>(
ptr.get())->
value()] =
ptr->vertex();
275 m_vertexBC[-
i] = vertices[
i-1];
282 std::unordered_map<int, GenVertexPtr> m_vertexBC;
283 std::unordered_map<int, GenParticlePtr> m_particleBC;
291 class ShadowParticle :
public HepMC3::Attribute {
299 : Attribute(), m_shadow(
p) {}
302 virtual bool from_string(
const std::string &)
override {
return false; }
305 virtual bool to_string(std::string &att)
const override
307 att =
"ShadowParticle";
321 e->add_attribute(
"long_long_event_number", std::make_shared<HepMC3::LongLongAttribute>(
num));
325 auto at =
e->attribute<HepMC3::LongLongAttribute>(
"long_long_event_number");
326 return at?at->value():
e->event_number();
329 inline std::map<std::string, std::size_t> weights_map(
const HepMC3::GenEvent*
e) {
330 std::map<std::string, std::size_t> ret;
331 auto run =
e->run_info();
332 if (!
run)
return ret;
333 std::vector<std::string>
names =
run->weight_names();
338 inline std::vector<HepMC3::GenParticlePtr>::const_iterator
begin(HepMC3::GenEvent&
e) {
return e.particles().begin(); }
339 inline std::vector<HepMC3::GenParticlePtr>::const_iterator
end(HepMC3::GenEvent&
e) {
return e.particles().end(); }
340 inline std::vector<HepMC3::ConstGenParticlePtr>::const_iterator
begin(
const HepMC3::GenEvent&
e) {
return e.particles().begin(); }
341 inline std::vector<HepMC3::ConstGenParticlePtr>::const_iterator
end(
const HepMC3::GenEvent&
e) {
return e.particles().end(); }
344 GenEvent*
e=
new GenEvent();
345 std::shared_ptr<HepMC3::IntAttribute> signal_process_id_A = std::make_shared<HepMC3::IntAttribute>(
signal_process_id);
346 e->add_attribute(
"signal_process_id",signal_process_id_A);
347 e->add_attribute(
"barcodes", std::make_shared<GenEventBarcodes>());
348 e->set_event_number(event_number);
353 GenEvent*
e=
new GenEvent();
354 e->set_event_number(inEvt->event_number());
355 e->weights()=inEvt->weights();
356 auto a_mpi = inEvt->attribute<HepMC3::IntAttribute>(
"mpi");
357 if (a_mpi)
e->add_attribute(
"mpi",std::make_shared<HepMC3::IntAttribute>(*a_mpi));
358 auto a_signal_process_id = inEvt->attribute<HepMC3::IntAttribute>(
"signal_process_id");
359 if (a_signal_process_id)
e->add_attribute(
"signal_process_id",std::make_shared<HepMC3::IntAttribute>(*a_signal_process_id));
360 auto a_event_scale = inEvt->attribute<HepMC3::DoubleAttribute>(
"event_scale");
361 if (a_event_scale)
e->add_attribute(
"event_scale",std::make_shared<HepMC3::DoubleAttribute>(*a_event_scale));
362 auto a_alphaQCD = inEvt->attribute<HepMC3::DoubleAttribute>(
"alphaQCD");
363 if (a_alphaQCD)
e->add_attribute(
"alphaQCD",std::make_shared<HepMC3::DoubleAttribute>(*a_alphaQCD));
364 auto a_alphaQED = inEvt->attribute<HepMC3::DoubleAttribute>(
"alphaQED");
365 if (a_alphaQED)
e->add_attribute(
"alphaQED",std::make_shared<HepMC3::DoubleAttribute>(*a_alphaQED));
366 auto a_pi = inEvt->pdf_info();
367 if (a_pi)
e->set_pdf_info(std::make_shared<HepMC3::GenPdfInfo>(*a_pi));
368 auto a_hi = inEvt->heavy_ion();
369 if (a_hi)
e->set_heavy_ion(std::make_shared<HepMC3::GenHeavyIon>(*a_hi));
370 auto a_random_states = inEvt->attribute<HepMC3::VectorLongIntAttribute>(
"random_states");
371 if (a_random_states)
e->add_attribute(
"random_states",std::make_shared<HepMC3::VectorLongIntAttribute>(*a_random_states));
372 e->add_attribute(
"barcodes", std::make_shared<GenEventBarcodes>());
377 auto barcodes =
e->attribute<GenEventBarcodes> (
"barcodes");
379 barcodes = std::make_shared<GenEventBarcodes>();
388 const auto &
barcodes =
e->attribute<GenEventBarcodes> (
"barcodes");
394 const auto eventAttributes =
e->attributes();
395 const auto barcodeAttributeIt = eventAttributes.find(
"barcode");
396 const bool hasBarcodeAttribute = barcodeAttributeIt != eventAttributes.end();
398 const auto &vertices =
e->vertices();
399 if (hasBarcodeAttribute) {
400 for (
size_t i = 1;
i <= vertices.size();
i++) {
401 const auto &ptrIt = barcodeAttributeIt->second.find(-
i);
402 if (ptrIt != barcodeAttributeIt->second.end()) {
403 const auto &
ptr = ptrIt->second;
404 if (
ptr->is_parsed()) {
405 if (
id ==
static_cast<HepMC3::IntAttribute*
>(
ptr.get())->value()) {
406 return ptr->vertex();
411 return ptr->vertex();
418 if (-
id > 0 && -
id <=
static_cast<int>(vertices.size())) {
419 if (!vertices[-
id-1]->attribute<HepMC3::IntAttribute>(
"barcode")) {
420 return vertices[-
id-1];
428 const auto &
barcodes =
e->attribute<GenEventBarcodes> (
"barcodes");
434 const auto eventAttributes =
e->attributes();
435 const auto barcodeAttributeIt = eventAttributes.find(
"barcode");
436 const bool hasBarcodeAttribute = barcodeAttributeIt != eventAttributes.end();
439 if (hasBarcodeAttribute) {
441 const auto &ptrIt = barcodeAttributeIt->second.find(
i);
442 if (ptrIt != barcodeAttributeIt->second.end()) {
443 const auto &
ptr = ptrIt->second;
444 if (
ptr->is_parsed()) {
445 if (
id ==
static_cast<HepMC3::IntAttribute*
>(
ptr.get())->value()) {
446 return ptr->particle();
451 return ptr->particle();
458 if (
id > 0 &&
id <=
static_cast<int>(
particles.size())) {
459 if (!
particles[
id-1]->attribute<HepMC3::IntAttribute>(
"barcode")) {
468 const auto &
barcodes =
e->attribute<GenEventBarcodes> (
"barcodes");
474 const auto eventAttributes =
e->attributes();
475 const auto barcodeAttributeIt = eventAttributes.find(
"barcode");
476 const bool hasBarcodeAttribute = barcodeAttributeIt != eventAttributes.end();
478 const auto &vertices =
e->vertices();
479 if (hasBarcodeAttribute) {
480 for (
size_t i = 1;
i <= vertices.size();
i++) {
481 const auto &ptrIt = barcodeAttributeIt->second.find(-
i);
482 if (ptrIt != barcodeAttributeIt->second.end()) {
483 const auto &
ptr = ptrIt->second;
484 if (
ptr->is_parsed()) {
485 if (
id ==
static_cast<HepMC3::IntAttribute*
>(
ptr.get())->value()) {
486 return ptr->vertex();
491 return ptr->vertex();
498 if (-
id > 0 && -
id <=
static_cast<int>(vertices.size())) {
499 if (!vertices[-
id-1]->attribute<HepMC3::IntAttribute>(
"barcode")) {
500 return vertices[-
id-1];
508 const auto &
barcodes =
e->attribute<GenEventBarcodes> (
"barcodes");
514 const auto eventAttributes =
e->attributes();
515 const auto barcodeAttributeIt = eventAttributes.find(
"barcode");
516 const bool hasBarcodeAttribute = barcodeAttributeIt != eventAttributes.end();
519 if (hasBarcodeAttribute) {
521 const auto &ptrIt = barcodeAttributeIt->second.find(
i);
522 if (ptrIt != barcodeAttributeIt->second.end()) {
523 const auto &
ptr = ptrIt->second;
524 if (
ptr->is_parsed()) {
525 if (
id ==
static_cast<HepMC3::IntAttribute*
>(
ptr.get())->value()) {
526 return ptr->particle();
531 return ptr->particle();
538 if (
id > 0 &&
id <=
static_cast<int>(
particles.size())) {
539 if (!
particles[
id-1]->attribute<HepMC3::IntAttribute>(
"barcode")) {
546 inline int mpi(
const GenEvent&
evt) {
547 std::shared_ptr<HepMC3::IntAttribute> A_mpi=
evt.attribute<HepMC3::IntAttribute>(
"mpi");
548 return A_mpi?(A_mpi->value()):0;
550 inline int mpi(
const GenEvent*
evt) {
551 std::shared_ptr<HepMC3::IntAttribute> A_mpi=
evt->attribute<HepMC3::IntAttribute>(
"mpi");
552 return A_mpi?(A_mpi->value()):0;
556 std::shared_ptr<HepMC3::IntAttribute> A_signal_process_id=
evt.attribute<HepMC3::IntAttribute>(
"signal_process_id");
557 return A_signal_process_id?(A_signal_process_id->value()):0;
560 std::shared_ptr<HepMC3::IntAttribute> A_signal_process_id=
evt->attribute<HepMC3::IntAttribute>(
"signal_process_id");
561 return A_signal_process_id?(A_signal_process_id->value()):0;
564 std::shared_ptr<HepMC3::IntAttribute>
signal_process_id = std::make_shared<HepMC3::IntAttribute>(
i);
567 inline void set_mpi(GenEvent*
e,
const int i=0) {
568 std::shared_ptr<HepMC3::IntAttribute>
mpi = std::make_shared<HepMC3::IntAttribute>(
i);
569 e->add_attribute(
"mpi",std::move(
mpi));
572 e->add_attribute(
"random_states",std::make_shared<HepMC3::VectorLongIntAttribute>(
a));
575 if (!
v || !
e)
return;
578 v->add_attribute(
"signal_process_vertex",std::make_shared<HepMC3::IntAttribute>(1));
583 if (!
e)
return false;
585 for (
const auto&
p :
e->beams()) {
if (
p->status() == 4) ++nBeams; }
586 if (nBeams != 2)
return false;
591 if (!
p->parent_event())
return false;
592 auto barcodes =
p->parent_event()->template attribute<GenEventBarcodes> (
"barcodes");
594 barcodes = std::make_shared<GenEventBarcodes>();
595 p->parent_event()->add_attribute(
"barcodes",
barcodes);
598 bool ret =
p->add_attribute(
"barcode",std::make_shared<HepMC3::IntAttribute>(
i));
615 e->set_event_number((
int)
num);
619 return e->event_number();
621 inline GenEvent::particle_iterator
begin(HepMC::GenEvent&
e) {
return e.particles_begin(); }
622 inline GenEvent::particle_iterator
end(HepMC::GenEvent&
e) {
return e.particles_end(); }
623 inline GenEvent::particle_const_iterator
begin(
const HepMC::GenEvent&
e) {
return e.particles_begin(); }
624 inline GenEvent::particle_const_iterator
end(
const HepMC::GenEvent&
e) {
return e.particles_end(); }
630 inline int mpi(
const GenEvent&
e) {
633 inline int mpi(
const GenEvent*
e) {
637 return e.signal_process_id();
640 return e->signal_process_id();
643 e->set_signal_process_id(
i);
649 e->set_random_states(
a);
652 e->set_signal_process_vertex(
v);
655 HepMC::GenEvent* outEvt =
new HepMC::GenEvent( inEvt->signal_process_id(), inEvt->event_number() );
656 outEvt->set_mpi ( inEvt->mpi() );
657 outEvt->set_event_scale ( inEvt->event_scale() );
658 outEvt->set_alphaQCD ( inEvt->alphaQCD() );
659 outEvt->set_alphaQED ( inEvt->alphaQED() );
660 outEvt->weights() = inEvt->weights();
661 outEvt->set_random_states( inEvt->random_states() );
662 if (
nullptr != inEvt->heavy_ion() ) {
663 outEvt->set_heavy_ion ( *inEvt->heavy_ion() );
665 if (
nullptr != inEvt->pdf_info() ) {
666 outEvt->set_pdf_info ( *inEvt->pdf_info() );
674 template <>
inline bool suggest_barcode<std::unique_ptr<HepMC::GenParticle> >(std::unique_ptr<HepMC::GenParticle>&
p,
int i) {
return p->suggest_barcode(
i);}
677 inline void line(std::ostream&
os,
const GenEvent&
e) {
e.print(
os);}
678 inline void line(std::ostream&
os,
const GenEvent*
e) {
e->print(
os);}