26 m_file(filename), m_stream(nullptr), m_isstream(false) {
28 HEPMC3_ERROR(
"ReaderAsciiHepMC2: could not open input file: " << filename )
35 : m_stream(&stream), m_isstream(true)
38 HEPMC3_ERROR(
"ReaderAsciiHepMC2: could not open input stream ")
45 : m_shared_stream(s_stream), m_stream(s_stream.get()), m_isstream(true)
48 HEPMC3_ERROR(
"ReaderAsciiHepMC2: could not open input stream ")
58 std::array<char, 262144> buf;
64 if ( peek ==
'E' ) nn--;
65 if (nn < 0) {
return true; }
75 std::array<char, 262144> buf;
76 bool parsed_event_header =
false;
77 bool is_parsing_successful =
true;
78 int parsing_result = 0;
79 unsigned int vertices_count = 0;
80 unsigned int current_vertex_particles_count = 0;
81 unsigned int current_vertex_particles_parsed = 0;
99 if ( strlen(buf.data()) == 0 )
continue;
101 if ( strncmp(buf.data(),
"HepMC", 5) == 0 ) {
102 if ( strncmp(buf.data(),
"HepMC::Version", 14) != 0 && strncmp(buf.data(),
"HepMC::IO_GenEvent", 18) != 0 )
104 HEPMC3_WARNING(
"ReaderAsciiHepMC2: found unsupported expression in header. Will close the input.")
105 std::cout <<buf.data() << std::endl;
108 if (parsed_event_header) {
109 is_parsing_successful =
true;
117 if (parsing_result < 0) {
118 is_parsing_successful =
false;
119 HEPMC3_ERROR(
"ReaderAsciiHepMC2: HEPMC3_ERROR parsing event information")
122 vertices_count = parsing_result;
131 is_parsing_successful =
true;
133 parsed_event_header =
true;
140 if (current_vertex_particles_parsed < current_vertex_particles_count) {
141 is_parsing_successful =
false;
144 current_vertex_particles_parsed = 0;
148 if (parsing_result < 0) {
149 is_parsing_successful =
false;
150 HEPMC3_ERROR(
"ReaderAsciiHepMC2: HEPMC3_ERROR parsing vertex information")
153 current_vertex_particles_count = parsing_result;
154 is_parsing_successful =
true;
161 if (parsing_result < 0) {
162 is_parsing_successful =
false;
163 HEPMC3_ERROR(
"ReaderAsciiHepMC2: HEPMC3_ERROR parsing particle information")
166 ++current_vertex_particles_parsed;
167 is_parsing_successful =
true;
171 is_parsing_successful =
parse_units(evt, buf.data());
186 HEPMC3_WARNING(
"ReaderAsciiHepMC2: skipping unrecognised prefix: " << buf[0])
187 is_parsing_successful =
true;
191 if ( !is_parsing_successful )
break;
195 if ( parsed_event_header && peek ==
'E' )
break;
201 if (is_parsing_successful && current_vertex_particles_parsed < current_vertex_particles_count) {
202 HEPMC3_ERROR(
"ReaderAsciiHepMC2: not all particles parsed")
203 is_parsing_successful =
false;
206 else if (is_parsing_successful &&
m_vertex_cache.size() != vertices_count) {
207 HEPMC3_ERROR(
"ReaderAsciiHepMC2: not all vertices parsed")
208 is_parsing_successful =
false;
211 if ( !is_parsing_successful ) {
212 HEPMC3_ERROR(
"ReaderAsciiHepMC2: event parsing failed. Returning empty event")
213 HEPMC3_DEBUG(1,
"Parsing failed at line:" << std::endl << buf.data())
219 run_info()->set_weight_names(std::vector<std::string> {
"Default"});
222 HEPMC3_WARNING(
"ReaderAsciiHepMC2: weights are empty, an event weight 1.0 will be added.")
243 std::vector<GenParticlePtr> beams;
245 for (
const auto& p:
m_vertex_cache[i]->particles_out())
if (p->status() == 4 && !(p->end_vertex())) beams.emplace_back(p);
250 HEPMC3_DEBUG(30,
"ReaderAsciiHepMC2::read_event - moved particle with status=4 from the outgoing to the incoming particles of vertex: " <<
m_vertex_cache[i]->
id());
269 if (
m_options.count(
"event_random_states_are_separated") != 0)
272 if (random_states_a) {
273 std::vector<long int> random_states_v = random_states_a->
value();
274 for (
size_t i = 0; i < random_states_v.size(); ++i ) {
275 evt.
add_attribute(
"random_states" + std::to_string((
long long unsigned int)i), std::make_shared<IntAttribute>(random_states_v[i]));
282 std::map< std::string, std::map<int, std::shared_ptr<Attribute> > > cached_attributes =
m_event_ghost->
attributes();
283 if (cached_attributes.count(
"flows") != 0) {
284 const std::map<int, std::shared_ptr<Attribute> >& flows = cached_attributes.at(
"flows");
285 if (
m_options.count(
"particle_flows_are_separated") == 0) {
288 for (
const auto& f: flows) {
290 std::shared_ptr<VectorIntAttribute> casted = std::dynamic_pointer_cast<VectorIntAttribute>(f.second);
291 if (!casted)
continue;
292 std::vector<int> this_p_flow = casted->value();
293 for (
size_t i = 0; i<this_p_flow.size(); i++)
m_particle_cache[f.first-1]->add_attribute(
"flow" + std::to_string(i + 1), std::make_shared<IntAttribute>(this_p_flow[i]));
299 if (cached_attributes.count(
"phi") != 0) {
300 const std::map<int, std::shared_ptr<Attribute> >& phi = cached_attributes.at(
"phi");
304 if (cached_attributes.count(
"theta") != 0) {
305 const std::map<int, std::shared_ptr<Attribute> >& theta = cached_attributes.at(
"theta");
309 if (cached_attributes.count(
"weights") != 0) {
310 const std::map<int, std::shared_ptr<Attribute> >& weights = cached_attributes.at(
"weights");
311 if (
m_options.count(
"vertex_weights_are_separated") == 0) {
312 for (
const auto& f: weights) {
if (f.first < 0 && f.first >= -(
int)
m_vertex_cache.size())
m_vertex_cache[-f.first-1]->add_attribute(
"weights", f.second);}
314 for (
const auto& f: weights) {
316 std::shared_ptr<VectorDoubleAttribute> casted = std::dynamic_pointer_cast<VectorDoubleAttribute>(f.second);
317 if (!casted)
continue;
318 std::vector<double> this_v_weight = casted->value();
319 for (
size_t i = 0; i < this_v_weight.size(); i++)
m_particle_cache[-f.first-1]->add_attribute(
"weight"+std::to_string(i), std::make_shared<DoubleAttribute>(this_v_weight[i]));
325 std::shared_ptr<IntAttribute> signal_process_vertex_barcode = evt.
attribute<
IntAttribute>(
"signal_process_vertex");
326 if (signal_process_vertex_barcode) {
327 int signal_process_vertex_barcode_value = signal_process_vertex_barcode->
value();
332 std::shared_ptr<IntAttribute> signal_process_vertex = std::make_shared<IntAttribute>(
m_vertex_cache.at(i)->id());
333 evt.
add_attribute(
"signal_process_vertex", signal_process_vertex);
344 const char *cursor = buf;
345 size_t vertices_count = 0;
346 int random_states_size = 0;
347 int weights_size = 0;
348 std::vector<long> random_states(0);
349 std::vector<double> weights(0);
352 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
356 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
357 evt.
add_attribute(
"mpi", std::make_shared<IntAttribute>(atoi(cursor)));
360 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
361 evt.
add_attribute(
"event_scale", std::make_shared<DoubleAttribute>(atof(cursor)));
364 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
365 evt.
add_attribute(
"alphaQCD", std::make_shared<DoubleAttribute>(atof(cursor)));
368 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
369 evt.
add_attribute(
"alphaQED", std::make_shared<DoubleAttribute>(atof(cursor)));
372 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
373 evt.
add_attribute(
"signal_process_id", std::make_shared<IntAttribute>(atoi(cursor)));
376 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
377 evt.
add_attribute(
"signal_process_vertex", std::make_shared<IntAttribute>(atoi(cursor)));
380 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
381 vertices_count = atoi(cursor);
384 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
387 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
390 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
391 random_states_size = atoi(cursor);
392 if (random_states_size >= 0 ) {
393 random_states.resize(random_states_size);
395 HEPMC3_DEBUG(0,
"ReaderAsciiHepMC2: E: " << evt.
event_number() <<
" (" << vertices_count <<
"V, " << random_states_size <<
"RS)")
397 for (
int i = 0; i < random_states_size; ++i ) {
398 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
399 random_states[i] = atoi(cursor);
402 if (!random_states.empty()) evt.
add_attribute(
"random_states", std::make_shared<VectorLongIntAttribute>(random_states));
405 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
406 weights_size = atoi(cursor);
407 if (weights_size >= 0 ) {
408 weights.resize(weights_size);
410 HEPMC3_DEBUG(0,
"ReaderAsciiHepMC2: E: " << evt.
event_number() <<
" (" << vertices_count <<
"V, " << weights_size <<
"WS)")
412 for (
int i = 0; i < weights_size; ++i ) {
413 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
414 weights[i] = atof(cursor);
419 HEPMC3_DEBUG(10,
"ReaderAsciiHepMC2: E: " << evt.
event_number() <<
" (" << vertices_count <<
"V, " << weights_size <<
"W, " << random_states_size <<
"RS)")
421 return vertices_count;
425 const char *cursor = buf;
428 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
433 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
437 evt.
set_units(momentum_unit, length_unit);
445 GenVertexPtr data = std::make_shared<GenVertex>();
446 GenVertexPtr data_ghost = std::make_shared<GenVertex>();
447 const char *cursor = buf;
449 int num_particles_out = 0;
450 int weights_size = 0;
451 std::vector<double> weights(0);
453 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
454 barcode = atoi(cursor);
457 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
458 data->set_status(atoi(cursor));
461 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
462 double X(atof(cursor));
465 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
466 double Y(atof(cursor));
469 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
470 double Z(atof(cursor));
473 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
474 double T(atof(cursor));
478 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
481 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
482 num_particles_out = atoi(cursor);
485 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
486 weights_size = atoi(cursor);
487 weights.resize(weights_size);
489 for (
int i = 0; i < weights_size; ++i ) {
490 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
491 weights[i] = atof(cursor);
502 if (!weights.empty()) data_ghost->add_attribute(
"weights", std::make_shared<VectorDoubleAttribute>(weights));
506 HEPMC3_DEBUG(10,
"ReaderAsciiHepMC2: V: " << -(
int)
m_vertex_cache.size() <<
" (old barcode " << barcode <<
") " << num_particles_out <<
" particles)")
508 return num_particles_out;
512 GenParticlePtr data = std::make_shared<GenParticle>();
513 GenParticlePtr data_ghost = std::make_shared<GenParticle>();
515 const char *cursor = buf;
519 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
522 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
523 data->set_pid(atoi(cursor));
526 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
527 double Px(atof(cursor));
530 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
531 double Py(atof(cursor));
534 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
535 double Pz(atof(cursor));
538 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
539 double E(atof(cursor));
543 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
544 data->set_generated_mass(atof(cursor));
547 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
548 data->set_status(atoi(cursor));
551 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
552 double theta_v = atof(cursor);
553 if (theta_v != 0.0) data_ghost->add_attribute(
"theta", std::make_shared<DoubleAttribute>(theta_v));
556 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
557 double phi_v = atof(cursor);
558 if (phi_v != 0.0) data_ghost->add_attribute(
"phi", std::make_shared<DoubleAttribute>(phi_v));
561 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
562 end_vtx = atoi(cursor);
565 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
566 int flowsize = atoi(cursor);
568 std::map<int, int> flows;
569 for (
int i = 0; i < flowsize; i++)
571 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
572 int flowindex = atoi(cursor);
573 if ( !(cursor = strchr(cursor+1,
' ')) )
return -1;
574 int flowvalue = atoi(cursor);
575 flows[flowindex] = flowvalue;
579 std::vector<int> vectorflows;
580 vectorflows.reserve(flows.size());
581 for (
const auto& f: flows) { vectorflows.emplace_back(f.second); }
582 data_ghost->add_attribute(
"flows", std::make_shared<VectorIntAttribute>(vectorflows));
603 const char *cursor = buf;
604 std::shared_ptr<GenCrossSection> xs = std::make_shared<GenCrossSection>();
606 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
607 const double xs_val = atof(cursor);
609 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
610 const double xs_err = atof(cursor);
611 const size_t all =
m_options.count(
"disable_pad_cross_sections") ?
size_t{1} : std::max(evt.
weights().size(),
size_t{1});
612 const double xs_val_dummy =
m_options.count(
"pad_cross_section_value") ? std::strtod(
m_options.at(
"pad_cross_section_value").c_str(),
nullptr) : 0.0;
613 const double xs_err_dummy =
m_options.count(
"pad_cross_section_error") ? std::strtod(
m_options.at(
"pad_cross_section_error").c_str(),
nullptr) : 0.0;
614 xs->set_cross_section(std::vector<double>(all,xs_val_dummy), std::vector<double>(all,xs_err_dummy));
615 xs->set_xsec(0,xs_val);
616 xs->set_xsec_err(0,xs_err);
622 const char *cursor = buf;
623 const char *cursor2 = buf;
625 std::vector<std::string> w_names;
630 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
631 w_count = atoi(cursor);
633 if ( w_count <= 0 )
return false;
635 w_names.resize(w_count);
637 for (
int i=0; i < w_count; ++i ) {
639 if ( !(cursor = strchr(cursor+1,
'"')) )
return false;
640 if ( !(cursor2 = strchr(cursor+1,
'"')) )
return false;
645 w_names[i].assign(cursor, cursor2-cursor);
650 run_info()->set_weight_names(w_names);
656 std::shared_ptr<GenHeavyIon> hi = std::make_shared<GenHeavyIon>();
657 const char *cursor = buf;
659 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
660 hi->Ncoll_hard = atoi(cursor);
662 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
663 hi->Npart_proj = atoi(cursor);
665 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
666 hi->Npart_targ = atoi(cursor);
668 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
669 hi->Ncoll = atoi(cursor);
671 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
672 hi->spectator_neutrons = atoi(cursor);
674 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
675 hi->spectator_protons = atoi(cursor);
677 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
678 hi->N_Nwounded_collisions = atoi(cursor);
680 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
681 hi->Nwounded_N_collisions = atoi(cursor);
683 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
684 hi->Nwounded_Nwounded_collisions = atoi(cursor);
686 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
687 hi->impact_parameter = atof(cursor);
689 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
690 hi->event_plane_angle = atof(cursor);
692 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
693 hi->eccentricity = atof(cursor);
695 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
696 hi->sigma_inel_NN = atof(cursor);
699 hi->centrality = 0.0;
707 std::shared_ptr<GenPdfInfo> pi = std::make_shared<GenPdfInfo>();
708 const char *cursor = buf;
710 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
711 pi->parton_id[0] = atoi(cursor);
713 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
714 pi->parton_id[1] = atoi(cursor);
716 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
717 pi->x[0] = atof(cursor);
719 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
720 pi->x[1] = atof(cursor);
722 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
723 pi->scale = atof(cursor);
725 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
726 pi->xf[0] = atof(cursor);
728 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
729 pi->xf[1] = atof(cursor);
733 if ( !(cursor = strchr(cursor+1,
' ')) ) pdfids =
false;
734 if (pdfids) {pi->pdf_id[0] = atoi(cursor);}
735 else {pi->pdf_id[0] = 0;}
737 if (pdfids)
if ( !(cursor = strchr(cursor+1,
' ')) ) pdfids =
false;
738 if (pdfids) { pi->pdf_id[1] = atoi(cursor);}
739 else {pi->pdf_id[1] = 0;}
749 if ( !
m_file.is_open() )
return;
#define HEPMC3_WARNING(MESSAGE)
Macro for printing HEPMC3_HEPMC3_WARNING messages.
#define HEPMC3_DEBUG(LEVEL, MESSAGE)
Macro for printing debug messages with appropriate debug level.
#define HEPMC3_ERROR(MESSAGE)
Macro for printing error messages.
Definition of class GenEvent.
Definition of attribute class GenHeavyIon.
Definition of class GenParticle.
Definition of event attribute class GenPdfInfo.
Definition of class GenVertex.
Definition of class ReaderAsciiHepMC2.
Definition of class Setup.
Stores event-related information.
std::shared_ptr< T > attribute(const std::string &name, const int &id=0) const
Get attribute of type T.
void add_vertex(GenVertexPtr v)
Add vertex.
int event_number() const
Get event number.
void add_particle(GenParticlePtr p)
Add particle.
void set_units(Units::MomentumUnit new_momentum_unit, Units::LengthUnit new_length_unit)
Change event units Converts event from current units to new ones.
void reserve(const size_t &parts, const size_t &verts=0)
Reserve memory for particles and vertices.
void set_event_number(const int &num)
Set event number.
void set_run_info(std::shared_ptr< GenRunInfo > run)
Set the GenRunInfo object by smart pointer.
const Units::MomentumUnit & momentum_unit() const
Get momentum unit.
const Units::LengthUnit & length_unit() const
Get length unit.
std::map< std::string, std::map< int, std::shared_ptr< Attribute > > > attributes() const
Get a copy of the list of attributes.
void add_attribute(const std::string &name, const std::shared_ptr< Attribute > &att, const int &id=0)
void remove_attribute(const std::string &name, const int &id=0)
Remove attribute.
const std::vector< double > & weights() const
Get event weight values as a vector.
void clear()
Remove contents of this event.
void add_tree(const std::vector< GenParticlePtr > &parts)
Add whole tree in topological order.
Attribute that holds an Integer implemented as an int.
int value() const
get the value associated to this Attribute.
bool m_isstream
toggles usage of m_file or m_stream
bool read_event(GenEvent &evt) override
Implementation of Reader::read_event.
int parse_event_information(GenEvent &evt, const char *buf)
Parse event.
std::vector< int > m_vertex_barcodes
Old vertex barcodes.
bool failed() override
Return status of the stream.
bool parse_pdf_info(GenEvent &evt, const char *buf)
Parse pdf information.
bool skip(const int) override
skip events
std::ifstream m_file
Input file.
bool parse_units(GenEvent &evt, const char *buf)
Parse units.
int parse_particle_information(const char *buf)
Parse particle.
std::vector< GenParticlePtr > m_particle_cache_ghost
Particle cache for attributes.
void close() override
Close file stream.
std::vector< GenVertexPtr > m_vertex_cache
Vertex cache.
ReaderAsciiHepMC2(const std::string &filename)
Default constructor.
std::vector< GenParticlePtr > m_particle_cache
Particle cache.
bool parse_weight_names(const char *buf)
Parse weight names.
bool parse_xs_info(GenEvent &evt, const char *buf)
Parse pdf information.
std::istream * m_stream
For ctor when reading from stream.
std::vector< GenVertexPtr > m_vertex_cache_ghost
Vertex cache for attributes.
~ReaderAsciiHepMC2()
Destructor.
int parse_vertex_information(const char *buf)
Parse vertex.
bool parse_heavy_ion(GenEvent &evt, const char *buf)
Parse heavy ion information.
GenEvent * m_event_ghost
To save particle and verstex attributes.
std::vector< int > m_end_vertex_barcodes
Old end vertex barcodes.
virtual void set_run_info(std::shared_ptr< GenRunInfo > run)
Set the global GenRunInfo object.
virtual std::shared_ptr< GenRunInfo > run_info() const
Get the global GenRunInfo object.
std::map< std::string, std::string > m_options
Options.
static LengthUnit length_unit(const std::string &name)
Get length unit based on its name.
LengthUnit
Position units.
static std::string name(MomentumUnit u)
Get name of momentum unit.
MomentumUnit
Momentum units.
static MomentumUnit momentum_unit(const std::string &name)
Get momentum unit based on its name.
Attribute that holds a vector of integers of type long int.
std::vector< long int > value() const
get the value associated to this Attribute.