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