cepgen is hosted by Hepforge, IPPP Durham
CepGen 1.2.5
Central exclusive processes event generator
Loading...
Searching...
No Matches
PythiaEventInterface.cpp
Go to the documentation of this file.
1/*
2 * CepGen: a central exclusive processes event generator
3 * Copyright (C) 2016-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
21#include "CepGen/Event/Event.h"
23#include "CepGen/Physics/PDG.h"
25
26namespace Pythia8 {
28 Vec4 momToVec4(const cepgen::Momentum& mom) { return Vec4(mom.px(), mom.py(), mom.pz(), mom.energy()); }
29
30 CepGenEvent::CepGenEvent() : LHAup(3), mp_(cepgen::PDG::get().mass(cepgen::PDG::proton)), mp2_(mp_ * mp_) {}
31
33 params_ = &params;
34 inel1_ = !params_->kinematics().incomingBeams().positive().elastic();
35 inel2_ = !params_->kinematics().incomingBeams().negative().elastic();
36
37 setBeamA((short)params_->kinematics().incomingBeams().positive().integerPdgId(),
38 params_->kinematics().incomingBeams().positive().momentum().pz());
39 setBeamB((short)params_->kinematics().incomingBeams().negative().integerPdgId(),
40 params_->kinematics().incomingBeams().negative().momentum().pz());
41 //addProcess( 0, params_->integration().result, params_->integration().err_result, 100. );
42 }
43
44 void CepGenEvent::addComments(const std::string& comments) {
45#if PYTHIA_VERSION_INTEGER >= 8200
46 osLHEF << comments;
47#else
48 CG_WARNING("CepGenEvent:addComments") << "Pythia 8 is too outdated... Unused comments: " << comments;
49#endif
50 }
51
52 void CepGenEvent::setCrossSection(int id, double cross_section, double cross_section_err) {
53 addProcess(0, cross_section, cross_section_err, 100.);
54 setXSec(id, cross_section);
55 setXErr(id, cross_section_err);
56 //listInit();
57 }
58
59 void CepGenEvent::feedEvent(const cepgen::Event& ev, const Type& type) {
60 const double scale = ev(cepgen::Particle::Intermediate)[0].momentum().mass();
61 setProcess(0, 1., scale, ev.metadata("alphaEM"), ev.metadata("alphaS"));
62
63 const auto &part1 = ev(cepgen::Particle::Parton1)[0], &part2 = ev(cepgen::Particle::Parton2)[0];
64 const auto &op1 = ev(cepgen::Particle::OutgoingBeam1)[0], &op2 = ev(cepgen::Particle::OutgoingBeam2)[0];
65 const double q2_1 = -part1.momentum().mass2(), q2_2 = -part2.momentum().mass2();
66 const double x1 = q2_1 / (q2_1 + op1.momentum().mass2() - mp2_), x2 = q2_2 / (q2_2 + op2.momentum().mass2() - mp2_);
67
68 unsigned short colour_index = MIN_COLOUR_INDEX;
69
70 const Vec4 mom_part1(momToVec4(part1.momentum())), mom_part2(momToVec4(part2.momentum()));
71
72 if (type == Type::centralAndBeamRemnants) { // full event content (with collinear partons)
73 Vec4 mom_iq1 = mom_part1, mom_iq2 = mom_part2;
74 unsigned short parton1_id, parton2_id;
75 unsigned short parton1_pdgid = part1.integerPdgId(), parton2_pdgid = part2.integerPdgId();
76 unsigned short parton1_colour = 0, parton2_colour = 0;
77 //FIXME select quark flavours accordingly
78 if (inel1_) {
79 parton1_pdgid = 2;
80 parton1_colour = colour_index++;
81 mom_iq1 = momToVec4(x1 * ev(cepgen::Particle::IncomingBeam1)[0].momentum());
82 }
83 if (inel2_) {
84 parton2_pdgid = 2;
85 parton2_colour = colour_index++;
86 mom_iq2 = momToVec4(x2 * ev(cepgen::Particle::IncomingBeam2)[0].momentum());
87 }
88
89 //--- flavour / x value of hard-process initiators
90 setIdX(part1.integerPdgId(), part2.integerPdgId(), x1, x2);
91 setPdf(parton1_pdgid, parton2_pdgid, x1, x2, scale, 0., 0., false);
92
93 //===========================================================================================
94 // incoming valence quarks
95 //===========================================================================================
96
97 parton1_id = sizePart();
98 addCorresp(parton1_id, op1.id());
99 addParticle(parton1_pdgid,
100 -1,
101 0,
102 0,
103 parton1_colour,
104 0,
105 mom_iq1.px(),
106 mom_iq1.py(),
107 mom_iq1.pz(),
108 mom_iq1.e(),
109 mom_iq1.mCalc(),
110 0.,
111 1.);
112
113 parton2_id = sizePart();
114 addCorresp(parton2_id, op2.id());
115 addParticle(parton2_pdgid,
116 -1,
117 0,
118 0,
119 parton2_colour,
120 0,
121 mom_iq2.px(),
122 mom_iq2.py(),
123 mom_iq2.pz(),
124 mom_iq2.e(),
125 mom_iq2.mCalc(),
126 0.,
127 1.);
128
129 //===========================================================================================
130 // outgoing valence quarks
131 //===========================================================================================
132
133 if (inel1_) {
134 const Vec4 mom_oq1 = mom_iq1 - mom_part1;
135 addParticle(parton1_pdgid,
136 1,
137 parton1_id,
138 parton2_id,
139 parton1_colour,
140 0,
141 mom_oq1.px(),
142 mom_oq1.py(),
143 mom_oq1.pz(),
144 mom_oq1.e(),
145 mom_oq1.mCalc(),
146 0.,
147 1.);
148 }
149 if (inel2_) {
150 const Vec4 mom_oq2 = mom_iq2 - mom_part2;
151 addParticle(parton2_pdgid,
152 1,
153 parton1_id,
154 parton2_id,
155 parton2_colour,
156 0,
157 mom_oq2.px(),
158 mom_oq2.py(),
159 mom_oq2.pz(),
160 mom_oq2.e(),
161 mom_oq2.mCalc(),
162 0.,
163 1.);
164 }
165 } else {
166 //===========================================================================================
167 // incoming partons
168 //===========================================================================================
169
170 addCepGenParticle(part1, -2);
171 addCepGenParticle(part2, -2);
172
174 //=========================================================================================
175 // full beam remnants content
176 //=========================================================================================
177
179 for (const auto& p : ev(syst))
180 addCepGenParticle(p, INVALID_ID, findMothers(ev, p));
181 }
182 }
183 }
184
185 //=============================================================================================
186 // central system
187 //=============================================================================================
188
189 const unsigned short central_colour = colour_index++;
190 for (const auto& p : ev(cepgen::Particle::CentralSystem)) {
191 std::pair<int, int> colours = {0, 0}, mothers = {1, 2};
193 mothers = findMothers(ev, p);
194 try {
195 if (cepgen::PDG::get().colours(p.pdgId()) > 1) {
196 if (p.integerPdgId() > 0) //--- particle
197 colours.first = central_colour;
198 else //--- anti-particle
199 colours.second = central_colour;
200 }
201 } catch (const cepgen::Exception&) {
202 }
203 int status = 1;
205 status = 2;
206 addCepGenParticle(p, status, mothers, colours);
207 }
208 }
209
210 void CepGenEvent::setProcess(int id, double cross_section, double q2_scale, double alpha_qed, double alpha_qcd) {
211 LHAup::setProcess(id, cross_section, q2_scale, alpha_qed, alpha_qcd);
212 py_cg_corresp_.clear();
213 }
214
215 unsigned short CepGenEvent::cepgenId(unsigned short py_id) const {
216 if (py_cg_corresp_.count(py_id) == 0)
217 return INVALID_ID;
218 return py_cg_corresp_.at(py_id);
219 }
220
221 unsigned short CepGenEvent::pythiaId(unsigned short cg_id) const {
222 auto it = std::find_if(
223 py_cg_corresp_.begin(), py_cg_corresp_.end(), [&cg_id](const auto& py_cg) { return py_cg.second == cg_id; });
224 if (it != py_cg_corresp_.end())
225 return it->first;
226 return INVALID_ID;
227 }
228
230 int status,
231 const std::pair<int, int>& mothers,
232 const std::pair<int, int>& colours) {
233 const Vec4 mom_part(momToVec4(part.momentum()));
234 int pdg_id = part.integerPdgId();
235 if (status == INVALID_ID)
236 switch (part.status()) {
239 status = 2;
240 break;
241 default: {
242 if (part.pdgId() == 21 && (int)part.status() == 12)
243 pdg_id = -21; // workaround for HepMC2 interface
244 else
245 status = 1;
246 } break;
247 }
248 addCorresp(sizePart(), part.id());
249 addParticle(pdg_id,
250 status,
251 mothers.first,
252 mothers.second,
253 colours.first,
254 colours.second,
255 mom_part.px(),
256 mom_part.py(),
257 mom_part.pz(),
258 mom_part.e(),
259 mom_part.mCalc(),
260 0.,
261 0.,
262 0.);
263 }
264
265 void CepGenEvent::addCorresp(unsigned short py_id, unsigned short cg_id) { py_cg_corresp_[py_id] = cg_id; }
266
268 CG_INFO("CepGenEvent:dump").log([&](auto& msg) {
269 msg << "List of Pythia ←|→ CepGen particle ids correspondence";
270 for (const auto& py_cg : py_cg_corresp_)
271 msg << "\n\t" << py_cg.first << " <-> " << py_cg.second;
272 });
273 }
274
275 std::pair<int, int> CepGenEvent::findMothers(const cepgen::Event& ev, const cepgen::Particle& p) const {
276 std::pair<int, int> out = {0, 0};
277
278 const auto& mothers = p.mothers();
279 if (mothers.empty())
280 return out;
281 const unsigned short moth1_cg_id = *mothers.begin();
282 out.first = pythiaId(moth1_cg_id);
283 if (out.first == INVALID_ID) {
284 const auto& moth = ev(moth1_cg_id);
285 out = {(moth.mothers().size() > 0) ? pythiaId(*moth.mothers().begin()) : 0,
286 (moth.mothers().size() > 1) ? pythiaId(*moth.mothers().rbegin()) : 0};
287 }
288 if (mothers.size() > 1) {
289 const unsigned short moth2_cg_id = *mothers.rbegin();
290 out.second = pythiaId(moth2_cg_id);
291 if (out.second == INVALID_ID)
292 out.second = 0;
293 }
294 return out;
295 }
296} // namespace Pythia8
#define CG_WARNING(mod)
Definition Message.h:228
#define CG_INFO(mod)
Definition Message.h:216
void addCorresp(unsigned short py_id, unsigned short cg_id)
Register a new Pythia8 / CepGen particle mapping.
void feedEvent(const cepgen::Event &ev, const Type &type)
Feed a new CepGen event to this conversion object.
Type
List of particles to be included to the event content.
@ centralAndFullBeamRemnants
include dissociated beam remnants and central system
@ centralAndBeamRemnants
include undissociated beam remnants and central system
void setCrossSection(int id, double cross_section, double cross_section_err)
Set the cross section for a given process.
static constexpr unsigned short INVALID_ID
Invalid id association.
unsigned short cepgenId(unsigned short py_id) const
Retrieve the CepGen particle index given its Pythia8 event id.
void initialise(const cepgen::RunParameters &)
Initialise this conversion object with CepGen parameters.
void addComments(const std::string &comments)
Feed comments to the LHEF block.
void addCepGenParticle(const cepgen::Particle &part, int status=INVALID_ID, const std::pair< int, int > &mothers={0, 0}, const std::pair< int, int > &colours={0, 0})
Add a CepGen particle to the event content.
static constexpr unsigned short MIN_COLOUR_INDEX
Minimal colour indexing number.
unsigned short pythiaId(unsigned short cg_id) const
Retrieve the Pythia8 particle index given its CepGen event id.
void dumpCorresp() const
Print all Pythia8 / CepGen Particles correspondences.
void setProcess(int id, double cross_section, double q2_scale, double alpha_qed, double alpha_qcd)
Specify new process attributes.
spdgid_t integerPdgId() const
Beam particle PDG id Set the beam particle PDG id.
Definition Beam.h:47
const Momentum & momentum() const
Beam particle 4-momentum Set the beam particle 4-momentum.
Definition Beam.h:54
bool elastic() const
Does the beam remain on-shell after parton emission? Specify if the beam remains on-shell after parto...
Definition Beam.h:40
Container for the information on the in- and outgoing particles' kinematics.
Definition Event.h:28
EventMetadata metadata
List of auxiliary information.
Definition Event.h:136
const Beam & positive() const
Reference to the positive-z beam information.
const Beam & negative() const
Reference to the negative-z beam information.
IncomingBeams & incomingBeams()
Beam/primary particle kinematics.
Definition Kinematics.h:36
Container for a particle's 4-momentum, along with useful methods to ease the development of any matri...
Definition Momentum.h:33
double pz() const
Longitudinal momentum (in GeV)
Definition Momentum.h:120
double px() const
Momentum along the -axis (in GeV)
Definition Momentum.h:112
double py() const
Momentum along the -axis (in GeV)
Definition Momentum.h:116
double energy() const
Energy (in GeV)
Definition Momentum.h:136
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
pdgid_t pdgId() const
Retrieve the objectified PDG identifier Set the PDG identifier (along with the particle's electric ch...
Definition Particle.cpp:91
long integerPdgId() const
Retrieve the integer value of the PDG identifier.
Definition Particle.cpp:102
@ Fragmented
Already fragmented outgoing beam.
@ Resonance
Already decayed intermediate resonance.
int id() const
Unique identifier (in a Event object context) Set the particle unique identifier in an event.
Definition Particle.h:76
ParticlesIds mothers() const
Identifier to the mother particles.
Definition Particle.h:144
@ 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
@ 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
Status status() const
Particle status Set the particle decay/stability status.
Definition Particle.h:94
List of parameters used to start and run the simulation job.
const Kinematics & kinematics() const
Events kinematics for phase space definition.
Vec4 momToVec4(const cepgen::Momentum &mom)
Convert a CepGen particle momentum into its Pythia8 counterpart.
Common namespace for this Monte Carlo generator.