ATLAS Offline Software
Loading...
Searching...
No Matches
GenEvent.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4/* Author: Andrii Verbytskyi andrii.verbytskyi@mpp.mpg.de */
5
6#ifndef ATLASHEPMC_GENEVENT_H
7#define ATLASHEPMC_GENEVENT_H
8#ifdef HEPMC3
9#include "HepMC3/GenEvent.h"
10#include "HepMC3/GenHeavyIon.h"
11#include "HepMC3/GenPdfInfo.h"
12#include "HepMC3/PrintStreams.h"
13#include "AtlasHepMC/Barcode.h"
18
19#include <algorithm>
20#include <cstdlib>
21#include <iomanip>
22#include <map>
23#include <memory>
24#include <sstream>
25#include <string>
26#include <vector>
27
28#include <unordered_map>
29
30namespace HepMC3 {
31inline std::vector<HepMC3::GenParticlePtr>::const_iterator begin(HepMC3::GenEvent& e) { return e.particles().begin(); }
32inline std::vector<HepMC3::GenParticlePtr>::const_iterator end(HepMC3::GenEvent& e) { return e.particles().end(); }
33inline std::vector<HepMC3::ConstGenParticlePtr>::const_iterator begin(const HepMC3::GenEvent& e) { return e.particles().begin(); }
34inline std::vector<HepMC3::ConstGenParticlePtr>::const_iterator end(const HepMC3::GenEvent& e) { return e.particles().end(); }
35}
36
37namespace HepMC {
38using Print = HepMC3::Print;
39using GenHeavyIon = HepMC3::GenHeavyIon;
40using GenEvent = HepMC3::GenEvent;
41
42class ShortEventAttribute : public HepMC3::Attribute {
43public:
44 ShortEventAttribute(): HepMC3::Attribute(){}
45 ShortEventAttribute(const HepMC3::GenEvent* e): HepMC3::Attribute(){ from_event(e); }
46
47 bool from_event(const HepMC3::GenEvent* e){
48 NUP=e->particles().size();
49 resize();
50 XWGTUP = e->weights().size() ? e->weights()[0] : 1.0;
51 auto A_signal_process_id = e->attribute<HepMC3::IntAttribute>(HepMCStr::signal_process_id);
52 IDPRUP = A_signal_process_id ? A_signal_process_id->value() : 0;
53 auto A_event_scale = e->attribute<HepMC3::DoubleAttribute>(HepMCStr::event_scale);
54 SCALUP = A_event_scale ? A_event_scale->value() : 0;
55 auto A_alphaQCD = e->attribute<HepMC3::DoubleAttribute>(HepMCStr::alphaQCD);
56 AQCDUP = A_alphaQCD ? A_alphaQCD->value() : 0;
57 auto A_alphaQED = e->attribute<HepMC3::DoubleAttribute>(HepMCStr::alphaQED);
58 AQEDUP = A_alphaQED ? A_alphaQED->value() : 0;
59 for ( int i = 0; i < NUP; ++i ){
60 const auto & thisParticle = e->particles().at(i);
61 PUP[i][0] = thisParticle->momentum().px();
62 PUP[i][1] = thisParticle->momentum().py();
63 PUP[i][2] = thisParticle->momentum().pz();
64 PUP[i][3] = thisParticle->momentum().e();
65 PUP[i][4] = thisParticle->momentum().m();
66 IDUP[i] = thisParticle->pdg_id();
67 const auto pv = thisParticle->production_vertex();
68 const auto ev = thisParticle->end_vertex();
69 if (pv && ev ) ISTUP[i] = 2;
70 if (pv && !ev ) ISTUP[i] = 1;
71 if (thisParticle->status() == 4 || !pv ) ISTUP[i] = -1;
72 const auto flow1 = thisParticle->attribute<HepMC3::IntAttribute>(HepMCStr::flow1);
73 const auto flow2 = thisParticle->attribute<HepMC3::IntAttribute>(HepMCStr::flow2);
74 ICOLUP[i].first = flow1 ? flow1->value() : 0;
75 ICOLUP[i].second = flow2 ? flow2->value() : 0;
76 int l = 0;
77 int h = 0;
78 if (pv && !pv->particles_in().empty()) {
79 l = pv->particles_in().front()->id();
80 h = l;
81 for (const auto& p : pv->particles_in()) {
82 const int id = p->id();
83 l = std::min(l, id);
84 h = std::max(h, id);
85 }
86 }
87 MOTHUP[i].first = h;
88 MOTHUP[i].second = l;
89 }
90 return true;
91 }
92
93 bool from_string(const std::string &att) override {
94 std::istringstream iss(att);
95 iss >> NUP;
96 iss >> IDPRUP;
97 iss >> XWGTUP;
98 iss >> SCALUP;
99 iss >> AQEDUP;
100 iss >> AQCDUP;
101 //assume input is a trusted source
102 //coverity[tainted_data]
103 resize();
104 for ( int i = 0; i < NUP; ++i ){
105 iss >> IDUP[i];
106 iss >> ISTUP[i];
107 iss >> MOTHUP[i].first;
108 iss >> MOTHUP[i].second;
109 iss >> ICOLUP[i].first;
110 iss >> ICOLUP[i].second;
111 iss >> PUP[i][0];
112 iss >> PUP[i][1];
113 iss >> PUP[i][2];
114 iss >> PUP[i][3];
115 iss >> PUP[i][4];
116 iss >> VTIMUP[i];
117 iss >> SPINUP[i];
118 }
119 set_is_parsed(true);
120 return true;
121 }
122
123 bool to_string(std::string &fl) const override {
124 std::ostringstream file;
125 file << " " << std::setw(4) << NUP
126 << " " << std::setw(6) << IDPRUP
127 << " " << std::setw(14) << XWGTUP
128 << " " << std::setw(14) << SCALUP
129 << " " << std::setw(14) << AQEDUP
130 << " " << std::setw(14) << AQCDUP << "\n";
131 for ( int i = 0; i < NUP; ++i )
132 file << " " << std::setw(8) << IDUP[i]
133 << " " << std::setw(2) << ISTUP[i]
134 << " " << std::setw(4) << MOTHUP[i].first
135 << " " << std::setw(4) << MOTHUP[i].second
136 << " " << std::setw(4) << ICOLUP[i].first
137 << " " << std::setw(4) << ICOLUP[i].second
138 << " " << std::setw(14) << PUP[i][0]
139 << " " << std::setw(14) << PUP[i][1]
140 << " " << std::setw(14) << PUP[i][2]
141 << " " << std::setw(14) << PUP[i][3]
142 << " " << std::setw(14) << PUP[i][4]
143 << " " << std::setw(1) << VTIMUP[i]
144 << " " << std::setw(1) << SPINUP[i] << std::endl;
145 fl += file.str();
146 return true;
147 }
148
149 void resize() {
150 IDUP.resize(NUP);
151 ISTUP.resize(NUP);
152 MOTHUP.resize(NUP);
153 ICOLUP.resize(NUP);
154 PUP.resize(NUP, std::vector<double>(5));
155 VTIMUP.resize(NUP);
156 SPINUP.resize(NUP);
157 }
158
159 int NUP = 0;
160 int IDPRUP = 0;
161 double XWGTUP = 0;
162 double SCALUP = 0;
163 double AQEDUP = 0;
164 double AQCDUP = 0;
165 std::vector<long> IDUP{};
166 std::vector<int> ISTUP{};
167 std::vector< std::pair<int,int> > MOTHUP{};
168 std::vector< std::pair<int,int> > ICOLUP{};
169 std::vector< std::vector<double> > PUP{};
170 std::vector<double> VTIMUP{};
171 std::vector<double> SPINUP{};
172};
173
174
175class GenEventBarcodes : public HepMC3::Attribute
176{
177public:
178 virtual bool from_string(const std::string & /*att*/) override { return false; }
179 virtual bool to_string(std::string &att) const override
180 {
181 att = "GenEventBarcodes";
182 return true;
183 }
184 ConstGenVertexPtr barcode_to_vertex (int id) const {
185 const auto it = m_vertexBC.find (id);
186 if (it != m_vertexBC.end()) return it->second;
187 return nullptr;
188 }
190 const auto it = m_vertexBC.find (id);
191 if (it != m_vertexBC.end()) return it->second;
192 return nullptr;
193 }
195 const auto it = m_particleBC.find (id);
196 if (it != m_particleBC.end()) return it->second;
197 return nullptr;
198 }
200 const auto it = m_particleBC.find (id);
201 if (it != m_particleBC.end()) return it->second;
202 return nullptr;
203 }
204
205 void add (GenVertexPtr p) {
206 if (!p) return;
207 auto barcode = p->attribute<HepMC3::IntAttribute>(HepMCStr::barcode);
208 if (barcode) {
209 m_vertexBC[barcode->value()] = std::move(p);
210 }
211 }
212
213 void remove (GenVertexPtr p) {
214 if (!p) return;
215 auto barcode = p->attribute<HepMC3::IntAttribute>(HepMCStr::barcode);
216 if (barcode) {
217 const auto it = m_vertexBC.find (barcode->value());
218 if (it != m_vertexBC.end()) {
219 m_vertexBC.erase (it);
220 }
221 }
222 }
223
224 void add (GenParticlePtr p) {
225 if (!p) return;
226 auto barcode = p->attribute<HepMC3::IntAttribute>(HepMCStr::barcode);
227 if (barcode) {
228 m_particleBC[barcode->value()] = std::move(p);
229 }
230 }
231
232 void remove (GenParticlePtr p) {
233 if (!p) return;
234 auto barcode = p->attribute<HepMC3::IntAttribute>(HepMCStr::barcode);
235 if (barcode) {
236 const auto it = m_particleBC.find (barcode->value());
237 if (it != m_particleBC.end()) {
238 m_particleBC.erase (it);
239 }
240 }
241 }
242
243 std::map<int, ConstGenVertexPtr> barcode_to_vertex_map() const {
244 std::map<int, ConstGenVertexPtr> ret;
245 for (const auto &bcvertpair: m_vertexBC)
246 ret.insert({bcvertpair.first, std::const_pointer_cast<const HepMC3::GenVertex>(bcvertpair.second)});
247 return ret;
248 }
249 std::map<int, ConstGenParticlePtr> barcode_to_particle_map() const {
250 std::map<int, ConstGenParticlePtr> ret;
251 for (const auto &bcpartpair: m_particleBC)
252 ret.insert({bcpartpair.first, std::const_pointer_cast<const HepMC3::GenParticle>(bcpartpair.second)});
253 return ret;
254 }
255 std::map<int,int> id_to_barcode_map() const {
256 std::map<int, int> ret;
257 for (const auto &bcvertpair: m_vertexBC) ret.insert({bcvertpair.second->id(), bcvertpair.first});
258 for (const auto &bcpartpair: m_particleBC) ret.insert({bcpartpair.second->id(), bcpartpair.first});
259 return ret;
260 }
261
262
263 void fillAttribute(GenEvent* e) {
264 const auto eventAttributes = e->attributes(); // this makes a copy
265 const auto barcodeAttributeIt = eventAttributes.find(HepMCStr::barcode);
266 const bool hasBarcodeAttribute = barcodeAttributeIt != eventAttributes.end();
267
268 const auto &particles = e->particles();
269 for (size_t i = 1; i <= particles.size(); i++) {
270 if (hasBarcodeAttribute && barcodeAttributeIt->second.count(i) > 0) {
271 const auto &ptr = barcodeAttributeIt->second.at(i);
272 if (ptr->is_parsed()) {
273 m_particleBC[static_cast<HepMC3::IntAttribute*>(ptr.get())->value()] = ptr->particle();
274 }
275 else {
276 m_particleBC[std::atoi(ptr->unparsed_string().c_str())] = ptr->particle();
277 }
278 } else {
279 m_particleBC[i] = particles[i-1];
280 }
281 }
282 const auto &vertices = e->vertices();
283 for (size_t i = 1; i <= vertices.size(); i++) {
284 if (hasBarcodeAttribute && barcodeAttributeIt->second.count(-i) > 0) {
285 const auto &ptr = barcodeAttributeIt->second.at(-i);
286 if (ptr->is_parsed()) {
287 m_vertexBC[static_cast<HepMC3::IntAttribute*>(ptr.get())->value()] = ptr->vertex();
288 }
289 else {
290 m_vertexBC[std::atoi(ptr->unparsed_string().c_str())] = ptr->vertex();
291 }
292 } else {
293 m_vertexBC[-i] = vertices[i-1];
294 }
295 }
296 set_is_parsed(true);
297 }
298
299private:
300 std::unordered_map<int, GenVertexPtr> m_vertexBC;
301 std::unordered_map<int, GenParticlePtr> m_particleBC;
302};
303
309class ShadowParticle : public HepMC3::Attribute {
310public:
311
313 ShadowParticle() {}
314
316 ShadowParticle(ConstGenParticlePtr p)
317 : Attribute(), m_shadow(p) {}
318
320 virtual bool from_string(const std::string &) override { return false; }
321
323 virtual bool to_string(std::string &att) const override
324 {
325 att = "ShadowParticle";
326 return true;
327 }
329 ConstGenParticlePtr value() const {
330 return m_shadow;
331 }
332
333private:
334
335 ConstGenParticlePtr m_shadow;
336};
337
338inline bool set_ll_event_number(HepMC3::GenEvent* e, long long int num){
339 e->add_attribute(HepMCStr::long_long_event_number, std::make_shared<HepMC3::LongLongAttribute>(num));
340 return true;
341}
342inline long long int get_ll_event_number(const HepMC3::GenEvent* e){
343 auto at = e->attribute<HepMC3::LongLongAttribute>(HepMCStr::long_long_event_number);
344 return at ? at->value() : e->event_number();
345}
346
347inline std::map<std::string, std::size_t> weights_map(const HepMC3::GenEvent* e) {
348 std::map<std::string, std::size_t> ret;
349 auto run = e->run_info();
350 if (!run) return ret;
351 const std::vector<std::string> names = run->weight_names();
352 for (const auto& name: names) ret[name] = run->weight_index(name);
353 return ret;
354}
355
356inline std::vector<HepMC3::GenParticlePtr>::const_iterator begin(HepMC3::GenEvent& e) { return e.particles().begin(); }
357inline std::vector<HepMC3::GenParticlePtr>::const_iterator end(HepMC3::GenEvent& e) { return e.particles().end(); }
358inline std::vector<HepMC3::ConstGenParticlePtr>::const_iterator begin(const HepMC3::GenEvent& e) { return e.particles().begin(); }
359inline std::vector<HepMC3::ConstGenParticlePtr>::const_iterator end(const HepMC3::GenEvent& e) { return e.particles().end(); }
360
361inline GenEvent* newGenEvent(const int signal_process_id, const int event_number) { // TODO Update event_number to long long int?
362 GenEvent* e = new GenEvent();
363 std::shared_ptr<HepMC3::IntAttribute> signal_process_id_A = std::make_shared<HepMC3::IntAttribute>(signal_process_id);
364 e->add_attribute(HepMCStr::signal_process_id, signal_process_id_A);
365 e->add_attribute(HepMCStr::barcodes, std::make_shared<GenEventBarcodes>());
366 e->set_event_number(event_number);
367 return e;
368}
369
370inline GenEvent* copyemptyGenEvent(const GenEvent* inEvt) {
371 GenEvent* e = new GenEvent();
372 e->set_event_number(inEvt->event_number());
373 e->weights() = inEvt->weights();
374 auto a_mpi = inEvt->attribute<HepMC3::IntAttribute>(HepMCStr::mpi);
375 if (a_mpi) e->add_attribute(HepMCStr::mpi, std::make_shared<HepMC3::IntAttribute>(*a_mpi));
376 auto a_signal_process_id = inEvt->attribute<HepMC3::IntAttribute>(HepMCStr::signal_process_id);
377 if (a_signal_process_id) e->add_attribute(HepMCStr::signal_process_id, std::make_shared<HepMC3::IntAttribute>(*a_signal_process_id));
378 auto a_event_scale = inEvt->attribute<HepMC3::DoubleAttribute>(HepMCStr::event_scale);
379 if (a_event_scale) e->add_attribute(HepMCStr::event_scale, std::make_shared<HepMC3::DoubleAttribute>(*a_event_scale));
380 auto a_alphaQCD = inEvt->attribute<HepMC3::DoubleAttribute>(HepMCStr::alphaQCD);
381 if (a_alphaQCD) e->add_attribute(HepMCStr::alphaQCD, std::make_shared<HepMC3::DoubleAttribute>(*a_alphaQCD));
382 auto a_alphaQED = inEvt->attribute<HepMC3::DoubleAttribute>(HepMCStr::alphaQED);
383 if (a_alphaQED) e->add_attribute(HepMCStr::alphaQED, std::make_shared<HepMC3::DoubleAttribute>(*a_alphaQED));
384 auto a_pi = inEvt->pdf_info();
385 if (a_pi) e->set_pdf_info(std::make_shared<HepMC3::GenPdfInfo>(*a_pi));
386 auto a_hi = inEvt->heavy_ion();
387 if (a_hi) e->set_heavy_ion(std::make_shared<HepMC3::GenHeavyIon>(*a_hi));
388 auto a_random_states = inEvt->attribute<HepMC3::VectorLongIntAttribute>(HepMCStr::random_states);
389 if (a_random_states) e->add_attribute(HepMCStr::random_states, std::make_shared<HepMC3::VectorLongIntAttribute>(*a_random_states));
390 e->add_attribute(HepMCStr::barcodes, std::make_shared<GenEventBarcodes>());
391 return e;
392}
393
394inline void fillBarcodesAttribute(GenEvent* e) {
395 auto barcodes = e->attribute<GenEventBarcodes> (HepMCStr::barcodes);
396 if (!barcodes) {
397 barcodes = std::make_shared<GenEventBarcodes>();
398 e->add_attribute(HepMCStr::barcodes, barcodes);
399 }
400 // force re-parsing as calling barcodes->is_parsed() returns true here
401 barcodes->fillAttribute(e);
402}
403
404inline ConstGenVertexPtr barcode_to_vertex(const GenEvent* e, int id) {
405 // Prefer to use optimized GenEvent barcodes attribute
406 const auto &barcodes = e->attribute<GenEventBarcodes> (HepMCStr::barcodes);
407 if (barcodes) {
408 ConstGenVertexPtr ptr = barcodes->barcode_to_vertex (id);
409 if (ptr) return ptr;
410 }
411 // Fallback to unoptimized GenVertex barcode attribute
412 const auto eventAttributes = e->attributes(); // this makes a copy
413 const auto barcodeAttributeIt = eventAttributes.find(HepMCStr::barcode);
414 const bool hasBarcodeAttribute = barcodeAttributeIt != eventAttributes.end();
415
416 const auto &vertices = e->vertices();
417 if (hasBarcodeAttribute) {
418 for (size_t i = 1; i <= vertices.size(); i++) {
419 const auto &ptrIt = barcodeAttributeIt->second.find(-i);
420 if (ptrIt != barcodeAttributeIt->second.end()) {
421 const auto &ptr = ptrIt->second;
422 if (ptr->is_parsed()) {
423 if (id == static_cast<HepMC3::IntAttribute*>(ptr.get())->value()) {
424 return ptr->vertex();
425 }
426 }
427 else {
428 if (id == std::atoi(ptr->unparsed_string().c_str())) {
429 return ptr->vertex();
430 }
431 }
432 }
433 }
434 }
435 // No barcodes attribute, so assume that we are passing the id member variable instead of a barcode
436 if (-id > 0 && -id <= static_cast<int>(vertices.size())) {
437 if (!vertices[-id-1]->attribute<HepMC3::IntAttribute>(HepMCStr::barcode)) {
438 return vertices[-id-1];
439 }
440 }
441 return HepMC3::ConstGenVertexPtr();
442}
443
444inline ConstGenParticlePtr barcode_to_particle(const GenEvent* e, int id) {
445 // Prefer to use optimized GenEvent barcodes attribute
446 const auto &barcodes = e->attribute<GenEventBarcodes> (HepMCStr::barcodes);
447 if (barcodes) {
448 ConstGenParticlePtr ptr = barcodes->barcode_to_particle (id);
449 if (ptr) return ptr;
450 }
451 // Fallback to unoptimized GenParticle barcode attribute
452 const auto eventAttributes = e->attributes(); // this makes a copy
453 const auto barcodeAttributeIt = eventAttributes.find(HepMCStr::barcode);
454 const bool hasBarcodeAttribute = barcodeAttributeIt != eventAttributes.end();
455
456 const auto &particles = e->particles();
457 if (hasBarcodeAttribute) {
458 for (size_t i = 1; i <= particles.size(); i++) {
459 const auto &ptrIt = barcodeAttributeIt->second.find(i);
460 if (ptrIt != barcodeAttributeIt->second.end()) {
461 const auto &ptr = ptrIt->second;
462 if (ptr->is_parsed()) {
463 if (id == static_cast<HepMC3::IntAttribute*>(ptr.get())->value()) {
464 return ptr->particle();
465 }
466 }
467 else {
468 if (id == std::atoi(ptr->unparsed_string().c_str())) {
469 return ptr->particle();
470 }
471 }
472 }
473 }
474 }
475 // No barcodes attribute, so assume that we are passing the id member variable instead of a barcode
476 if (id > 0 && id <= static_cast<int>(particles.size())) {
477 if (!particles[id-1]->attribute<HepMC3::IntAttribute>(HepMCStr::barcode)) {
478 return particles[id-1];
479 }
480 }
481 return HepMC3::ConstGenParticlePtr();
482}
483
484inline GenVertexPtr barcode_to_vertex(GenEvent* e, int id) {
485 // Prefer to use optimized GenEvent barcodes attribute
486 const auto &barcodes = e->attribute<GenEventBarcodes> (HepMCStr::barcodes);
487 if (barcodes) {
488 GenVertexPtr ptr = barcodes->barcode_to_vertex (id);
489 if (ptr) return ptr;
490 }
491 // Fallback to unoptimized GenVertex barcode attribute
492 const auto eventAttributes = e->attributes(); // this makes a copy
493 const auto barcodeAttributeIt = eventAttributes.find(HepMCStr::barcode);
494 const bool hasBarcodeAttribute = barcodeAttributeIt != eventAttributes.end();
495
496 const auto &vertices = e->vertices();
497 if (hasBarcodeAttribute) {
498 for (size_t i = 1; i <= vertices.size(); i++) {
499 const auto &ptrIt = barcodeAttributeIt->second.find(-i);
500 if (ptrIt != barcodeAttributeIt->second.end()) {
501 const auto &ptr = ptrIt->second;
502 if (ptr->is_parsed()) {
503 if (id == static_cast<HepMC3::IntAttribute*>(ptr.get())->value()) {
504 return ptr->vertex();
505 }
506 }
507 else {
508 if (id == std::atoi(ptr->unparsed_string().c_str())) {
509 return ptr->vertex();
510 }
511 }
512 }
513 }
514 }
515 // No barcodes attribute, so assume that we are passing the id member variable instead of a barcode
516 if (-id > 0 && -id <= static_cast<int>(vertices.size())) {
517 if (!vertices[-id-1]->attribute<HepMC3::IntAttribute>(HepMCStr::barcode)) {
518 return vertices[-id-1];
519 }
520 }
521 return HepMC3::GenVertexPtr();
522}
523
524inline GenParticlePtr barcode_to_particle(GenEvent* e, int id) {
525 // Prefer to use optimized GenEvent barcodes attribute
526 const auto &barcodes = e->attribute<GenEventBarcodes> (HepMCStr::barcodes);
527 if (barcodes) {
528 GenParticlePtr ptr = barcodes->barcode_to_particle (id);
529 if (ptr) return ptr;
530 }
531 // Fallback to unoptimized GenParticle barcode attribute
532 const auto eventAttributes = e->attributes(); // this makes a copy
533 const auto barcodeAttributeIt = eventAttributes.find(HepMCStr::barcode);
534 const bool hasBarcodeAttribute = barcodeAttributeIt != eventAttributes.end();
535
536 const auto &particles = e->particles();
537 if (hasBarcodeAttribute) {
538 for (size_t i = 1; i <= particles.size(); i++) {
539 const auto &ptrIt = barcodeAttributeIt->second.find(i);
540 if (ptrIt != barcodeAttributeIt->second.end()) {
541 const auto &ptr = ptrIt->second;
542 if (ptr->is_parsed()) {
543 if (id == static_cast<HepMC3::IntAttribute*>(ptr.get())->value()) {
544 return ptr->particle();
545 }
546 }
547 else {
548 if (id == std::atoi(ptr->unparsed_string().c_str())) {
549 return ptr->particle();
550 }
551 }
552 }
553 }
554 }
555 // No barcodes attribute, so assume that we are passing the id member variable instead of a barcode
556 if (id > 0 && id <= static_cast<int>(particles.size())) {
557 if (!particles[id-1]->attribute<HepMC3::IntAttribute>(HepMCStr::barcode)) {
558 return particles[id-1];
559 }
560 }
561 return HepMC3::GenParticlePtr();
562}
563
564inline int mpi(const GenEvent& evt) {
565 std::shared_ptr<HepMC3::IntAttribute> A_mpi = evt.attribute<HepMC3::IntAttribute>(HepMCStr::mpi);
566 return A_mpi ? (A_mpi->value()) : 0;
567}
568inline int mpi(const GenEvent* evt) {
569 std::shared_ptr<HepMC3::IntAttribute> A_mpi = evt->attribute<HepMC3::IntAttribute>(HepMCStr::mpi);
570 return A_mpi ? (A_mpi->value()) : 0;
571}
572
573inline int signal_process_id(const GenEvent& evt) {
574 std::shared_ptr<HepMC3::IntAttribute> A_signal_process_id = evt.attribute<HepMC3::IntAttribute>(HepMCStr::signal_process_id);
575 return A_signal_process_id ? (A_signal_process_id->value()) : 0;
576}
577inline int signal_process_id(const GenEvent* evt) {
578 std::shared_ptr<HepMC3::IntAttribute> A_signal_process_id = evt->attribute<HepMC3::IntAttribute>(HepMCStr::signal_process_id);
579 return A_signal_process_id ? (A_signal_process_id->value()) : 0;
580}
581inline void set_signal_process_id(GenEvent* e, const int i = 0) {
582 std::shared_ptr<HepMC3::IntAttribute> signal_process_id = std::make_shared<HepMC3::IntAttribute>(i);
583 e->add_attribute(HepMCStr::signal_process_id, std::move(signal_process_id));
584}
585inline void set_mpi(GenEvent* e, const int i = 0) {
586 std::shared_ptr<HepMC3::IntAttribute> mpi = std::make_shared<HepMC3::IntAttribute>(i);
587 e->add_attribute(HepMCStr::mpi, std::move(mpi));
588}
589inline void set_random_states(GenEvent* e, std::vector<long int>& a) {
590 e->add_attribute(HepMCStr::random_states, std::make_shared<HepMC3::VectorLongIntAttribute>(a));
591}
592template <class T> void set_signal_process_vertex(GenEvent* e, T& v) {
593 if (!v || !e) return;
594/* AV: HepMC2 adds the vertex to event */
595 e->add_vertex(v);
596 v->add_attribute(HepMCStr::signal_process_vertex, std::make_shared<HepMC3::IntAttribute>(1));
597}
598inline ConstGenVertexPtr signal_process_vertex(const GenEvent* e) { for (auto& v: e->vertices()) if (v->attribute<HepMC3::IntAttribute>(HepMCStr::signal_process_vertex)) return v; return nullptr; }
599inline GenVertexPtr signal_process_vertex(GenEvent* e) { for (auto& v: e->vertices()) if (v->attribute<HepMC3::IntAttribute>(HepMCStr::signal_process_vertex)) return v; return nullptr; }
600inline bool valid_beam_particles(const GenEvent* e) {
601 if (!e) return false;
602 size_t nBeams = 0;
603 for (const auto& p : e->beams()) { if (p->status() == 4) ++nBeams; }
604 if (nBeams != 2) return false;
605 return true;
606}
607
608template <class T> bool suggest_barcode(T& p, int i) {
609 if (!p->parent_event()) return false;
610 auto barcodes = p->parent_event()->template attribute<GenEventBarcodes> (HepMCStr::barcodes);
611 if (!barcodes) {
612 barcodes = std::make_shared<GenEventBarcodes>();
613 p->parent_event()->add_attribute(HepMCStr::barcodes, barcodes);
614 }
615 barcodes->remove(p);
616 const bool ret = p->add_attribute(HepMCStr::barcode, std::make_shared<HepMC3::IntAttribute>(i));
617 if (ret) barcodes->add(p);
618 return ret;
619}
620
621}
622
623#else
624
625#include "HepMC/GenEvent.h"
626#include "HepMC/GenVertex.h"
627#include "AtlasHepMC/GenVertex.h"
628#include "AtlasHepMC/Barcode.h"
629#include <memory>
630namespace HepMC {
631inline bool set_ll_event_number(HepMC::GenEvent* e, long long int num){
632 if (num > std::numeric_limits<int>::max()) return false;
633 e->set_event_number((int)num);
634 return true;
635}
636inline long long int get_ll_event_number(const HepMC::GenEvent* e){
637 return e->event_number();
638}
639inline GenEvent::particle_iterator begin(HepMC::GenEvent& e) { return e.particles_begin(); }
640inline GenEvent::particle_iterator end(HepMC::GenEvent& e) { return e.particles_end(); }
641inline GenEvent::particle_const_iterator begin(const HepMC::GenEvent& e) { return e.particles_begin(); }
642inline GenEvent::particle_const_iterator end(const HepMC::GenEvent& e) { return e.particles_end(); }
643inline GenEvent* newGenEvent(const int a, const int b) { return new GenEvent(a,b); }
644inline GenVertex* signal_process_vertex(const GenEvent* e) { return e->signal_process_vertex(); }
645inline void fillBarcodesAttribute(GenEvent* ) { }
646inline GenVertex* barcode_to_vertex(const GenEvent* e, int id) {return e->barcode_to_vertex(id);}
647inline GenParticle* barcode_to_particle(const GenEvent* e, int id) {return e->barcode_to_particle(id);}
648inline int mpi(const GenEvent& e) {
649 return e.mpi();
650}
651inline int mpi(const GenEvent* e) {
652 return e->mpi();
653}
654inline int signal_process_id(const GenEvent& e) {
655 return e.signal_process_id();
656}
657inline int signal_process_id(const GenEvent* e) {
658 return e->signal_process_id();
659}
660inline void set_signal_process_id(GenEvent* e, const int i) {
661 e->set_signal_process_id(i);
662}
663inline void set_mpi(GenEvent* e, const int i) {
664 e->set_mpi(i);
665}
666template <class T> void set_random_states(GenEvent* e, std::vector<T> a) {
667 e->set_random_states(a);
668}
669template <class T> void set_signal_process_vertex(GenEvent* e, T v) {
670 e->set_signal_process_vertex(v);
671}
672inline GenEvent* copyemptyGenEvent(const GenEvent* inEvt) {
673 HepMC::GenEvent* outEvt = new HepMC::GenEvent( inEvt->signal_process_id(), inEvt->event_number() );
674 outEvt->set_mpi ( inEvt->mpi() );
675 outEvt->set_event_scale ( inEvt->event_scale() );
676 outEvt->set_alphaQCD ( inEvt->alphaQCD() );
677 outEvt->set_alphaQED ( inEvt->alphaQED() );
678 outEvt->weights() = inEvt->weights();
679 outEvt->set_random_states( inEvt->random_states() );
680 if ( nullptr != inEvt->heavy_ion() ) {
681 outEvt->set_heavy_ion ( *inEvt->heavy_ion() );
682 }
683 if ( nullptr != inEvt->pdf_info() ) {
684 outEvt->set_pdf_info ( *inEvt->pdf_info() );
685 }
686 return outEvt;
687}
688
689template <class T> bool suggest_barcode(T& p, int i) {return p.suggest_barcode(i);}
690template <class T> bool suggest_barcode(T* p, int i) {return p->suggest_barcode(i);}
691//Smart pointers should not be used with HepMC2. But it happens.
692template <> inline bool suggest_barcode<std::unique_ptr<HepMC::GenParticle> >(std::unique_ptr<HepMC::GenParticle>& p, int i) {return p->suggest_barcode(i);}
693
694namespace Print {
695inline void line(std::ostream& os,const GenEvent& e) {e.print(os);}
696inline void line(std::ostream& os,const GenEvent* e) {e->print(os);}
697inline void content(std::ostream& os,const GenEvent& e) {e.print(os);}
698inline void content(std::ostream& os,const GenEvent* e) {e->print(os);}
699}
700inline bool valid_beam_particles(const GenEvent* e) {return e->valid_beam_particles();}
701}
703#endif
704#endif
static std::string to_string(const std::vector< T > &v)
static Double_t a
@ GenParticle
bool add(const std::string &hname, TKey *tobj)
Definition fastadd.cxx:55
int ev
Definition globals.cxx:25
mapped_type at(key_type key) const
Look up an element in the map.
const std::string event_scale
const std::string flow2
const std::string barcode
const std::string long_long_event_number
const std::string signal_process_vertex
const std::string flow1
const std::string signal_process_id
const std::string random_states
const std::string alphaQED
const std::string alphaQCD
const std::string barcodes
const std::string ShadowParticle
const std::string mpi
void line(std::ostream &os, const GenEvent &e)
Definition GenEvent.h:695
void content(std::ostream &os, const GenEvent &e)
Definition GenEvent.h:697
int signal_process_id(const GenEvent &e)
Definition GenEvent.h:654
void set_mpi(GenEvent *e, const int i)
Definition GenEvent.h:663
bool set_ll_event_number(HepMC::GenEvent *e, long long int num)
Definition GenEvent.h:631
void set_signal_process_vertex(GenEvent *e, T v)
Definition GenEvent.h:669
GenParticle * barcode_to_particle(const GenEvent *e, int id)
Definition GenEvent.h:647
GenEvent::particle_iterator begin(HepMC::GenEvent &e)
Definition GenEvent.h:639
GenEvent::particle_iterator end(HepMC::GenEvent &e)
Definition GenEvent.h:640
void set_random_states(GenEvent *e, std::vector< T > a)
Definition GenEvent.h:666
GenVertex * barcode_to_vertex(const GenEvent *e, int id)
Definition GenEvent.h:646
long long int get_ll_event_number(const HepMC::GenEvent *e)
Definition GenEvent.h:636
HepMC::GenVertex * GenVertexPtr
Definition GenVertex.h:38
bool suggest_barcode(T &p, int i)
Definition GenEvent.h:689
void set_signal_process_id(GenEvent *e, const int i)
Definition GenEvent.h:660
GenEvent * copyemptyGenEvent(const GenEvent *inEvt)
Definition GenEvent.h:672
void fillBarcodesAttribute(GenEvent *)
Definition GenEvent.h:645
GenParticle * GenParticlePtr
Definition GenParticle.h:37
const GenParticle * ConstGenParticlePtr
Definition GenParticle.h:38
GenVertex * signal_process_vertex(const GenEvent *e)
Definition GenEvent.h:644
int mpi(const GenEvent &e)
Definition GenEvent.h:648
bool valid_beam_particles(const GenEvent *e)
Definition GenEvent.h:700
const HepMC::GenVertex * ConstGenVertexPtr
Definition GenVertex.h:39
GenEvent * newGenEvent(const int a, const int b)
Definition GenEvent.h:643
l
Printing final latex table to .tex output file.
virtual bool resize(size_t sz) override
Change the size of all aux data vectors.
void * ptr(T *p)
Definition SGImplSvc.cxx:74
TFile * file
int run(int argc, char *argv[])