cepgen is hosted by Hepforge, IPPP Durham
CepGen 1.2.5
Central exclusive processes event generator
Loading...
Searching...
No Matches
HepMC2EventInterface.cpp
Go to the documentation of this file.
1/*
2 * CepGen: a central exclusive processes event generator
3 * Copyright (C) 2021-2024 Laurent Forthomme
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <HepMC/GenEvent.h>
20#include <HepMC/GenParticle.h>
21#include <HepMC/GenVertex.h>
22#include <HepMC/SimpleVector.h>
23#include <HepMC/Version.h>
24
25#include <list>
26#include <numeric>
27
29#include "CepGen/Event/Event.h"
31#include "CepGen/Physics/PDG.h"
33#include "CepGen/Utils/String.h"
35
36namespace HepMC {
37 CepGenEvent::CepGenEvent(const cepgen::Event& evt) : GenEvent(Units::GEV, Units::MM) {
38 set_alphaQCD(evt.metadata("alphaS"));
39 set_alphaQED(evt.metadata("alphaEM"));
40
41 weights().push_back(1.); // unweighted events
42
43 // filling the particles content
44 const FourVector origin(0., 0., 0., 0.);
45 int cm_id = 0;
46
47 auto convert_particle = [](const cepgen::Particle& cg_part) -> GenParticle* {
48 const auto cg_mom = cg_part.momentum();
49 auto* part = new GenParticle(FourVector(cg_mom.px(), cg_mom.py(), cg_mom.pz(), cg_mom.energy()),
50 cg_part.integerPdgId(),
51 (int)cg_part.status());
52 part->set_generated_mass(cepgen::PDG::get().mass(cg_part.pdgId()));
53 return part;
54 };
55
56 auto v1 = new GenVertex(origin), v2 = new GenVertex(origin), vcm = new GenVertex(origin);
57 unsigned short idx = 1;
58 for (const auto& part_orig : evt.particles()) {
59 auto* part = convert_particle(part_orig);
60 part->suggest_barcode(idx);
61 assoc_map_[idx] = part;
62
63 switch (part_orig.role()) {
65 v1->add_particle_in(part);
66 break;
68 v2->add_particle_in(part);
69 break;
71 v1->add_particle_out(part);
72 break;
74 v2->add_particle_out(part);
75 break;
77 v1->add_particle_out(part);
78 vcm->add_particle_in(part);
79 break;
81 v2->add_particle_out(part);
82 vcm->add_particle_in(part);
83 break;
85 // skip the two-parton system and propagate the parentage
86 cm_id = idx;
87 continue;
89 default: {
90 const auto& moth = part_orig.mothers();
91 if (moth.empty())
92 // skip disconnected lines
93 continue;
94 // get mother(s) id(s)
95 const short m1 = *moth.begin();
96 const short m2 = moth.size() > 1 ? *moth.rbegin() : -1;
97 // check if particle is connected to the two-parton system
98 if (m1 == cm_id || (m2 >= 0 && (m1 < cm_id && cm_id <= m2))) // also supports range
99 vcm->add_particle_out(part);
100 // if part of the decay chain of central system, find parents
101 else if (assoc_map_.count(m1) != 0) {
102 auto vprod = assoc_map_.at(m1)->end_vertex();
103 std::list<short> ids{m1}; // list of mother particles
104 if (assoc_map_.count(m2) != 0 && m2 > m1) {
105 ids.resize(m2 - m1 + 1);
106 std::iota(ids.begin(), ids.end(), m1);
107 }
108 if (!vprod) {
109 vprod = new GenVertex();
110 for (const auto& id : ids)
111 vprod->add_particle_in(assoc_map_.at(id));
112 add_vertex(vprod);
113 }
114 vprod->add_particle_out(part);
115 } else {
116 if (v1)
117 delete v1;
118 if (v2)
119 delete v2;
120 if (vcm)
121 delete vcm;
122 throw CG_FATAL("HepMC2:fillEvent") << "Other particle requested! Not yet implemented!";
123 }
124 } break;
125 }
126 idx++;
127 }
128 add_vertex(v1);
129 add_vertex(v2);
130 add_vertex(vcm);
131
132 if (v1->particles_in_size() > 0 && v2->particles_in_size() > 0)
133 set_beam_particles(*v1->particles_in_const_begin(), *v2->particles_in_const_begin());
136 set_signal_process_vertex(vcm);
137 }
138
139 CepGenEvent::operator cepgen::Event() const {
140 cepgen::Event evt;
141 auto convert_particle = [](const GenParticle& part,
142 const cepgen::Particle::Role& role =
144 auto convert_momentum = [](const FourVector& mom) -> cepgen::Momentum {
145 return cepgen::Momentum::fromPxPyPzE(mom.px(), mom.py(), mom.pz(), mom.e());
146 };
147 auto cg_part = cepgen::Particle(role, 0, (cepgen::Particle::Status)part.status());
148 cg_part.setPdgId((long)part.pdg_id());
149 cg_part.setMomentum(convert_momentum(part));
150 return cg_part;
151 };
152
153 auto [ip1, ip2] = beam_particles();
154 std::unordered_map<size_t, size_t> h_to_cg;
155 std::vector<int> beam_vtx_barcodes;
156 for (auto it_vtx = vertices_begin(); it_vtx != vertices_end(); ++it_vtx) {
157 if ((*it_vtx)->particles_in_size() == 1) {
158 auto role1 = cepgen::Particle::Role::UnknownRole, role2 = role1, role3 = role1;
159 size_t id_beam_in = 0;
160 if (auto* part = *(*it_vtx)->particles_in_const_begin(); part) {
161 if (part->barcode() == ip1->barcode()) {
165 } else if (part->barcode() == ip2->barcode()) {
169 }
170 auto cg_part = convert_particle(*part, role1);
172 evt.addParticle(cg_part);
173 h_to_cg[part->barcode()] = cg_part.id();
174 id_beam_in = cg_part.id();
175 }
176 if ((*it_vtx)->particles_out_size() == 2) { //FIXME handle cases with multiple partons?
177 size_t num_op = 0;
178 for (auto it_op = (*it_vtx)->particles_out_const_begin(); it_op != (*it_vtx)->particles_out_const_end();
179 ++it_op, ++num_op) {
180 auto cg_part = convert_particle(*(*it_op), num_op == 0 ? role2 : role3);
181 cg_part.setStatus(num_op == 0 ? cepgen::Particle::Status::Incoming
183 cg_part.addMother(evt[id_beam_in]);
184 evt.addParticle(cg_part);
185 h_to_cg[(*it_op)->barcode()] = cg_part.id();
186 }
187 }
188 beam_vtx_barcodes.emplace_back((*it_vtx)->barcode());
189 }
190 }
191
195 cg_interm.setMomentum(part1.momentum() + part2.momentum(), true);
196 cg_interm.addMother(part1);
197 cg_interm.addMother(part2);
198 evt.addParticle(cg_interm);
199
200 for (auto it_vtx = vertices_begin(); it_vtx != vertices_end(); ++it_vtx) {
201 if (cepgen::utils::contains(beam_vtx_barcodes, (*it_vtx)->barcode()))
202 continue;
203 if ((*it_vtx)->barcode() == signal_process_vertex()->barcode()) {
204 for (auto it_op = (*it_vtx)->particles_out_const_begin(); it_op != (*it_vtx)->particles_out_const_end();
205 ++it_op) {
206 auto cg_part = convert_particle(*(*it_op), cepgen::Particle::Role::CentralSystem);
208 evt.addParticle(cg_part);
209 h_to_cg[(*it_op)->barcode()] = cg_part.id();
210 }
211 } else {
212 (*it_vtx)->print(std::cout);
213 throw CG_FATAL("CepGenEvent") << "Not yet supporting secondary decay of central system.";
214 }
215 }
216 return evt;
217 }
218} // namespace HepMC
#define CG_FATAL(mod)
Definition Exception.h:61
CepGenEvent(const cepgen::Event &ev)
Construct an event interface from a CepGen Event object.
Container for the information on the in- and outgoing particles' kinematics.
Definition Event.h:28
Particle & oneWithRole(Particle::Role role)
First Particle object with a given role in the event.
Definition Event.cpp:190
ParticleRef addParticle(Particle &part, bool replace=false)
Set the information on one particle in the process.
Definition Event.cpp:323
Particles particles() const
Vector of all particles in the event.
Definition Event.cpp:353
EventMetadata metadata
List of auxiliary information.
Definition Event.h:136
bool hasRole(Particle::Role role) const
Check whether a particle role is represented in this event.
Definition Event.h:82
Container for a particle's 4-momentum, along with useful methods to ease the development of any matri...
Definition Momentum.h:33
static Momentum fromPxPyPzE(double px, double py, double pz, double e)
Build a 4-momentum from its four momentum and energy coordinates.
Definition Momentum.cpp:82
double mass() const
Mass (in GeV) as computed from its energy and momentum.
Definition Momentum.cpp:222
static PDG & get()
Retrieve a unique instance of this particles info collection.
Definition PDG.cpp:41
Kinematic information for one particle.
Definition Particle.h:33
Momentum & momentum()
Retrieve the momentum object associated with this particle Retrieve the momentum object associated wi...
Definition Particle.h:123
Particle & setMomentum(const Momentum &, bool offshell=false)
Associate a momentum object to this particle.
Definition Particle.cpp:77
Particle & addMother(Particle &part)
Set the mother particle.
Definition Particle.cpp:47
Status
Internal status code for a particle.
Definition Particle.h:36
@ PrimordialIncoming
Incoming beam particle.
@ Incoming
Incoming parton.
@ Unfragmented
Particle to be hadronised externally.
@ Propagator
Generic propagator.
@ IncomingBeam2
incoming beam particle
Definition Particle.h:53
@ Parton2
beam incoming parton
Definition Particle.h:59
@ OutgoingBeam1
outgoing beam state/particle
Definition Particle.h:54
@ UnknownRole
Undefined role.
Definition Particle.h:51
@ IncomingBeam1
incoming beam particle
Definition Particle.h:52
@ OutgoingBeam2
outgoing beam state/particle
Definition Particle.h:55
@ Parton1
beam incoming parton
Definition Particle.h:58
@ CentralSystem
Central particles system.
Definition Particle.h:56
@ Intermediate
Intermediate two-parton system.
Definition Particle.h:57
bool contains(const std::vector< T > &coll, const T &item)
Check if a vector contains an item.
Definition Collections.h:47