HepMC3 event record library: ReaderAsciiHepMC2.cc Source File

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