cepgen is hosted by Hepforge, IPPP Durham
CepGen 1.2.5
Central exclusive processes event generator
Loading...
Searching...
No Matches
KulaginBarinov.cpp
Go to the documentation of this file.
1/*
2 * CepGen: a central exclusive processes event generator
3 * Copyright (C) 2022-2024 Laurent Forthomme
4 * 2021 Sergey Kulagin
5 * Vladislav Barinov
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <cmath>
22#include <fstream>
23
29#include "CepGen/Physics/PDG.h"
36
37namespace cepgen {
38 namespace strfun {
42 public:
43 explicit KulaginBarinov(const ParametersList&);
44
47 desc.setDescription("Kulagin-Barinov (hybrid)");
48 desc.add<ParametersDescription>("derivator", DerivatorFactory::get().describeParameters("gsl"));
50 "resonances",
52 {ParametersList() // Delta(1232)
53 .set<double>("mass", 1.2270)
54 .set<double>("width", 0.11279)
55 .set<int>("angularMomentum", 1)
56 .set<double>("x0", 0.055384)
57 .set<std::vector<double> >("a", {0.31115, 2.0294, 1.6713, 2.76})
58 .set<std::vector<double> >("c", {0.05029, 0., 0.42522})
59 .set<ParametersList>(
60 "branchingRatios",
61 ParametersList().set<double>("singlePi", 1.).set<double>("doublePi", 0.).set<double>("eta", 0.)),
62 ParametersList() // N(1440)
63 .set<double>("mass", 1.4497)
64 .set<double>("width", 0.40223)
65 .set<int>("angularMomentum", 1)
66 .set<double>("x0", 0.1125)
67 .set<std::vector<double> >("a", {0.089547, 0.18087, 0.23431, 4.1173})
68 .set<std::vector<double> >("c", {0., 0.23847, 1.4982})
69 .set<ParametersList>(
70 "branchingRatios",
71 ParametersList().set<double>("singlePi", 0.65).set<double>("doublePi", 0.35).set<double>("eta", 0.)),
72 ParametersList() // R1
73 .set<double>("mass", 1.5123)
74 .set<double>("width", 0.094542)
75 .set<int>("angularMomentum", 2)
76 .set<double>("x0", 0.4959)
77 .set<std::vector<double> >("a", {0.10677, 0.24897, 0.55621, 3.0798})
78 .set<std::vector<double> >("c", {0.091979, -0.10652, 1.0758})
79 .set<ParametersList>(
80 "branchingRatios",
81 ParametersList().set<double>("singlePi", 0.75).set<double>("doublePi", 0.25).set<double>("eta", 0.)),
82 ParametersList() // R2
83 .set<double>("mass", 1.5764)
84 .set<double>("width", 0.50046)
85 .set<int>("angularMomentum", 0)
86 .set<double>("x0", 0.30969)
87 .set<std::vector<double> >("a", {0.38953, -0.17962, 0.37638, 2.9622})
88 .set<std::vector<double> >("c", {0., 0., 0.})
89 .set<ParametersList>(
90 "branchingRatios",
91 ParametersList().set<double>("singlePi", 0.15).set<double>("doublePi", 0.85).set<double>("eta", 0.)),
92 ParametersList() // R3
93 .set<double>("mass", 1.7002)
94 .set<double>("width", 0.11768)
95 .set<int>("angularMomentum", 2)
96 .set<double>("x0", 0.25831)
97 .set<std::vector<double> >("a", {0.067075, 0.097330, 0.27891, 3.5372})
98 .set<std::vector<double> >("c", {0.12027, 0., 0.89367})
99 .set<ParametersList>("branchingRatios",
101 .set<double>("singlePi", 0.15)
102 .set<double>("doublePi", 0.6)
103 .set<double>("eta", 0.25))});
104 // DIS block
105 auto dis_desc = ParametersDescription();
106 dis_desc.add<double>("bg1l", 3.4742);
107 dis_desc.add<double>("bg2l", 0.54193);
108 dis_desc.add<double>("pml", 1.1).setDescription("exponent of t dependence for FL");
109 dis_desc.add<double>("bg1t", 0.14453);
110 dis_desc.add<double>("bg2t", 3.1297);
111 dis_desc.add<double>("pmt", 1.6302).setDescription("exponent of t dependence for FT");
112 desc.add<ParametersDescription>("disParameters", dis_desc);
113
114 desc.add<double>("t0", 2.);
115 desc.add<Limits>("Q2range", Limits{1.e-12, 1.e3});
116 desc.add<Limits>("Q2gridRange", Limits{0.8, 1.e3}).setDescription("Q^2 range covered by the grid");
117 desc.add<std::string>("gridFile", "a08tmc.dat").setDescription("path to the DIS grid");
118 return desc;
119 }
120
121 void eval() override;
122
123 private:
124 static constexpr double prefactor_ = M_1_PI * M_1_PI / constants::ALPHA_EM;
125 const double t0_;
126 const Limits q2_range_, q2_grid_range_;
127 const std::string sfs_grid_file_;
128 enum Polarisation { L, T };
129 class Resonance : public ResonanceObject, public SteeredObject<Resonance> {
130 public:
131 explicit Resonance(const ParametersList& params)
132 : ResonanceObject(params),
133 SteeredObject<Resonance>(params),
134 a_(SteeredObject<Resonance>::steer<std::vector<double> >("a")),
135 c_(SteeredObject<Resonance>::steer<std::vector<double> >("c")) {}
136
137 static ParametersDescription description() {
138 auto desc = ResonanceObject::description();
139 desc.add<std::vector<double> >("a", std::vector<double>(4, 0.));
140 desc.add<std::vector<double> >("c", std::vector<double>(3, 0.));
141 return desc;
142 }
143
144 bool computeStrFuns(const KinematicsBlock& kin, double& fl, double& ft) const {
145 // compute contributions to the total resonance width
146 const double width_t = partialWidth(kin);
147 if (width_t <= 0.)
148 return false;
149 // off-shell effect on electrocouplings
150 const double f_gamma = photonWidth(kin) / width_;
151 const double mass2 = mass_ * mass_;
152
153 // Breit-Wigner factor together with off-shell factor
154 const double f_bw =
155 f_gamma * kcmr() * mass2 * width_t / (std::pow(kin.w2 - mass2, 2) + mass2 * std::pow(width_t, 2));
156
157 // compute structure functions using model of resonance helicity amplitudes
158 fl = f_bw * std::pow((c_.at(0) + c_.at(1) * kin.q2) * exp(-c_.at(2) * kin.q2), 2);
159 ft = f_bw * std::pow((a_.at(0) + a_.at(1) * kin.q2) * std::pow(1. + a_.at(2) * kin.q2, -a_.at(3)), 2);
160 return true;
161 }
162
163 private:
164 const std::vector<double> a_;
165 const std::vector<double> c_;
166 };
167 std::vector<Resonance> resonances_;
168 const struct DISParameters : SteeredObject<DISParameters> {
169 explicit DISParameters(const ParametersList& params)
170 : SteeredObject(params),
171 bg1l(steer<double>("bg1l")),
172 bg2l(steer<double>("bg2l")),
173 pml(steer<double>("pml")),
174 bg1t(steer<double>("bg1t")),
175 bg2t(steer<double>("bg2t")),
176 pmt(steer<double>("pmt")) {}
177 double bg1l, bg2l, pml;
178 double bg1t, bg2t, pmt;
179 } dis_params_;
180 GridHandler<2, 2> sfs_grid_{GridType::linear};
181 std::unique_ptr<utils::Derivator> deriv_;
182 const double mpi2_, meta2_;
183 };
184
186 : Parameterisation(params),
187 t0_(steer<double>("t0")),
188 q2_range_(steer<Limits>("Q2range")),
189 q2_grid_range_(steer<Limits>("Q2gridRange")),
190 sfs_grid_file_(steerPath("gridFile")),
191 dis_params_(steer<ParametersList>("disParameters")),
192 deriv_(DerivatorFactory::get().build(steer<ParametersList>("derivator"))),
193 mpi2_(std::pow(PDG::get().mass(PDG::piZero), 2)),
194 meta2_(std::pow(PDG::get().mass(PDG::eta), 2)) {
195 for (const auto& res : steer<std::vector<ParametersList> >("resonances"))
196 resonances_.emplace_back(res);
197 { // build the FT and F2 grid
198 if (!utils::fileExists(sfs_grid_file_))
199 throw CG_FATAL("KulaginBarinov")
200 << "Failed to load the DIS structure functions interpolation grid from '" << sfs_grid_file_ << "'!";
201 CG_INFO("KulaginBarinov") << "Loading A08 structure function values from '" << sfs_grid_file_ << "' file.";
202 std::ifstream grid_file(sfs_grid_file_);
203 static const size_t num_xbj = 99, num_q2 = 70, num_sf = 2;
204 static const double min_xbj = 1.01e-5;
205 //--- xbj & Q2 binning
206 const size_t nxbb = num_xbj / 2;
207 const double x1 = 0.3, xlog1 = log(x1), delx = (xlog1 - log(min_xbj)) / (nxbb - 1),
208 delx1 = std::pow(1. - x1, 2) / (nxbb + 1);
209 const double dels =
210 (log(log(q2_grid_range_.max() / 0.04)) - log(log(q2_grid_range_.min() / 0.04))) / (num_q2 - 1);
211 // parameterisation of Twist-4 correction from A08 analysis arXiv:0710.0124 [hep-ph] (assuming F2ht=FTht)
212 auto sfnht = [](double xbj, double q2) -> double {
213 return (std::pow(xbj, 0.9) * std::pow(1. - xbj, 3.63) * (xbj - 0.356) *
214 (1.0974 + 47.7352 * std::pow(xbj, 4))) /
215 q2;
216 };
217
218 for (size_t idx_xbj = 0; idx_xbj < num_xbj; ++idx_xbj) { // xbj grid
219 const double xbj = idx_xbj < nxbb ? exp(log(min_xbj) + delx * idx_xbj)
220 : 1. - std::sqrt(fabs(std::pow(1. - x1, 2) - delx1 * (idx_xbj - nxbb + 1)));
221 for (size_t idx_q2 = 0; idx_q2 < num_q2; ++idx_q2) { // Q^2 grid
222 const double q2 = 0.04 * exp(exp(log(log(q2_grid_range_.min() / 0.04)) + dels * idx_q2));
223 std::array<double, num_sf> sfs{};
224 for (size_t idx_sf = 0; idx_sf < num_sf; ++idx_sf) {
225 grid_file >> sfs[idx_sf]; // FT, F2
226 sfs[idx_sf] += sfnht(xbj, q2);
227 }
228 CG_DEBUG("KulaginBarinov:grid") << "Inserting new values into grid: " << std::vector<double>{xbj, q2} << "("
229 << std::vector<size_t>{idx_xbj, idx_q2} << "): " << sfs;
230 sfs_grid_.insert({xbj, q2}, sfs);
231 }
232 }
233 sfs_grid_.initialise();
234 CG_DEBUG("KulaginBarinov:grid") << "Grid boundaries: " << sfs_grid_.boundaries();
235 }
236 }
237
239 const double w2 = utils::mX2(args_.xbj, args_.q2, mp2_), w = std::sqrt(w2);
240 double fl{0.}, f2{0.};
241 { //--- resonances region
242 const auto kin = Resonance::KinematicsBlock(w2, args_.q2, mp2_, mpi2_, meta2_);
243 // proton c.m. energy and momentum (needed to compute additional kinematics factor for FL)
244 const double ecm = utils::energyFromW(w, -args_.q2, mp2_), q2cm = ecm * ecm - mp2_;
245 double fl_res{0.}, ft_res{0.};
246 for (const auto& res : resonances_) { // sum over the resonant contributions
247 double fl_sng_res, ft_sng_res;
248 if (!res.computeStrFuns(kin, fl_sng_res, ft_sng_res)) {
249 setFL(0.);
250 setF2(0.);
251 return;
252 }
253 fl_res += fl_sng_res;
254 ft_res += ft_sng_res;
255 } // end of resonance loop
256
257 // finalize calculation of sfn and xsec taking into account normalization factors
258 ft_res *= prefactor_ * args_.xbj * mp_;
259 fl_res *= 2. * prefactor_ * args_.xbj * mp_ * args_.q2 / q2cm;
260 const double f2_res = (fl_res + ft_res) / gamma2(args_.xbj, args_.q2);
261 fl += fl_res;
262 f2 += f2_res;
263 } //--- end of resonances region
264 { //--- perturbative region
265 double f2_dis = 0., fl_dis = 0.;
266 if (q2_range_.contains(args_.q2)) {
267 double ft_dis = 0.;
268 const double t = std::max(args_.q2, t0_), xbj_t = utils::xBj(t, mp2_, w2), gam2 = gamma2(xbj_t, t);
269 if (t > q2_grid_range_.min()) {
270 const auto sfs = sfs_grid_.eval({xbj_t, t}); // FT, F2
271 ft_dis = sfs.at(0);
272 f2_dis = sfs.at(1);
273 fl_dis = gam2 * f2_dis - ft_dis;
274 }
275 if (args_.q2 < t0_) {
276 // make extrapolation in q2 from q2=t down to q2=0
277 // compute derivative of SF with respect to q2 at q2=t
278
279 double ddt{0.}, ddl{0.};
280 if (xbj_t >= 1.e-6) { // check the range of validity
281 // DIS structure function model using the results of A08 analysis arXiv:0710.0124 [hep-ph]
282 ddt = deriv_->derivate(
283 [this, &xbj_t](double qsq) -> double {
284 return sfs_grid_.eval({xbj_t, qsq}).at(0);
285 }, // TM-corrected FT with twist-4 correction
286 t,
287 t * 1.e-2);
288 ddl = deriv_->derivate(
289 [this, &xbj_t](double qsq) -> double {
290 const auto vals = sfs_grid_.eval({xbj_t, qsq}); // FT, F2
291 const auto &ft_l = vals.at(0), &f2_l = vals.at(1);
292 return gamma2(xbj_t, qsq) * f2_l - ft_l;
293 }, // TM-corrected FL with twist-4 correction
294 t,
295 t * 1.e-2);
296 }
297 const double fl_der = args_.q2 * (std::pow(args_.q2, dis_params_.pml - 1.) / std::pow(t, dis_params_.pml) *
298 (fl_dis + log(t / args_.q2) * (dis_params_.pml * fl_dis - t * ddl)));
299
303 auto photot = [](double w2) -> double {
304 return 0.0598 * std::pow(w2, 0.0933) + 0.1164 * std::pow(w2, -0.357);
305 };
306 // extrapolation in q2 ; note cross-section in mb units, and converted to GeV units
307 const double f0t = photot(w2) / constants::G_EM_SQ * M_1_PI / (constants::GEVM2_TO_PB * 1.e-9);
308 const double ft_der =
309 args_.q2 * (f0t + std::pow(args_.q2, dis_params_.pmt - 1.) / std::pow(t, dis_params_.pmt) *
310 (ft_dis - f0t * t +
311 log(t / args_.q2) *
312 (dis_params_.pmt * ft_dis - t * ddt - (dis_params_.pmt - 1.) * f0t * t)));
313 fl_dis = fl_der;
314 ft_dis = ft_der;
315 }
316 const double bl = 1. - exp(-dis_params_.bg1l * std::pow(w2 - mx_min_, dis_params_.bg2l)),
317 bt = 1. - exp(-dis_params_.bg1t * std::pow(w2 - mx_min_, dis_params_.bg2t));
318 fl_dis *= bl;
319 ft_dis *= bt;
320 f2_dis = (fl_dis + ft_dis) / gamma2(args_.xbj, args_.q2);
321 }
322 fl += fl_dis;
323 f2 += f2_dis;
324 } //--- end of perturbative region
325 setFL(fl);
326 setF2(f2);
327 }
328 } // namespace strfun
329} // namespace cepgen
331REGISTER_STRFUN("KulaginBarinov", 303, KulaginBarinov);
#define CG_FATAL(mod)
Definition Exception.h:61
#define CG_DEBUG(mod)
Definition Message.h:220
#define CG_INFO(mod)
Definition Message.h:216
#define REGISTER_STRFUN(name, id, obj)
Add a structure functions definition to the list of handled parameterisation.
void initialise()
Initialise the grid and all useful interpolators/accelerators.
void insert(coord_t coord, values_t value)
Insert a new value in the grid.
std::array< Limits, D > boundaries() const
Grid boundaries (collection of (min,max))
values_t eval(coord_t in_coords) const
Interpolate a point to a given coordinate.
Validity interval for a variable.
Definition Limits.h:28
double min() const
Lower limit to apply on the variable.
Definition Limits.h:52
bool contains(double val, bool exclude_boundaries=false) const
Check if value is inside limits' boundaries.
Definition Limits.cpp:77
double max() const
Upper limit to apply on the variable.
Definition Limits.h:54
A singleton holding all physics constants associated to particles.
Definition PDG.h:28
A description object for parameters collection.
ParametersDescription & add(const std::string &name, const T &def)
Add the description to a new parameter.
ParametersDescription & addParametersDescriptionVector(const std::string &, const ParametersDescription &, const std::vector< ParametersList > &def={})
Add the description to a collection of ParametersList objects.
ParametersList & set(const std::string &, const T &)
Set a parameter value Set a recast parameter value.
General definition for a resonance.
double partialWidth(const KinematicsBlock &) const
partial widths for all decays
const double width_
full width, in GeV
double photonWidth(const KinematicsBlock &) const
virtual photon width
static ParametersDescription description()
const double mass_
mass, in GeV/c2
T steer(const std::string &key) const
Retrieve a parameters as previously steered.
Definition Steerable.h:39
Base user-steerable object.
SteeredObject()
Build a module.
Kulagin and Barinov hybrid parameterisation .
static ParametersDescription description()
KulaginBarinov(const ParametersList &)
void eval() override
Local structure functions evaluation method.
Base object for the parameterisation of nucleon structure functions.
double gamma2(double xbj, double q2) const
Dimensionless variable .
Arguments args_
Last couple computed.
Parameterisation & setF2(double f2)
const double mx_min_
Minimum diffractive mass, in GeV/c^2.
const double mp2_
Squared proton mass, in GeV^2/c^4.
static ParametersDescription description()
Generic description for the structure functions.
Parameterisation & setFL(double fl)
const double mp_
Proton mass, in GeV/c^2.
constexpr double G_EM_SQ
Electromagnetic charge (~0.303 in natural units)
Definition Constants.h:31
constexpr double GEVM2_TO_PB
Conversion factor between GeV and barn i.e. in GeV .
Definition Constants.h:37
constexpr double ALPHA_EM
Electromagnetic coupling constant .
Definition Constants.h:28
double xBj(double q2, double mp2, double mx2)
Compute Bjorken x from virtuality/diffractive mass.
Definition Utils.cpp:41
bool fileExists(const std::string &path)
Check if the file exists.
double energyFromW(double w, double mp2, double m2)
Compute energy from mass and emitted mass.
Definition Utils.cpp:47
double mX2(double xbj, double q2, double mp2)
Compute the diffractive mass from virtuality/Bjorken x.
Definition Utils.cpp:29
Common namespace for this Monte Carlo generator.
Kinematics needed for threshold relativistic B-W.