30#ifndef MARLEY_FOUND_HEPMC3
46#include "HepMC3/Setup.h"
62bool Setup::m_is_printing_errors =
true;
63bool Setup::m_is_printing_warnings =
true;
64int Setup::m_debug_level = 5;
65int Setup::m_errors_level = 1000;
66int Setup::m_warnings_level = 750;
86#include "HepMC3/Data/GenRunInfoData.h"
87#include "HepMC3/GenRunInfo.h"
94 m_weight_indices.clear();
95 m_weight_names = names;
96 for (
int i = 0, N = names.size(); i < N; ++i ) {
97 std::string name = names[i];
99 std::ostringstream oss;
102 m_weight_names[i] = name;
105 throw std::logic_error(
"GenRunInfo::set_weight_names: "
106 "Duplicate weight name '" + name +
109 m_weight_indices[name] = i;
114 std::lock_guard<std::recursive_mutex> lock(m_lock_attributes);
115 auto i = m_attributes.find(name);
116 if ( i == m_attributes.end() )
return {};
118 if ( !i->second )
return {};
121 i->second->to_string(ret);
131 using att_val_t = std::map<std::string, std::shared_ptr<Attribute>>::value_type;
133 for (
const att_val_t& vt: m_attributes) {
135 vt.second->to_string(att);
151 std::vector<std::string> results;
152 results.reserve(m_attributes.size());
153 for (
const auto& vt1: m_attributes) {
154 results.emplace_back(vt1.first);
170 for (
unsigned int i = 0; i < data.
tool_name.size(); ++i) {
176 this->
tools().emplace_back(ti);
184 std::lock(m_lock_attributes, r.m_lock_attributes);
185 std::lock_guard<std::recursive_mutex> lhs_lk(m_lock_attributes, std::adopt_lock);
186 std::lock_guard<std::recursive_mutex> rhs_lk(r.m_lock_attributes, std::adopt_lock);
196 std::lock(m_lock_attributes, r.m_lock_attributes);
197 std::lock_guard<std::recursive_mutex> lhs_lk(m_lock_attributes, std::adopt_lock);
198 std::lock_guard<std::recursive_mutex> rhs_lk(r.m_lock_attributes, std::adopt_lock);
222#include "HepMC3/Attribute.h"
223#include "HepMC3/GenEvent.h"
224#include "HepMC3/GenParticle.h"
225#include "HepMC3/GenVertex.h"
226#include "HepMC3/Setup.h"
235 m_data.momentum = mom;
236 m_data.status = stat;
237 m_data.is_mass_set =
false;
248 return m_data.is_mass_set ? m_data.mass : m_data.momentum.m();
256 m_data.status = stat;
260 m_data.momentum = mom;
265 m_data.is_mass_set =
true;
270 m_data.is_mass_set =
false;
274 return m_production_vertex.lock();
278 return std::const_pointer_cast<const GenVertex>(m_production_vertex.lock());
282 return m_end_vertex.lock();
286 return std::const_pointer_cast<const GenVertex>(m_end_vertex.lock());
290 return (m_production_vertex.expired())? std::vector<GenParticlePtr>() :
production_vertex()->particles_in();
294 return (m_production_vertex.expired()) ? std::vector<ConstGenParticlePtr>() :
production_vertex()->particles_in();
298 return (m_end_vertex.expired())? std::vector<GenParticlePtr>() :
end_vertex()->particles_out();
302 return (m_end_vertex.expired()) ? std::vector<ConstGenParticlePtr>() :
end_vertex()->particles_out();
342#include "HepMC3/Attribute.h"
343#include "HepMC3/GenEvent.h"
344#include "HepMC3/GenParticle.h"
345#include "HepMC3/GenVertex.h"
346#include "HepMC3/Setup.h"
355 m_data.position = pos;
371 m_particles_in.emplace_back(p);
373 if ( p->end_vertex() ) p->end_vertex()->remove_particle_in(p);
375 p->m_end_vertex = shared_from_this();
377 if (m_event) m_event->add_particle(p);
387 m_particles_out.emplace_back(p);
389 if ( p->production_vertex() ) p->production_vertex()->remove_particle_out(p);
391 p->m_production_vertex = shared_from_this();
393 if (m_event) m_event->add_particle(p);
398 if (std::find(m_particles_in.begin(), m_particles_in.end(), p) == m_particles_in.end())
return;
399 p->m_end_vertex.reset();
400 m_particles_in.erase(std::remove(m_particles_in.begin(), m_particles_in.end(), p), m_particles_in.end());
406 if (std::find(m_particles_out.begin(), m_particles_out.end(), p) == m_particles_out.end())
return;
407 p->m_production_vertex.reset();
408 m_particles_out.erase(std::remove(m_particles_out.begin(), m_particles_out.end(), p), m_particles_out.end());
412 return *(
reinterpret_cast<const std::vector<ConstGenParticlePtr>*
>(&m_particles_in));
416 return *(
reinterpret_cast<const std::vector<ConstGenParticlePtr>*
>(&m_particles_out));
427 if (!cycles || cycles->value() == 0)
429 for (
const auto& p: m_particles_in) {
430 ConstGenVertexPtr v = p->production_vertex();
431 if (v)
return v->position();
440 m_data.position = new_pos;
482#include "HepMC3/Data/GenEventData.h"
483#include "HepMC3/GenEvent.h"
484#include "HepMC3/GenParticle.h"
485#include "HepMC3/GenVertex.h"
492 : m_momentum_unit(mu), m_length_unit(lu),
493 m_rootvertex(std::make_shared<
GenVertex>()) {}
499 : m_momentum_unit(mu), m_length_unit(lu),
500 m_rootvertex(std::make_shared<
GenVertex>()),
502 if ( run && !run->weight_names().empty() ) {
503 m_weights = std::vector<double>(run->weight_names().size(), 1.0);
508 return *(
reinterpret_cast<const std::vector<ConstGenParticlePtr>*
>(&m_particles));
512 return *(
reinterpret_cast<const std::vector<ConstGenVertexPtr>*
>(&m_vertices));
517 if ( !p || p->in_event() )
return;
519 m_particles.emplace_back(p);
525 if ( !p->production_vertex() ) {
526 m_rootvertex->add_particle_out(p);
534 std::lock(m_lock_attributes, e.m_lock_attributes);
535 std::lock_guard<std::recursive_mutex> lhs_lk(m_lock_attributes, std::adopt_lock);
536 std::lock_guard<std::recursive_mutex> rhs_lk(e.m_lock_attributes, std::adopt_lock);
540 m_run_info = e.m_run_info;
545 for (
auto attm = m_attributes.begin(); attm != m_attributes.end(); ++attm) {
546 for (
auto att = attm->second.begin(); att != attm->second.end(); ++att) {
if (att->second) att->second->m_event =
nullptr;}
548 for (
auto v = m_vertices.begin(); v != m_vertices.end(); ++v )
if (*v)
if ((*v)->m_event ==
this) (*v)->m_event =
nullptr;
549 for (
auto p = m_particles.begin(); p != m_particles.end(); ++p )
if (*p)
if ((*p)->m_event ==
this) (*p)->m_event =
nullptr;
555 std::lock(m_lock_attributes, e.m_lock_attributes);
556 std::lock_guard<std::recursive_mutex> lhs_lk(m_lock_attributes, std::adopt_lock);
557 std::lock_guard<std::recursive_mutex> rhs_lk(e.m_lock_attributes, std::adopt_lock);
561 m_run_info = e.m_run_info;
568 if ( !v|| v->in_event() )
return;
569 m_vertices.emplace_back(v);
575 for (
const auto& p: v->particles_in()) {
577 p->m_end_vertex = v->shared_from_this();
580 for (
const auto& p: v->particles_out()) {
582 p->m_production_vertex = v;
588 if ( !p || p->parent_event() !=
this )
return;
590 HEPMC3_DEBUG(30,
"GenEvent::remove_particle - called with particle: " << p->id());
591 GenVertexPtr end_vtx = p->end_vertex();
593 end_vtx->remove_particle_in(p);
596 if ( end_vtx->particles_in().empty() )
remove_vertex(end_vtx);
599 GenVertexPtr prod_vtx = p->production_vertex();
601 prod_vtx->remove_particle_out(p);
604 if ( prod_vtx->particles_out().empty() )
remove_vertex(prod_vtx);
607 HEPMC3_DEBUG(30,
"GenEvent::remove_particle - erasing particle: " << p->id())
610 auto it = m_particles.erase(m_particles.begin() + idx-1);
613 std::lock_guard<std::recursive_mutex> lock(m_lock_attributes);
614 for (att_key_t& vt1: m_attributes) {
615 auto vt2 = vt1.second.find(idx);
616 if (vt2 == vt1.second.end())
continue;
617 vt1.second.erase(vt2);
623 std::vector< std::pair< int, std::shared_ptr<Attribute> > > changed_attributes;
625 for (att_key_t& vt1: m_attributes) {
626 changed_attributes.clear();
628 for (
auto vt2 = vt1.second.begin(); vt2 != vt1.second.end(); ++vt2) {
629 if ( (*vt2).first > p->id() ) {
630 changed_attributes.emplace_back(*vt2);
634 std::sort(changed_attributes.begin(),changed_attributes.end(), [](
const std::pair<
int, std::shared_ptr<Attribute> > &a,
const std::pair<
int, std::shared_ptr<Attribute> > &b) { return a.first < b.first; });
635 for (
const auto& val: changed_attributes ) {
636 vt1.second.erase(val.first);
637 vt1.second[val.first-1] = val.second;
641 for (; it != m_particles.end(); ++it) {
646 p->m_event =
nullptr;
651 std::sort(v.begin(), v.end(), [](
const GenParticlePtr& p1,
const GenParticlePtr& p2) { return p1->id() > p2->id();});
653 for (
auto p = v.begin(); p != v.end(); ++p) {
659 if ( !v || v->parent_event() !=
this )
return;
661 HEPMC3_DEBUG(30,
"GenEvent::remove_vertex - called with vertex: " << v->id());
662 std::shared_ptr<GenVertex> null_vtx;
664 for (
const auto& p: v->particles_in()) {
665 p->m_end_vertex = std::weak_ptr<GenVertex>();
668 for (
const auto& p: v->particles_out()) {
669 p->m_production_vertex = std::weak_ptr<GenVertex>();
676 HEPMC3_DEBUG(30,
"GenEvent::remove_vertex - erasing vertex: " << v->id())
679 auto it = m_vertices.erase(m_vertices.begin() + idx-1);
681 std::lock_guard<std::recursive_mutex> lock(m_lock_attributes);
682 for (att_key_t& vt1: m_attributes) {
683 auto vt2 = vt1.second.find(-idx);
684 if (vt2 == vt1.second.end())
continue;
685 vt1.second.erase(vt2);
692 std::vector< std::pair< int, std::shared_ptr<Attribute> > > changed_attributes;
694 for ( att_key_t& vt1: m_attributes ) {
695 changed_attributes.clear();
697 for (
auto vt2 = vt1.second.begin(); vt2 != vt1.second.end(); ++vt2) {
698 if ( (*vt2).first < v->id() ) {
699 changed_attributes.emplace_back(*vt2);
703 std::reverse(changed_attributes.begin(),changed_attributes.end());
704 std::sort(changed_attributes.begin(),changed_attributes.end(),[](
const std::pair<
int, std::shared_ptr<Attribute> > &a,
const std::pair<
int, std::shared_ptr<Attribute> > &b) { return a.first > b.first; });
705 for (
const auto& val: changed_attributes ) {
706 vt1.second.erase(val.first);
707 vt1.second[val.first+1] = val.second;
712 for (; it != m_vertices.end(); ++it) {
717 v->m_event =
nullptr;
723static bool visit_children(std::map<ConstGenVertexPtr, int> &a,
const ConstGenVertexPtr& v)
728 if (a[p->end_vertex()] != 0) {
return true; }
729 a[p->end_vertex()]++;
730 if (visit_children(a, p->end_vertex()))
return true;
737 m_particles.reserve(m_particles.size() + parts.size());
738 m_vertices.reserve(m_vertices.size() + parts.size());
740 bool has_cycles =
false;
741 std::map<GenVertexPtr, int> sortingv;
742 std::vector<GenVertexPtr> noinv;
743 if (existing_hc)
if (existing_hc->value() != 0) has_cycles =
true;
746 for (
const GenParticlePtr& p: parts) {
747 GenVertexPtr v = p->production_vertex();
748 if (v) sortingv[v]=0;
749 if ( !v || v->particles_in().empty()) {
750 GenVertexPtr v2 = p->end_vertex();
751 if (v2) {noinv.emplace_back(v2); sortingv[v2] = 0;}
754 for (
const GenVertexPtr& v: noinv) {
755 std::map<ConstGenVertexPtr, int> sorting_temp(sortingv.begin(), sortingv.end());
756 has_cycles = (has_cycles || visit_children(sorting_temp, v));
767 std::deque<GenVertexPtr> sorting;
770 for (
const auto& p: parts) {
771 const GenVertexPtr &v = p->production_vertex();
772 if ( !v || v->particles_in().empty() ) {
773 const GenVertexPtr &v2 = p->end_vertex();
774 if (v2) sorting.emplace_back(v2);
778 HEPMC3_DEBUG_CODE_BLOCK(
779 unsigned int sorting_loop_count = 0;
780 unsigned int max_deque_size = 0;
784 while ( !sorting.empty() ) {
785 HEPMC3_DEBUG_CODE_BLOCK(
786 if ( sorting.size() > max_deque_size ) max_deque_size = sorting.size();
787 ++sorting_loop_count;
790 GenVertexPtr &v = sorting.front();
795 for (
const auto& p: v->particles_in() ) {
796 GenVertexPtr v2 = p->production_vertex();
797 if ( v2 && !v2->in_event() && find(sorting.begin(), sorting.end(), v2) == sorting.end() ) {
798 sorting.push_front(v2);
805 if ( added )
continue;
808 if ( !v->in_event() ) {
812 for (
const auto& p: v->particles_out()) {
813 GenVertexPtr v2 = p->end_vertex();
814 if ( v2 && !v2->in_event()&& find(sorting.begin(), sorting.end(), v2) == sorting.end() ) {
815 sorting.emplace_back(v2);
824 if ( m_rootvertex->id() != 0 ) {
825 const int vx = -1 - m_rootvertex->id();
826 const int rootid = m_rootvertex->id();
827 if ( vx >= 0 && vx < (
int) m_vertices.size() && m_vertices[vx] == m_rootvertex ) {
828 auto next = m_vertices.erase(m_vertices.begin() + vx);
829 std::lock_guard<std::recursive_mutex> lock(m_lock_attributes);
830 for (
auto & vt1: m_attributes) {
831 std::vector< std::pair< int, std::shared_ptr<Attribute> > > changed_attributes;
832 for (
const auto& vt2 : vt1.second ) {
833 if ( vt2.first <= rootid ) {
834 changed_attributes.emplace_back(vt2);
837 for (
const auto& val : changed_attributes ) {
838 vt1.second.erase(val.first);
839 vt1.second[val.first == rootid? 0: val.first + 1] = val.second;
842 m_rootvertex->m_id = 0;
843 while ( next != m_vertices.end() ) {
847 HEPMC3_WARNING_LEVEL(700,
"GenEvent::add_tree Suspicious looking rootvertex found. Will try to cope.")
851 HEPMC3_DEBUG_CODE_BLOCK(
852 HEPMC3_DEBUG(6,
"GenEvent - particles sorted: "
853 << this->
particles().size() <<
", max deque size: "
854 << max_deque_size <<
", iterations: " << sorting_loop_count)
860 m_particles.reserve(parts);
861 m_vertices.reserve(verts);
866 if ( new_momentum_unit != m_momentum_unit ) {
867 for ( GenParticlePtr& p: m_particles ) {
868 Units::convert(p->m_data.momentum, m_momentum_unit, new_momentum_unit);
869 Units::convert(p->m_data.mass, m_momentum_unit, new_momentum_unit);
872 m_momentum_unit = new_momentum_unit;
875 if ( new_length_unit != m_length_unit ) {
876 for (GenVertexPtr& v: m_vertices) {
881 m_length_unit = new_length_unit;
887 return m_rootvertex->data().position;
891 if (!status)
return std::const_pointer_cast<const GenVertex>(m_rootvertex)->particles_out();
892 std::vector<ConstGenParticlePtr> ret;
893 for (
auto& p: m_rootvertex->particles_out())
if (p->status() == status) ret.emplace_back(p);
898 return std::const_pointer_cast<const GenVertex>(m_rootvertex)->particles_out();
903 return m_rootvertex->particles_out();
907 m_rootvertex->set_position(
event_pos() + delta);
910 for ( GenVertexPtr& v: m_vertices ) {
911 if ( v->has_set_position() ) {
912 v->set_position(v->position() + delta);
919 long double cosa = std::cos(delta.
x());
920 long double sina = std::sin(delta.
x());
921 long double cosb = std::cos(delta.
y());
922 long double sinb = std::sin(delta.
y());
923 long double cosg = std::cos(delta.
z());
924 long double sing = std::sin(delta.
z());
926 for (
auto& p: m_particles)
929 long double tempX = mom.
x();
930 long double tempY = mom.
y();
931 long double tempZ = mom.
z();
933 long double tempY_ = cosa*tempY+sina*tempZ;
934 long double tempZ_ = -sina*tempY+cosa*tempZ;
938 long double tempX_ = cosb*tempX-sinb*tempZ;
939 tempZ_ = sinb*tempX+cosb*tempZ;
943 tempX_ = cosg*tempX+sing*tempY;
944 tempY_ = -sing*tempX+cosg*tempY;
949 p->set_momentum(temp);
951 for (
auto& v: m_vertices)
956 long double tempX = pos.
x();
957 long double tempY = pos.
y();
958 long double tempZ = pos.
z();
960 long double tempY_ = cosa*tempY+sina*tempZ;
961 long double tempZ_ = -sina*tempY+cosa*tempZ;
965 long double tempX_ = cosb*tempX-sinb*tempZ;
966 tempZ_ = sinb*tempX+cosb*tempZ;
970 tempX_ = cosg*tempX+sing*tempY;
971 tempY_ = -sing*tempX+cosg*tempY;
976 v->set_position(temp);
985 if ( axis > 3 || axis < 0 )
987 HEPMC3_WARNING_LEVEL(400,
"GenEvent::reflect: wrong axis")
993 for (
auto& p: m_particles) {
FourVector temp = p->momentum(); temp.
setX(-p->momentum().x()); p->set_momentum(temp);}
994 for (
auto& v: m_vertices) {
FourVector temp = v->position(); temp.
setX(-v->position().x()); v->set_position(temp);}
997 for (
auto& p: m_particles) {
FourVector temp = p->momentum(); temp.
setY(-p->momentum().y()); p->set_momentum(temp);}
998 for (
auto& v: m_vertices) {
FourVector temp = v->position(); temp.
setY(-v->position().y()); v->set_position(temp);}
1001 for (
auto& p: m_particles) {
FourVector temp = p->momentum(); temp.
setZ(-p->momentum().z()); p->set_momentum(temp);}
1002 for (
auto& v: m_vertices) {
FourVector temp = v->position(); temp.
setZ(-v->position().z()); v->set_position(temp);}
1005 for (
auto& p: m_particles) {
FourVector temp = p->momentum(); temp.
setT(-p->momentum().e()); p->set_momentum(temp);}
1006 for (
auto& v: m_vertices) {
FourVector temp = v->position(); temp.
setT(-v->position().t()); v->set_position(temp);}
1017 double deltalength2 = delta.
length2();
1018 if (deltalength2 > 1.0)
1020 HEPMC3_WARNING_LEVEL(400,
"GenEvent::boost: wrong large boost vector. Will leave event as is.")
1023 if (std::abs(deltalength2-1.0) < std::numeric_limits<double>::epsilon())
1025 HEPMC3_WARNING_LEVEL(400,
"GenEvent::boost: too large gamma. Will leave event as is.")
1028 if (std::abs(deltalength2) < std::numeric_limits<double>::epsilon())
1030 HEPMC3_WARNING_LEVEL(400,
"GenEvent::boost: wrong small boost vector. Will leave event as is.")
1033 long double deltaX = delta.
x();
1034 long double deltaY = delta.
y();
1035 long double deltaZ = delta.
z();
1036 long double deltalength = std::sqrt(deltalength2);
1037 long double gamma = 1.0/std::sqrt(1.0-deltalength2);
1039 for (
auto& p: m_particles)
1043 long double tempX = mom.
x();
1044 long double tempY = mom.
y();
1045 long double tempZ = mom.
z();
1046 long double tempE = mom.
e();
1047 long double nr = (deltaX*tempX+deltaY*tempY+deltaZ*tempZ)/deltalength;
1048 long double gfac = (gamma-1)*nr/deltalength-tempE*gamma;
1049 tempX+=(deltaX*gfac);
1050 tempY+=(deltaY*gfac);
1051 tempZ+=(deltaZ*gfac);
1052 tempE = gamma*(tempE-deltalength*nr);
1054 p->set_momentum(temp);
1061 std::lock_guard<std::recursive_mutex> lock(m_lock_attributes);
1063 m_rootvertex = std::make_shared<GenVertex>();
1065 m_attributes.clear();
1066 m_particles.clear();
1071 std::lock_guard<std::recursive_mutex> lock(m_lock_attributes);
1072 auto i1 = m_attributes.find(name);
1073 if ( i1 == m_attributes.end() )
return;
1075 auto i2 = i1->second.find(
id);
1076 if ( i2 == i1->second.end() )
return;
1078 i1->second.erase(i2);
1082 std::vector<std::string> results;
1084 for (
const att_key_t& vt1: m_attributes) {
1085 if ( vt1.second.count(
id) == 1 ) {
1086 results.emplace_back(vt1.first);
1112 for (
const ConstGenParticlePtr& p: this->
particles()) {
1116 for (
const ConstGenVertexPtr& v: this->
vertices()) {
1117 data.
vertices.emplace_back(v->data());
1120 for (
const ConstGenParticlePtr& p: v->particles_in()) {
1121 data.
links1.emplace_back(p->id());
1122 data.
links2.emplace_back(v_id);
1125 for (
const ConstGenParticlePtr& p: v->particles_out()) {
1126 data.
links1.emplace_back(v_id);
1127 data.
links2.emplace_back(p->id());
1131 for (
const att_key_t& vt1: this->
attributes()) {
1132 for (
const att_val_t& vt2: vt1.second) {
1135 bool status = vt2.second->to_string(st);
1138 HEPMC3_WARNING_LEVEL(300,
"GenEvent::write_data: problem serializing attribute: " << vt1.first)
1160 m_particles.reserve(data.
particles.size());
1161 m_vertices.reserve(data.
vertices.size());
1165 m_particles.emplace_back(std::make_shared<GenParticle>(pd));
1166 m_particles.back()->m_event =
this;
1167 m_particles.back()->m_id = m_particles.size();
1172 m_vertices.emplace_back(std::make_shared<GenVertex>(vd));
1173 m_vertices.back()->m_event =
this;
1174 m_vertices.back()->m_id = -(int)m_vertices.size();
1178 for (
unsigned int i = 0; i < data.
links1.size(); ++i) {
1179 const int id1 = data.
links1[i];
1180 const int id2 = data.
links2[i];
1186 if ((id1 < 0 && id2 <0) || (id1 > 0 && id2 > 0)) {
1187 HEPMC3_WARNING_LEVEL(600,
"GenEvent::read_data: wrong link: " << id1 <<
" " << id2);
1191 if ( id1 > 0 ) { m_vertices[ (-id2)-1 ]->add_particle_in ( m_particles[ id1-1 ] );
continue; }
1192 if ( id1 < 0 ) { m_vertices[ (-id1)-1 ]->add_particle_out( m_particles[ id2-1 ] );
continue; }
1194 for (
auto& p: m_particles)
if (!p->production_vertex()) m_rootvertex->add_particle_out(p);
1197 std::lock_guard<std::recursive_mutex> lock(m_lock_attributes);
1198 for (
unsigned int i = 0; i < data.
attribute_id.size(); ++i) {
1201 if (name.length() == 0)
continue;
1203 if (m_attributes.count(name) == 0) m_attributes[name] = std::map<int, std::shared_ptr<Attribute> >();
1205 att->m_event =
this;
1206 if (
id > 0 &&
id <=
int(m_particles.size()) ) {
1207 att->m_particle = m_particles[
id - 1];
1209 if (
id < 0 && -
id <=
int(m_vertices.size()) ) {
1210 att->m_vertex = m_vertices[-
id - 1];
1212 m_attributes[name][id] = att;
1222 m_rootvertex->add_particle_out(p1);
1223 m_rootvertex->add_particle_out(p2);
1229 HEPMC3_WARNING_LEVEL(700,
"Attempting to add an empty particle as beam particle. Ignored.")
1232 if (p1->in_event() && p1->parent_event() !=
this)
1234 HEPMC3_WARNING_LEVEL(700,
"Attempting to add particle from another event. Ignored.")
1237 if (p1->production_vertex()) p1->production_vertex()->remove_particle_out(p1);
1245 std::lock_guard<std::recursive_mutex> lock(m_lock_attributes);
1246 auto i1 = m_attributes.find(name);
1247 if ( i1 == m_attributes.end() ) {
1249 return run_info()->attribute_as_string(name);
1254 auto i2 = i1->second.find(
id);
1255 if (i2 == i1->second.end() )
return {};
1257 if ( !i2->second )
return {};
1260 i2->second->to_string(ret);
1267 if (name.length() == 0)
return;
1269 std::lock_guard<std::recursive_mutex> lock(m_lock_attributes);
1270 if (m_attributes.count(name) == 0) m_attributes[name] = std::map<int, std::shared_ptr<Attribute> >();
1271 m_attributes[name][id] = att;
1272 att->m_event =
this;
1273 if (
id > 0 &&
id <=
int(
particles().size()) ) {
1276 if (
id < 0 && -
id <=
int(
vertices().size()) ) {
1277 att->m_vertex =
vertices()[-
id - 1];
1282void GenEvent::add_attributes(
const std::vector<std::string> &names,
const std::vector<std::shared_ptr<Attribute> > &atts,
const std::vector<int>& ids) {
1283 size_t N = names.size();
1284 if ( N == 0 )
return;
1285 if (N != atts.size())
return;
1286 if (N != ids.size())
return;
1288 std::vector<std::string> unames = names;
1289 vector<std::string>::iterator ip;
1290 ip = std::unique(unames.begin(), unames.end());
1291 unames.resize(std::distance(unames.begin(), ip));
1292 std::lock_guard<std::recursive_mutex> lock(m_lock_attributes);
1293 for (
const auto& name: unames) {
1294 if (m_attributes.count(name) == 0) m_attributes[name] = std::map<int, std::shared_ptr<Attribute> >();
1298 for (
size_t i = 0; i < N; i++) {
1300 if (names.at(i).length() == 0)
continue;
1301 if (!atts[i])
continue;
1302 m_attributes[names.at(i)][ids.at(i)] = atts[i];
1303 atts[i]->m_event =
this;
1305 { atts[i]->m_particle = m_particles[ids.at(i) - 1]; }
1308 atts[i]->m_vertex = m_vertices[-ids.at(i) - 1];
1314void GenEvent::add_attributes(
const std::string& name,
const std::vector<std::shared_ptr<Attribute> > &atts,
const std::vector<int>& ids) {
1315 if (name.length() == 0)
return;
1316 size_t N = ids.size();
1318 if ( N != atts.size())
return;
1320 std::lock_guard<std::recursive_mutex> lock(m_lock_attributes);
1321 if (m_attributes.count(name) == 0) m_attributes[name] = std::map<int, std::shared_ptr<Attribute> >();
1322 auto& tmap = m_attributes[name];
1325 for (
size_t i = 0; i < N; i++) {
1327 if (!atts[i])
continue;
1328 tmap[ids.at(i)] = atts[i];
1329 atts[i]->m_event =
this;
1331 { atts[i]->m_particle = m_particles[ids.at(i) - 1]; }
1334 atts[i]->m_vertex = m_vertices[-ids.at(i) - 1];
1340 if (name.length() == 0)
return;
1341 if (atts.empty())
return;
1342 std::lock_guard<std::recursive_mutex> lock(m_lock_attributes);
1343 if (m_attributes.count(name) == 0) m_attributes[name] = std::map<int, std::shared_ptr<Attribute> >();
1344 auto& tmap = m_attributes[name];
1347 for (
const auto& att: atts) {
1349 if (!att.second)
continue;
1351 att.second->m_event =
this;
1353 { att.second->m_particle = m_particles[att.first - 1]; }
1356 att.second->m_vertex = m_vertices[-att.first - 1];
1378#include "HepMC3/Print.h"
1379#include "HepMC3/Attribute.h"
1385 os <<
"--------------------------------" << std::endl;
1386 os <<
"--------- EVENT CONTENT --------" << std::endl;
1387 os <<
"--------------------------------" << std::endl;
1390 os <<
"Weights (" <<
event.weights().size() <<
"): " << std::endl;
1391 for (
const auto& w: event.
weights()) {
1395 os <<
"Attributes:" << std::endl;
1398 for (
const auto& vt2: vt1.second) {
1399 os << vt2.first <<
": " << vt1.first << std::endl;
1403 os <<
"GenParticlePtr (" <<
event.particles().size() <<
")" << std::endl;
1405 for (
const ConstGenParticlePtr& p: event.
particles()) {
1410 os <<
"GenVertexPtr (" <<
event.vertices().size() <<
")" << std::endl;
1411 for (
const ConstGenVertexPtr& v: event.
vertices() ) {
1416 os <<
"-----------------------------" << std::endl;
1421 std::ios_base::fmtflags orig = os.flags();
1422 std::streamsize prec = os.precision();
1425 os.precision(precision);
1427 os <<
"________________________________________________________________________" << std::endl;
1428 os <<
"GenEvent: #" <<
event.event_number() << std::endl;
1431 os <<
" Entries in this event: " <<
event.vertices().size() <<
" vertices, "
1432 <<
event.particles().size() <<
" particles, "
1433 <<
event.weights().size() <<
" weights." << std::endl;
1436 os <<
" Position offset: " << pos.
x() <<
", " << pos.
y() <<
", " << pos.
z() <<
", " << pos.
t() << std::endl;
1439 os <<
" GenParticle Legend" << std::endl;
1441 <<
"( px, py, pz, E )"
1442 <<
" Stat ProdVtx" << std::endl;
1443 os <<
"________________________________________________________________________" << std::endl;
1446 for (
const ConstGenVertexPtr& v: event.
vertices()) {
1453 os <<
"________________________________________________________________________" << std::endl;
1458 std::ios_base::fmtflags orig = os.flags();
1459 std::streamsize prec = os.precision();
1462 os.precision(precision);
1464 os <<
"________________________________________________________________________" << std::endl;
1465 os <<
"GenRunInfo:" << std::endl;
1469 for (
const auto& n: names) os << n;
1470 os <<
" )" << std::endl;
1472 os <<
" Tools: " << std::endl;
1474 for (
const auto& t: ri.
tools()) {
1477 os <<
"Attributes:" << std::endl;
1480 if ( !att.second->to_string(st) ) {
1481 HEPMC3_WARNING_LEVEL(300,
"Print::listing: problem serializing attribute: " << att.first)
1483 else { os << att.first <<
" " << st;}
1490 os <<
"________________________________________________________________________" << std::endl;
1494 if (!v) { os <<
"Vtx: Empty vertex" << std::endl;
return;}
1497 os << v->id() <<
" stat: ";
1501 const FourVector &pos = v->position();
1502 if ( !pos.is_zero() ) {
1503 os <<
" (X,cT): " << pos.x() <<
" " << pos.y() <<
" " << pos.z() <<
" " << pos.t();
1505 else os <<
" (X,cT): 0";
1509 bool printed_header =
false;
1512 for (
const ConstGenParticlePtr& p: v->particles_in()) {
1513 if ( !printed_header ) {
1515 printed_header =
true;
1522 printed_header =
false;
1525 for (
const ConstGenParticlePtr& p: v->particles_out()) {
1526 if ( !printed_header ) {
1528 printed_header =
true;
1537 if (!p) { os <<
" Empty particle" << std::endl;
return;}
1542 os << p->pid() <<
" ";
1544 os.setf(std::ios::scientific, std::ios::floatfield);
1545 os.setf(std::ios_base::showpos);
1547 const FourVector &momentum = p->momentum();
1550 os << momentum.px() <<
",";
1552 os << momentum.py() <<
",";
1554 os << momentum.pz() <<
",";
1556 os << momentum.e() <<
" ";
1557 os.setf(std::ios::fmtflags(0), std::ios::floatfield);
1558 os.unsetf(std::ios_base::showpos);
1562 ConstGenVertexPtr prod = p->production_vertex();
1572 os <<
"GenEvent: #" <<
event.event_number();
1575 os <<
" " << s <<
"=" <<
event.attribute_as_string(s);
1581 os <<
"GenRunInfo: Number of tools:" << RunInfo.
tools().size();
1595void line_v(std::ostream& os, T v,
bool attributes) {
1596 if (!v) { os <<
"GenVertex: Empty" << std::endl;
return;}
1597 os <<
"GenVertex: " << v->id() <<
" stat: ";
1600 os <<
" in: " << v->particles_in().size();
1602 os <<
" out: " << v->particles_out().size();
1604 const FourVector &pos = v->position();
1605 os <<
" has_set_position: ";
1606 if ( v->has_set_position() ) { os <<
"true"; }
1607 else { os <<
"false"; }
1609 os <<
" (X,cT): " << pos.x() <<
", " <<pos.y() <<
", " << pos.z() <<
", " << pos.t();
1612 auto names = v->attribute_names();
1613 for (
const auto& ss: names) {
1614 os <<
" " << ss <<
"=" << (*v).attribute_as_string(ss);
1618void Print::line(std::ostream& os, ConstGenVertexPtr v,
bool attributes) { line_v(os,v,attributes); }
1619void Print::line(std::ostream& os, GenVertexPtr v,
bool attributes) { line_v(os,v,attributes); }
1624 os <<
"FourVector: ";
1626 std::ios_base::fmtflags orig = os.flags();
1627 os.setf(std::ios::scientific, std::ios::floatfield);
1628 os.setf(std::ios_base::showpos);
1629 std::streamsize prec = os.precision();
1632 os <<
" (P,E)=" << p.
x()
1643void line_p(std::ostream& os, T p,
bool attributes) {
1644 if (!p) { os <<
"GenParticle: Empty" << std::endl;
return;}
1645 os <<
"GenParticle: ";
1647 os << p->id() <<
" PDGID: ";
1652 std::ios_base::fmtflags orig = os.flags();
1654 os.setf(std::ios::scientific, std::ios::floatfield);
1655 os.setf(std::ios_base::showpos);
1656 std::streamsize prec = os.precision();
1661 const FourVector &momentum = p->momentum();
1663 os <<
" (P,E)=" << momentum.px()
1664 <<
"," << momentum.py()
1665 <<
"," << momentum.pz()
1666 <<
"," << momentum.e();
1672 const ConstGenVertexPtr prod = p->production_vertex();
1673 const ConstGenVertexPtr end = p->end_vertex();
1674 int prod_vtx_id = (prod) ? prod->
id() : 0;
1675 int end_vtx_id = (end) ? end->id() : 0;
1676 auto names = p->attribute_names();
1678 os <<
" Stat: " << p->status()
1679 <<
" PV: " << prod_vtx_id
1680 <<
" EV: " << end_vtx_id
1681 <<
" Attr: " << names.size();
1685 for (
const auto& ss: names) {
1686 os <<
" " << ss <<
"=" << (*p).attribute_as_string(ss);
1691void Print::line(std::ostream& os, ConstGenParticlePtr p,
bool attributes) { line_p(os,p,attributes); }
1692void Print::line(std::ostream& os, GenParticlePtr p,
bool attributes) { line_p(os,p,attributes); }
1694void Print::line(std::ostream& os, std::shared_ptr<GenCrossSection> &cs) {
1695 if (!cs) {os <<
" GenCrossSection: Empty";
return;}
1696 os <<
" GenCrossSection: " << cs->xsec(0)
1697 <<
" " << cs->xsec_err(0)
1698 <<
" " << cs->get_accepted_events()
1699 <<
" " << cs->get_attempted_events();
1703 if (!hi) {os <<
" GenHeavyIon: Empty";
return;}
1704 os <<
" GenHeavyIon: " << hi->Ncoll_hard
1705 <<
" " << hi->Npart_proj
1706 <<
" " << hi->Npart_targ
1708 <<
" " << hi->spectator_neutrons
1709 <<
" " << hi->spectator_protons
1710 <<
" " << hi->N_Nwounded_collisions
1711 <<
" " << hi->Nwounded_N_collisions
1712 <<
" " << hi->Nwounded_Nwounded_collisions
1713 <<
" " << hi->impact_parameter
1714 <<
" " << hi->event_plane_angle
1715 <<
" " << hi->eccentricity
1716 <<
" " << hi->sigma_inel_NN;
1720 if (!pi) {os <<
" GenPdfInfo: Empty";
return;}
1721 os <<
" GenPdfInfo: " << pi->parton_id[0]
1722 <<
" " << pi->parton_id[1]
1728 <<
" " << pi->pdf_id[0]
1729 <<
" " << pi->pdf_id[1];
1752#include "HepMC3/GenEvent.h"
1753#include "HepMC3/GenParticle.h"
1754#include "HepMC3/GenVertex.h"
1755#include "HepMC3/Units.h"
1756#include "HepMC3/Version.h"
1757#include "HepMC3/WriterAscii.h"
1767 if ( !m_file.is_open() ) {
1768 HEPMC3_ERROR_LEVEL(200,
"WriterAscii: could not open output file: " << filename)
1770 const std::string header =
"HepMC::Version " + version() +
"\nHepMC::Asciiv3-START_EVENT_LISTING\n";
1771 m_file.write(header.data(), header.length());
1774 m_float_printf_specifier =
" %." + std::to_string(m_precision) +
"e";
1775 m_particle_printf_specifier =
"P %i %i %i"
1776 + m_float_printf_specifier
1777 + m_float_printf_specifier
1778 + m_float_printf_specifier
1779 + m_float_printf_specifier
1780 + m_float_printf_specifier +
" %i\n";
1781 m_vertex_short_printf_specifier =
"V %i %i [%s]\n";
1782 m_vertex_long_printf_specifier =
"V %i %i [%s] @"+ m_float_printf_specifier + m_float_printf_specifier + m_float_printf_specifier + m_float_printf_specifier +
"\n";
1790 const std::string header =
"HepMC::Version " + version() +
"\nHepMC::Asciiv3-START_EVENT_LISTING\n";
1791 m_stream->write(header.data(), header.length());
1793 m_float_printf_specifier =
" %." + std::to_string(m_precision) +
"e";
1794 m_particle_printf_specifier =
"P %i %i %i"
1795 + m_float_printf_specifier
1796 + m_float_printf_specifier
1797 + m_float_printf_specifier
1798 + m_float_printf_specifier
1799 + m_float_printf_specifier +
" %i\n";
1800 m_vertex_short_printf_specifier =
"V %i %i [%s]\n";
1801 m_vertex_long_printf_specifier =
"V %i %i [%s] @"+ m_float_printf_specifier + m_float_printf_specifier + m_float_printf_specifier + m_float_printf_specifier +
"\n";
1805 : m_shared_stream(s_stream),
1806 m_stream(s_stream.get())
1809 const std::string header =
"HepMC::Version " + version() +
"\nHepMC::Asciiv3-START_EVENT_LISTING\n";
1810 m_stream->write(header.data(), header.length());
1812 m_float_printf_specifier =
" %." + std::to_string(m_precision) +
"e";
1813 m_particle_printf_specifier =
"P %i %i %i"
1814 + m_float_printf_specifier
1815 + m_float_printf_specifier
1816 + m_float_printf_specifier
1817 + m_float_printf_specifier
1818 + m_float_printf_specifier +
" %i\n";
1819 m_vertex_short_printf_specifier =
"V %i %i [%s]\n";
1820 m_vertex_long_printf_specifier =
"V %i %i [%s] @"+ m_float_printf_specifier + m_float_printf_specifier + m_float_printf_specifier + m_float_printf_specifier +
"\n";
1831 if ( !m_buffer )
return;
1832 auto float_printf_specifier_option =
m_options.find(
"float_printf_specifier");
1833 std::string letter=(float_printf_specifier_option !=
m_options.end())?float_printf_specifier_option->second.substr(0,2):
"e";
1834 if (letter !=
"e" && letter !=
"E" && letter !=
"G" && letter !=
"g" && letter !=
"f" && letter !=
"F" ) letter =
"e";
1835 m_float_printf_specifier =
" %." + std::to_string(m_precision) + letter;
1838 m_particle_printf_specifier =
"P %i %i %i"
1839 + m_float_printf_specifier
1840 + m_float_printf_specifier
1841 + m_float_printf_specifier
1842 + m_float_printf_specifier
1843 + m_float_printf_specifier +
" %i\n";
1844 m_vertex_short_printf_specifier =
"V %i %i [%s]\n";
1845 m_vertex_long_printf_specifier =
"V %i %i [%s] @"+ m_float_printf_specifier + m_float_printf_specifier + m_float_printf_specifier + m_float_printf_specifier +
"\n";
1855 HEPMC3_WARNING_LEVEL(600,
"WriterAscii::write_event: GenEvents contain different GenRunInfo objects from - only the first such object will be serialized.")
1861 std::string especifier =
"E " + std::to_string(evt.
event_number()) +
" "
1862 + std::to_string(evt.
vertices().size()) +
" "
1863 + std::to_string(evt.
particles().size());
1867 especifier += (
" @" + m_float_printf_specifier + m_float_printf_specifier + m_float_printf_specifier + m_float_printf_specifier +
"\n" );
1868 m_cursor += sprintf(m_cursor, especifier.c_str(), pos.
x(), pos.
y(), pos.
z(), pos.
t());
1870 m_cursor += sprintf(m_cursor,
"%s\n", especifier.c_str());
1879 if ( !evt.
weights().empty() ) {
1880 m_cursor += sprintf(m_cursor,
"W");
1881 for (
const auto& w: evt.
weights())
1883 m_cursor += sprintf(m_cursor,
" %.*e", std::min(3*m_precision, 22), w);
1886 m_cursor += sprintf(m_cursor,
"\n");
1892 for (
const auto& vt2: vt1.second ) {
1894 bool status = vt2.second->to_string(st);
1897 HEPMC3_WARNING_LEVEL(300,
"WriterAscii::write_event: problem serializing attribute: " << vt1.first)
1900 m_cursor += sprintf(m_cursor,
"A %i ", vt2.first);
1901 write_string(escape(vt1.first));
1903 m_cursor += sprintf(m_cursor,
" ");
1904 write_string(escape(st));
1905 m_cursor += sprintf(m_cursor,
"\n");
1913 std::map<int, bool> alreadywritten;
1914 for (
const ConstGenParticlePtr& p: evt.
particles()) {
1916 ConstGenVertexPtr v = p->production_vertex();
1917 int parent_object = 0;
1922 if ( v->particles_in().size() > 1 || !v->data().is_zero() ) { parent_object = v->id(); }
1926 if ( v->particles_in().size() == 1 ) { parent_object = v->particles_in().front()->id();}
1927 else {
if ( v->particles_in().empty() ) {HEPMC3_DEBUG(30,
"WriterAscii::write_event - found a vertex without incoming particles: " << v->id());}}
1930 if (alreadywritten.count(v->id()) == 0 && parent_object < 0)
1931 { write_vertex(v); alreadywritten[v->id()] =
true; }
1934 write_particle(p, parent_object);
1936 alreadywritten.clear();
1943void WriterAscii::allocate_buffer() {
1944 if ( m_buffer )
return;
1945 while ( m_buffer ==
nullptr && m_buffer_size >= 512 ) {
1947 m_buffer =
new char[ m_buffer_size ]();
1948 }
catch (
const std::bad_alloc& e) {
1951 HEPMC3_WARNING_LEVEL(200,
"WriterAscii::allocate_buffer:" << e.what() <<
" buffer size too large. Dividing by 2. New size: " << m_buffer_size)
1956 HEPMC3_ERROR_LEVEL(200,
"WriterAscii::allocate_buffer: could not allocate buffer!")
1959 m_cursor = m_buffer;
1963std::
string WriterAscii::escape(const std::
string& s) {
1965 ret.reserve(s.length()*2);
1966 for ( std::string::const_iterator it = s.begin(); it != s.end(); ++it ) {
1981void WriterAscii::write_vertex(
const ConstGenVertexPtr& v) {
1984 std::vector<int> pids;
1985 pids.reserve(v->particles_in().size());
1986 for (
const ConstGenParticlePtr& p: v->particles_in()) pids.emplace_back(p->id());
1988 std::sort(pids.begin(), pids.end());
1989 for (
const auto& p: pids) vlist.append( std::to_string(p).append(
",") );
1990 if ( !pids.empty() ) vlist.pop_back();
1991 const FourVector &pos = v->position();
1992 if ( !pos.is_zero() ) {
1993 m_cursor += sprintf(m_cursor, m_vertex_long_printf_specifier.c_str(), v->id(), v->status(), vlist.c_str(), pos.x(), pos.y(), pos.z(), pos.t() );
1995 m_cursor += sprintf(m_cursor, m_vertex_short_printf_specifier.c_str(), v->id(), v->status(), vlist.c_str());
2001inline void WriterAscii::flush() {
2005 if ( m_buffer + m_buffer_size < m_cursor + 512 ) {
2006 std::ptrdiff_t length = m_cursor - m_buffer;
2007 m_stream->write(m_buffer, length);
2008 m_cursor = m_buffer;
2013inline void WriterAscii::forced_flush() {
2014 std::ptrdiff_t length = m_cursor - m_buffer;
2015 m_stream->write(m_buffer, length);
2016 m_cursor = m_buffer;
2026 const std::vector<std::string> names =
run_info()->weight_names();
2028 if ( !names.empty() ) {
2029 std::string out = names[0];
2030 for (
int i = 1, N = names.size(); i < N; ++i ) {
2031 out +=
"\n" + names[i];
2033 m_cursor += sprintf(m_cursor,
"W ");
2035 write_string(escape(out));
2036 m_cursor += sprintf(m_cursor,
"\n");
2039 for (
const auto& tool:
run_info()->tools()) {
2040 std::string out =
"T " + tool.name +
"\n" + tool.version +
"\n" + tool.description;
2041 write_string(escape(out));
2042 m_cursor += sprintf(m_cursor,
"\n");
2046 for (
const auto& att:
run_info()->attributes() ) {
2048 if ( !att.second->to_string(st) ) {
2049 HEPMC3_WARNING_LEVEL(300,
"WriterAscii::write_run_info: problem serializing attribute: " << att.first)
2052 m_cursor += sprintf(m_cursor,
"A ");
2053 write_string(att.first);
2055 m_cursor += sprintf(m_cursor,
" ");
2056 write_string(escape(st));
2057 m_cursor += sprintf(m_cursor,
"\n");
2063void WriterAscii::write_particle(
const ConstGenParticlePtr& p,
int second_field) {
2065 m_cursor += sprintf(m_cursor, m_particle_printf_specifier.c_str(), p->id(), second_field, p->pid(), p->momentum().px(), p->momentum().py(), p->momentum().pz(), p->momentum().e(), p->generated_mass(), p->status());
2070inline void WriterAscii::write_string(
const std::string &str) {
2072 if ( m_buffer + m_buffer_size > m_cursor + str.length() ) {
2073 strncpy(m_cursor, str.data(), str.length());
2074 m_cursor += str.length();
2080 m_stream->write(str.data(), str.length());
2086 if (!m_stream)
return;
2087 auto* ofs =
dynamic_cast<std::ofstream*
>(m_stream);
2088 if (ofs && !ofs->is_open())
return;
2090 const std::string footer(
"HepMC::Asciiv3-END_EVENT_LISTING\n\n");
2091 if (m_stream) m_stream->write(footer.data(),footer.length());
2093 if (ofs) ofs->close();
2098 if (prec < 2 || prec > 24)
return;
2106void WriterAscii::set_buffer_size(
const size_t& size ) {
2107 if (m_buffer)
return;
2108 if (size < 1024)
return;
2109 m_buffer_size = size;
2132#include "HepMC3/ReaderAscii.h"
2134#include "HepMC3/GenEvent.h"
2135#include "HepMC3/GenParticle.h"
2136#include "HepMC3/GenVertex.h"
2137#include "HepMC3/Units.h"
2143 : m_file(filename), m_isstream(false)
2145 if ( !m_file.is_open() ) {
2146 HEPMC3_ERROR_LEVEL(100,
"ReaderAscii: could not open input file: " << filename)
2152 : m_stream(&stream), m_isstream(true)
2154 if ( !m_stream->good() ) {
2155 HEPMC3_ERROR_LEVEL(100,
"ReaderAscii: could not open input stream ")
2162 : m_shared_stream(s_stream), m_stream(s_stream.get()), m_isstream(true)
2164 if ( !m_stream->good() ) {
2165 HEPMC3_ERROR_LEVEL(100,
"ReaderAscii: could not open input stream ")
2174 std::array<char, 262144> buf{};
2175 bool event_context =
false;
2176 bool run_info_context =
false;
2180 if ( (!m_file.is_open()) && (!m_isstream) )
return false;
2181 m_isstream ? peek = m_stream->peek() : peek = m_file.peek();
2182 if ( peek ==
'E' ) { event_context =
true; nn--; }
2184 if ( !event_context && ( peek ==
'W' || peek ==
'A' || peek ==
'T' ) ) {
2185 m_isstream ? m_stream->getline(buf.data(), buf.size()) : m_file.getline(buf.data(), buf.size());
2186 if (!run_info_context) {
2188 run_info_context =
true;
2190 if ( peek ==
'W' ) {
2191 parse_weight_names(buf.data());
2193 if ( peek ==
'T' ) {
2194 parse_tool(buf.data());
2196 if ( peek ==
'A' ) {
2197 parse_run_attribute(buf.data());
2200 if ( event_context && ( peek ==
'V' || peek ==
'P' ) ) event_context=
false;
2201 if (nn < 0)
return true;
2202 m_isstream ? m_stream->getline(buf.data(), buf.size()) : m_file.getline(buf.data(), buf.size());
2209 if ( (!m_file.is_open()) && (!m_isstream) )
return false;
2212 std::array<char, 262144> buf{};
2213 bool event_context =
false;
2214 bool parsed_weights =
false;
2215 bool parsed_particles_or_vertices =
false;
2216 bool run_info_context =
false;
2217 bool is_parsing_successful =
true;
2218 std::pair<int, int> vertices_and_particles(0, 0);
2222 m_io_explicit.clear();
2223 m_io_implicit.clear();
2224 m_io_implicit_ids.clear();
2225 m_io_explicit_ids.clear();
2226 m_data.particles.clear();
2227 m_data.vertices.clear();
2228 m_data.links1.clear();
2229 m_data.links2.clear();
2230 m_data.attribute_id.clear();
2231 m_data.attribute_name.clear();
2232 m_data.attribute_string.clear();
2237 m_isstream ? m_stream->getline(buf.data(), buf.size()) : m_file.getline(buf.data(), buf.size());
2239 if ( strlen(buf.data()) == 0 )
continue;
2242 if ( strncmp(buf.data(),
"HepMC", 5) == 0 ) {
2243 if ( strncmp(buf.data(),
"HepMC::Version", 14) != 0 && strncmp(buf.data(),
"HepMC::Asciiv3", 14) != 0 )
2245 HEPMC3_WARNING_LEVEL(500,
"ReaderAscii: found unsupported expression in header. Will close the input.")
2246 std::cout << buf.data() << std::endl;
2247 m_isstream ? m_stream->clear(std::ios::eofbit) : m_file.clear(std::ios::eofbit);
2249 if (event_context) {
2250 is_parsing_successful =
true;
2258 vertices_and_particles = parse_event_information( buf.data());
2259 if (vertices_and_particles.second < 0) {
2260 is_parsing_successful =
false;
2262 is_parsing_successful =
true;
2263 event_context =
true;
2264 parsed_weights =
false;
2265 parsed_particles_or_vertices =
false;
2269 run_info_context =
false;
2272 is_parsing_successful = parse_vertex_information( buf.data());
2273 parsed_particles_or_vertices =
true;
2276 is_parsing_successful = parse_particle_information( buf.data());
2277 parsed_particles_or_vertices =
true;
2280 if ( event_context ) {
2281 is_parsing_successful = parse_weight_values( buf.data());
2282 parsed_weights=
true;
2284 if ( !run_info_context ) {
2288 run_info_context =
true;
2289 is_parsing_successful = parse_weight_names(buf.data());
2293 is_parsing_successful = parse_units( buf.data());
2296 if ( event_context ) {
2299 if ( !run_info_context ) {
2303 run_info_context =
true;
2304 is_parsing_successful = parse_tool(buf.data());
2308 if ( event_context ) {
2309 is_parsing_successful = parse_attribute( buf.data());
2311 if ( !run_info_context ) {
2315 run_info_context =
true;
2316 is_parsing_successful = parse_run_attribute(buf.data());
2320 HEPMC3_WARNING_LEVEL(500,
"ReaderAscii: skipping unrecognised prefix: " << buf[0])
2321 is_parsing_successful =
true;
2325 if ( !is_parsing_successful )
break;
2328 m_isstream ? peek = m_stream->peek() : peek = m_file.peek();
2330 if ( event_context && peek ==
'E' )
break;
2333 if ( event_context && peek ==
'W' && parsed_weights )
break;
2336 if ( event_context && peek ==
'A' && parsed_particles_or_vertices )
break;
2339 if ( event_context && peek ==
'T' )
break;
2345 int currid = -
static_cast<int>(m_data.vertices.size());
2346 auto fir = m_io_implicit_ids.rbegin();
2347 for (
const auto& iofirst: m_io_explicit_ids) {
2348 for (; currid < iofirst; ++currid, ++fir) {
2349 if (fir == m_io_implicit_ids.rend()) {
2350 HEPMC3_ERROR_LEVEL(600,
"ReaderAscii: not enough implicit vertices")
2353 m_io_explicit[currid] = std::move(m_io_implicit[*fir]);
2358 for (
const auto& io: m_io_explicit) {
2359 for (
const auto& i: io.second.first) { m_data.links1.push_back(i); m_data.links2.push_back(io.first); }
2360 for (
const auto& o: io.second.second) { m_data.links1.push_back(io.first); m_data.links2.push_back(o); }
2365 if ((
int)evt.
particles().size() > vertices_and_particles.second) {
2366 HEPMC3_ERROR_LEVEL(600,
"ReaderAscii: too many particles were parsed")
2367 printf(
"%zu vs %i expected\n", evt.
particles().size(), vertices_and_particles.second);
2368 is_parsing_successful =
false;
2370 if ((
int)evt.
particles().size() < vertices_and_particles.second) {
2371 HEPMC3_ERROR_LEVEL(600,
"ReaderAscii: too few particles were parsed")
2372 printf(
"%zu vs %i expected\n", evt.
particles().size(), vertices_and_particles.second);
2373 is_parsing_successful =
false;
2376 if ((
int)evt.
vertices().size() > vertices_and_particles.first) {
2377 HEPMC3_ERROR_LEVEL(600,
"ReaderAscii: too many vertices were parsed")
2378 printf(
"%zu vs %i expected\n", evt.
vertices().size(), vertices_and_particles.first);
2379 is_parsing_successful =
false;
2382 if ((
int)evt.
vertices().size() < vertices_and_particles.first) {
2383 HEPMC3_ERROR_LEVEL(600,
"ReaderAscii: too few vertices were parsed")
2384 printf(
"%zu vs %i expected\n", evt.
vertices().size(), vertices_and_particles.first);
2385 is_parsing_successful =
false;
2388 if ( !is_parsing_successful ) {
2389 HEPMC3_ERROR_LEVEL(600,
"ReaderAscii: event parsing failed. Returning empty event")
2390 HEPMC3_DEBUG(1,
"Parsing failed at line:" << std::endl << buf.data())
2393 m_isstream ? m_stream->clear(std::ios::badbit) : m_file.clear(std::ios::badbit);
2403std::pair<int, int> ReaderAscii::parse_event_information(
const char *buf) {
2404 static const std::pair<int, int> err(-1, -1);
2405 std::pair<int, int> ret(-1, -1);
2406 const char *cursor = buf;
2410 if ( !(cursor = strchr(cursor+1,
' ')) )
return err;
2414 if ( !(cursor = strchr(cursor+1,
' ')) )
return err;
2415 ret.first = atoi(cursor);
2418 if ( !(cursor = strchr(cursor+1,
' ')) )
return err;
2419 ret.second = atoi(cursor);
2420 m_data.
vertices = std::vector<GenVertexData>(ret.first);
2421 m_data.
particles = std::vector<GenParticleData>(ret.second);
2423 m_data.
links1.reserve(ret.second*2);
2424 m_data.
links2.reserve(ret.second*2);
2428 m_io_implicit_ids.reserve(ret.second);
2430 if ( (cursor = strchr(cursor+1,
'@')) ) {
2432 if ( !(cursor = strchr(cursor+1,
' ')) )
return err;
2433 position.
setX(atof(cursor));
2436 if ( !(cursor = strchr(cursor+1,
' ')) )
return err;
2437 position.
setY(atof(cursor));
2440 if ( !(cursor = strchr(cursor+1,
' ')) )
return err;
2441 position.
setZ(atof(cursor));
2444 if ( !(cursor = strchr(cursor+1,
' ')) )
return err;
2445 position.
setT(atof(cursor));
2448 HEPMC3_DEBUG(10,
"ReaderAscii: E: " << m_data.
event_number <<
" (" <<ret.first <<
"V, " << ret.second <<
"P)")
2454bool ReaderAscii::parse_weight_values(const
char *buf) {
2455 std::istringstream iss(buf + 1);
2456 std::vector<double> wts;
2458 while (iss >> w) wts.emplace_back(w);
2460 &&
run_info()->weight_names().size() != wts.size() ) {
2461 throw std::logic_error(
"ReaderAscii::parse_weight_values: "
2462 "The number of weights ("+std::to_string((
long long int)(wts.size()))+
") does not match "
2463 "the number weight names("+std::to_string((
long long int)(
run_info()->weight_names().size()))+
") in the GenRunInfo object");
2465 m_data.weights = wts;
2471bool ReaderAscii::parse_units(
const char *buf) {
2472 const char *cursor = buf;
2475 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
2480 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
2484 HEPMC3_DEBUG(10,
"ReaderAscii: U: " <<
Units::name(m_data.momentum_unit) <<
" " <<
Units::name(m_data.length_unit))
2490bool ReaderAscii::parse_vertex_information(const
char *buf) {
2491 GenVertexPtr data = std::make_shared<GenVertex>();
2492 const char *cursor = buf;
2493 const char *cursor2 =
nullptr;
2497 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
2501 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
2502 m_data.vertices[-
id-1].status = atoi(cursor);
2503 FourVector& position = m_data.vertices[-
id-1].position;
2506 if ( !(cursor = strchr(cursor+1,
'[')) )
return false;
2511 int particle_in = atoi(cursor);
2514 if (particle_in > 0) {
2516 m_io_explicit[id].first.insert(particle_in);
2520 if ( !(cursor = strchr(cursor+1,
',')) ) {
2521 if ( !(cursor = strchr(cursor2+1,
']')) )
return false;
2527 if ( (cursor = strchr(cursor+1,
'@')) ) {
2529 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
2530 position.setX(atof(cursor));
2533 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
2534 position.setY(atof(cursor));
2537 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
2538 position.setZ(atof(cursor));
2541 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
2542 position.setT(atof(cursor));
2549bool ReaderAscii::parse_particle_information(
const char *buf) {
2550 const char *cursor = buf;
2554 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
2556 int id = atoi(cursor);
2557 if ( id < 1 || id >
static_cast<int>(m_data.particles.size()) ) {
2558 HEPMC3_ERROR_LEVEL(600,
"ReaderAscii: particle ID is out of expected range.")
2562 FourVector& momentum = m_data.particles[
id-1].momentum;
2564 if ( !(cursor = strchr(cursor+1,
' ')) ) return false;
2565 mother_id = atoi(cursor);
2566 if ( mother_id < -static_cast<
int>(m_data.vertices.size()) || mother_id > static_cast<
int>(m_data.particles.size()) ) {
2567 HEPMC3_ERROR_LEVEL(600,
"ReaderAscii: ID of particle mother is out of expected range.")
2571 if ( mother_id > 0) {
2574 if (m_io_implicit.count(mother_id) == 0) m_io_implicit_ids.push_back(mother_id);
2575 m_io_implicit[mother_id].first.insert(mother_id);
2576 m_io_implicit[mother_id].second.insert(
id);
2578 m_io_explicit[mother_id].second.insert(
id);
2579 m_io_explicit_ids.insert(mother_id);
2582 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
2583 m_data.particles[
id-1].pid = atoi(cursor);
2586 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
2587 momentum.setPx(atof(cursor));
2590 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
2591 momentum.setPy(atof(cursor));
2594 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
2595 momentum.setPz(atof(cursor));
2598 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
2599 momentum.setE(atof(cursor));
2602 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
2603 m_data.particles[
id-1].mass = atof(cursor);
2604 m_data.particles[
id-1].is_mass_set =
true;
2607 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
2608 m_data.particles[
id-1].status = atoi(cursor);
2614bool ReaderAscii::parse_attribute(
const char *buf) {
2615 const char *cursor = buf;
2616 const char *cursor2 = buf;
2617 std::array<char, 512> name{};
2620 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
2623 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
2626 if ( !(cursor2 = strchr(cursor,
' ')) )
return false;
2627 snprintf(name.data(), name.size(),
"%.*s", (
int)(cursor2-cursor), cursor);
2631 m_data.attribute_id.push_back(
id);
2632 m_data.attribute_name.emplace_back(name.data());
2633 m_data.attribute_string.push_back(unescape(cursor));
2638bool ReaderAscii::parse_run_attribute(
const char *buf) {
2639 const char *cursor = buf;
2640 const char *cursor2 = buf;
2641 std::array<char, 512> name{};
2643 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
2646 if ( !(cursor2 = strchr(cursor,
' ')) )
return false;
2647 snprintf(name.data(), name.size(),
"%.*s", (
int)(cursor2-cursor), cursor);
2651 std::shared_ptr<StringAttribute> att =
2652 std::make_shared<StringAttribute>(StringAttribute(unescape(cursor)));
2654 run_info()->add_attribute(std::string(name.data()), att);
2660bool ReaderAscii::parse_weight_names(
const char *buf) {
2661 const char *cursor = buf;
2663 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
2666 std::istringstream iss(unescape(cursor));
2667 std::vector<std::string> names;
2669 while (iss >> name) names.emplace_back(name);
2671 run_info()->set_weight_names(names);
2676bool ReaderAscii::parse_tool(
const char *buf) {
2677 const char *cursor = buf;
2679 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
2681 std::string line = unescape(cursor);
2682 GenRunInfo::ToolInfo tool;
2683 std::string::size_type pos = line.find(
'\n');
2684 tool.name = line.substr(0, pos);
2685 line = line.substr(pos + 1);
2686 pos = line.find(
'\n');
2687 tool.version = line.substr(0, pos);
2688 tool.description = line.substr(pos + 1);
2689 run_info()->tools().emplace_back(tool);
2695std::string ReaderAscii::unescape(
const std::string& s) {
2697 ret.reserve(s.length());
2698 for ( std::string::const_iterator it = s.begin(); it != s.end(); ++it ) {
2699 if ( *it ==
'\\' ) {
2717 if ( !m_file.is_open())
return;
double z() const
z-component of position/displacement
static const FourVector & ZERO_VECTOR()
Static null FourVector = (0,0,0,0)
double t() const
Time component of position/displacement.
bool is_zero() const
Check if the length of this vertex is zero.
double x() const
x-component of position/displacement
double y() const
y-component of position/displacement
double e() const
Energy component of momentum.
double length2() const
Squared magnitude of (x, y, z) 3-vector.
Stores event-related information.
std::vector< std::string > attribute_names(const int &id=0) const
Get list of attribute names.
int vertices_size() const
Vertices size, HepMC2 compatibility.
void set_beam_particles(GenParticlePtr p1, GenParticlePtr p2)
Set incoming beam particles.
void add_attributes(const std::vector< std::string > &names, const std::vector< std::shared_ptr< Attribute > > &atts, const std::vector< int > &ids)
Add multiple attributes to event.
const std::vector< ConstGenParticlePtr > & particles() const
Get list of particles (const)
std::map< std::string, std::map< int, std::shared_ptr< Attribute > > > attributes() const
Get a copy of the list of attributes.
const std::vector< double > & weights() const
Get event weight values as a vector.
void remove_particles(std::vector< GenParticlePtr > v)
Remove a set of particles.
void shift_position_to(const FourVector &newpos)
Shift position of all vertices in the event to op.
void add_particle(GenParticlePtr p)
Add particle.
void set_event_number(const int &num)
Set event number.
bool boost(const FourVector &delta)
Boost event using x,y,z components of delta as velocities.
int event_number() const
Get event number.
void add_tree(const std::vector< GenParticlePtr > &parts)
Add whole tree in topological order.
void set_units(Units::MomentumUnit new_momentum_unit, Units::LengthUnit new_length_unit)
Change event units Converts event from current units to new ones.
GenEvent & operator=(const GenEvent &)
Copy Assignment operator.
std::shared_ptr< T > attribute(const std::string &name, const int &id=0) const
Get attribute of type T.
const Units::MomentumUnit & momentum_unit() const
Get momentum unit.
void set_run_info(std::shared_ptr< GenRunInfo > run)
Set the GenRunInfo object by smart pointer.
const std::vector< ConstGenVertexPtr > & vertices() const
Get list of vertices (const)
void clear()
Remove contents of this event.
void read_data(const GenEventData &data)
Fill GenEvent based on GenEventData.
void remove_vertex(GenVertexPtr v)
Remove vertex from the event.
GenEvent(Units::MomentumUnit mu=Units::GEV, Units::LengthUnit lu=Units::MM)
Event constructor without a run.
std::shared_ptr< GenRunInfo > run_info() const
Get a pointer to the the GenRunInfo object.
bool rotate(const FourVector &delta)
Rotate event using x,y,z components of delta as rotation angles.
void remove_particle(GenParticlePtr p)
Remove particle from the event.
std::vector< ConstGenParticlePtr > beams() const
Vector of beam particles.
void write_data(GenEventData &data) const
Fill GenEventData object.
void reserve(const size_t &parts, const size_t &verts=0)
Reserve memory for particles and vertices.
void add_vertex(GenVertexPtr v)
Add vertex.
void add_beam_particle(GenParticlePtr p1)
Add particle to root vertex.
void remove_attribute(const std::string &name, const int &id=0)
Remove attribute.
const FourVector & event_pos() const
Vertex representing the overall event position.
std::string attribute_as_string(const std::string &name, const int &id=0) const
Get attribute of any type as string.
void shift_position_by(const FourVector &delta)
Shift position of all vertices in the event by delta.
void add_attribute(const std::string &name, const std::shared_ptr< Attribute > &att, const int &id=0)
const Units::LengthUnit & length_unit() const
Get length unit.
int particles_size() const
Particles size, HepMC2 compatibility.
bool reflect(const int axis)
Change sign of axis.
std::vector< std::string > attribute_names() const
Get list of names of attributes assigned to this particle.
bool add_attribute(const std::string &name, std::shared_ptr< Attribute > att)
Add an attribute to this particle.
void set_momentum(const FourVector &momentum)
Set momentum.
std::vector< GenParticlePtr > parents()
Convenience access to immediate incoming particles via production vertex.
void set_pid(int pid)
Set PDG ID.
void remove_attribute(const std::string &name)
Remove attribute.
std::vector< GenParticlePtr > children()
Convenience access to immediate outgoing particles via end vertex.
ConstGenVertexPtr end_vertex() const
Get end vertex (const version)
void set_generated_mass(double m)
Set generated mass.
std::string attribute_as_string(const std::string &name) const
Get attribute of any type as string.
double generated_mass() const
Get generated mass.
GenParticle(const FourVector &momentum=FourVector::ZERO_VECTOR(), int pid=0, int status=0)
Default constructor.
ConstGenVertexPtr production_vertex() const
Get production vertex (const version)
void unset_generated_mass()
Declare that generated mass is not set.
GenEvent * parent_event()
Get the parent event.
void set_status(int status)
Set status code.
Stores run-related information.
std::string version
The version of the tool.
void add_attribute(const std::string &name, const std::shared_ptr< Attribute > &att)
add an attribute This will overwrite existing attribute if an attribute with the same name is present
void read_data(const GenRunInfoData &data)
Fill GenRunInfo based on GenRunInfoData.
bool has_weight(const std::string &name) const
Check if a weight name is present.
void set_weight_names(const std::vector< std::string > &names)
Set the names of the weights in this run.
GenRunInfo & operator=(const GenRunInfo &r)
Assignmet.
const std::vector< std::string > & weight_names() const
Get the vector of weight names.
std::map< std::string, std::shared_ptr< Attribute > > attributes() const
Get a copy of the list of attributes.
std::string description
Other information about how the tool was used in the run.
const std::vector< ToolInfo > & tools() const
The vector of tools used to produce this run.
GenRunInfo()
Default constructor.
std::string attribute_as_string(const std::string &name) const
Get attribute of any type as string.
std::string name
The name of the tool.
void write_data(GenRunInfoData &data) const
Fill GenRunInfoData object.
std::vector< std::string > attribute_names() const
Get list of attribute names.
Stores vertex-related information.
std::vector< std::string > attribute_names() const
Get list of names of attributes assigned to this particle.
GenEvent * parent_event()
Get parent event.
void add_particle_in(GenParticlePtr p)
Add incoming particle.
std::string attribute_as_string(const std::string &name) const
Get attribute of any type as string.
void remove_attribute(const std::string &name)
Remove attribute.
void remove_particle_in(GenParticlePtr p)
Remove incoming particle.
const std::vector< GenParticlePtr > & particles_out()
Get list of outgoing particles.
void set_position(const FourVector &new_pos)
Set vertex position.
bool has_set_position() const
Check if position of this vertex is set.
bool add_attribute(const std::string &name, std::shared_ptr< Attribute > att)
Add event attribute to this vertex.
const FourVector & position() const
Get vertex position.
const std::vector< GenParticlePtr > & particles_in()
Get list of incoming particles.
void add_particle_out(GenParticlePtr p)
Add outgoing particle.
GenVertex(const FourVector &position=FourVector::ZERO_VECTOR())
Default constructor.
void remove_particle_out(GenParticlePtr p)
Remove outgoing particle.
Attribute that holds an Integer implemented as an int.
static void content(std::ostream &os, const GenEvent &event)
Print content of all GenEvent containers.
static void line(std::ostream &os, const GenEvent &event, bool attributes=false)
Print one-line info.
static void listing(std::ostream &os, const GenEvent &event, unsigned short precision=2)
Print event in listing (HepMC2) format.
ReaderAscii(const std::string &filename)
Constructor.
bool failed() override
Return status of the stream.
bool skip(const int) override
skip events
bool read_event(GenEvent &evt) override
Load event from file.
void close() override
Close file stream.
~ReaderAscii()
Destructor.
virtual std::shared_ptr< GenRunInfo > run_info() const
Get the global GenRunInfo object.
virtual void set_run_info(std::shared_ptr< GenRunInfo > run)
Set the global GenRunInfo object.
static int errors_level()
Get error messages printing level.
static const unsigned int DEFAULT_DOUBLE_ALMOST_EQUAL_MAXULPS
Default maxUlps for AlmostEqual2sComplement function (double precision)
static int debug_level()
Get debug level.
static void set_debug_level(const int level)
Set debug level.
static bool print_warnings()
Get warning messages printing flag.
static void set_errors_level(const int flag)
set error messages printing level
static int warnings_level()
Get warning messages printing level.
static void set_print_errors(const bool flag)
set error messages printing flag
static void set_print_warnings(const bool flag)
Set warning messages printing flag.
static bool print_errors()
Get error messages printing flag.
static void set_warnings_level(const int flag)
Set warning messages printing level.
static const double DOUBLE_EPSILON
Default threshold for comparing double variables.
LengthUnit
Position units.
static MomentumUnit momentum_unit(const std::string &name)
Get momentum unit based on its name.
static std::string name(MomentumUnit u)
Get name of momentum unit.
static LengthUnit length_unit(const std::string &name)
Get length unit based on its name.
MomentumUnit
Momentum units.
static void convert(T &m, MomentumUnit from, MomentumUnit to)
Convert FourVector to different momentum unit.
bool failed() override
Return status of the stream.
int precision() const
Return output precision.
~WriterAscii()
Destructor.
void write_event(const GenEvent &evt) override
Write event to file.
WriterAscii(const std::string &filename, std::shared_ptr< GenRunInfo > run=std::shared_ptr< GenRunInfo >())
Constructor.
void close() override
Close file stream.
void write_run_info()
Write the GenRunInfo object to file.
void set_precision(const int &prec)
Set output precision.
std::map< std::string, std::string > m_options
options
virtual std::shared_ptr< GenRunInfo > run_info() const
Get the global GenRunInfo object.
virtual void set_run_info(std::shared_ptr< GenRunInfo > run)
Set the global GenRunInfo object.
Stores serializable event information.
std::vector< int > links2
Second id of the vertex links.
std::vector< std::string > attribute_string
Attribute serialized as string.
std::vector< GenParticleData > particles
Particles.
std::vector< int > links1
First id of the vertex links.
std::vector< std::string > attribute_name
Attribute name.
FourVector event_pos
Event position.
int event_number
Event number.
std::vector< int > attribute_id
Attribute owner id.
Units::LengthUnit length_unit
Length unit.
std::vector< GenVertexData > vertices
Vertices.
std::vector< double > weights
Weights.
Units::MomentumUnit momentum_unit
Momentum unit.
Stores serializable particle information.
Stores serializable run information.
std::vector< std::string > weight_names
Weight names.
std::vector< std::string > tool_name
Tool names.
std::vector< std::string > attribute_string
Attribute serialized as string.
std::vector< std::string > tool_version
Tool versions.
std::vector< std::string > tool_description
Tool descriptions.
std::vector< std::string > attribute_name
Attribute name.
Stores serializable vertex information.