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);}