cepgen is hosted by Hepforge, IPPP Durham
CepGen 1.2.5
Central exclusive processes event generator
Loading...
Searching...
No Matches
IncomingBeams.cpp
Go to the documentation of this file.
1/*
2 * CepGen: a central exclusive processes event generator
3 * Copyright (C) 2013-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 <cmath>
20
30#include "CepGen/Physics/PDG.h"
31#include "CepGen/Utils/Math.h"
32
33namespace cepgen {
35 (*this).add("structureFunctions", strfun_);
36 }
37
40 ParametersList plist_pos, plist_neg;
41
42 //----- single beam definition
43
44 auto& pos_pdg = plist_pos.operator[]<int>("pdgId"); // positive-z incoming beam
45 if (pos_pdg = steer<int>("beam1id"); pos_pdg == PDG::invalid) {
46 if (const auto& hi_Z1 = steerAs<int, Element>("beam1Z"); hi_Z1 != Element::invalid)
47 pos_pdg = HeavyIon(steer<int>("beam1A"), hi_Z1);
48 else if (const auto& hi_beam1 = steer<std::vector<int> >("heavyIon1"); hi_beam1.size() >= 2)
49 pos_pdg = HeavyIon{(unsigned short)hi_beam1.at(0), static_cast<Element>(hi_beam1.at(1))};
50 }
51 auto& neg_pdg = plist_neg.operator[]<int>("pdgId"); // negative-z incoming beam
52 if (neg_pdg = steer<int>("beam2id"); neg_pdg == PDG::invalid) {
53 if (const auto& hi_Z2 = steerAs<int, Element>("beam2Z"); hi_Z2 != Element::invalid)
54 neg_pdg = HeavyIon(steer<int>("beam2A"), hi_Z2);
55 else if (const auto& hi_beam2 = steer<std::vector<int> >("heavyIon2"); hi_beam2.size() >= 2)
56 neg_pdg = HeavyIon{(unsigned short)hi_beam2.at(0), (Element)hi_beam2.at(1)};
57 }
58
59 //----- combined two-beam system
60
61 //--- beams PDG ids
62 if (const auto& beams_pdg = steer<std::vector<ParametersList> >("pdgIds"); beams_pdg.size() >= 2) {
63 pos_pdg = beams_pdg.at(0).get<int>("pdgid");
64 neg_pdg = beams_pdg.at(1).get<int>("pdgid");
65 } else if (const auto& beams_pdg = steer<std::vector<int> >("pdgIds"); beams_pdg.size() >= 2) {
66 pos_pdg = beams_pdg.at(0);
67 neg_pdg = beams_pdg.at(1);
68 }
69
70 //--- beams longitudinal momentum
71 double p1z = 0., p2z = 0;
72 if (const auto& beams_pz = steer<std::vector<double> >("pz"); beams_pz.size() >= 2) {
73 // fill from beam momenta
74 p1z = beams_pz.at(0);
75 p2z = beams_pz.at(1);
76 } else if (const auto& beams_ene = steer<std::vector<double> >("energies"); beams_ene.size() >= 2) {
77 // fill from beam energies
78 p1z = utils::fastSqrtSqDiff(beams_ene.at(0), PDG::get().mass(pos_pdg));
79 p2z = utils::fastSqrtSqDiff(beams_ene.at(1), PDG::get().mass(neg_pdg));
80 } else {
81 // when everything failed, retrieve "beamNpz" attributes
82 params_.fill<double>("beam1pz", p1z);
83 params_.fill<double>("beam2pz", p2z);
84 if (std::abs(pos_pdg) == std::abs(neg_pdg)) { // special case: symmetric beams -> fill from centre-of-mass energy
85 if (const auto sqrts = params_.has<double>("sqrtS") && steer<double>("sqrtS") > 0. ? steer<double>("sqrtS")
86 : params_.has<double>("cmEnergy") && steer<double>("cmEnergy") > 0.
87 ? steer<double>("cmEnergy")
88 : 0.;
89 sqrts > 0.) { // compute momenta from energy
90 const auto pz_abs = utils::fastSqrtSqDiff(0.5 * sqrts, PDG::get().mass(pos_pdg));
91 p1z = +pz_abs;
92 p2z = -pz_abs;
93 }
94 }
95 }
96 //--- check the sign of both beams' pz
97 if (p1z * p2z < 0. && p1z < 0.)
98 std::swap(p1z, p2z);
99 else if (p1z * p2z > 0. && p2z > 0.)
100 p2z *= -1.;
101
102 plist_pos.set<double>("pz", +fabs(p1z)).set<int>("pdgId", pos_pdg);
103 plist_neg.set<double>("pz", -fabs(p2z)).set<int>("pdgId", neg_pdg);
104
105 //--- form factors
106 ParametersList pos_formfac, neg_formfac;
107 if (auto formfacs = steer<std::vector<ParametersList> >("formFactors"); formfacs.size() >= 2) {
108 pos_formfac = formfacs.at(0);
109 neg_formfac = formfacs.at(1);
110 } else if (auto formfacs = steer<ParametersList>("formFactors"); !formfacs.empty())
111 pos_formfac = neg_formfac = formfacs;
112 pos_formfac.set<int>("pdgId", std::abs(pos_pdg));
113 neg_formfac.set<int>("pdgId", std::abs(neg_pdg));
114 plist_pos.set("formFactors", pos_formfac);
115 plist_neg.set("formFactors", neg_formfac);
116
117 //--- structure functions
118 const auto strfuns = steer<ParametersList>("structureFunctions");
119 if (!strfuns.empty()) {
120 plist_pos.set<ParametersList>("structureFunctions", strfuns);
121 plist_neg.set<ParametersList>("structureFunctions", strfuns);
122 }
123 //--- parton fluxes
124 ParametersList pos_flux, neg_flux;
125 auto set_part_fluxes_from_name_vector = [&](const std::vector<std::string>& fluxes) {
126 pos_flux = PartonFluxFactory::get().describeParameters(fluxes.at(0)).parameters();
127 neg_flux = fluxes.size() > 1 ? PartonFluxFactory::get().describeParameters(fluxes.at(1)).parameters() : pos_flux;
128 };
129 auto set_part_fluxes_from_name = [&](const std::string& fluxes) {
130 pos_flux = neg_flux = PartonFluxFactory::get().describeParameters(fluxes).parameters();
131 };
132
133 if (auto fluxes = steer<std::vector<ParametersList> >("partonFluxes"); fluxes.size() >= 2) {
134 pos_flux = fluxes.at(0);
135 neg_flux = fluxes.at(1);
136 } else if (auto fluxes = steer<ParametersList>("partonFluxes"); !fluxes.empty())
137 pos_flux = neg_flux = fluxes;
138 else if (const auto& fluxes = steer<std::vector<std::string> >("partonFluxes"); !fluxes.empty())
139 set_part_fluxes_from_name_vector(fluxes);
140 else if (const auto& flux = steer<std::string>("partonFluxes"); !flux.empty())
141 set_part_fluxes_from_name(flux);
142 else if (const auto& fluxes = steer<std::vector<std::string> >("ktFluxes"); !fluxes.empty()) {
143 set_part_fluxes_from_name_vector(fluxes);
144 CG_WARNING("IncomingBeams") << "Key 'ktFluxes' is deprecated. Please use 'partonFluxes' instead.";
145 } else if (const auto& flux = steer<std::string>("ktFluxes"); !flux.empty()) {
146 set_part_fluxes_from_name(flux);
147 CG_WARNING("IncomingBeams") << "Key 'ktFluxes' is deprecated. Please use 'partonFluxes' instead.";
148 }
149 pos_flux.set("formFactors", pos_formfac).set("structureFunctions", strfuns);
150 neg_flux.set("formFactors", neg_formfac).set("structureFunctions", strfuns);
151 plist_pos.set("partonFlux", pos_flux);
152 plist_neg.set("partonFlux", neg_flux);
153
154 if (auto mode = steerAs<int, mode::Kinematics>("mode"); mode != mode::Kinematics::invalid) {
155 plist_pos.set<bool>("elastic",
157 plist_neg.set<bool>("elastic",
159 } else {
160 const auto set_beam_elasticity = [](ParametersList& plist_beam) {
161 if (const auto& parton_flux_mod = plist_beam.get<ParametersList>("partonFlux"); !parton_flux_mod.name().empty())
162 plist_beam.set<bool>("elastic", PartonFluxFactory::get().elastic(parton_flux_mod));
163 else if (const auto& formfac_mod = plist_beam.get<ParametersList>("formFactors"); !formfac_mod.name().empty())
164 plist_beam.set<bool>("elastic", !FormFactorsFactory::get().build(formfac_mod)->fragmenting());
165 else {
166 CG_WARNING("IncomingBeams") << "Neither kinematics mod, parton flux modelling, or form factors modelling "
167 "were set. Assuming elastic emission.";
168 plist_beam.set<bool>("elastic", true);
169 }
170 };
171 set_beam_elasticity(plist_pos);
172 set_beam_elasticity(plist_neg);
173 }
174
175 CG_DEBUG("IncomingBeams") << "Will build the following incoming beams:\n"
176 << "* " << plist_pos << "\n"
177 << "* " << plist_neg << ".";
178 pos_beam_ = Beam(plist_pos);
179 neg_beam_ = Beam(plist_neg);
180 }
181
182 void IncomingBeams::setSqrtS(double sqrts) {
183 if (std::abs(pos_beam_.integerPdgId()) != std::abs(neg_beam_.integerPdgId()))
184 throw CG_FATAL("IncomingBeams:setSqrtS")
185 << "Trying to set √s with asymmetric beams"
186 << " (" << pos_beam_.integerPdgId() << "/" << neg_beam_.integerPdgId() << ").\n"
187 << "Please fill incoming beams objects manually!";
188 const auto pz_abs = utils::fastSqrtSqDiff(0.5 * sqrts, PDG::get().mass(pos_beam_.integerPdgId()));
189 pos_beam_.setMomentum(Momentum::fromPxPyPzM(0., 0., +pz_abs, PDG::get().mass(pos_beam_.integerPdgId())));
190 neg_beam_.setMomentum(Momentum::fromPxPyPzM(0., 0., -pz_abs, PDG::get().mass(neg_beam_.integerPdgId())));
191 }
192
193 double IncomingBeams::s() const {
194 const auto sval = (pos_beam_.momentum() + neg_beam_.momentum()).mass2();
195 CG_DEBUG("IncomingBeams:s") << "Beams momenta:\n"
196 << "\t" << pos_beam_.momentum() << "\n"
197 << "\t" << neg_beam_.momentum() << "\n"
198 << "\ts = (p1 + p2)^2 = " << sval << ", sqrt(s) = " << std::sqrt(sval) << ".";
199 return sval;
200 }
201
202 double IncomingBeams::sqrtS() const { return std::sqrt(s()); }
203
205 if (const auto& mode = steerAs<int, mode::Kinematics>("mode"); mode != mode::Kinematics::invalid)
206 return mode;
207 return modeFromBeams(pos_beam_, neg_beam_);
208 }
209
211 if (pos.elastic()) {
212 if (neg.elastic())
214 else
216 }
217 if (neg.elastic())
219 else
221 }
222
223 void IncomingBeams::setStructureFunctions(int sf_model, int sr_model) {
224 const unsigned long kLHAPDFCodeDec = 10000000, kLHAPDFPartDec = 1000000;
225 sf_model = (sf_model == 0 ? 11 /* SuriYennie */ : sf_model);
226 sr_model = (sr_model == 0 ? 4 /* SibirtsevBlunden */ : sr_model);
227 auto& sf_params = params_.operator[]<ParametersList>("structureFunctions");
228 sf_params = StructureFunctionsFactory::get().describeParameters(sf_model).parameters().set(
229 "sigmaRatio", SigmaRatiosFactory::get().describeParameters(sr_model).parameters());
230 if (sf_model / kLHAPDFCodeDec == 1) { // SF from parton
231 const unsigned long icode = sf_model % kLHAPDFCodeDec;
232 sf_params.setName("lhapdf")
233 .set<int>("pdfId", icode % kLHAPDFPartDec)
234 .set<int>("mode", icode / kLHAPDFPartDec); // 0, 1, 2
235 }
236 CG_DEBUG("IncomingBeams:setStructureFunctions")
237 << "Structure functions modelling to be built: " << sf_params << ".";
238 }
239
242 .set<int>("beam1id", pos_beam_.integerPdgId())
243 .set<double>("beam1pz", +pos_beam_.momentum().pz())
244 .set<int>("beam2id", neg_beam_.integerPdgId())
245 .set<double>("beam2pz", -neg_beam_.momentum().pz())
246 .setAs<int, mode::Kinematics>("mode", mode());
247 if (HeavyIon::isHI(pos_beam_.integerPdgId())) {
248 const auto hi1 = HeavyIon::fromPdgId(std::abs(pos_beam_.integerPdgId()));
249 params_.set<int>("beam1A", hi1.A).set<int>("beam1Z", (int)hi1.Z);
250 }
251 if (HeavyIon::isHI(neg_beam_.integerPdgId())) {
252 const auto hi2 = HeavyIon::fromPdgId(std::abs(neg_beam_.integerPdgId()));
253 params_.set<int>("beam2A", hi2.A).set<int>("beam2Z", (int)hi2.Z);
254 }
255 return params_;
256 }
257
259 auto desc = ParametersDescription();
260 desc.addAs<int, pdgid_t>("beam1id", PDG::invalid).setDescription("PDG id of the positive-z beam particle");
261 desc.add<int>("beam1A", 0).setDescription("Atomic weight of the positive-z ion beam");
262 desc.addAs<int, Element>("beam1Z", Element::invalid).setDescription("Atomic number of the positive-z ion beam");
263 desc.addAs<int, pdgid_t>("beam2id", PDG::invalid).setDescription("PDG id of the negative-z beam particle");
264 desc.add<int>("beam2A", 0).setDescription("Atomic weight of the negative-z ion beam");
265 desc.addAs<int, Element>("beam2Z", Element::invalid).setDescription("Atomic number of the negative-z ion beam");
266 desc.add<std::vector<ParametersList> >("pdgIds", {}).setDescription("PDG description of incoming beam particles");
267 desc.add<std::vector<int> >("pdgIds", {}).setDescription("PDG ids of incoming beam particles");
268 desc.add<std::vector<double> >("pz", {}).setDescription("Beam momenta (in GeV/c)");
269 desc.add<std::vector<double> >("energies", {}).setDescription("Beam energies (in GeV/c)");
270 desc.add<double>("sqrtS", 0.).setDescription("Two-beam centre of mass energy (in GeV)");
271 desc.addAs<int, mode::Kinematics>("mode", mode::Kinematics::invalid)
272 .setDescription("Process kinematics mode")
273 .allow(1, "elastic")
274 .allow(2, "elastic-inelastic")
275 .allow(3, "inelastic-elastic")
276 .allow(4, "double-dissociative")
277 .allowAll();
278 desc.addParametersDescriptionVector(
279 "formFactors",
280 FormFactorsFactory::get().describeParameters(formfac::gFFStandardDipoleHandler),
281 std::vector<ParametersList>(
282 2, FormFactorsFactory::get().describeParameters(formfac::gFFStandardDipoleHandler).parameters()))
283 .setDescription("Beam form factors modelling");
284 desc.add<ParametersDescription>("structureFunctions",
285 StructureFunctionsFactory::get().describeParameters("SuriYennie"))
286 .setDescription("Beam inelastic structure functions modelling");
287 return desc;
288 }
289} // namespace cepgen
#define CG_FATAL(mod)
Definition Exception.h:61
#define CG_WARNING(mod)
Definition Message.h:228
#define CG_DEBUG(mod)
Definition Message.h:220
Incoming beams characteristics.
Definition Beam.h:30
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
Beam & setMomentum(const Momentum &mom)
Definition Beam.h:56
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
void setParameters(const ParametersList &) override
Set module parameters.
static mode::Kinematics modeFromBeams(const Beam &, const Beam &)
Extract kinematics type from both beams.
double s() const
Incoming beams squared centre of mass energy (in GeV^2)
double sqrtS() const
Incoming beams centre of mass energy (in GeV)
IncomingBeams(const ParametersList &)
void setSqrtS(double)
Set the incoming beams centre of mass energy (in GeV)
void setStructureFunctions(int, int)
Set the integer-type of structure functions evaluator to build.
static ParametersDescription description()
const ParametersList & parameters() const override
List containing all parameters handled.
mode::Kinematics mode() const
Type of kinematics to consider for the phase space.
double pz() const
Longitudinal momentum (in GeV)
Definition Momentum.h:120
static Momentum fromPxPyPzM(double px, double py, double pz, double m)
Build a 4-momentum from its three momentum coordinates and mass.
Definition Momentum.cpp:84
@ invalid
Definition PDG.h:34
double mass(spdgid_t) const
Particle mass (in GeV)
Definition PDG.cpp:90
static PDG & get()
Retrieve a unique instance of this particles info collection.
Definition PDG.cpp:41
A description object for parameters collection.
ParametersList & parameters()
List of parameters associated to this description object.
bool has(const std::string &key) const
Check if a given parameter is handled in this list.
std::string name(const std::string &def="") const
Retrieve the module name if any.
ParametersList & setName(const std::string &)
Set the module name.
ParametersList & set(const std::string &, const T &)
Set a parameter value Set a recast parameter value.
const ParametersList & fill(const std::string &key, T &value) const
Fill a variable with the key content if exists.
ParametersList params_
Module parameters.
Definition Steerable.h:50
T steer(const std::string &key) const
Retrieve a parameters as previously steered.
Definition Steerable.h:39
Base user-steerable object.
virtual void setParameters(const ParametersList &params) override
Set module parameters.
const ParametersList & parameters() const override
Module user-defined parameters.
static constexpr const char * gFFStandardDipoleHandler
Standard dipole handler name.
Kinematics
Type of scattering.
Definition Modes.h:28
@ ElasticElastic
proton-proton elastic case
@ InelasticElastic
proton-proton single-dissociative (or elastic-inelastic) case
@ InelasticInelastic
proton-proton double-dissociative case
@ ElasticInelastic
proton-proton single-dissociative (or inelastic-elastic) case
double fastSqrtSqDiff(double x, double y)
Compute the square root of the squared difference (sqrt(a^2-b^2))
Definition Math.cpp:43
Common namespace for this Monte Carlo generator.
Element
Enumeration of chemical elements.
Definition HeavyIon.h:28
unsigned long long pdgid_t
Alias for the integer-like particle PDG id.
Heavy ion container (Z+A)
Definition HeavyIon.h:44
static HeavyIon fromPdgId(pdgid_t)
Build from a custom PDG id.
Definition HeavyIon.cpp:34
static bool isHI(const spdgid_t &)
Check if the PDG id is compatible with a HI.
Definition HeavyIon.cpp:54
static PartonFluxFactory & get()
bool elastic(const ParametersList &) const
Is the beam modelling elastic?
ParametersDescription describeParameters(const std::string &name, const ParametersList &params=ParametersList()) const