24 : m_file(filename), m_stream(0), m_isstream(false)
27 HEPMC3_ERROR(
"ReaderAscii: could not open input file: " << filename)
33 : m_stream(&stream), m_isstream(true)
36 HEPMC3_ERROR(
"ReaderAscii: could not open input stream ")
43 : m_shared_stream(s_stream), m_stream(s_stream.get()), m_isstream(true)
46 HEPMC3_ERROR(
"ReaderAscii: could not open input stream ")
55 const size_t max_buffer_size = 512*512;
56 char buf[max_buffer_size];
57 bool event_context =
false;
58 bool run_info_context =
false;
64 if ( peek ==
'E' ) { event_context =
true; nn--; }
66 if ( !event_context && ( peek ==
'W' || peek ==
'A' || peek ==
'T' ) ) {
68 if (!run_info_context) {
70 run_info_context =
true;
82 if ( event_context && ( peek ==
'V' || peek ==
'P' ) ) event_context=
false;
83 if (nn < 0)
return true;
94 const size_t max_buffer_size = 512*512;
95 char buf[max_buffer_size];
96 bool event_context =
false;
97 bool parsed_weights =
false;
98 bool parsed_particles_or_vertices =
false;
99 bool run_info_context =
false;
100 bool is_parsing_successful =
true;
101 std::pair<int, int> vertices_and_particles(0, 0);
113 if ( strlen(buf) == 0 )
continue;
116 if ( strncmp(buf,
"HepMC", 5) == 0 ) {
117 if ( strncmp(buf,
"HepMC::Version", 14) != 0 && strncmp(buf,
"HepMC::Asciiv3", 14) != 0 )
119 HEPMC3_WARNING(
"ReaderAscii: found unsupported expression in header. Will close the input.")
120 std::cout << buf << std::endl;
124 is_parsing_successful =
true;
133 if (vertices_and_particles.second < 0) {
134 is_parsing_successful =
false;
136 is_parsing_successful =
true;
137 event_context =
true;
138 parsed_weights =
false;
139 parsed_particles_or_vertices =
false;
141 run_info_context =
false;
145 parsed_particles_or_vertices =
true;
149 parsed_particles_or_vertices =
true;
152 if ( event_context ) {
156 if ( !run_info_context ) {
160 run_info_context =
true;
168 if ( event_context ) {
171 if ( !run_info_context ) {
175 run_info_context =
true;
180 if ( event_context ) {
183 if ( !run_info_context ) {
187 run_info_context =
true;
192 HEPMC3_WARNING(
"ReaderAscii: skipping unrecognised prefix: " << buf[0])
193 is_parsing_successful =
true;
197 if ( !is_parsing_successful )
break;
202 if ( event_context && peek ==
'E' )
break;
205 if ( event_context && peek ==
'W' && parsed_weights )
break;
208 if ( event_context && peek ==
'A' && parsed_particles_or_vertices )
break;
211 if ( event_context && peek ==
'T' )
break;
218 if ((
int)evt.
particles().size() > vertices_and_particles.second) {
219 HEPMC3_ERROR(
"ReaderAscii: too many particles were parsed")
220 printf(
"%zu vs %i expected\n", evt.
particles().size(), vertices_and_particles.second);
221 is_parsing_successful =
false;
223 if ((
int)evt.
particles().size() < vertices_and_particles.second) {
224 HEPMC3_ERROR(
"ReaderAscii: too few particles were parsed")
225 printf(
"%zu vs %i expected\n", evt.
particles().size(), vertices_and_particles.second);
226 is_parsing_successful =
false;
229 if ((
int)evt.
vertices().size() > vertices_and_particles.first) {
230 HEPMC3_ERROR(
"ReaderAscii: too many vertices were parsed")
231 printf(
"%zu vs %i expected\n", evt.
vertices().size(), vertices_and_particles.first);
232 is_parsing_successful =
false;
235 if ((
int)evt.
vertices().size() < vertices_and_particles.first) {
236 HEPMC3_ERROR(
"ReaderAscii: too few vertices were parsed")
237 printf(
"%zu vs %i expected\n", evt.
vertices().size(), vertices_and_particles.first);
238 is_parsing_successful =
false;
241 if ( !is_parsing_successful ) {
242 HEPMC3_ERROR(
"ReaderAscii: event parsing failed. Returning empty event")
243 HEPMC3_DEBUG(1,
"Parsing failed at line:" << std::endl << buf)
252 if (p.second == v->id())
253 v->add_particle_out(p.first);
257 std::vector<int> all_ids;
258 std::vector<int> filled_ids;
259 std::vector<int> diff;
260 for (
auto v: evt.
vertices())
if (v->id() != 0) filled_ids.push_back(v->id());
261 for (
int i = -((
long)evt.
vertices().size()); i < 0; i++) all_ids.push_back(i);
262 std::sort(all_ids.begin(), all_ids.end());
263 std::sort(filled_ids.begin(), filled_ids.end());
265 std::set_difference(all_ids.begin(), all_ids.end(), filled_ids.begin(), filled_ids.end(), std::inserter(diff, diff.begin()));
266 auto it = diff.rbegin();
268 for (
auto v: evt.
vertices())
if (v->id() == 0) { v->set_id(*it); it++;}
275 static const std::pair<int, int> err(-1, -1);
276 std::pair<int, int> ret(-1, -1);
277 const char *cursor = buf;
282 if ( !(cursor = strchr(cursor+1,
' ')) )
return err;
283 event_no = atoi(cursor);
287 if ( !(cursor = strchr(cursor+1,
' ')) )
return err;
288 ret.first = atoi(cursor);
291 if ( !(cursor = strchr(cursor+1,
' ')) )
return err;
292 ret.second = atoi(cursor);
295 if ( (cursor = strchr(cursor+1,
'@')) ) {
297 if ( !(cursor = strchr(cursor+1,
' ')) )
return err;
298 position.
setX(atof(cursor));
301 if ( !(cursor = strchr(cursor+1,
' ')) )
return err;
302 position.
setY(atof(cursor));
305 if ( !(cursor = strchr(cursor+1,
' ')) )
return err;
306 position.
setZ(atof(cursor));
309 if ( !(cursor = strchr(cursor+1,
' ')) )
return err;
310 position.
setT(atof(cursor));
314 HEPMC3_DEBUG(10,
"ReaderAscii: E: " << event_no <<
" (" <<ret.first <<
"V, " << ret.second <<
"P)")
321 std::istringstream iss(buf + 1);
322 std::vector<double> wts;
324 while (iss >> w) wts.push_back(w);
326 &&
run_info()->weight_names().size() != wts.size() )
327 throw std::logic_error(
"ReaderAscii::parse_weight_values: "
328 "The number of weights ("+std::to_string((
long long int)(wts.size()))+
") does not match "
329 "the number weight names("+std::to_string((
long long int)(
run_info()->weight_names().size()))+
") in the GenRunInfo object");
337 const char *cursor = buf;
340 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
345 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
349 evt.
set_units(momentum_unit, length_unit);
358 GenVertexPtr data = std::make_shared<GenVertex>();
360 const char *cursor = buf;
361 const char *cursor2 =
nullptr;
366 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
370 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
371 data->set_status(atoi(cursor));
374 if ( !(cursor = strchr(cursor+1,
'[')) )
return false;
379 int particle_in = atoi(cursor);
382 if (particle_in > 0) {
384 if (particle_in <= highest_id) {
385 data->add_particle_in(evt.
particles()[particle_in-1]);
393 if ( !(cursor = strchr(cursor+1,
',')) ) {
394 if ( !(cursor = strchr(cursor2+1,
']')) )
return false;
400 if ( (cursor = strchr(cursor+1,
'@')) ) {
402 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
403 position.
setX(atof(cursor));
406 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
407 position.
setY(atof(cursor));
410 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
411 position.
setZ(atof(cursor));
414 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
415 position.
setT(atof(cursor));
416 data->set_position(position);
419 HEPMC3_DEBUG(10,
"ReaderAscii: V: " <<
id <<
" with "<< data->particles_in().size() <<
" particles)")
430 GenParticlePtr data = std::make_shared<GenParticle>();
432 const char *cursor = buf;
436 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
438 if ( atoi(cursor) != (
int)evt.
particles().size() + 1 ) {
445 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
446 mother_id = atoi(cursor);
449 if ( mother_id > 0 && mother_id <= (
int)evt.
particles().size() ) {
450 GenParticlePtr mother = evt.
particles()[ mother_id-1 ];
451 GenVertexPtr vertex = mother->end_vertex();
455 vertex = std::make_shared<GenVertex>();
456 vertex->add_particle_in(mother);
459 vertex->add_particle_out(data);
465 else if ( mother_id < 0 )
469 for (
auto v: evt.
vertices())
if (v->id() == mother_id) {v->add_particle_out(data); found =
true;
break; }
480 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
481 data->set_pid(atoi(cursor));
484 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
485 momentum.
setPx(atof(cursor));
488 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
489 momentum.
setPy(atof(cursor));
492 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
493 momentum.
setPz(atof(cursor));
496 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
497 momentum.
setE(atof(cursor));
498 data->set_momentum(momentum);
501 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
502 data->set_generated_mass(atof(cursor));
505 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
506 data->set_status(atoi(cursor));
510 HEPMC3_DEBUG(10,
"ReaderAscii: P: " << data->id() <<
" ( mother: " << mother_id <<
", pid: " << data->pid() <<
")")
517 const char *cursor = buf;
518 const char *cursor2 = buf;
522 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
525 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
528 if ( !(cursor2 = strchr(cursor,
' ')) )
return false;
529 snprintf(name, 512,
"%.*s", (
int)(cursor2-cursor), cursor);
533 std::shared_ptr<Attribute> att =
542 const char *cursor = buf;
543 const char *cursor2 = buf;
546 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
549 if ( !(cursor2 = strchr(cursor,
' ')) )
return false;
550 snprintf(name, 512,
"%.*s", (
int)(cursor2-cursor), cursor);
554 std::shared_ptr<StringAttribute> att =
557 run_info()->add_attribute(std::string(name), att);
564 const char *cursor = buf;
566 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
569 std::istringstream iss(
unescape(cursor));
570 std::vector<std::string> names;
572 while (iss >> name) names.push_back(name);
574 run_info()->set_weight_names(names);
580 const char *cursor = buf;
582 if ( !(cursor = strchr(cursor+1,
' ')) )
return false;
584 std::string line =
unescape(cursor);
586 std::string::size_type pos = line.find(
"\n");
587 tool.
name = line.substr(0, pos);
588 line = line.substr(pos + 1);
589 pos = line.find(
"\n");
590 tool.
version = line.substr(0, pos);
592 run_info()->tools().push_back(tool);
600 ret.reserve(s.length());
601 for ( std::string::const_iterator it = s.begin(); it != s.end(); ++it ) {
618 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 class GenParticle.
Definition of class GenVertex.
Definition of class ReaderAscii.
Definition of class Units.
Stores event-related information.
void add_vertex(GenVertexPtr v)
Add vertex.
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_units(Units::MomentumUnit new_momentum_unit, Units::LengthUnit new_length_unit)
Change event units Converts event from current units to new ones.
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 std::vector< ConstGenVertexPtr > & vertices() const
Get list of vertices (const)
const Units::MomentumUnit & momentum_unit() const
Get momentum unit.
const Units::LengthUnit & length_unit() const
Get length unit.
void add_attribute(const std::string &name, const std::shared_ptr< Attribute > &att, const int &id=0)
const std::vector< double > & weights() const
Get event weight values as a vector.
void clear()
Remove contents of this event.
const std::vector< ConstGenParticlePtr > & particles() const
Get list of particles (const)
bool parse_tool(const char *buf)
Parse run-level tool information.
bool m_isstream
toggles usage of m_file or m_stream
bool parse_weight_values(GenEvent &evt, const char *buf)
Parse weight value lines.
std::map< GenParticlePtr, int > m_forward_daughters
Temp storage for prod vertex ids.
bool read_event(GenEvent &evt) override
Load event from file.
std::string unescape(const std::string &s)
Unsecape '\' and ' ' characters in string.
bool failed() override
Return status of the stream.
bool skip(const int) override
skip events
std::ifstream m_file
Input file.
bool parse_units(GenEvent &evt, const char *buf)
Parse units.
bool parse_particle_information(GenEvent &evt, const char *buf)
Parse particle.
std::map< GenVertexPtr, std::set< int > > m_forward_mothers
Temp storage for outgoing particle ids.
bool parse_attribute(GenEvent &evt, const char *buf)
Parse attribute.
void close() override
Close file stream.
bool parse_vertex_information(GenEvent &evt, const char *buf)
Parse vertex.
~ReaderAscii()
Destructor.
bool parse_weight_names(const char *buf)
Parse run-level weight names.
ReaderAscii(const std::string &filename)
Constructor.
std::istream * m_stream
For ctor when reading from stream.
bool parse_run_attribute(const char *buf)
Parse run-level attribute.
std::pair< int, int > parse_event_information(GenEvent &evt, const char *buf)
Parse event.
std::shared_ptr< GenRunInfo > run_info() const
Get the global GenRunInfo object.
void set_run_info(std::shared_ptr< GenRunInfo > run)
Set the global GenRunInfo object.
Attribute that holds a string.
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.