HepMC3 event record library
ReaderAsciiHepMC2.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // This file is part of HepMC
4 // Copyright (C) 2014-2019 The HepMC collaboration (see AUTHORS for details)
5 //
6 /**
7  * @file ReaderAsciiHepMC2.cc
8  * @brief Implementation of \b class ReaderAsciiHepMC2
9  *
10  */
12 
13 #include "HepMC3/GenEvent.h"
14 #include "HepMC3/GenVertex.h"
15 #include "HepMC3/GenParticle.h"
16 #include "HepMC3/GenHeavyIon.h"
17 #include "HepMC3/GenPdfInfo.h"
18 #include "HepMC3/Setup.h"
19 #include <cstring>
20 #include <cstdlib>
21 namespace HepMC3 {
22 
23 ReaderAsciiHepMC2::ReaderAsciiHepMC2(const std::string& filename):
24  m_file(filename), m_stream(0), m_isstream(false) {
25  if( !m_file.is_open() ) {
26  HEPMC3_ERROR( "ReaderAsciiHepMC2: could not open input file: "<<filename )
27  }
28  set_run_info(make_shared<GenRunInfo>());
29  m_event_ghost= new GenEvent();
30 }
31 // Ctor for reading from stdin
33  : m_stream(&stream), m_isstream(true)
34 {
35  if( !m_stream->good() ) {
36  HEPMC3_ERROR( "ReaderAsciiHepMC2: could not open input stream " )
37  }
38  set_run_info(make_shared<GenRunInfo>());
39  m_event_ghost= new GenEvent();
40 }
41 
43 
44 bool ReaderAsciiHepMC2::skip(const int n)
45 {
46  const size_t max_buffer_size=512*512;
47  char buf[max_buffer_size];
48  int nn=n;
49  char peek;
50  while(!failed()) {
51  if ( (!m_file.is_open()) && (!m_isstream) ) return false;
52  m_isstream ? peek = m_stream->peek() : peek = m_file.peek();
53  if( peek=='E' ) nn--;
54  if (nn<0) return true;
55  m_isstream ? m_stream->getline(buf,max_buffer_size) : m_file.getline(buf,max_buffer_size);
56  }
57  return true;
58 }
59 
61  if ( (!m_file.is_open()) && (!m_isstream) ) return false;
62 
63  char peek;
64  const size_t max_buffer_size=512*512;
65  const size_t max_weights_size=256;
66  char buf[max_buffer_size];
67  bool parsed_event_header = false;
68  bool is_parsing_successful = true;
69  int parsing_result = 0;
70  unsigned int vertices_count = 0;
71  unsigned int current_vertex_particles_count = 0;
72  unsigned int current_vertex_particles_parsed= 0;
73 
74  evt.clear();
75  evt.set_run_info(run_info());
76 
77  // Empty cache
78  m_vertex_cache.clear();
79  m_vertex_barcodes.clear();
80 
81  m_particle_cache.clear();
82  m_end_vertex_barcodes.clear();
83  m_particle_cache_ghost.clear();
84  //
85  // Parse event, vertex and particle information
86  //
87  while(!failed()) {
88  m_isstream ? m_stream->getline(buf,max_buffer_size) : m_file.getline(buf,max_buffer_size);
89  if( strlen(buf) == 0 ) continue;
90  // Check for IO_GenEvent header/footer
91  if( strncmp(buf,"HepMC",5) == 0 ) {
92  if( strncmp(buf,"HepMC::Version",14) != 0 && strncmp(buf,"HepMC::IO_GenEvent",18)!=0 )
93  {
94  HEPMC3_WARNING( "ReaderAsciiHepMC2: found unsupported expression in header. Will close the input." )
95  std::cout<<buf<<std::endl;
96  m_isstream ? m_stream->clear(ios::eofbit) : m_file.clear(ios::eofbit);
97  }
98  if(parsed_event_header) {
99  is_parsing_successful = true;
100  break;
101  }
102  continue;
103  }
104  switch(buf[0]) {
105  case 'E':
106  parsing_result = parse_event_information(evt,buf);
107  if(parsing_result<0) {
108  is_parsing_successful = false;
109  HEPMC3_ERROR( "ReaderAsciiHepMC2: HEPMC3_ERROR parsing event information" )
110  }
111  else {
112  vertices_count = parsing_result;
113  m_vertex_cache.reserve(vertices_count);
114  m_particle_cache.reserve(vertices_count*3);
115  m_vertex_barcodes.reserve(vertices_count);
116  m_end_vertex_barcodes.reserve(vertices_count*3);
117  is_parsing_successful = true;
118  }
119  parsed_event_header = true;
120  break;
121  case 'V':
122  // If starting new vertex: verify if previous was fully parsed
123 
124  /** @bug HepMC2 files produced with Pythia8 are known to have wrong
125  information about number of particles in vertex. Hence '<' sign */
126  if(current_vertex_particles_parsed < current_vertex_particles_count) {
127  is_parsing_successful = false;
128  break;
129  }
130  current_vertex_particles_parsed = 0;
131 
132  parsing_result = parse_vertex_information(buf);
133 
134  if(parsing_result<0) {
135  is_parsing_successful = false;
136  HEPMC3_ERROR( "ReaderAsciiHepMC2: HEPMC3_ERROR parsing vertex information" )
137  }
138  else {
139  current_vertex_particles_count = parsing_result;
140  is_parsing_successful = true;
141  }
142  break;
143  case 'P':
144 
145  parsing_result = parse_particle_information(buf);
146 
147  if(parsing_result<0) {
148  is_parsing_successful = false;
149  HEPMC3_ERROR( "ReaderAsciiHepMC2: HEPMC3_ERROR parsing particle information" )
150  }
151  else {
152  ++current_vertex_particles_parsed;
153  is_parsing_successful = true;
154  }
155  break;
156  case 'U':
157  is_parsing_successful = parse_units(evt,buf);
158  break;
159  case 'F':
160  is_parsing_successful = parse_pdf_info(evt,buf);
161  break;
162  case 'H':
163  is_parsing_successful = parse_heavy_ion(evt,buf);
164  break;
165  case 'N':
166  is_parsing_successful = parse_weight_names(buf);
167  break;
168  case 'C':
169  is_parsing_successful = parse_xs_info(evt,buf);
170  break;
171  default:
172  HEPMC3_WARNING( "ReaderAsciiHepMC2: skipping unrecognised prefix: " << buf[0] )
173  is_parsing_successful = true;
174  break;
175  }
176 
177  if( !is_parsing_successful ) break;
178 
179  // Check for next event
180  m_isstream ? peek = m_stream->peek() : peek = m_file.peek();
181  if( parsed_event_header && peek=='E' ) break;
182  }
183 
184  // Check if all particles in last vertex were parsed
185  /** @bug HepMC2 files produced with Pythia8 are known to have wrong
186  information about number of particles in vertex. Hence '<' sign */
187  if( is_parsing_successful && current_vertex_particles_parsed < current_vertex_particles_count ) {
188  HEPMC3_ERROR( "ReaderAsciiHepMC2: not all particles parsed" )
189  is_parsing_successful = false;
190  }
191  // Check if all vertices were parsed
192  else if( is_parsing_successful && m_vertex_cache.size() != vertices_count ) {
193  HEPMC3_ERROR( "ReaderAsciiHepMC2: not all vertices parsed" )
194  is_parsing_successful = false;
195  }
196 
197  if( !is_parsing_successful ) {
198  HEPMC3_ERROR( "ReaderAsciiHepMC2: event parsing failed. Returning empty event" )
199  HEPMC3_DEBUG( 1, "Parsing failed at line:" << std::endl << buf )
200  evt.clear();
201  m_isstream ? m_stream->clear(ios::badbit) : m_file.clear(ios::badbit);
202  return 0;
203  }
204 
205  // Restore production vertex pointers
206  for(unsigned int i=0; i<m_particle_cache.size(); ++i) {
207  if( !m_end_vertex_barcodes[i] ) continue;
208 
209  for(unsigned int j=0; j<m_vertex_cache.size(); ++j) {
211  m_vertex_cache[j]->add_particle_in(m_particle_cache[i]);
212  break;
213  }
214  }
215  }
216 
217  // Remove vertices with no incoming particles or no outgoing particles
218  for(unsigned int i=0; i<m_vertex_cache.size(); ++i) {
219  if( m_vertex_cache[i]->particles_in().size() == 0 ) {
220  m_vertex_cache[i] = nullptr;
221  }
222  else if( m_vertex_cache[i]->particles_out().size() == 0 ) {
223  m_vertex_cache[i] = nullptr;
224  }
225  }
226 
227  // Reserve memory for the event
228  evt.reserve( m_particle_cache.size(), m_vertex_cache.size() );
229 
230  // Add whole event tree in topological order
231  evt.add_tree( m_particle_cache );
232 
233  for(unsigned int i=0; i<m_particle_cache.size(); ++i) {
234  if(m_particle_cache_ghost[i]->attribute_names().size())
235  {
236  shared_ptr<DoubleAttribute> phi = m_particle_cache_ghost[i]->attribute<DoubleAttribute>("phi");
237  if (phi) m_particle_cache[i]->add_attribute("phi",phi);
238  shared_ptr<DoubleAttribute> theta = m_particle_cache_ghost[i]->attribute<DoubleAttribute>("theta");
239  if (theta) m_particle_cache[i]->add_attribute("theta",theta);
240  shared_ptr<IntAttribute> flow1 = m_particle_cache_ghost[i]->attribute<IntAttribute>("flow1");
241  if (m_options.find("particle_flows_are_separated")!=m_options.end())
242  {
243  if (flow1) m_particle_cache[i]->add_attribute("flow1",flow1);
244  shared_ptr<IntAttribute> flow2 = m_particle_cache_ghost[i]->attribute<IntAttribute>("flow2");
245  if (flow2) m_particle_cache[i]->add_attribute("flow2",flow2);
246  shared_ptr<IntAttribute> flow3 = m_particle_cache_ghost[i]->attribute<IntAttribute>("flow3");
247  if (flow3) m_particle_cache[i]->add_attribute("flow3",flow3);
248  }
249  else
250  {
251  shared_ptr<VectorIntAttribute> flows = m_particle_cache_ghost[i]->attribute<VectorIntAttribute>("flows");
252  if (flows) m_particle_cache[i]->add_attribute("flows",flows);
253  }
254  }
255  }
256 
257  for(unsigned int i=0; i<m_vertex_cache.size(); ++i)
258  if(m_vertex_cache_ghost[i]->attribute_names().size())
259  {
260  for (size_t ii=0; ii<max_weights_size; ii++)
261  {
262  shared_ptr<DoubleAttribute> rs=m_vertex_cache_ghost[i]->attribute<DoubleAttribute>("weight"+to_string((long long unsigned int)ii));
263  if (!rs) break;
264  m_vertex_cache[i]->add_attribute("weight"+to_string((long long unsigned int)ii),rs);
265  }
266  }
267  m_particle_cache_ghost.clear();
268  m_vertex_cache_ghost.clear();
269  m_event_ghost->clear();
270  return 1;
271 }
272 
274  const char *cursor = buf;
275  int event_no = 0;
276  int vertices_count = 0;
277  int random_states_size = 0;
278  int weights_size = 0;
279  std::vector<long> random_states(0);
280  std::vector<double> weights(0);
281 
282  // event number
283  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
284  event_no = atoi(cursor);
285  evt.set_event_number(event_no);
286 
287  //mpi
288  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
289  shared_ptr<IntAttribute> mpi = make_shared<IntAttribute>(atoi(cursor));
290  evt.add_attribute("mpi",mpi);
291 
292  //event scale
293  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
294  shared_ptr<DoubleAttribute> event_scale = make_shared<DoubleAttribute>(atof(cursor));
295  evt.add_attribute("event_scale",event_scale);
296 
297  //alpha_qcd
298  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
299  shared_ptr<DoubleAttribute> alphaQCD = make_shared<DoubleAttribute>(atof(cursor));
300  evt.add_attribute("alphaQCD",alphaQCD);
301 
302  //alpha_qed
303  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
304  shared_ptr<DoubleAttribute> alphaQED = make_shared<DoubleAttribute>(atof(cursor));
305  evt.add_attribute("alphaQED",alphaQED);
306 
307  //signal_process_id
308  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
309  shared_ptr<IntAttribute> signal_process_id = make_shared<IntAttribute>(atoi(cursor));
310  evt.add_attribute("signal_process_id",signal_process_id);
311 
312  //signal_process_vertex
313  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
314  shared_ptr<IntAttribute> signal_process_vertex = make_shared<IntAttribute>(atoi(cursor));
315  evt.add_attribute("signal_process_vertex",signal_process_vertex);
316 
317  // num_vertices
318  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
319  vertices_count = atoi(cursor);
320 
321  // SKIPPED: beam 1
322  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
323 
324  // SKIPPED: beam 2
325  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
326 
327  //random states
328  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
329  random_states_size = atoi(cursor);
330  random_states.resize(random_states_size);
331 
332  for ( int i = 0; i < random_states_size; ++i ) {
333  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
334  random_states[i] = atoi(cursor);
335  }
336  if (m_options.find("event_random_states_are_separated")!=m_options.end())
337  {
338  evt.add_attribute("random_states",make_shared<VectorLongIntAttribute>(random_states));
339  }
340  else
341  {
342  for ( int i = 0; i < random_states_size; ++i )
343  evt.add_attribute("random_states"+to_string((long long unsigned int)i),make_shared<IntAttribute>(random_states[i]));
344  }
345  // weights
346  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
347  weights_size = atoi(cursor);
348  weights.resize(weights_size);
349 
350  for ( int i = 0; i < weights_size; ++i ) {
351  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
352  weights[i] = atof(cursor);
353  }
354 
355  evt.weights() = weights;
356 
357  HEPMC3_DEBUG( 10, "ReaderAsciiHepMC2: E: "<<event_no<<" ("<<vertices_count<<"V, "<<weights_size<<"W, "<<random_states_size<<"RS)" )
358 
359  return vertices_count;
360 }
361 
362 bool ReaderAsciiHepMC2::parse_units(GenEvent &evt, const char *buf) {
363  const char *cursor = buf;
364 
365  // momentum
366  if( !(cursor = strchr(cursor+1,' ')) ) return false;
367  ++cursor;
368  Units::MomentumUnit momentum_unit = Units::momentum_unit(cursor);
369 
370  // length
371  if( !(cursor = strchr(cursor+1,' ')) ) return false;
372  ++cursor;
373  Units::LengthUnit length_unit = Units::length_unit(cursor);
374 
375  evt.set_units(momentum_unit,length_unit);
376 
377  HEPMC3_DEBUG( 10, "ReaderAsciiHepMC2: U: " << Units::name(evt.momentum_unit()) << " " << Units::name(evt.length_unit()) )
378 
379  return true;
380 }
381 
383  GenVertexPtr data = make_shared<GenVertex>();
384  GenVertexPtr data_ghost = make_shared<GenVertex>();
385  FourVector position;
386  const char *cursor = buf;
387  int barcode = 0;
388  int num_particles_out = 0;
389  int weights_size = 0;
390  std::vector<double> weights(0);
391  // barcode
392  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
393  barcode = atoi(cursor);
394 
395  // status
396  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
397  data->set_status( atoi(cursor) );
398 
399  // x
400  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
401  position.setX(atof(cursor));
402 
403  // y
404  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
405  position.setY(atof(cursor));
406 
407  // z
408  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
409  position.setZ(atof(cursor));
410 
411  // t
412  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
413  position.setT(atof(cursor));
414  data->set_position( position );
415 
416  // SKIPPED: num_orphans_in
417  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
418 
419  // num_particles_out
420  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
421  num_particles_out = atoi(cursor);
422 
423  // weights
424 
425  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
426  weights_size = atoi(cursor);
427  weights.resize(weights_size);
428 
429  for ( int i = 0; i < weights_size; ++i ) {
430  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
431  weights[i] = atof(cursor);
432  }
433 
434 
435 
436  // Add original vertex barcode to the cache
437  m_vertex_cache.push_back( data );
438  m_vertex_barcodes.push_back( barcode );
439 
440  m_event_ghost->add_vertex(data_ghost);
441  if (m_options.find("vertex_weights_are_separated")!=m_options.end())
442  {
443  for ( int i = 0; i < weights_size; ++i )
444  data_ghost->add_attribute("weight"+to_string((long long unsigned int)i),make_shared<DoubleAttribute>(weights[i]));
445  }
446  else
447  {
448  data_ghost->add_attribute("weights",make_shared<VectorDoubleAttribute>(weights));
449  }
450  m_vertex_cache_ghost.push_back( data_ghost );
451 
452  HEPMC3_DEBUG( 10, "ReaderAsciiHepMC2: V: "<<-(int)m_vertex_cache.size()<<" (old barcode"<<barcode<<") "<<num_particles_out<<" particles)" )
453 
454  return num_particles_out;
455 }
456 
458  GenParticlePtr data = make_shared<GenParticle>();
459  GenParticlePtr data_ghost = make_shared<GenParticle>();
460  m_event_ghost->add_particle(data_ghost);
461  FourVector momentum;
462  const char *cursor = buf;
463  int end_vtx = 0;
464 
465  /// @note barcode is ignored
466  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
467 
468  // id
469  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
470  data->set_pid( atoi(cursor) );
471 
472  // px
473  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
474  momentum.setPx(atof(cursor));
475 
476  // py
477  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
478  momentum.setPy(atof(cursor));
479 
480  // pz
481  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
482  momentum.setPz(atof(cursor));
483 
484  // pe
485  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
486  momentum.setE(atof(cursor));
487  data->set_momentum(momentum);
488 
489  // m
490  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
491  data->set_generated_mass( atof(cursor) );
492 
493  // status
494  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
495  data->set_status( atoi(cursor) );
496 
497  //theta
498  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
499  shared_ptr<DoubleAttribute> theta = make_shared<DoubleAttribute>(atof(cursor));
500  if (theta->value()!=0.0) data_ghost->add_attribute("theta",theta);
501 
502  //phi
503  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
504  shared_ptr<DoubleAttribute> phi = make_shared<DoubleAttribute>(atof(cursor));
505  if (phi->value()!=0.0) data_ghost->add_attribute("phi",phi);
506 
507  // end_vtx_code
508  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
509  end_vtx = atoi(cursor);
510 
511  //flow
512  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
513  int flowsize=atoi(cursor);
514 
515  std::map<int,int> flows;
516  for (int i=0; i<flowsize; i++)
517  {
518  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
519  int flowindex=atoi(cursor);
520  if( !(cursor = strchr(cursor+1,' ')) ) return -1;
521  int flowvalue=atoi(cursor);
522  flows[flowindex]=flowvalue;
523  }
524  if (m_options.find("particle_flows_are_separated")!=m_options.end())
525  {
526  std::vector<int> vectorflows;
527  for (auto f: flows) vectorflows.push_back(f.second);
528  data_ghost->add_attribute("flows",make_shared<VectorIntAttribute>(vectorflows));
529  }
530  else
531  {
532  for (auto f: flows) data_ghost->add_attribute("flow"+to_string((long long int)f.first),make_shared<IntAttribute>(f.second));
533  }
534 // Set prod_vtx link
535  if( end_vtx == m_vertex_barcodes.back() ) {
536  m_vertex_cache.back()->add_particle_in(data);
537  end_vtx = 0;
538  }
539  else {
540  m_vertex_cache.back()->add_particle_out(data);
541  }
542 
543  m_particle_cache.push_back( data );
544  m_particle_cache_ghost.push_back( data_ghost );
545  m_end_vertex_barcodes.push_back( end_vtx );
546 
547  HEPMC3_DEBUG( 10, "ReaderAsciiHepMC2: P: "<<m_particle_cache.size()<<" ( pid: "<<data->pid()<<") end vertex: "<<end_vtx )
548 
549  return 0;
550 }
551 
552 bool ReaderAsciiHepMC2::parse_xs_info(GenEvent &evt, const char *buf) {
553  const char *cursor = buf;
554  shared_ptr<GenCrossSection> xs = make_shared<GenCrossSection>();
555 
556  if( !(cursor = strchr(cursor+1,' ')) ) return false;
557  double xs_val = atof(cursor);
558 
559  if( !(cursor = strchr(cursor+1,' ')) ) return false;
560  double xs_err = atof(cursor);
561 
562  xs->set_cross_section( xs_val , xs_err);
563  evt.add_attribute("GenCrossSection",xs);
564 
565  return true;
566 }
567 
569  const char *cursor = buf;
570  const char *cursor2 = buf;
571  int w_count = 0;
572  vector<string> w_names;
573 
574  // Ignore weight names if no GenRunInfo object
575  if( !run_info() ) return true;
576 
577  if( !(cursor = strchr(cursor+1,' ')) ) return false;
578  w_count = atoi(cursor);
579 
580  if( w_count <= 0 ) return false;
581 
582  w_names.resize(w_count);
583 
584  for( int i=0; i < w_count; ++i ) {
585  // Find pair of '"' characters
586  if( !(cursor = strchr(cursor+1,'"')) ) return false;
587  if( !(cursor2 = strchr(cursor+1,'"')) ) return false;
588 
589  // Strip cursor of leading '"' character
590  ++cursor;
591 
592  w_names[i].assign(cursor, cursor2-cursor);
593 
594  cursor = cursor2;
595  }
596 
597  run_info()->set_weight_names(w_names);
598 
599  return true;
600 }
601 
602 bool ReaderAsciiHepMC2::parse_heavy_ion(GenEvent &evt, const char *buf) {
603  shared_ptr<GenHeavyIon> hi = make_shared<GenHeavyIon>();
604  const char *cursor = buf;
605 
606  if( !(cursor = strchr(cursor+1,' ')) ) return false;
607  hi->Ncoll_hard = atoi(cursor);
608 
609  if( !(cursor = strchr(cursor+1,' ')) ) return false;
610  hi->Npart_proj = atoi(cursor);
611 
612  if( !(cursor = strchr(cursor+1,' ')) ) return false;
613  hi->Npart_targ = atoi(cursor);
614 
615  if( !(cursor = strchr(cursor+1,' ')) ) return false;
616  hi->Ncoll = atoi(cursor);
617 
618  if( !(cursor = strchr(cursor+1,' ')) ) return false;
619  hi->spectator_neutrons = atoi(cursor);
620 
621  if( !(cursor = strchr(cursor+1,' ')) ) return false;
622  hi->spectator_protons = atoi(cursor);
623 
624  if( !(cursor = strchr(cursor+1,' ')) ) return false;
625  hi->N_Nwounded_collisions = atoi(cursor);
626 
627  if( !(cursor = strchr(cursor+1,' ')) ) return false;
628  hi->Nwounded_N_collisions = atoi(cursor);
629 
630  if( !(cursor = strchr(cursor+1,' ')) ) return false;
631  hi->Nwounded_Nwounded_collisions = atoi(cursor);
632 
633  if( !(cursor = strchr(cursor+1,' ')) ) return false;
634  hi->impact_parameter = atof(cursor);
635 
636  if( !(cursor = strchr(cursor+1,' ')) ) return false;
637  hi->event_plane_angle = atof(cursor);
638 
639  if( !(cursor = strchr(cursor+1,' ')) ) return false;
640  hi->eccentricity = atof(cursor);
641 
642  if( !(cursor = strchr(cursor+1,' ')) ) return false;
643  hi->sigma_inel_NN = atof(cursor);
644 
645  // Not in HepMC2:
646  hi->centrality = 0.0;
647 
648  evt.add_attribute("GenHeavyIon",hi);
649 
650  return true;
651 }
652 
653 bool ReaderAsciiHepMC2::parse_pdf_info(GenEvent &evt, const char *buf) {
654  shared_ptr<GenPdfInfo> pi = make_shared<GenPdfInfo>();
655  const char *cursor = buf;
656 
657  if( !(cursor = strchr(cursor+1,' ')) ) return false;
658  pi->parton_id[0] = atoi(cursor);
659 
660  if( !(cursor = strchr(cursor+1,' ')) ) return false;
661  pi->parton_id[1] = atoi(cursor);
662 
663  if( !(cursor = strchr(cursor+1,' ')) ) return false;
664  pi->x[0] = atof(cursor);
665 
666  if( !(cursor = strchr(cursor+1,' ')) ) return false;
667  pi->x[1] = atof(cursor);
668 
669  if( !(cursor = strchr(cursor+1,' ')) ) return false;
670  pi->scale = atof(cursor);
671 
672  if( !(cursor = strchr(cursor+1,' ')) ) return false;
673  pi->xf[0] = atof(cursor);
674 
675  if( !(cursor = strchr(cursor+1,' ')) ) return false;
676  pi->xf[1] = atof(cursor);
677 
678  //For compatibility with original HepMC2
679  bool pdfids=true;
680  if( !(cursor = strchr(cursor+1,' ')) ) pdfids=false;
681  if(pdfids) pi->pdf_id[0] = atoi(cursor);
682  else pi->pdf_id[0] =0;
683 
684  if(pdfids) if( !(cursor = strchr(cursor+1,' ')) ) pdfids=false;
685  if(pdfids) pi->pdf_id[1] = atoi(cursor);
686  else pi->pdf_id[1] =0;
687 
688  evt.add_attribute("GenPdfInfo",pi);
689 
690  return true;
691 }
692 bool ReaderAsciiHepMC2::failed() { return m_isstream ? (bool)m_stream->rdstate() :(bool)m_file.rdstate(); }
693 
695  if (m_event_ghost) { m_event_ghost->clear(); delete m_event_ghost; m_event_ghost=nullptr;}
696  if( !m_file.is_open() ) return;
697  m_file.close();
698 }
699 
700 } // namespace HepMC3
HepMC3::Units::momentum_unit
static MomentumUnit momentum_unit(const std::string &name)
Get momentum unit based on its name.
Definition: Units.h:36
HepMC3::FourVector
Generic 4-vector.
Definition: FourVector.h:35
HepMC3::ReaderAsciiHepMC2::parse_event_information
int parse_event_information(GenEvent &evt, const char *buf)
Parse event.
Definition: ReaderAsciiHepMC2.cc:273
GenEvent.h
Definition of class GenEvent.
HepMC3::ReaderAsciiHepMC2::parse_xs_info
bool parse_xs_info(GenEvent &evt, const char *buf)
Parse pdf information.
Definition: ReaderAsciiHepMC2.cc:552
HepMC3::ReaderAsciiHepMC2::close
void close() override
Close file stream.
Definition: ReaderAsciiHepMC2.cc:694
HepMC3::Units::length_unit
static LengthUnit length_unit(const std::string &name)
Get length unit based on its name.
Definition: Units.h:46
HepMC3::ReaderAsciiHepMC2::parse_units
bool parse_units(GenEvent &evt, const char *buf)
Parse units.
Definition: ReaderAsciiHepMC2.cc:362
HepMC3::ReaderAsciiHepMC2::skip
bool skip(const int) override
skip events
Definition: ReaderAsciiHepMC2.cc:44
HepMC3::ReaderAsciiHepMC2::failed
bool failed() override
Return status of the stream.
Definition: ReaderAsciiHepMC2.cc:692
HepMC3::GenEvent
Stores event-related information.
Definition: GenEvent.h:41
HepMC3::ReaderAsciiHepMC2::m_end_vertex_barcodes
vector< int > m_end_vertex_barcodes
Old end vertex barcodes.
Definition: ReaderAsciiHepMC2.h:138
HepMC3::GenEvent::add_vertex
void add_vertex(GenVertexPtr v)
Add vertex.
Definition: GenEvent.cc:98
HepMC3::Reader::m_options
std::map< std::string, std::string > m_options
options
Definition: Reader.h:68
GenVertex.h
Definition of class GenVertex.
HepMC3
HepMC3 main namespace.
Definition: AnalysisExample.h:18
HepMC3::Units::MomentumUnit
MomentumUnit
Momentum units.
Definition: Units.h:29
HepMC3::ReaderAsciiHepMC2::m_event_ghost
GenEvent * m_event_ghost
To save particle and verstex attributes.
Definition: ReaderAsciiHepMC2.h:140
HepMC3::ReaderAsciiHepMC2::m_vertex_barcodes
vector< int > m_vertex_barcodes
Old vertex barcodes.
Definition: ReaderAsciiHepMC2.h:135
HepMC3::GenEvent::clear
void clear()
Remove contents of this event.
Definition: GenEvent.cc:609
HepMC3::GenEvent::momentum_unit
const Units::MomentumUnit & momentum_unit() const
Get momentum unit.
Definition: GenEvent.h:140
HepMC3::FourVector::setX
void setX(double xx)
Definition: FourVector.h:84
HepMC3::GenEvent::reserve
void reserve(const size_t &particles, const size_t &vertices=0)
Reserve memory for particles and vertices.
Definition: GenEvent.cc:390
HepMC3::IntAttribute
Attribute that holds an Integer implemented as an int.
Definition: Attribute.h:158
HepMC3::ReaderAsciiHepMC2::~ReaderAsciiHepMC2
~ReaderAsciiHepMC2()
Destructor.
Definition: ReaderAsciiHepMC2.cc:42
HEPMC3_DEBUG
#define HEPMC3_DEBUG(LEVEL, MESSAGE)
Macro for printing debug messages with appropriate debug level.
Definition: Errors.h:32
HepMC3::GenEvent::set_run_info
void set_run_info(shared_ptr< GenRunInfo > run)
Set the GenRunInfo object by smart pointer.
Definition: GenEvent.h:128
HepMC3::ReaderAsciiHepMC2::m_stream
std::istream * m_stream
For ctor when reading from stdin.
Definition: ReaderAsciiHepMC2.h:131
GenHeavyIon.h
Definition of attribute class GenHeavyIon.
GenParticle.h
Definition of class GenParticle.
GenPdfInfo.h
Definition of event attribute class GenPdfInfo.
HepMC3::ReaderAsciiHepMC2::m_particle_cache
vector< GenParticlePtr > m_particle_cache
Particle cache.
Definition: ReaderAsciiHepMC2.h:137
HepMC3::GenEvent::set_event_number
void set_event_number(const int &num)
Set event number.
Definition: GenEvent.h:137
HepMC3::FourVector::setY
void setY(double yy)
Definition: FourVector.h:91
HepMC3::GenEvent::weights
const std::vector< double > & weights() const
Get event weight values as a vector.
Definition: GenEvent.h:86
HepMC3::ReaderAsciiHepMC2::m_vertex_cache_ghost
vector< GenVertexPtr > m_vertex_cache_ghost
Vertex cache for attributes.
Definition: ReaderAsciiHepMC2.h:142
HepMC3::FourVector::setZ
void setZ(double zz)
Definition: FourVector.h:98
HepMC3::FourVector::setT
void setT(double tt)
Definition: FourVector.h:105
ReaderAsciiHepMC2.h
Definition of class ReaderAsciiHepMC2.
HepMC3::ReaderAsciiHepMC2::parse_heavy_ion
bool parse_heavy_ion(GenEvent &evt, const char *buf)
Parse heavy ion information.
Definition: ReaderAsciiHepMC2.cc:602
HepMC3::ReaderAsciiHepMC2::parse_vertex_information
int parse_vertex_information(const char *buf)
Parse vertex.
Definition: ReaderAsciiHepMC2.cc:382
HepMC3::Units::name
static std::string name(MomentumUnit u)
Get name of momentum unit.
Definition: Units.h:56
HepMC3::ReaderAsciiHepMC2::m_vertex_cache
vector< GenVertexPtr > m_vertex_cache
Vertex cache.
Definition: ReaderAsciiHepMC2.h:134
HepMC3::GenEvent::add_attribute
void add_attribute(const string &name, const shared_ptr< Attribute > &att, const int &id=0)
Add event attribute to event.
Definition: GenEvent.h:208
HepMC3::GenEvent::add_tree
void add_tree(const std::vector< GenParticlePtr > &particles)
Add whole tree in topological order.
Definition: GenEvent.cc:268
HepMC3::ReaderAsciiHepMC2::ReaderAsciiHepMC2
ReaderAsciiHepMC2(const std::string &filename)
Default constructor.
Definition: ReaderAsciiHepMC2.cc:23
HepMC3::FourVector::setPz
void setPz(double pzz)
Definition: FourVector.h:127
HepMC3::GenEvent::length_unit
const Units::LengthUnit & length_unit() const
Get length unit.
Definition: GenEvent.h:142
HepMC3::FourVector::setE
void setE(double ee)
Definition: FourVector.h:134
HepMC3::DoubleAttribute
Attribute that holds a real number as a double.
Definition: Attribute.h:242
HepMC3::VectorIntAttribute
Attribute that holds a vector of integers of type int.
Definition: Attribute.h:1002
HepMC3::ReaderAsciiHepMC2::parse_particle_information
int parse_particle_information(const char *buf)
Parse particle.
Definition: ReaderAsciiHepMC2.cc:457
HepMC3::FourVector::setPy
void setPy(double pyy)
Definition: FourVector.h:120
HepMC3::ReaderAsciiHepMC2::m_isstream
bool m_isstream
toggles usage of m_file or m_stream
Definition: ReaderAsciiHepMC2.h:132
HepMC3::ReaderAsciiHepMC2::parse_weight_names
bool parse_weight_names(const char *buf)
Parse weight names.
Definition: ReaderAsciiHepMC2.cc:568
HEPMC3_ERROR
#define HEPMC3_ERROR(MESSAGE)
Macro for printing error messages.
Definition: Errors.h:23
HepMC3::ReaderAsciiHepMC2::m_particle_cache_ghost
vector< GenParticlePtr > m_particle_cache_ghost
Particle cache for attributes.
Definition: ReaderAsciiHepMC2.h:141
HepMC3::Reader::run_info
shared_ptr< GenRunInfo > run_info() const
Get the global GenRunInfo object.
Definition: Reader.h:44
HepMC3::ReaderAsciiHepMC2::m_file
std::ifstream m_file
Input file.
Definition: ReaderAsciiHepMC2.h:130
Setup.h
Definition of class Setup.
HepMC3::GenEvent::add_particle
void add_particle(GenParticlePtr p)
Add particle.
Definition: GenEvent.cc:50
HepMC3::GenEvent::set_units
void set_units(Units::MomentumUnit new_momentum_unit, Units::LengthUnit new_length_unit)
Change event units Converts event from current units to new ones.
Definition: GenEvent.cc:396
HEPMC3_WARNING
#define HEPMC3_WARNING(MESSAGE)
Macro for printing HEPMC3_HEPMC3_WARNING messages.
Definition: Errors.h:26
HepMC3::Reader::set_run_info
void set_run_info(shared_ptr< GenRunInfo > run)
Set the global GenRunInfo object.
Definition: Reader.h:64
HepMC3::ReaderAsciiHepMC2::parse_pdf_info
bool parse_pdf_info(GenEvent &evt, const char *buf)
Parse pdf information.
Definition: ReaderAsciiHepMC2.cc:653
HepMC3::ReaderAsciiHepMC2::read_event
bool read_event(GenEvent &evt) override
Implementation of Reader::read_event.
Definition: ReaderAsciiHepMC2.cc:60
HepMC3::Units::LengthUnit
LengthUnit
Position units.
Definition: Units.h:32
HepMC3::FourVector::setPx
void setPx(double pxx)
Definition: FourVector.h:113