23 : m_file(filename), m_stream(0), m_isstream(false)
26 HEPMC3_ERROR(
"ReaderAscii: could not open input file: "<<filename )
34 : m_stream(&stream), m_isstream(true)
37 HEPMC3_ERROR(
"ReaderAscii: could not open input stream " )
48 const size_t max_buffer_size=512*512;
49 char buf[max_buffer_size];
56 if (nn<0)
return true;
67 const size_t max_buffer_size=512*512;
68 char buf[max_buffer_size];
69 bool parsed_event_header =
false;
70 bool is_parsing_successful =
true;
71 pair<int,int> vertices_and_particles(0,0);
84 if( strlen(buf) == 0 )
continue;
87 if( strncmp(buf,
"HepMC",5) == 0 ) {
88 if( strncmp(buf,
"HepMC::Version",14) != 0 && strncmp(buf,
"HepMC::Asciiv3",14)!=0 )
90 HEPMC3_WARNING(
"ReaderAscii: found unsupported expression in header. Will close the input." )
91 std::cout<<buf<<std::endl;
94 if(parsed_event_header) {
95 is_parsing_successful =
true;
104 if (vertices_and_particles.second < 0) {
105 is_parsing_successful =
false;
107 is_parsing_successful =
true;
108 parsed_event_header =
true;
118 if ( parsed_event_header )
130 if ( parsed_event_header )
136 HEPMC3_WARNING(
"ReaderAscii: skipping unrecognised prefix: " << buf[0] )
137 is_parsing_successful =
true;
141 if( !is_parsing_successful )
break;
145 if( parsed_event_header && peek==
'E' )
break;
150 if ((
int)evt.
particles().size() > vertices_and_particles.second ) {
151 HEPMC3_ERROR(
"ReaderAscii: too many particles were parsed" )
152 printf(
"%zu vs %i expected\n",evt.
particles().size(),vertices_and_particles.second );
153 is_parsing_successful =
false;
155 if ((
int)evt.
particles().size() < vertices_and_particles.second ) {
156 HEPMC3_ERROR(
"ReaderAscii: too few particles were parsed" )
157 printf(
"%zu vs %i expected\n",evt.
particles().size(),vertices_and_particles.second );
158 is_parsing_successful =
false;
161 if ((
int)evt.
vertices().size() > vertices_and_particles.first) {
162 HEPMC3_ERROR(
"ReaderAscii: too many vertices were parsed" )
163 printf(
"%zu vs %i expected\n",evt.
vertices().size(),vertices_and_particles.first );
164 is_parsing_successful =
false;
167 if ((
int)evt.
vertices().size() < vertices_and_particles.first) {
168 HEPMC3_ERROR(
"ReaderAscii: too few vertices were parsed" )
169 printf(
"%zu vs %i expected\n",evt.
vertices().size(),vertices_and_particles.first );
170 is_parsing_successful =
false;
173 if( !is_parsing_successful ) {
174 HEPMC3_ERROR(
"ReaderAscii: event parsing failed. Returning empty event" )
175 HEPMC3_DEBUG( 1,
"Parsing failed at line:" << endl << buf )
184 if (p.second==v->id())
185 v->add_particle_out(p.first);
189 std::vector<int> all_ids;
190 std::vector<int> filled_ids;
191 std::vector<int> diff;
192 for (
auto v: evt.
vertices())
if (v->id()!=0) filled_ids.push_back(v->id());
193 for (
int i=-((
long)evt.
vertices().size()); i<0; i++) all_ids.push_back(i);
194 std::sort(all_ids.begin(),all_ids.end());
195 std::sort(filled_ids.begin(),filled_ids.end());
197 std::set_difference(all_ids.begin(), all_ids.end(), filled_ids.begin(), filled_ids.end(), std::inserter(diff, diff.begin()));
198 auto it= diff.rbegin();
200 for (
auto v: evt.
vertices())
if (v->id()==0) { v->set_id(*it); it++;}
207 static const pair<int,int> err(-1,-1);
208 pair<int,int> ret(-1,-1);
209 const char *cursor = buf;
214 if( !(cursor = strchr(cursor+1,
' ')) )
return err;
215 event_no = atoi(cursor);
219 if( !(cursor = strchr(cursor+1,
' ')) )
return err;
220 ret.first = atoi(cursor);
223 if( !(cursor = strchr(cursor+1,
' ')) )
return err;
224 ret.second = atoi(cursor);
227 if( (cursor = strchr(cursor+1,
'@')) ) {
230 if( !(cursor = strchr(cursor+1,
' ')) )
return err;
231 position.
setX(atof(cursor));
234 if( !(cursor = strchr(cursor+1,
' ')) )
return err;
235 position.
setY(atof(cursor));
238 if( !(cursor = strchr(cursor+1,
' ')) )
return err;
239 position.
setZ(atof(cursor));
242 if( !(cursor = strchr(cursor+1,
' ')) )
return err;
243 position.
setT(atof(cursor));
247 HEPMC3_DEBUG( 10,
"ReaderAscii: E: "<<event_no<<
" ("<<ret.first<<
"V, "<<ret.second<<
"P)" )
255 std::istringstream iss(buf + 1);
258 while ( iss >> w ) wts.push_back(w);
260 &&
run_info()->weight_names().size() != wts.size() )
261 throw std::logic_error(
"ReaderAscii::parse_weight_values: "
262 "The number of weights ("+std::to_string((
long long int)(wts.size()))+
") does not match "
263 "the number weight names("+std::to_string((
long long int)(
run_info()->weight_names().size()))+
") in the GenRunInfo object");
271 const char *cursor = buf;
274 if( !(cursor = strchr(cursor+1,
' ')) )
return false;
279 if( !(cursor = strchr(cursor+1,
' ')) )
return false;
283 evt.
set_units(momentum_unit,length_unit);
292 GenVertexPtr data = make_shared<GenVertex>();
294 const char *cursor = buf;
295 const char *cursor2 =
nullptr;
300 if( !(cursor = strchr(cursor+1,
' ')) )
return false;
304 if( !(cursor = strchr(cursor+1,
' ')) )
return false;
305 data->set_status( atoi(cursor) );
308 if( !(cursor = strchr(cursor+1,
'[')) )
return false;
313 int particle_in = atoi(cursor);
316 if( particle_in > 0) {
318 if (particle_in <= highest_id)
319 data->add_particle_in( evt.
particles()[particle_in-1] );
325 if( !(cursor = strchr(cursor+1,
',')) ) {
326 if( !(cursor = strchr(cursor2+1,
']')) )
return false;
332 if( (cursor = strchr(cursor+1,
'@')) ) {
335 if( !(cursor = strchr(cursor+1,
' ')) )
return false;
336 position.setX(atof(cursor));
339 if( !(cursor = strchr(cursor+1,
' ')) )
return false;
340 position.setY(atof(cursor));
343 if( !(cursor = strchr(cursor+1,
' ')) )
return false;
344 position.setZ(atof(cursor));
347 if( !(cursor = strchr(cursor+1,
' ')) )
return false;
348 position.setT(atof(cursor));
349 data->set_position( position );
353 HEPMC3_DEBUG( 10,
"ReaderAscii: V: "<<
id<<
" with "<<data->particles_in().size()<<
" particles)" )
364 GenParticlePtr data = make_shared<GenParticle>();
366 const char *cursor = buf;
370 if( !(cursor = strchr(cursor+1,
' ')) )
return false;
372 if( atoi(cursor) != (int)evt.
particles().size() + 1 ) {
379 if( !(cursor = strchr(cursor+1,
' ')) )
return false;
380 mother_id = atoi(cursor);
383 if( mother_id > 0 && mother_id <= (
int)evt.
particles().size() ) {
385 GenParticlePtr mother = evt.
particles()[ mother_id-1 ];
386 GenVertexPtr vertex = mother->end_vertex();
390 vertex = make_shared<GenVertex>();
391 vertex->add_particle_in(mother);
394 vertex->add_particle_out(data);
400 else if( mother_id < 0 )
404 for (
auto v: evt.
vertices())
if (v->id()==mother_id) {v->add_particle_out(data); found=
true;
break; }
415 if( !(cursor = strchr(cursor+1,
' ')) )
return false;
416 data->set_pid( atoi(cursor) );
419 if( !(cursor = strchr(cursor+1,
' ')) )
return false;
420 momentum.setPx(atof(cursor));
423 if( !(cursor = strchr(cursor+1,
' ')) )
return false;
424 momentum.setPy(atof(cursor));
427 if( !(cursor = strchr(cursor+1,
' ')) )
return false;
428 momentum.setPz(atof(cursor));
431 if( !(cursor = strchr(cursor+1,
' ')) )
return false;
432 momentum.setE(atof(cursor));
433 data->set_momentum(momentum);
436 if( !(cursor = strchr(cursor+1,
' ')) )
return false;
437 data->set_generated_mass( atof(cursor) );
440 if( !(cursor = strchr(cursor+1,
' ')) )
return false;
441 data->set_status( atoi(cursor) );
445 HEPMC3_DEBUG( 10,
"ReaderAscii: P: "<<data->id()<<
" ( mother: "<<mother_id<<
", pid: "<<data->pid()<<
")" )
452 const char *cursor = buf;
453 const char *cursor2 = buf;
457 if( !(cursor = strchr(cursor+1,
' ')) )
return false;
460 if( !(cursor = strchr(cursor+1,
' ')) )
return false;
463 if( !(cursor2 = strchr(cursor,
' ')) )
return false;
464 sprintf(name,
"%.*s", (
int)(cursor2-cursor), cursor);
468 shared_ptr<Attribute> att =
477 const char *cursor = buf;
478 const char *cursor2 = buf;
481 if( !(cursor = strchr(cursor+1,
' ')) )
return false;
484 if( !(cursor2 = strchr(cursor,
' ')) )
return false;
485 sprintf(name,
"%.*s", (
int)(cursor2-cursor), cursor);
489 shared_ptr<StringAttribute> att =
492 run_info()->add_attribute(
string(name), att);
500 const char *cursor = buf;
502 if( !(cursor = strchr(cursor+1,
' ')) )
return false;
505 istringstream iss(
unescape(cursor));
506 vector<string> names;
508 while ( iss >> name ) names.push_back(name);
510 run_info()->set_weight_names(names);
517 const char *cursor = buf;
519 if( !(cursor = strchr(cursor+1,
' ')) )
return false;
523 string::size_type pos = line.find(
"\n");
524 tool.
name = line.substr(0, pos);
525 line = line.substr(pos + 1);
526 pos = line.find(
"\n");
527 tool.
version = line.substr(0, pos);
529 run_info()->tools().push_back(tool);
538 ret.reserve(s.length());
539 for ( string::const_iterator it = s.begin(); it != s.end(); ++it ) {
556 if( !
m_file.is_open())
return;
void set_run_info(shared_ptr< GenRunInfo > run)
Set the GenRunInfo object by smart pointer.
const std::vector< ConstGenVertexPtr > & vertices() const
Get list of vertices (const)
bool parse_run_attribute(const char *buf)
Parse run-level attribute.
ReaderAscii(const std::string &filename)
Constructor.
bool parse_units(GenEvent &evt, const char *buf)
Parse units.
#define HEPMC3_WARNING(MESSAGE)
Macro for printing HEPMC3_HEPMC3_WARNING messages.
void add_vertex(GenVertexPtr v)
Add vertex.
static LengthUnit length_unit(const std::string &name)
Get length unit based on its name.
bool parse_tool(const char *buf)
Parse run-level tool information.
bool read_event(GenEvent &evt) override
Load event from file.
Definition of class GenParticle.
std::pair< int, int > parse_event_information(GenEvent &evt, const char *buf)
Parse event.
std::ifstream m_file
Input file.
std::map< GenVertexPtr, std::set< int > > m_forward_mothers
Temp storage for outgoing particle ids.
Definition of class GenVertex.
#define HEPMC3_DEBUG(LEVEL, MESSAGE)
Macro for printing debug messages with appropriate debug level.
const Units::LengthUnit & length_unit() const
Get length unit.
Attribute that holds a string.
void add_particle(GenParticlePtr p)
Add particle.
static std::string name(MomentumUnit u)
Get name of momentum unit.
bool parse_weight_names(const char *buf)
Parse run-level weight names.
bool parse_attribute(GenEvent &evt, const char *buf)
Parse attribute.
shared_ptr< GenRunInfo > run_info() const
Get the global GenRunInfo object.
LengthUnit
Position units.
MomentumUnit
Momentum units.
const Units::MomentumUnit & momentum_unit() const
Get momentum unit.
Stores event-related information.
std::istream * m_stream
For ctor when reading from stdin.
bool failed() override
Return status of the stream.
Definition of class ReaderAscii.
Definition of class Units.
bool skip(const int) override
skip events
static MomentumUnit momentum_unit(const std::string &name)
Get momentum unit based on its name.
std::map< GenParticlePtr, int > m_forward_daughters
Temp storage for prod vertex ids.
bool m_isstream
toggles usage of m_file or m_stream
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 add_attribute(const string &name, const shared_ptr< Attribute > &att, const int &id=0)
Add event attribute to event.
void set_run_info(shared_ptr< GenRunInfo > run)
Set the global GenRunInfo object.
bool parse_vertex_information(GenEvent &evt, const char *buf)
Parse vertex.
#define HEPMC3_ERROR(MESSAGE)
Macro for printing error messages.
const std::vector< double > & weights() const
Get event weight values as a vector.
std::string unescape(const std::string &s)
Unsecape '\' and ' ' characters in string.
Definition of class GenEvent.
bool parse_particle_information(GenEvent &evt, const char *buf)
Parse particle.
~ReaderAscii()
Destructor.
void close() override
Close file stream.
void clear()
Remove contents of this event.
const std::vector< ConstGenParticlePtr > & particles() const
Get list of particles (const)
bool parse_weight_values(GenEvent &evt, const char *buf)
Parse weight value lines.
void set_event_number(const int &num)
Set event number.
void shift_position_to(const FourVector &newpos)
Shift position of all vertices in the event to op.