HepMC3 event record library
ReaderAscii.cc
Go to the documentation of this file.
1// -*- C++ -*-
2//
3// This file is part of HepMC
4// Copyright (C) 2014-2023 The HepMC collaboration (see AUTHORS for details)
5//
6///
7/// @file ReaderAscii.cc
8/// @brief Implementation of \b class ReaderAscii
9///
10#include <array>
11#include <cstring>
12#include <sstream>
13
14#include "HepMC3/ReaderAscii.h"
15
16#include "HepMC3/GenEvent.h"
17#include "HepMC3/GenParticle.h"
18#include "HepMC3/GenVertex.h"
19#include "HepMC3/Units.h"
20
21namespace HepMC3 {
22
23
24ReaderAscii::ReaderAscii(const std::string &filename)
25 : m_file(filename), m_isstream(false)
26{
27 if ( !m_file.is_open() ) {
28 HEPMC3_ERROR_LEVEL(100,"ReaderAscii: could not open input file: " << filename)
29 }
30 set_run_info(std::make_shared<GenRunInfo>());
31}
32
33ReaderAscii::ReaderAscii(std::istream & stream)
34 : m_stream(&stream), m_isstream(true)
35{
36 if ( !m_stream->good() ) {
37 HEPMC3_ERROR_LEVEL(100,"ReaderAscii: could not open input stream ")
38 }
39 set_run_info(std::make_shared<GenRunInfo>());
40}
41
42
43ReaderAscii::ReaderAscii(std::shared_ptr<std::istream> s_stream)
44 : m_shared_stream(s_stream), m_stream(s_stream.get()), m_isstream(true)
45{
46 if ( !m_stream->good() ) {
47 HEPMC3_ERROR_LEVEL(100,"ReaderAscii: could not open input stream ")
48 }
49 set_run_info(std::make_shared<GenRunInfo>());
50}
51
53
54bool ReaderAscii::skip(const int n)
55{
56 std::array<char, 262144> buf{};
57 bool event_context = false;
58 bool run_info_context = false;
59 int nn = n;
60 while (!failed()) {
61 char peek(0);
62 if ( (!m_file.is_open()) && (!m_isstream) ) return false;
63 m_isstream ? peek = m_stream->peek() : peek = m_file.peek();
64 if ( peek == 'E' ) { event_context = true; nn--; }
65 //We have to read each run info.
66 if ( !event_context && ( peek == 'W' || peek == 'A' || peek == 'T' ) ) {
67 m_isstream ? m_stream->getline(buf.data(), buf.size()) : m_file.getline(buf.data(), buf.size());
68 if (!run_info_context) {
69 set_run_info(std::make_shared<GenRunInfo>());
70 run_info_context = true;
71 }
72 if ( peek == 'W' ) {
73 parse_weight_names(buf.data());
74 }
75 if ( peek == 'T' ) {
76 parse_tool(buf.data());
77 }
78 if ( peek == 'A' ) {
79 parse_run_attribute(buf.data());
80 }
81 }
82 if ( event_context && ( peek == 'V' || peek == 'P' ) ) event_context=false;
83 if (nn < 0) return true;
84 m_isstream ? m_stream->getline(buf.data(), buf.size()) : m_file.getline(buf.data(), buf.size());
85 }
86 return true;
87}
88
89
91 if ( (!m_file.is_open()) && (!m_isstream) ) return false;
92
93 char peek(0);
94 std::array<char, 262144> buf{};
95 bool event_context = false;
96 bool parsed_weights = false;
97 bool parsed_particles_or_vertices = false;
98 bool run_info_context = false;
99 bool is_parsing_successful = true;
100 std::pair<int, int> vertices_and_particles(0, 0);
101
102 evt.clear();
103 evt.set_run_info(run_info());
104 m_io_explicit.clear();
105 m_io_implicit.clear();
106 m_io_implicit_ids.clear();
107 m_io_explicit_ids.clear();
108 m_data.particles.clear();
109 m_data.vertices.clear();
110 m_data.links1.clear();
111 m_data.links2.clear();
112 m_data.attribute_id.clear();
113 m_data.attribute_name.clear();
114 m_data.attribute_string.clear();
115 //
116 // Parse event, vertex and particle information
117 //
118 while (!failed()) {
119 m_isstream ? m_stream->getline(buf.data(), buf.size()) : m_file.getline(buf.data(), buf.size());
120
121 if ( strlen(buf.data()) == 0 ) continue;
122
123 // Check for ReaderAscii header/footer
124 if ( strncmp(buf.data(), "HepMC", 5) == 0 ) {
125 if ( strncmp(buf.data(), "HepMC::Version", 14) != 0 && strncmp(buf.data(), "HepMC::Asciiv3", 14) != 0 )
126 {
127 HEPMC3_WARNING_LEVEL(500,"ReaderAscii: found unsupported expression in header. Will close the input.")
128 std::cout << buf.data() << std::endl;
129 m_isstream ? m_stream->clear(std::ios::eofbit) : m_file.clear(std::ios::eofbit);
130 }
131 if (event_context) {
132 is_parsing_successful = true;
133 break;
134 }
135 continue;
136 }
137
138 switch (buf[0]) {
139 case 'E':
140 vertices_and_particles = parse_event_information( buf.data());
141 if (vertices_and_particles.second < 0) {
142 is_parsing_successful = false;
143 } else {
144 is_parsing_successful = true;
145 event_context = true;
146 parsed_weights = false;
147 parsed_particles_or_vertices = false;
148 }
149
150
151 run_info_context = false;
152 break;
153 case 'V':
154 is_parsing_successful = parse_vertex_information( buf.data());
155 parsed_particles_or_vertices = true;
156 break;
157 case 'P':
158 is_parsing_successful = parse_particle_information( buf.data());
159 parsed_particles_or_vertices = true;
160 break;
161 case 'W':
162 if ( event_context ) {
163 is_parsing_successful = parse_weight_values( buf.data());
164 parsed_weights=true;
165 } else {
166 if ( !run_info_context ) {
167 set_run_info(std::make_shared<GenRunInfo>());
168 evt.set_run_info(run_info());
169 }
170 run_info_context = true;
171 is_parsing_successful = parse_weight_names(buf.data());
172 }
173 break;
174 case 'U':
175 is_parsing_successful = parse_units( buf.data());
176 break;
177 case 'T':
178 if ( event_context ) {
179 //We ignore T in the event context
180 } else {
181 if ( !run_info_context ) {
182 set_run_info(std::make_shared<GenRunInfo>());
183 evt.set_run_info(run_info());
184 }
185 run_info_context = true;
186 is_parsing_successful = parse_tool(buf.data());
187 }
188 break;
189 case 'A':
190 if ( event_context ) {
191 is_parsing_successful = parse_attribute( buf.data());
192 } else {
193 if ( !run_info_context ) {
194 set_run_info(std::make_shared<GenRunInfo>());
195 evt.set_run_info(run_info());
196 }
197 run_info_context = true;
198 is_parsing_successful = parse_run_attribute(buf.data());
199 }
200 break;
201 default:
202 HEPMC3_WARNING_LEVEL(500,"ReaderAscii: skipping unrecognised prefix: " << buf[0])
203 is_parsing_successful = true;
204 break;
205 }
206
207 if ( !is_parsing_successful ) break;
208
209 // Check for next event or run info
210 m_isstream ? peek = m_stream->peek() : peek = m_file.peek();
211 //End of event. The next entry is event.
212 if ( event_context && peek == 'E' ) break;
213
214 //End of event. The next entry is run info which starts from weight name.
215 if ( event_context && peek == 'W' && parsed_weights ) break;
216
217 //End of event. The next entry is run info which starts from attribute.
218 if ( event_context && peek == 'A' && parsed_particles_or_vertices ) break;
219
220 //End of event. The next entry is run info which starts from tool.
221 if ( event_context && peek == 'T' ) break;
222
223 }
224
225 /// Insert the implicit vertices in the gaps of explicit vertices:
226 /// Find the gaps looping over the explicit vertices
227 int currid = -static_cast<int>(m_data.vertices.size());
228 auto fir = m_io_implicit_ids.rbegin();
229 for (const auto& iofirst: m_io_explicit_ids) {
230 for (; currid < iofirst; ++currid, ++fir) {
231 if (fir == m_io_implicit_ids.rend()) {
232 HEPMC3_ERROR_LEVEL(600,"ReaderAscii: not enough implicit vertices")
233 }
234 /// Found a gap in ids, insert an implicit vertex into a list of gaps.
235 m_io_explicit[currid] = std::move(m_io_implicit[*fir]);
236 }
237 ++currid;
238 }
239
240 for (const auto& io: m_io_explicit) {
241 for (const auto& i: io.second.first) { m_data.links1.push_back(i); m_data.links2.push_back(io.first); }
242 for (const auto& o: io.second.second) { m_data.links1.push_back(io.first); m_data.links2.push_back(o); }
243 }
244 evt.read_data(m_data);
245
246 // Check if all particles and vertices were parsed
247 if (static_cast<int>(evt.particles().size()) > vertices_and_particles.second) {
248 HEPMC3_ERROR_LEVEL(600,"ReaderAscii: too many particles were parsed")
249 printf("%zu vs %i expected\n", evt.particles().size(), vertices_and_particles.second);
250 is_parsing_successful = false;
251 }
252 if (static_cast<int>(evt.particles().size()) < vertices_and_particles.second) {
253 HEPMC3_ERROR_LEVEL(600,"ReaderAscii: too few particles were parsed")
254 printf("%zu vs %i expected\n", evt.particles().size(), vertices_and_particles.second);
255 is_parsing_successful = false;
256 }
257
258 if (static_cast<int>(evt.vertices().size()) > vertices_and_particles.first) {
259 HEPMC3_ERROR_LEVEL(600,"ReaderAscii: too many vertices were parsed")
260 printf("%zu vs %i expected\n", evt.vertices().size(), vertices_and_particles.first);
261 is_parsing_successful = false;
262 }
263
264 if (static_cast<int>(evt.vertices().size()) < vertices_and_particles.first) {
265 HEPMC3_ERROR_LEVEL(600,"ReaderAscii: too few vertices were parsed")
266 printf("%zu vs %i expected\n", evt.vertices().size(), vertices_and_particles.first);
267 is_parsing_successful = false;
268 }
269 // Check if there were HEPMC3_ERRORs during parsing
270 if ( !is_parsing_successful ) {
271 HEPMC3_ERROR_LEVEL(600,"ReaderAscii: event parsing failed. Returning empty event")
272 HEPMC3_DEBUG(1, "Parsing failed at line:" << std::endl << buf.data())
273
274 evt.clear();
275 m_isstream ? m_stream->clear(std::ios::badbit) : m_file.clear(std::ios::badbit);
276
277 return false;
278 }
279
280
281 return true;
282}
283
284
285std::pair<int, int> ReaderAscii::parse_event_information(const char *buf) {
286 static const std::pair<int, int> err(-1, -1);
287 std::pair<int, int> ret(-1, -1);
288 const char *cursor = buf;
289 FourVector& position = m_data.event_pos;
290
291 // event number
292 if ( !(cursor = strchr(cursor+1, ' ')) ) return err;
293 m_data.event_number = atoi(cursor);
294
295 // num_vertices
296 if ( !(cursor = strchr(cursor+1, ' ')) ) return err;
297 ret.first = atoi(cursor);
298
299 // num_particles
300 if ( !(cursor = strchr(cursor+1, ' ')) ) return err;
301 ret.second = atoi(cursor);
302 m_data.vertices = std::vector<GenVertexData>(ret.first);
303 m_data.particles = std::vector<GenParticleData>(ret.second);
304
305 m_data.links1.reserve(ret.second*2);
306 m_data.links2.reserve(ret.second*2);
307 m_data.attribute_id.reserve(ret.second + ret.first);
308 m_data.attribute_name.reserve(ret.second + ret.first);
309 m_data.attribute_string.reserve(ret.second + ret.first);
310 m_io_implicit_ids.reserve(ret.second);
311 // check if there is position information
312 if ( (cursor = strchr(cursor+1, '@')) ) {
313 // x
314 if ( !(cursor = strchr(cursor+1, ' ')) ) return err;
315 position.setX(atof(cursor));
316
317 // y
318 if ( !(cursor = strchr(cursor+1, ' ')) ) return err;
319 position.setY(atof(cursor));
320
321 // z
322 if ( !(cursor = strchr(cursor+1, ' ')) ) return err;
323 position.setZ(atof(cursor));
324
325 // t
326 if ( !(cursor = strchr(cursor+1, ' ')) ) return err;
327 position.setT(atof(cursor));
328 }
329
330 HEPMC3_DEBUG(10, "ReaderAscii: E: " << m_data.event_number << " (" <<ret.first << "V, " << ret.second << "P)")
331
332 return ret;
333}
334
335
336bool ReaderAscii::parse_weight_values(const char *buf) {
337 std::istringstream iss(buf + 1);
338 std::vector<double> wts;
339 double w = 0.0;
340 while (iss >> w) wts.emplace_back(w);
341 if ( run_info() && !run_info()->weight_names().empty()
342 && run_info()->weight_names().size() != wts.size() ) {
343 throw std::logic_error("ReaderAscii::parse_weight_values: "
344 "The number of weights ("+std::to_string(static_cast<long long int>(wts.size()))+") does not match "
345 "the number weight names("+std::to_string(static_cast<long long int>(run_info()->weight_names().size()))+") in the GenRunInfo object");
346 }
347 m_data.weights = wts;
348
349 return true;
350}
351
352
353bool ReaderAscii::parse_units(const char *buf) {
354 const char *cursor = buf;
355
356 // momentum
357 if ( !(cursor = strchr(cursor+1, ' ')) ) return false;
358 ++cursor;
359 m_data.momentum_unit = Units::momentum_unit(cursor);
360
361 // length
362 if ( !(cursor = strchr(cursor+1, ' ')) ) return false;
363 ++cursor;
364 m_data.length_unit = Units::length_unit(cursor);
365
366 HEPMC3_DEBUG(10, "ReaderAscii: U: " << Units::name(m_data.momentum_unit) << " " << Units::name(m_data.length_unit))
367
368 return true;
369}
370
371
373 GenVertexPtr data = std::make_shared<GenVertex>();
374 const char *cursor = buf;
375 const char *cursor2 = nullptr;
376 int id = 0;
377
378 // id
379 if ( !(cursor = strchr(cursor+1, ' ')) ) return false;
380 id = atoi(cursor);
381
382 // status
383 if ( !(cursor = strchr(cursor+1, ' ')) ) return false;
384 m_data.vertices[-id-1].status = atoi(cursor);
385 FourVector& position = m_data.vertices[-id-1].position;
386
387 // skip to the list of particles
388 if ( !(cursor = strchr(cursor+1, '[')) ) return false;
389
390 while (true) {
391 ++cursor; // skip the '[' or ',' character
392 cursor2 = cursor; // save cursor position
393 int particle_in = atoi(cursor);
394
395 // add incoming particle to the vertex
396 if (particle_in > 0) {
397 //If the particle has not been red yet, we store its id to add the particle later.
398 m_io_explicit[id].first.insert(particle_in);
399 }
400
401 // check for next particle or end of particle list
402 if ( !(cursor = strchr(cursor+1, ',')) ) {
403 if ( !(cursor = strchr(cursor2+1, ']')) ) return false;
404 break;
405 }
406 }
407
408 // check if there is position information
409 if ( (cursor = strchr(cursor+1, '@')) ) {
410 // x
411 if ( !(cursor = strchr(cursor+1, ' ')) ) return false;
412 position.setX(atof(cursor));
413
414 // y
415 if ( !(cursor = strchr(cursor+1, ' ')) ) return false;
416 position.setY(atof(cursor));
417
418 // z
419 if ( !(cursor = strchr(cursor+1, ' ')) ) return false;
420 position.setZ(atof(cursor));
421
422 // t
423 if ( !(cursor = strchr(cursor+1, ' ')) ) return false;
424 position.setT(atof(cursor));
425 }
426
427 return true;
428}
429
430
432 const char *cursor = buf;
433 int mother_id = 0;
434
435 // verify id
436 if ( !(cursor = strchr(cursor+1, ' ')) ) return false;
437
438 int id = atoi(cursor);
439 if ( id < 1 || id > static_cast<int>(m_data.particles.size()) ) {
440 HEPMC3_ERROR_LEVEL(600,"ReaderAscii: particle ID is out of expected range.")
441 return false;
442 }
443
444 FourVector& momentum = m_data.particles[id-1].momentum;
445 // mother id
446 if ( !(cursor = strchr(cursor+1, ' ')) ) return false;
447 mother_id = atoi(cursor);
448 if ( mother_id < -static_cast<int>(m_data.vertices.size()) || mother_id > static_cast<int>(m_data.particles.size()) ) {
449 HEPMC3_ERROR_LEVEL(600,"ReaderAscii: ID of particle mother is out of expected range.")
450 return false;
451 }
452
453 if ( mother_id > 0) {
454 /// Parent object is a particle, i.e. the vertex is implicit.
455 /// If the vertex is not known -- mark its first appearence.
456 if (m_io_implicit.count(mother_id) == 0) m_io_implicit_ids.push_back(mother_id);
457 m_io_implicit[mother_id].first.insert(mother_id);
458 m_io_implicit[mother_id].second.insert(id);
459 } else {
460 m_io_explicit[mother_id].second.insert(id);
461 m_io_explicit_ids.insert(mother_id);
462 }
463 // pdg id
464 if ( !(cursor = strchr(cursor+1, ' ')) ) return false;
465 m_data.particles[id-1].pid = atoi(cursor);
466
467 // px
468 if ( !(cursor = strchr(cursor+1, ' ')) ) return false;
469 momentum.setPx(atof(cursor));
470
471 // py
472 if ( !(cursor = strchr(cursor+1, ' ')) ) return false;
473 momentum.setPy(atof(cursor));
474
475 // pz
476 if ( !(cursor = strchr(cursor+1, ' ')) ) return false;
477 momentum.setPz(atof(cursor));
478
479 // pe
480 if ( !(cursor = strchr(cursor+1, ' ')) ) return false;
481 momentum.setE(atof(cursor));
482
483 // m
484 if ( !(cursor = strchr(cursor+1, ' ')) ) return false;
485 m_data.particles[id-1].mass = atof(cursor);
486 m_data.particles[id-1].is_mass_set = true;
487
488 // status
489 if ( !(cursor = strchr(cursor+1, ' ')) ) return false;
490 m_data.particles[id-1].status = atoi(cursor);
491
492 return true;
493}
494
495
496bool ReaderAscii::parse_attribute(const char *buf) {
497 const char *cursor = buf;
498 const char *cursor2 = buf;
499 std::array<char, 512> name{};
500 int id = 0;
501
502 if ( !(cursor = strchr(cursor+1, ' ')) ) return false;
503 id = atoi(cursor);
504
505 if ( !(cursor = strchr(cursor+1, ' ')) ) return false;
506 ++cursor;
507
508 if ( !(cursor2 = strchr(cursor, ' ')) ) return false;
509 snprintf(name.data(), name.size(), "%.*s", static_cast<int>(cursor2-cursor), cursor);
510
511 cursor = cursor2+1;
512
513 m_data.attribute_id.push_back(id);
514 m_data.attribute_name.emplace_back(name.data());
515 m_data.attribute_string.push_back(unescape(cursor));
516
517 return true;
518}
519
520bool ReaderAscii::parse_run_attribute(const char *buf) {
521 const char *cursor = buf;
522 const char *cursor2 = buf;
523 std::array<char, 512> name{};
524
525 if ( !(cursor = strchr(cursor+1, ' ')) ) return false;
526 ++cursor;
527
528 if ( !(cursor2 = strchr(cursor, ' ')) ) return false;
529 snprintf(name.data(), name.size(), "%.*s", static_cast<int>(cursor2-cursor), cursor);
530
531 cursor = cursor2+1;
532
533 std::shared_ptr<StringAttribute> att =
534 std::make_shared<StringAttribute>(StringAttribute(unescape(cursor)));
535
536 run_info()->add_attribute(std::string(name.data()), att);
537
538 return true;
539}
540
541
542bool ReaderAscii::parse_weight_names(const char *buf) {
543 const char *cursor = buf;
544
545 if ( !(cursor = strchr(cursor+1, ' ')) ) return false;
546 ++cursor;
547
548 std::istringstream iss(unescape(cursor));
549 std::vector<std::string> names;
550 std::string name;
551 while (iss >> name) names.emplace_back(name);
552
553 run_info()->set_weight_names(names);
554
555 return true;
556}
557
558bool ReaderAscii::parse_tool(const char *buf) {
559 const char *cursor = buf;
560
561 if ( !(cursor = strchr(cursor+1, ' ')) ) return false;
562 ++cursor;
563 std::string line = unescape(cursor);
565 std::string::size_type pos = line.find('\n');
566 tool.name = line.substr(0, pos);
567 line = line.substr(pos + 1);
568 pos = line.find('\n');
569 tool.version = line.substr(0, pos);
570 tool.description = line.substr(pos + 1);
571 run_info()->tools().emplace_back(tool);
572
573 return true;
574}
575
576
577std::string ReaderAscii::unescape(const std::string& s) {
578 std::string ret;
579 ret.reserve(s.length());
580 for ( std::string::const_iterator it = s.begin(); it != s.end(); ++it ) {
581 if ( *it == '\\' ) {
582 ++it;
583 if ( *it == '|' ) {
584 ret += '\n';
585 }
586 else {
587 ret += *it;
588 }
589 } else
590 {ret += *it;}
591 }
592
593 return ret;
594}
595
596bool ReaderAscii::failed() { return m_isstream ? static_cast<bool>(m_stream->rdstate()) :static_cast<bool>(m_file.rdstate()); }
597
599 if ( !m_file.is_open()) return;
600 m_file.close();
601}
602
603
604} // namespace HepMC3
#define HEPMC3_WARNING_LEVEL(LEVEL, MESSAGE)
Macro for printing HEPMC3_HEPMC3_WARNING messages.
Definition Errors.h:34
#define HEPMC3_ERROR_LEVEL(LEVEL, MESSAGE)
Macro for printing error messages.
Definition Errors.h:27
#define HEPMC3_DEBUG(LEVEL, MESSAGE)
Macro for printing debug messages with appropriate debug level.
Definition Errors.h:41
Definition of class GenEvent.
Definition of class GenParticle.
Definition of class GenVertex.
Definition of class ReaderAscii.
Definition of class Units.
Generic 4-vector.
Definition FourVector.h:36
void setE(double ee)
Definition FourVector.h:139
void setT(double tt)
Definition FourVector.h:110
void setPz(double pzz)
Definition FourVector.h:132
void setY(double yy)
Definition FourVector.h:96
void setPy(double pyy)
Definition FourVector.h:125
void setX(double xx)
Definition FourVector.h:89
void setPx(double pxx)
Definition FourVector.h:118
void setZ(double zz)
Definition FourVector.h:103
Stores event-related information.
Definition GenEvent.h:47
void set_run_info(std::shared_ptr< GenRunInfo > run)
Set the GenRunInfo object by smart pointer.
Definition GenEvent.h:148
const std::vector< ConstGenVertexPtr > & vertices() const
Get list of vertices (const)
Definition GenEvent.cc:43
void read_data(const GenEventData &data)
Fill GenEvent based on GenEventData.
void clear()
Remove contents of this event.
Definition GenEvent.cc:592
const std::vector< ConstGenParticlePtr > & particles() const
Get list of particles (const)
Definition GenEvent.cc:39
bool parse_weight_values(const char *buf)
Parse weight value lines.
bool parse_tool(const char *buf)
Parse run-level tool information.
bool m_isstream
toggles usage of m_file or m_stream
std::map< int, std::pair< std::set< int >, std::set< int > > > m_io_explicit
Temp storage for sets of incoming/outgoing ids for explicit vertices.
std::pair< int, int > parse_event_information(const char *buf)
Parse event.
bool read_event(GenEvent &evt) override
Load event from file.
static 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.
std::set< int > m_io_explicit_ids
Temp storage to keep the order of explicit vertices.
void close() override
Close file stream.
std::vector< int > m_io_implicit_ids
Temp storage to keep the order of implicit vertices.
bool parse_vertex_information(const char *buf)
Parse vertex.
GenEventData m_data
To hold event information.
bool parse_attribute(const char *buf)
Parse attribute.
~ReaderAscii()
Destructor.
bool parse_weight_names(const char *buf)
Parse run-level weight names.
bool parse_units(const char *buf)
Parse units.
ReaderAscii(const std::string &filename)
Constructor.
std::istream * m_stream
For ctor when reading from stream.
std::shared_ptr< std::istream > m_shared_stream
For ctor when reading from temp. stream.
std::unordered_map< int, std::pair< std::set< int >, std::set< int > > > m_io_implicit
Temp storage for sets of incoming/outgoing ids for implicit vertices.
bool parse_particle_information(const char *buf)
Parse particle.
bool parse_run_attribute(const char *buf)
Parse run-level attribute.
virtual void set_run_info(std::shared_ptr< GenRunInfo > run)
Set the global GenRunInfo object.
Definition Reader.h:56
virtual std::shared_ptr< GenRunInfo > run_info() const
Get the global GenRunInfo object.
Definition Reader.h:44
Attribute that holds a string.
Definition Attribute.h:343
static LengthUnit length_unit(const std::string &name)
Get length unit based on its name.
Definition Units.h:46
static std::string name(MomentumUnit u)
Get name of momentum unit.
Definition Units.h:56
static MomentumUnit momentum_unit(const std::string &name)
Get momentum unit based on its name.
Definition Units.h:36
HepMC3 main namespace.
Interrnal struct for keeping track of tools.
Definition GenRunInfo.h:38
std::string description
Other information about how the tool was used in the run.
Definition GenRunInfo.h:48
std::string version
The version of the tool.
Definition GenRunInfo.h:44
std::string name
The name of the tool.
Definition GenRunInfo.h:41