Version: SMASH-3.3
parametrizations.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2013-2025
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
10 #include "smash/parametrizations.h"
11 
12 #include <cmath>
13 #include <initializer_list>
14 #include <iostream>
15 #include <memory>
16 #include <set>
17 #include <vector>
18 
19 #include "smash/average.h"
20 #include "smash/clebschgordan.h"
21 #include "smash/constants.h"
22 #include "smash/kinematics.h"
23 #include "smash/logging.h"
24 #include "smash/lowess.h"
26 #include "smash/pow.h"
27 
28 namespace smash {
29 
30 bool parametrization_exists(const PdgCode& pdg_a, const PdgCode& pdg_b) {
31  const bool two_nucleons = pdg_a.is_nucleon() && pdg_b.is_nucleon();
32  const bool nucleon_and_kaon = (pdg_a.is_nucleon() && pdg_b.is_kaon()) ||
33  (pdg_a.is_kaon() && pdg_b.is_nucleon());
34  const bool nucleon_and_pion = (pdg_a.is_nucleon() && pdg_b.is_pion()) ||
35  (pdg_a.is_pion() && pdg_b.is_nucleon());
36  const bool two_pions = pdg_a.is_pion() && pdg_b.is_pion();
37  return two_nucleons || nucleon_and_kaon || nucleon_and_pion || two_pions;
38 }
39 
40 double xs_high_energy(double mandelstam_s, bool is_opposite_charge, double ma,
41  double mb, double P, double R1, double R2) {
42  const double M = 2.1206;
43  const double H = 0.272;
44  const double eta1 = 0.4473;
45  const double eta2 = 0.5486;
46  const double s_sab = mandelstam_s / (ma + mb + M) / (ma + mb + M);
47  double xs =
48  H * std::log(s_sab) * std::log(s_sab) + P + R1 * std::pow(s_sab, -eta1);
49  xs = is_opposite_charge ? xs + R2 * std::pow(s_sab, -eta2)
50  : xs - R2 * std::pow(s_sab, -eta2);
51  return xs;
52 }
53 
54 double pp_high_energy(double mandelstam_s) {
55  return xs_high_energy(mandelstam_s, false, 0.939, 0.939, 34.41, 13.07, 7.394);
56 }
57 
58 double ppbar_high_energy(double mandelstam_s) {
59  return xs_high_energy(mandelstam_s, true, 0.939, 0.939, 34.41, 13.07, 7.394);
60 }
61 
62 double np_high_energy(double mandelstam_s) {
63  return xs_high_energy(mandelstam_s, false, 0.939, 0.939, 34.41, 12.52, 6.66);
64 }
65 
66 double npbar_high_energy(double mandelstam_s) {
67  return xs_high_energy(mandelstam_s, true, 0.939, 0.939, 34.41, 12.52, 6.66);
68 }
69 
70 double piplusp_high_energy(double mandelstam_s) {
71  return xs_high_energy(mandelstam_s, false, 0.939, 0.138, 18.75, 9.56, 1.767);
72 }
73 
74 double piminusp_high_energy(double mandelstam_s) {
75  return xs_high_energy(mandelstam_s, true, 0.939, 0.138, 18.75, 9.56, 1.767);
76 }
77 
78 double xs_ppbar_annihilation(double mandelstam_s) {
79  const double xs_ref = 120.;
80  const double s_ref = 4. * nucleon_mass * nucleon_mass;
81  const double constant_a = 0.05;
82  const double constant_b = 0.6;
83  const double factor = constant_a * constant_a * s_ref /
84  ((mandelstam_s - s_ref) * (mandelstam_s - s_ref) +
85  constant_a * constant_a * s_ref) +
86  constant_b;
87  return xs_ref * (s_ref / mandelstam_s) * factor;
88 }
89 
90 double xs_string_hard(double mandelstam_s, double xs_0, double e_0,
91  double lambda_pow) {
92  const double sqrts = std::sqrt(mandelstam_s);
93  if (sqrts < e_0) {
94  return 0.;
95  } else {
96  double xs = xs_0 * std::pow(std::log(sqrts / e_0), lambda_pow);
97  return xs;
98  }
99 }
100 
101 double NN_string_hard(double mandelstam_s) {
102  return xs_string_hard(mandelstam_s, 0.087, 4.1, 3.8);
103 }
104 
105 double Npi_string_hard(double mandelstam_s) {
106  return xs_string_hard(mandelstam_s, 0.042, 3.5, 4.2);
107 }
108 
109 double pipi_string_hard(double mandelstam_s) {
110  return xs_string_hard(mandelstam_s, 0.013, 2.3, 4.7);
111 }
112 
113 double pipluspiminus_total(double sqrts) {
114  if (pipluspiminus_total_interpolation == nullptr) {
115  auto [dedup_x, dedup_y] =
117  dedup_y = smooth(dedup_x, dedup_y, 0.01, 10);
119  std::make_unique<InterpolateDataLinear<double>>(dedup_x, dedup_y);
120  }
121  const double last = *(PIPLUSPIMINUS_TOT_SQRTS.end() - 1);
122  if (sqrts < last)
123  return (*pipluspiminus_total_interpolation)(sqrts);
124  else
125  return pipi_string_hard(sqrts * sqrts);
126 }
127 
128 double pizeropizero_total(double sqrts) {
129  if (pizeropizero_total_interpolation == nullptr) {
130  auto [dedup_x, dedup_y] =
131  dedup_avg<double>(PIZEROPIZERO_TOT_SQRTS, PIZEROPIZERO_TOT_SIG);
132  dedup_y = smooth(dedup_x, dedup_y, 0.01, 10);
134  std::make_unique<InterpolateDataLinear<double>>(dedup_x, dedup_y);
135  }
136  const double last = *(PIZEROPIZERO_TOT_SQRTS.end() - 1);
137  if (sqrts < last)
138  return (*pizeropizero_total_interpolation)(sqrts);
139  else
140  return pipi_string_hard(sqrts * sqrts);
141 }
142 
143 double piplusp_total(double sqrts) {
144  if (piplusp_total_interpolation == nullptr) {
145  auto [dedup_x, dedup_y] =
146  dedup_avg<double>(PIPLUSP_TOT_SQRTS, PIPLUSP_TOT_SIG);
147  dedup_y = smooth(dedup_x, dedup_y, 0.01, 10);
149  std::make_unique<InterpolateDataLinear<double>>(dedup_x, dedup_y);
150  }
151  const double last = *(PIPLUSP_TOT_SQRTS.end() - 1);
152  if (sqrts < last)
153  return (*piplusp_total_interpolation)(sqrts);
154  else
155  return piplusp_high_energy(sqrts * sqrts);
156 }
157 
158 /* pi+ p elastic cross section parametrization, PDG data.
159  *
160  * The PDG data is smoothed using the LOWESS algorithm. If more than one
161  * cross section was given for one p_lab value, the corresponding cross sections
162  * are averaged. */
163 static double piplusp_elastic_pdg(double mandelstam_s) {
164  if (piplusp_elastic_interpolation == nullptr) {
165  auto [dedup_x, dedup_y] =
166  dedup_avg<double>(PIPLUSP_ELASTIC_P_LAB, PIPLUSP_ELASTIC_SIG);
167  dedup_y = smooth(dedup_x, dedup_y, 0.1, 5);
169  std::make_unique<InterpolateDataLinear<double>>(dedup_x, dedup_y);
170  }
171  const double p_lab = plab_from_s(mandelstam_s, pion_mass, nucleon_mass);
172  return (*piplusp_elastic_interpolation)(p_lab);
173 }
174 
175 double piplusp_elastic_high_energy(double mandelstam_s, double m1, double m2) {
176  const double p_lab = (m1 > m2) ? plab_from_s(mandelstam_s, m2, m1)
177  : plab_from_s(mandelstam_s, m1, m2);
178  const auto logp = std::log(p_lab);
179  return 11.4 * std::pow(p_lab, -0.4) + 0.079 * logp * logp;
180 }
181 
182 double piplusp_elastic_AQM(double mandelstam_s, double m1, double m2) {
183  const double p_lab = (m1 > m2) ? plab_from_s(mandelstam_s, m2, m1)
184  : plab_from_s(mandelstam_s, m1, m2);
185  if (p_lab < 3.05) { // the plab from which the param starts to explode
186  return 7.5; // this will be scaled down by 2/3 for meson-meson
187  } else {
188  return piplusp_elastic_high_energy(mandelstam_s, m1, m2);
189  }
190 }
191 
192 double piplusp_elastic(double mandelstam_s) {
193  double sigma;
194  const double p_lab = plab_from_s(mandelstam_s, pion_mass, nucleon_mass);
195  if (mandelstam_s < 2.25) {
196  sigma = really_small;
197  } else if (mandelstam_s > 4.84) {
198  const auto logp = std::log(p_lab);
199  sigma = 11.4 * std::pow(p_lab, -0.4) + 0.079 * logp * logp;
200  } else {
201  sigma = piplusp_elastic_pdg(mandelstam_s);
202  }
203 
204  // The elastic contributions from decays still need to be subtracted.
205  if (piplusp_elastic_res_interpolation == nullptr) {
206  std::vector<double> x = PIPLUSP_RES_SQRTS;
207  for (auto& i : x) {
208  i = i * i;
209  }
210  std::vector<double> y = PIPLUSP_RES_SIG;
212  std::make_unique<InterpolateDataSpline>(x, y);
213  }
214  sigma -= (*piplusp_elastic_res_interpolation)(mandelstam_s);
215  if (sigma < 0) {
216  sigma = really_small;
217  }
218  return sigma;
219 }
220 
221 /* pi+ p to Sigma+ K+ cross section parametrization, PDG data.
222  *
223  * The PDG data is smoothed using the LOWESS algorithm. If more than one
224  * cross section was given for one p_lab value, the corresponding cross sections
225  * are averaged. */
226 double piplusp_sigmapluskplus_pdg(double mandelstam_s) {
227  if (piplusp_sigmapluskplus_interpolation == nullptr) {
228  auto [dedup_x, dedup_y] = dedup_avg<double>(PIPLUSP_SIGMAPLUSKPLUS_P_LAB,
230  dedup_y = smooth(dedup_x, dedup_y, 0.2, 5);
232  std::make_unique<InterpolateDataLinear<double>>(dedup_x, dedup_y);
233  }
234  const double p_lab = plab_from_s(mandelstam_s, pion_mass, nucleon_mass);
235  /* If p_lab is beyond the upper bound of the linear interpolation,
236  * InterpolationDataLinear will return the value at the upper bound and this
237  * is what we want here. */
238  return (*piplusp_sigmapluskplus_interpolation)(p_lab);
239 }
240 
241 double piminusp_total(double sqrts) {
242  if (piminusp_total_interpolation == nullptr) {
243  auto [dedup_x, dedup_y] =
244  dedup_avg<double>(PIMINUSP_TOT_SQRTS, PIMINUSP_TOT_SIG);
245  dedup_y = smooth(dedup_x, dedup_y, 0.01, 6);
247  std::make_unique<InterpolateDataLinear<double>>(dedup_x, dedup_y);
248  }
249  const double last = *(PIMINUSP_TOT_SQRTS.end() - 1);
250  if (sqrts < last)
251  return (*piminusp_total_interpolation)(sqrts);
252  else
253  return piminusp_high_energy(sqrts * sqrts);
254 }
255 
256 /* pi- p elastic cross section parametrization, PDG data.
257  *
258  * The PDG data is smoothed using the LOWESS algorithm. If more than one
259  * cross section was given for one p_lab value, the corresponding cross sections
260  * are averaged. */
261 static double piminusp_elastic_pdg(double mandelstam_s) {
262  if (piminusp_elastic_interpolation == nullptr) {
263  auto [dedup_x, dedup_y] =
264  dedup_avg<double>(PIMINUSP_ELASTIC_P_LAB, PIMINUSP_ELASTIC_SIG);
265  dedup_y = smooth(dedup_x, dedup_y, 0.2, 6);
267  std::make_unique<InterpolateDataLinear<double>>(dedup_x, dedup_y);
268  }
269  const double p_lab = plab_from_s(mandelstam_s, pion_mass, nucleon_mass);
270  return (*piminusp_elastic_interpolation)(p_lab);
271 }
272 
273 double piminusp_elastic(double mandelstam_s) {
274  double sigma;
275  const double p_lab = plab_from_s(mandelstam_s, pion_mass, nucleon_mass);
276  const auto logp = std::log(p_lab);
277  if (mandelstam_s < 1.69) {
278  sigma = really_small;
279  } else if (mandelstam_s > 4.84) {
280  sigma = 1.76 + 11.2 * std::pow(p_lab, -0.64) + 0.043 * logp * logp;
281  } else {
282  sigma = piminusp_elastic_pdg(mandelstam_s);
283  }
284  /* Tune down the elastic cross section when sqrt s is between 1.8 GeV
285  * and 1.97 GeV so that the total cross section can fit the data. The
286  * scaling factor is chosen so that the it's equal to one and its
287  * derivate vanishes at the both ends. The minimum scaling factor in this
288  * region is 0.88-0.12=0.76. */
289  if (mandelstam_s > 3.24 && mandelstam_s < 3.8809) {
290  sigma *= (0.12 * std::cos(2 * M_PI * (std::sqrt(mandelstam_s) - 1.8) /
291  (1.97 - 1.8)) +
292  0.88);
293  }
294  // The elastic contributions from decays still need to be subtracted.
295  if (piminusp_elastic_res_interpolation == nullptr) {
296  std::vector<double> x = PIMINUSP_RES_SQRTS;
297  for (auto& i : x) {
298  i = i * i;
299  }
300  std::vector<double> y = PIMINUSP_RES_SIG;
301  auto [dedup_x, dedup_y] = dedup_avg(x, y);
303  std::make_unique<InterpolateDataSpline>(dedup_x, dedup_y);
304  }
305  sigma -= (*piminusp_elastic_res_interpolation)(mandelstam_s);
306  if (sigma < 0) {
307  sigma = really_small;
308  }
309  return sigma;
310 }
311 
312 /* pi- p -> Lambda K0 cross section parametrization, PDG data.
313  *
314  * The PDG data is smoothed using the LOWESS algorithm. If more than one
315  * cross section was given for one p_lab value, the corresponding cross sections
316  * are averaged. */
317 double piminusp_lambdak0_pdg(double mandelstam_s) {
318  if (piminusp_lambdak0_interpolation == nullptr) {
319  auto [dedup_x, dedup_y] =
321  dedup_y = smooth(dedup_x, dedup_y, 0.2, 6);
323  std::make_unique<InterpolateDataLinear<double>>(dedup_x, dedup_y);
324  }
325  const double p_lab = plab_from_s(mandelstam_s, pion_mass, nucleon_mass);
326  return (*piminusp_lambdak0_interpolation)(p_lab);
327 }
328 
329 /* pi- p -> Sigma- K+ cross section parametrization, PDG data.
330  *
331  * The PDG data is smoothed using the LOWESS algorithm. If more than one
332  * cross section was given for one p_lab value, the corresponding cross sections
333  * are averaged. */
334 double piminusp_sigmaminuskplus_pdg(double mandelstam_s) {
336  auto [dedup_x, dedup_y] = dedup_avg<double>(PIMINUSP_SIGMAMINUSKPLUS_P_LAB,
338  dedup_y = smooth(dedup_x, dedup_y, 0.2, 6);
340  std::make_unique<InterpolateDataLinear<double>>(dedup_x, dedup_y);
341  }
342  const double p_lab = plab_from_s(mandelstam_s, pion_mass, nucleon_mass);
344 }
345 
346 /* pi- p -> Sigma0 K0 cross section parametrization, resonance contribution.
347  *
348  * The data is smoothed using the LOWESS algorithm. If more than one
349  * cross section was given for one sqrts value, the corresponding cross sections
350  * are averaged. */
351 double piminusp_sigma0k0_res(double mandelstam_s) {
352  if (piminusp_sigma0k0_interpolation == nullptr) {
353  auto [dedup_x, dedup_y] = dedup_avg<double>(PIMINUSP_SIGMA0K0_RES_SQRTS,
355  dedup_y = smooth(dedup_x, dedup_y, 0.2, 6);
357  std::make_unique<InterpolateDataLinear<double>>(dedup_x, dedup_y);
358  }
359  const double sqrts = std::sqrt(mandelstam_s);
360  return (*piminusp_sigma0k0_interpolation)(sqrts);
361 }
362 
363 double pp_elastic(double mandelstam_s) {
364  const double p_lab = plab_from_s(mandelstam_s);
365  if (p_lab < 0.435) {
366  return 5.12 * nucleon_mass /
367  (mandelstam_s - 4 * nucleon_mass * nucleon_mass) +
368  1.67;
369  } else if (p_lab < 0.8) {
370  return 23.5 + 1000 * pow_int(p_lab - 0.7, 4);
371  } else if (p_lab < 2.0) {
372  return 1250 / (p_lab + 50) - 4 * (p_lab - 1.3) * (p_lab - 1.3);
373  } else if (p_lab < 2.776) {
374  return 77 / (p_lab + 1.5);
375  } else {
376  const auto logp = std::log(p_lab);
377  return 11.9 + 26.9 * std::pow(p_lab, -1.21) + 0.169 * logp * logp -
378  1.85 * logp;
379  }
380 }
381 
382 double pp_elastic_high_energy(double mandelstam_s, double m1, double m2) {
383  const double p_lab = (m1 > m2) ? plab_from_s(mandelstam_s, m2, m1)
384  : plab_from_s(mandelstam_s, m1, m2);
385  const auto logp = std::log(p_lab);
386  return 11.9 + 26.9 * std::pow(p_lab, -1.21) + 0.169 * logp * logp -
387  1.85 * logp;
388 }
389 
390 double pp_total(double mandelstam_s) {
391  const double p_lab = plab_from_s(mandelstam_s);
392  if (p_lab < 0.4) {
393  return 34 * std::pow(p_lab / 0.4, -2.104);
394  } else if (p_lab < 0.8) {
395  return 23.5 + 1000 * pow_int(p_lab - 0.7, 4);
396  } else if (p_lab < 1.5) {
397  return 23.5 + 24.6 / (1 + std::exp(-(p_lab - 1.2) / 0.1));
398  } else if (p_lab < 5.0) {
399  return 41 + 60 * (p_lab - 0.9) * std::exp(-1.2 * p_lab);
400  } else {
401  const auto logp = std::log(p_lab);
402  return 48.0 + 0.522 * logp * logp - 4.51 * logp;
403  }
404 }
405 
406 double np_elastic(double mandelstam_s) {
407  const double p_lab = plab_from_s(mandelstam_s);
408  if (p_lab < 0.525) {
409  return 17.05 * nucleon_mass /
410  (mandelstam_s - 4 * nucleon_mass * nucleon_mass) -
411  6.83;
412  } else if (p_lab < 0.8) {
413  return 33 + 196 * std::pow(std::abs(p_lab - 0.95), 2.5);
414  } else if (p_lab < 2.0) {
415  return 31 / std::sqrt(p_lab);
416  } else if (p_lab < 2.776) {
417  return 77 / (p_lab + 1.5);
418  } else {
419  const auto logp = std::log(p_lab);
420  return 11.9 + 26.9 * std::pow(p_lab, -1.21) + 0.169 * logp * logp -
421  1.85 * logp;
422  }
423 }
424 
425 double np_total(double mandelstam_s) {
426  const double p_lab = plab_from_s(mandelstam_s);
427  const auto logp = std::log(p_lab);
428  if (p_lab < 0.4) {
429  return 6.3555 * std::pow(p_lab, -3.2481) * std::exp(-0.377 * logp * logp);
430  } else if (p_lab < 1.0) {
431  return 33 + 196 * std::pow(std::abs(p_lab - 0.95), 2.5);
432  } else if (p_lab < 2.0) {
433  return 24.2 + 8.9 * p_lab;
434  } else if (p_lab < 5.0) {
435  return 42;
436  } else {
437  return 48.0 + 0.522 * logp * logp - 4.51 * logp;
438  }
439 }
440 
441 double ppbar_elastic(double mandelstam_s) {
442  if (mandelstam_s < 4 * nucleon_mass * nucleon_mass) {
443  // Needed, since called directly from p_52
444  return 0.0;
445  }
446  const double p_lab = plab_from_s(mandelstam_s);
447  if (p_lab < 0.3) {
448  return 78.6;
449  } else if (p_lab < 5.0) {
450  return 31.6 + 18.3 / p_lab - 1.1 / (p_lab * p_lab) - 3.8 * p_lab;
451  } else {
452  const auto logp = std::log(p_lab);
453  return 10.2 + 52.7 * std::pow(p_lab, -1.16) + 0.125 * logp * logp -
454  1.28 * logp;
455  }
456 }
457 
458 double ppbar_total(double mandelstam_s) {
459  if (mandelstam_s < 4 * nucleon_mass * nucleon_mass) {
460  // Needed, since called directly from p_52
461  return 0.0;
462  }
463  const double p_lab = plab_from_s(mandelstam_s);
464  if (p_lab < 0.3) {
465  return 271.6 * std::exp(-1.1 * p_lab * p_lab);
466  } else if (p_lab < 5.0) {
467  return 75.0 + 43.1 / p_lab + 2.6 / (p_lab * p_lab) - 3.9 * p_lab;
468  } else {
469  const auto logp = std::log(p_lab);
470  return 38.4 + 77.6 * std::pow(p_lab, -0.64) + 0.26 * logp * logp -
471  1.2 * logp;
472  }
473 }
474 
475 double deuteron_pion_elastic(double mandelstam_s) {
476  const double tmp = std::sqrt(mandelstam_s) - 2.172;
477  return 4.0 + 0.27 / (tmp * tmp + 0.065 * 0.065);
478 }
479 
480 double deuteron_nucleon_elastic(double mandelstam_s) {
481  const double excess = (mandelstam_s - 7.93);
482  const double excess_sqr = excess * excess;
483  return 2500.0 * std::exp(-excess_sqr / 0.003) +
484  600.0 * std::exp(-excess_sqr / 0.1) + 10.0;
485 }
486 
487 double kplusp_total(double mandelstam_s) {
488  if (kplusp_total_interpolation == nullptr) {
489  auto [dedup_x, dedup_y] =
490  dedup_avg<double>(KPLUSP_TOT_PLAB, KPLUSP_TOT_SIG);
491  dedup_y = smooth(dedup_x, dedup_y, 0.1, 5);
493  std::make_unique<InterpolateDataLinear<double>>(dedup_x, dedup_y);
494  }
495  const double p_lab = plab_from_s(mandelstam_s, kaon_mass, nucleon_mass);
496  return (*kplusp_total_interpolation)(p_lab);
497 }
498 
499 double kplusn_total(double mandelstam_s) {
500  if (kplusn_total_interpolation == nullptr) {
501  auto [dedup_x, dedup_y] =
502  dedup_avg<double>(KPLUSN_TOT_PLAB, KPLUSN_TOT_SIG);
503  dedup_y = smooth(dedup_x, dedup_y, 0.05, 5);
505  std::make_unique<InterpolateDataLinear<double>>(dedup_x, dedup_y);
506  }
507  const double p_lab = plab_from_s(mandelstam_s, kaon_mass, nucleon_mass);
508  return (*kplusn_total_interpolation)(p_lab);
509 }
510 
511 double kminusp_total(double mandelstam_s) {
512  if (kminusp_total_interpolation == nullptr) {
513  auto [dedup_x, dedup_y] =
514  dedup_avg<double>(KMINUSP_TOT_PLAB, KMINUSP_TOT_SIG);
515  // Parametrization data is pre-smoothed
516  dedup_y = smooth(dedup_x, dedup_y, 0.01, 5);
518  std::make_unique<InterpolateDataLinear<double>>(dedup_x, dedup_y);
519  }
520  const double p_lab = plab_from_s(mandelstam_s, kaon_mass, nucleon_mass);
521  return (*kminusp_total_interpolation)(p_lab);
522 }
523 
524 double kminusn_total(double mandelstam_s) {
525  if (kminusn_total_interpolation == nullptr) {
526  auto [dedup_x, dedup_y] =
527  dedup_avg<double>(KMINUSN_TOT_PLAB, KMINUSN_TOT_SIG);
528  dedup_y = smooth(dedup_x, dedup_y, 0.05, 5);
530  std::make_unique<InterpolateDataLinear<double>>(dedup_x, dedup_y);
531  }
532  const double p_lab = plab_from_s(mandelstam_s, kaon_mass, nucleon_mass);
533  return (*kminusn_total_interpolation)(p_lab);
534 }
535 
536 double kplusp_elastic_background(double mandelstam_s) {
537  constexpr double a0 = 10.508; // mb
538  constexpr double a1 = -3.716; // mb/GeV
539  constexpr double a2 = 1.845; // mb/GeV^2
540  constexpr double a3 = -0.764; // GeV^-1
541  constexpr double a4 = 0.508; // GeV^-2
542 
543  const double p_lab = plab_from_s(mandelstam_s, kaon_mass, nucleon_mass);
544  const double p_lab2 = p_lab * p_lab;
545 
546  return (a0 + a1 * p_lab + a2 * p_lab2) / (1 + a3 * p_lab + a4 * p_lab2);
547 }
548 
549 double kplusn_elastic_background(double mandelstam_s) {
550  return 0.25 * kplusp_elastic_background(mandelstam_s);
551 }
552 
553 double kplusn_k0p(double mandelstam_s) {
554  return 0.25 * kplusp_elastic_background(mandelstam_s);
555 }
556 
557 /* K- p elastic cross section parametrization, PDG data.
558  *
559  * The PDG data is smoothed using the LOWESS algorithm. If more than one
560  * cross section was given for one p_lab value, the corresponding cross sections
561  * are averaged. */
562 static double kminusp_elastic_pdg(double mandelstam_s) {
563  if (kminusp_elastic_interpolation == nullptr) {
564  auto [dedup_x, dedup_y] =
565  dedup_avg<double>(KMINUSP_ELASTIC_P_LAB, KMINUSP_ELASTIC_SIG);
566  dedup_y = smooth(dedup_x, dedup_y, 0.1, 5);
568  std::make_unique<InterpolateDataLinear<double>>(dedup_x, dedup_y);
569  }
570  const double p_lab = plab_from_s(mandelstam_s, kaon_mass, nucleon_mass);
571  return (*kminusp_elastic_interpolation)(p_lab);
572 }
573 
574 double kminusp_elastic_background(double mandelstam_s) {
575  const double p_lab = plab_from_s(mandelstam_s, kaon_mass, nucleon_mass);
576  double sigma;
577  if (std::sqrt(mandelstam_s) < 1.68) {
578  /* The parametrization here also works for anti-K0 n, Lambda pi0,
579  * Sigma+ pi-, Sigma- pi+, Sigma0 pi0 with different parameters a0, a1, a2.
580  *
581  * The values of the parameters are *not* taken from the source above,
582  * they come from a fit to PDG data. */
583  constexpr double a0 = 186.03567644; // mb GeV^2
584  constexpr double a1 = 0.22002795; // Gev
585  constexpr double a2 = 0.64907116;
586 
587  const double p_i = p_lab;
588  const double p_f = p_lab;
589 
590  const double ratio = a1 * a1 / (a1 * a1 + p_f * p_f);
591  sigma = a0 * p_f / (p_i * mandelstam_s) * std::pow(ratio, a2);
592  } else {
593  sigma = kminusp_elastic_pdg(mandelstam_s);
594  }
595  // The elastic contributions from decays still need to be subtracted.
596  if (kminusp_elastic_res_interpolation == nullptr) {
597  std::vector<double> x = KMINUSP_RES_SQRTS;
598  for (auto& i : x) {
599  i = plab_from_s(i * i, kaon_mass, nucleon_mass);
600  }
601  std::vector<double> y = KMINUSP_RES_SIG;
603  std::make_unique<InterpolateDataSpline>(x, y);
604  }
605  const auto old_sigma = sigma;
606  sigma -= (*kminusp_elastic_res_interpolation)(p_lab);
607  if (sigma < 0) {
608  std::cout << "NEGATIVE SIGMA: sigma=" << sigma
609  << ", sqrt(s)=" << std::sqrt(mandelstam_s)
610  << ", sig_el_exp=" << old_sigma
611  << ", sig_el_res=" << (*kminusp_elastic_res_interpolation)(p_lab)
612  << std::endl;
613  }
614  assert(sigma >= 0);
615  return sigma;
616 }
617 
618 double kminusn_elastic_background(double) { return 4.0; }
619 
620 double k0p_elastic_background(double mandelstam_s) {
621  // by isospin symmetry
622  return kplusn_elastic_background(mandelstam_s);
623 }
624 
625 double k0n_elastic_background(double mandelstam_s) {
626  // by isospin symmetry
627  return kplusp_elastic_background(mandelstam_s);
628 }
629 
630 double kbar0p_elastic_background(double mandelstam_s) {
631  // by isospin symmetry
632  return kminusn_elastic_background(mandelstam_s);
633 }
634 
635 double kbar0n_elastic_background(double mandelstam_s) {
636  // by isospin symmetry
637  return kminusp_elastic_background(mandelstam_s);
638 }
639 
640 double kplusp_inelastic_background(double mandelstam_s) {
641  if (kplusp_total_interpolation == nullptr) {
642  auto [dedup_x, dedup_y] =
643  dedup_avg<double>(KPLUSP_TOT_PLAB, KPLUSP_TOT_SIG);
644  dedup_y = smooth(dedup_x, dedup_y, 0.1, 5);
646  std::make_unique<InterpolateDataLinear<double>>(dedup_x, dedup_y);
647  }
648  const double p_lab = plab_from_s(mandelstam_s, kaon_mass, nucleon_mass);
650  mandelstam_s);
651 }
652 
653 double kplusn_inelastic_background(double mandelstam_s) {
654  if (kplusn_total_interpolation == nullptr) {
655  auto [dedup_x, dedup_y] =
656  dedup_avg<double>(KPLUSN_TOT_PLAB, KPLUSN_TOT_SIG);
657  dedup_y = smooth(dedup_x, dedup_y, 0.05, 5);
659  std::make_unique<InterpolateDataLinear<double>>(dedup_x, dedup_y);
660  }
661  const double p_lab = plab_from_s(mandelstam_s, kaon_mass, nucleon_mass);
663  mandelstam_s) -
664  kplusn_k0p(mandelstam_s);
665 }
666 
675 static void initialize(std::unordered_map<std::pair<uint64_t, uint64_t>, double,
676  pair_hash>& ratios) {
677  const auto& type_p = ParticleType::find(pdg::p);
678  const auto& type_n = ParticleType::find(pdg::n);
679  const auto& type_K_p = ParticleType::find(pdg::K_p);
680  const auto& type_K_z = ParticleType::find(pdg::K_z);
681  const auto& type_Delta_pp = ParticleType::find(pdg::Delta_pp);
682  const auto& type_Delta_p = ParticleType::find(pdg::Delta_p);
683  const auto& type_Delta_z = ParticleType::find(pdg::Delta_z);
684  const auto& type_Delta_m = ParticleType::find(pdg::Delta_m);
685 
686  /* Store the isospin ratio of the given reaction relative to all other
687  * possible isospin-symmetric reactions. */
688  auto add_to_ratios = [&](const ParticleType& a, const ParticleType& b,
689  const ParticleType& c, const ParticleType& d,
690  double weight_numerator, double weight_other) {
691  assert(weight_numerator + weight_other != 0);
692  const auto key =
693  std::make_pair(pack(a.pdgcode().code(), b.pdgcode().code()),
694  pack(c.pdgcode().code(), d.pdgcode().code()));
695  const double ratio = weight_numerator / (weight_numerator + weight_other);
696  ratios[key] = ratio;
697  };
698 
699  /* All inelastic channels are K N -> K Delta -> K pi N or charge exchange,
700  * with identical cross section, weighted by the isospin factor.
701  *
702  * For charge exchange, the isospin factors are 1,
703  * so they are excluded here. */
704  {
705  const auto weight1 = isospin_clebsch_gordan_sqr_2to2(
706  type_p, type_K_p, type_K_z, type_Delta_pp);
707  const auto weight2 = isospin_clebsch_gordan_sqr_2to2(
708  type_p, type_K_p, type_K_p, type_Delta_p);
709 
710  add_to_ratios(type_p, type_K_p, type_K_z, type_Delta_pp, weight1, weight2);
711  add_to_ratios(type_p, type_K_p, type_K_p, type_Delta_p, weight2, weight1);
712  }
713  {
714  const auto weight1 = isospin_clebsch_gordan_sqr_2to2(
715  type_n, type_K_p, type_K_z, type_Delta_p);
716  const auto weight2 = isospin_clebsch_gordan_sqr_2to2(
717  type_n, type_K_p, type_K_p, type_Delta_z);
718 
719  add_to_ratios(type_n, type_K_p, type_K_z, type_Delta_p, weight1, weight2);
720  add_to_ratios(type_n, type_K_p, type_K_p, type_Delta_z, weight2, weight1);
721  }
722  /* K+ and K0 have the same mass and spin, their cross sections are assumed to
723  * only differ in isospin factors. */
724  {
725  const auto weight1 = isospin_clebsch_gordan_sqr_2to2(
726  type_p, type_K_z, type_K_z, type_Delta_p);
727  const auto weight2 = isospin_clebsch_gordan_sqr_2to2(
728  type_p, type_K_z, type_K_p, type_Delta_z);
729 
730  add_to_ratios(type_p, type_K_z, type_K_z, type_Delta_p, weight1, weight2);
731  add_to_ratios(type_p, type_K_z, type_K_p, type_Delta_z, weight2, weight1);
732  }
733  {
734  const auto weight1 = isospin_clebsch_gordan_sqr_2to2(
735  type_n, type_K_z, type_K_z, type_Delta_z);
736  const auto weight2 = isospin_clebsch_gordan_sqr_2to2(
737  type_n, type_K_z, type_K_p, type_Delta_m);
738 
739  add_to_ratios(type_n, type_K_z, type_K_z, type_Delta_z, weight1, weight2);
740  add_to_ratios(type_n, type_K_z, type_K_p, type_Delta_m, weight2, weight1);
741  }
742 }
743 
745  const ParticleType& b,
746  const ParticleType& c,
747  const ParticleType& d) const {
748  /* If this method is called with anti-nucleons, flip all particles to
749  * anti-particles;
750  * the ratio is equal */
751  int flip = 0;
752  for (const auto& p : {&a, &b, &c, &d}) {
753  if (p->is_nucleon()) {
754  if (flip == 0) {
755  flip = p->antiparticle_sign();
756  } else {
757  assert(p->antiparticle_sign() == flip);
758  }
759  }
760  }
761  const auto key = std::make_pair(
762  pack(a.pdgcode().code() * flip, b.pdgcode().code() * flip),
763  pack(c.pdgcode().code() * flip, d.pdgcode().code() * flip));
764  if (ratios_.empty()) {
766  }
767  return ratios_.at(key);
768 }
769 
770 /*thread_local (see #3075)*/ KaonNucleonRatios kaon_nucleon_ratios;
771 
772 double kminusp_kbar0n(double mandelstam_s) {
773  constexpr double a0 = 100; // mb GeV^2
774  constexpr double a1 = 0.15; // GeV
775  constexpr unsigned a2 = 2;
776 
777  const double p_lab = plab_from_s(mandelstam_s, kaon_mass, nucleon_mass);
778  const double p_i = p_lab;
779  const double p_f = p_lab;
780 
781  return a0 * p_f / (p_i * mandelstam_s) *
782  pow_int(a1 * a1 / (a1 * a1 + p_f * p_f), a2);
783 }
784 
785 double kminusp_piminussigmaplus(double sqrts) {
786  return 0.0788265 / ((sqrts - 1.38841) * (sqrts - 1.38841));
787 }
788 
789 double kminusp_piplussigmaminus(double sqrts) {
790  return 0.0196741 / ((sqrts - 1.42318) * (sqrts - 1.42318));
791 }
792 
793 double kminusp_pi0sigma0(double sqrts) {
794  return 0.0403364 / ((sqrts - 1.39830305) * (sqrts - 1.39830305));
795 }
796 
797 double kminusp_pi0lambda(double sqrts) {
798  return 0.05932562 / ((sqrts - 1.38786692) * (sqrts - 1.38786692));
799 }
800 
801 double kminusn_piminussigma0(double sqrts) {
802  return kminusp_piminussigmaplus(sqrts) + kminusp_piplussigmaminus(sqrts) -
803  2. * kminusp_pi0sigma0(sqrts);
804 }
805 
806 double kminusn_piminuslambda(double sqrts) {
807  return 2. * kminusp_pi0lambda(sqrts);
808 }
809 
810 // All K+ p and K+ n channels are forbidden by isospin.
811 
812 double lambdalambda_ximinusp(double sqrts_sqrts0, double p_N, double p_lambda) {
813  assert(p_lambda != 0);
814  assert(sqrts_sqrts0 >= 0);
815  return 37.15 / 2 * p_N / p_lambda * std::pow(sqrts_sqrts0, -0.16);
816 }
817 
818 double lambdalambda_xi0n(double sqrts_sqrts0, double p_N, double p_lambda) {
819  return lambdalambda_ximinusp(sqrts_sqrts0, p_N, p_lambda);
820 }
821 
822 double lambdasigmaplus_xi0p(double sqrts_sqrts0) {
823  assert(sqrts_sqrts0 >= 0);
824  return 24.3781 * std::pow(sqrts_sqrts0, -0.479);
825 }
826 
827 double lambdasigmaminus_ximinusn(double sqrts_sqrts0) {
828  return lambdasigmaplus_xi0p(sqrts_sqrts0);
829 }
830 
831 double lambdasigma0_ximinusp(double sqrts_sqrts0) {
832  assert(sqrts_sqrts0 >= 0);
833  if (sqrts_sqrts0 < 0.03336) {
834  return 6.475 * std::pow(sqrts_sqrts0, -0.4167);
835  } else {
836  return 14.5054 * std::pow(sqrts_sqrts0, -0.1795);
837  }
838 }
839 
840 double lambdasigma0_xi0n(double sqrts_sqrts0) {
841  return lambdasigma0_ximinusp(sqrts_sqrts0);
842 }
843 
844 double sigma0sigma0_ximinusp(double sqrts_sqrts0) {
845  assert(sqrts_sqrts0 >= 0);
846  if (sqrts_sqrts0 < 0.09047) {
847  return 5.625 * std::pow(sqrts_sqrts0, -0.318);
848  } else {
849  return 4.174 * std::pow(sqrts_sqrts0, -0.4421);
850  }
851 }
852 
853 double sigma0sigma0_xi0n(double sqrts_sqrts0) {
854  return sigma0sigma0_ximinusp(sqrts_sqrts0);
855 }
856 
857 double sigmaplussigmaminus_xi0p(double sqrts_sqrts0) {
858  return 4 * sigma0sigma0_ximinusp(sqrts_sqrts0);
859 }
860 
861 double sigma0sigmaminus_ximinusn(double sqrts_sqrts0) {
862  return 4 * sigma0sigma0_ximinusp(sqrts_sqrts0);
863 }
864 
865 double sigmaplussigmaminus_ximinusp(double sqrts_sqrts0) {
866  return 14.194 * std::pow(sqrts_sqrts0, -0.442);
867 }
868 
869 double sigmaplussigmaminus_xi0n(double sqrts_sqrts0) {
870  return sigmaplussigmaminus_ximinusp(sqrts_sqrts0);
871 }
872 
873 } // namespace smash
Calculate and store isospin ratios for K N -> K Delta reactions.
std::unordered_map< std::pair< uint64_t, uint64_t >, double, pair_hash > ratios_
Internal representation of isospin weights once calculated.
double get_ratio(const ParticleType &a, const ParticleType &b, const ParticleType &c, const ParticleType &d) const
Return the isospin ratio of the given K N -> K Delta cross section.
Particle type contains the static properties of a particle species.
Definition: particletype.h:98
static const ParticleType & find(PdgCode pdgcode)
Returns the ParticleType object for the given pdgcode.
Definition: particletype.cc:99
PdgCode pdgcode() const
Definition: particletype.h:157
PdgCode stores a Particle Data Group Particle Numbering Scheme particle type number.
Definition: pdgcode.h:108
std::int32_t code() const
Definition: pdgcode.h:319
bool is_pion() const
Definition: pdgcode.h:471
bool is_kaon() const
Definition: pdgcode.h:465
bool is_nucleon() const
Definition: pdgcode.h:404
Collection of useful constants that are known at compile time.
constexpr int Delta_p
Δ⁺.
constexpr int Delta_pp
Δ⁺⁺.
constexpr int K_p
K⁺.
constexpr int K_z
K⁰.
constexpr int p
Proton.
constexpr int n
Neutron.
constexpr int Delta_m
Δ⁻.
constexpr int Delta_z
Δ⁰.
Definition: action.h:24
double kplusn_k0p(double mandelstam_s)
K+ n charge exchange cross section parametrization.
double plab_from_s(double mandelstam_s, double mass)
Convert Mandelstam-s to p_lab in a fixed-target collision.
Definition: kinematics.h:157
bool parametrization_exists(const PdgCode &pdg_a, const PdgCode &pdg_b)
Checks if supplied codes have existing parametrizations of total cross sections.
double kplusp_total(double mandelstam_s)
K+ p total cross section parametrization.
static double piplusp_elastic_pdg(double mandelstam_s)
const std::initializer_list< double > KMINUSN_TOT_PLAB
PDG data on K- n total cross section: momentum in lab frame.
double pizeropizero_total(double sqrts)
pi0 pi0 total cross section parametrized from PDG2018, smoothed using the LOWESS algorithm.
double kminusp_pi0lambda(double sqrts)
K- p <-> pi0 Lambda cross section parametrization Fit to Landolt-Börnstein instead of UrQMD values.
const std::initializer_list< double > PIPLUSP_RES_SQRTS
Center-of-mass energy.
const std::initializer_list< double > KMINUSP_RES_SQRTS
Center-of-mass energy list for K̅⁻ N⁺
const std::initializer_list< double > PIMINUSP_ELASTIC_P_LAB
PDG data on pi- p elastic cross section: momentum in lab frame.
std::vector< T > smooth(const std::vector< T > &x, const std::vector< T > &y, T span=2./3, size_t iter=3, T delta=0)
Apply the LOWESS smoother (see the reference below) to the given data (x, y).
Definition: lowess.h:289
const std::initializer_list< double > PIPLUSPIMINUS_TOT_SQRTS
Center-of-mass energy.
double pipluspiminus_total(double sqrts)
pi+ pi- total cross section parametrized from PDG2018, smoothed using the LOWESS algorithm.
double piminusp_sigma0k0_res(double mandelstam_s)
pi- p -> Sigma0 K0 cross section parametrization, resonance contribution.
double ppbar_total(double mandelstam_s)
ppbar total cross section parametrization Source: Bass:1998ca
double np_total(double mandelstam_s)
np total cross section parametrization Sources: low-p: Cugnon:1996kh highest-p: Buss:2011mx
static std::unique_ptr< InterpolateDataLinear< double > > piplusp_sigmapluskplus_interpolation
An interpolation that gets lazily filled using the PIPLUSP_SIGMAPLUSKPLUS_SIG data.
static std::unique_ptr< InterpolateDataSpline > piplusp_elastic_res_interpolation
A null interpolation that gets filled using the PIPLUSP_RES data.
double piminusp_elastic(double mandelstam_s)
pi-p elastic cross section parametrization Source: GiBUU:parametrizationBarMes_HighEnergy....
double npbar_high_energy(double mandelstam_s)
npbar total cross section at high energies
const std::initializer_list< double > KPLUSP_TOT_SIG
PDG data on K+ p total cross section: cross section.
const std::initializer_list< double > KMINUSP_TOT_PLAB
PDG smoothed data on K- p total cross section: momentum in lab frame.
double kminusn_piminussigma0(double sqrts)
K- n <-> pi- Sigma0 cross section parametrization Follow from the parametrization with the same stran...
const std::initializer_list< double > KMINUSP_RES_SIG
Elastic K̅⁻ N⁺ cross section contributions from decays.
double kbar0p_elastic_background(double mandelstam_s)
Kbar0 p elastic background cross section parametrization Source: Buss:2011mx , B.3....
const std::initializer_list< double > PIPLUSP_SIGMAPLUSKPLUS_SIG
PDG data on pi+ p to Sigma+ K+ section: cross section.
const std::initializer_list< double > PIMINUSP_RES_SIG
Elastic π⁻N⁺ cross section contributions from decays.
const std::initializer_list< double > PIPLUSP_SIGMAPLUSKPLUS_P_LAB
PDG data on pi+ p to Sigma+ K+ cross section: momentum in lab frame.
static std::unique_ptr< InterpolateDataSpline > kminusp_elastic_res_interpolation
An interpolation that gets lazily filled using the KMINUSP_RES data.
const std::initializer_list< double > KPLUSN_TOT_SIG
PDG data on K+ n total cross section: cross section.
KaonNucleonRatios kaon_nucleon_ratios
double sigma0sigma0_ximinusp(double sqrts_sqrts0)
Sigma0 Sigma0 <-> Xi- p cross section parametrization Two hyperon exchange, based on effective model ...
double ppbar_elastic(double mandelstam_s)
ppbar elastic cross section parametrization Source: Bass:1998ca
const std::initializer_list< double > PIPLUSP_RES_SIG
Elastic π⁺N⁺ cross section contributions from decays.
static double piminusp_elastic_pdg(double mandelstam_s)
double lambdasigmaplus_xi0p(double sqrts_sqrts0)
Lambda Sigma+ <-> Xi0 p cross section parametrization Two hyperon exchange, based on effective model ...
double kminusp_elastic_background(double mandelstam_s)
K- p elastic background cross section parametrization Source: Buss:2011mx , B.3.9.
double lambdasigma0_xi0n(double sqrts_sqrts0)
Lambda Sigma0 <-> Xi0 n cross section parametrization Two hyperon exchange, based on effective model ...
double np_high_energy(double mandelstam_s)
np total cross section at high energies
double pp_elastic_high_energy(double mandelstam_s, double m1, double m2)
pp elastic cross section parametrization, with only the high energy part generalized to all energy re...
const std::initializer_list< double > PIMINUSP_ELASTIC_SIG
PDG data on pi- p elastic cross section: cross section.
const std::initializer_list< double > KPLUSN_TOT_PLAB
PDG data on K+ n total cross section: momentum in lab frame.
double xs_string_hard(double mandelstam_s, double xs_0, double e_0, double lambda_pow)
Utility function called by specific other parametrizations Parametrized hard scattering cross section...
double Npi_string_hard(double mandelstam_s)
nucleon-pion hard scattering cross section (with partonic scattering)
static std::unique_ptr< InterpolateDataLinear< double > > kminusp_total_interpolation
An interpolation that gets lazily filled using the KMINUSP_TOT data.
static double kminusp_elastic_pdg(double mandelstam_s)
double kminusn_piminuslambda(double sqrts)
K- n <-> pi- Lambda cross section parametrization Follow from the parametrization with the same stran...
double lambdasigmaminus_ximinusn(double sqrts_sqrts0)
Lambda Sigma- <-> Xi- n cross section parametrization Two hyperon exchange, based on effective model ...
double isospin_clebsch_gordan_sqr_2to2(const ParticleType &p_a, const ParticleType &p_b, const ParticleType &p_c, const ParticleType &p_d, const int I=-1)
Calculate the squared isospin Clebsch-Gordan coefficient for a 2-to-2 reaction A + B -> C + D.
static std::unique_ptr< InterpolateDataLinear< double > > piplusp_elastic_interpolation
An interpolation that gets lazily filled using the PIPLUSP_ELASTIC_SIG data.
const std::initializer_list< double > PIMINUSP_TOT_SQRTS
Center-of-mass energy.
double ppbar_high_energy(double mandelstam_s)
ppbar total cross section at high energies
static std::unique_ptr< InterpolateDataLinear< double > > piminusp_elastic_interpolation
An interpolation that gets lazily filled using the PIMINUSP_ELASTIC data.
double pp_high_energy(double mandelstam_s)
pp total cross section at high energies
double xs_high_energy(double mandelstam_s, bool is_opposite_charge, double ma, double mb, double P, double R1, double R2)
total hadronic cross sections at high energies parametrized in the 2016 PDG book(http://pdg....
const std::initializer_list< double > KMINUSP_ELASTIC_P_LAB
PDG data on K- p elastic cross section: momentum in lab frame.
double pipi_string_hard(double mandelstam_s)
pion-pion hard scattering cross section (with partonic scattering)
double piplusp_high_energy(double mandelstam_s)
pi+p total cross section at high energies
double lambdalambda_xi0n(double sqrts_sqrts0, double p_N, double p_lambda)
Lambda Lambda <-> Xi0 n cross section parametrization Two hyperon exchange, based on effective model ...
double kminusp_piminussigmaplus(double sqrts)
K- p <-> pi- Sigma+ cross section parametrization Taken from UrQMD (Graef:2014mra ).
static std::unique_ptr< InterpolateDataLinear< double > > kplusn_total_interpolation
An interpolation that gets lazily filled using the KPLUSN_TOT data.
double lambdalambda_ximinusp(double sqrts_sqrts0, double p_N, double p_lambda)
Lambda Lambda <-> Xi- p cross section parametrization Two hyperon exchange, based on effective model ...
const std::initializer_list< double > PIMINUSP_LAMBDAK0_P_LAB
PDG data on pi- p to Lambda K0 cross section: momentum in lab frame.
const std::initializer_list< double > KPLUSP_TOT_PLAB
PDG data on K+ p total cross section: momentum in lab frame.
double piplusp_elastic_high_energy(double mandelstam_s, double m1, double m2)
pi+p elactic cross section parametrization.
static std::unique_ptr< InterpolateDataLinear< double > > kplusp_total_interpolation
An interpolation that gets lazily filled using the KPLUSP_TOT data.
const std::initializer_list< double > PIPLUSPIMINUS_TOT_SIG
Total π⁺ π⁻ cross section parametrized from bottom-up SMASH-3.0, using the hadronic list from PDG2018...
double piplusp_sigmapluskplus_pdg(double mandelstam_s)
pi+ p to Sigma+ K+ cross section parametrization, PDG data.
static std::unique_ptr< InterpolateDataLinear< double > > kminusp_elastic_interpolation
An interpolation that gets lazily filled using the KMINUSP_ELASTIC data.
const std::initializer_list< double > PIMINUSP_SIGMAMINUSKPLUS_P_LAB
PDG data on pi- p to Sigma- K+ cross section: momentum in lab frame.
const std::initializer_list< double > KMINUSN_TOT_SIG
PDG data on K- n total cross section: cross section.
double piminusp_total(double sqrts)
pi- p total cross section parametrized from PDG2018, smoothed using the LOWESS algorithm.
double deuteron_nucleon_elastic(double mandelstam_s)
Deuteron nucleon elastic cross-section [mb] parametrized by Oh:2009gx .
constexpr double nucleon_mass
Nucleon mass in GeV.
Definition: constants.h:62
constexpr T pow_int(const T base, unsigned const exponent)
Efficient template for calculating integer powers using squaring.
Definition: pow.h:23
const std::initializer_list< double > PIMINUSP_SIGMA0K0_RES_SIG
pi- p to Sigma0 K0 cross section: cross section
double piminusp_sigmaminuskplus_pdg(double mandelstam_s)
pi- p -> Sigma- K+ cross section parametrization, PDG data.
double piminusp_lambdak0_pdg(double mandelstam_s)
pi- p -> Lambda K0 cross section parametrization, PDG data.
const std::initializer_list< double > PIPLUSP_ELASTIC_P_LAB
PDG data on pi+ p elastic cross section: momentum in lab frame.
static void initialize(std::unordered_map< std::pair< uint64_t, uint64_t >, double, pair_hash > &ratios)
Calculate and store isospin ratios for K N -> K Delta reactions.
double k0p_elastic_background(double mandelstam_s)
K0 p elastic background cross section parametrization Source: Buss:2011mx , B.3.9.
constexpr uint64_t pack(int32_t x, int32_t y)
Pack two int32_t into an uint64_t.
double deuteron_pion_elastic(double mandelstam_s)
Deuteron pion elastic cross-section [mb] parametrized to fit pi-d elastic scattering data (the data c...
const std::initializer_list< double > PIZEROPIZERO_TOT_SIG
Total π⁰ π⁰ cross section parametrized from bottom-up SMASH-3.0 using the hadronic list from PDG2018.
double lambdasigma0_ximinusp(double sqrts_sqrts0)
Lambda Sigma0 <-> Xi- p cross section parametrization Two hyperon exchange, based on effective model ...
const std::initializer_list< double > PIMINUSP_TOT_SIG
Total p π⁻ cross section parametrized from bottom-up SMASH-3.0, using the hadronic list from PDG2018.
double NN_string_hard(double mandelstam_s)
nucleon-nucleon hard scattering cross section (with partonic scattering)
double xs_ppbar_annihilation(double mandelstam_s)
parametrized cross-section for proton-antiproton annihilation used in the UrQMD model
static std::unique_ptr< InterpolateDataLinear< double > > piplusp_total_interpolation
An interpolation that gets lazily filled using the PIPLUSP_TOT data.
const std::initializer_list< double > PIPLUSP_ELASTIC_SIG
PDG data on pi+ p elastic cross section: cross section.
double kplusp_inelastic_background(double mandelstam_s)
K+ p inelastic background cross section parametrization Source: Buss:2011mx , B.3....
const std::initializer_list< double > PIMINUSP_SIGMA0K0_RES_SQRTS
pi- p to Sigma0 K0 cross section: square root s
const std::initializer_list< double > PIMINUSP_SIGMAMINUSKPLUS_SIG
PDG data on pi- p to Sigma- K+ cross section: cross section.
double sigmaplussigmaminus_xi0n(double sqrts_sqrts0)
Sigma+ Sigma- <-> Xi0 n cross section parametrization Two hyperon exchange, based on effective model ...
constexpr double pion_mass
Pion mass in GeV.
Definition: constants.h:69
const std::initializer_list< double > PIPLUSP_TOT_SQRTS
Center-of-mass energy.
double kminusp_pi0sigma0(double sqrts)
K- p <-> pi0 Sigma0 cross section parametrization Fit to Landolt-Börnstein instead of UrQMD values.
double kplusn_elastic_background(double mandelstam_s)
K+ n elastic background cross section parametrization sigma(K+n->K+n) = sigma(K+n->K0p) = 0....
double pp_total(double mandelstam_s)
pp total cross section parametrization Sources: low-p: Cugnon:1996kh highest-p: Buss:2011mx
const std::initializer_list< double > KMINUSP_ELASTIC_SIG
PDG data on K- p elastic cross section: cross section.
static std::unique_ptr< InterpolateDataLinear< double > > piminusp_sigma0k0_interpolation
An interpolation that gets lazily filled using the PIMINUSP_SIGMA0K0_RES data.
const std::initializer_list< double > PIPLUSP_TOT_SIG
Total p π⁺ cross section parametrized from bottom-up SMASH-3.0, using the hadronic list from PDG2018.
static std::unique_ptr< InterpolateDataLinear< double > > piminusp_total_interpolation
An interpolation that gets lazily filled using the PIMINUSP_TOT data.
const std::initializer_list< double > PIMINUSP_RES_SQRTS
Center-of-mass energy.
double kplusn_total(double mandelstam_s)
K+ n total cross section parametrization.
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:41
double np_elastic(double mandelstam_s)
np elastic cross section parametrization Source: Weil:2013mya , eq.
double k0n_elastic_background(double mandelstam_s)
K0 n elastic background cross section parametrization Source: Buss:2011mx , B.3.9.
double sigma0sigma0_xi0n(double sqrts_sqrts0)
Sigma0 Sigma0 <-> Xi0 n cross section parametrization Two hyperon exchange, based on effective model ...
constexpr double kaon_mass
Kaon mass in GeV.
Definition: constants.h:76
double kminusp_piplussigmaminus(double sqrts)
K- p <-> pi+ Sigma- cross section parametrization Taken from UrQMD (Graef:2014mra ).
double kminusp_total(double mandelstam_s)
K- p total cross section parametrization.
double kbar0n_elastic_background(double mandelstam_s)
Kbar0 n elastic background cross section parametrization Source: Buss:2011mx , B.3....
double kminusp_kbar0n(double mandelstam_s)
K- p <-> Kbar0 n cross section parametrization.
double sigmaplussigmaminus_ximinusp(double sqrts_sqrts0)
Sigma+ Sigma- <-> Xi- p cross section parametrization Two hyperon exchange, based on effective model ...
static std::unique_ptr< InterpolateDataLinear< double > > pizeropizero_total_interpolation
An interpolation that gets lazily filled using the PIZEROPIZERO_TOT data.
std::pair< std::vector< T >, std::vector< T > > dedup_avg(const std::vector< T > &x, const std::vector< T > &y)
Remove duplicates from data (x, y) by averaging y.
Definition: average.h:65
static std::unique_ptr< InterpolateDataLinear< double > > pipluspiminus_total_interpolation
An interpolation that gets lazily filled using the PIPLUSPIMINUS_TOT data.
static std::unique_ptr< InterpolateDataLinear< double > > kminusn_total_interpolation
An interpolation that gets lazily filled using the KMINUSN_TOT data.
double piplusp_total(double sqrts)
pi+ p total cross section parametrized from PDG2018, smoothed using the LOWESS algorithm.
double piminusp_high_energy(double mandelstam_s)
pi-p total cross section at high energies
double kminusn_total(double mandelstam_s)
K- n total cross section parametrization.
double kminusn_elastic_background(double mandelstam_s)
K- n elastic background cross section parametrization Source: Buss:2011mx , B.3.9.
double pp_elastic(double mandelstam_s)
pp elastic cross section parametrization Source: Weil:2013mya , eq.
const std::initializer_list< double > KMINUSP_TOT_SIG
PDG smoothed data on K- p total cross section: cross section.
double kplusn_inelastic_background(double mandelstam_s)
K+ n inelastic background cross section parametrization Source: Buss:2011mx , B.3....
const std::initializer_list< double > PIZEROPIZERO_TOT_SQRTS
Center-of-mass energy.
static std::unique_ptr< InterpolateDataLinear< double > > piminusp_lambdak0_interpolation
An interpolation that gets lazily filled using the PIMINUSP_LAMBDAK0 data.
static std::unique_ptr< InterpolateDataLinear< double > > piminusp_sigmaminuskplus_interpolation
An interpolation that gets lazily filled using the PIMINUSP_SIGMAMINUSKPLUS data.
double kplusp_elastic_background(double mandelstam_s)
K+ p elastic background cross section parametrization.
double piplusp_elastic_AQM(double mandelstam_s, double m1, double m2)
An overload of piplusp_elastic_high_energy in which the very low part is replaced by a flat 5 mb cros...
double piplusp_elastic(double mandelstam_s)
pi+p elastic cross section parametrization, PDG data.
static std::unique_ptr< InterpolateDataSpline > piminusp_elastic_res_interpolation
An interpolation that gets lazily filled using the PIMINUSP_RES data.
double sigma0sigmaminus_ximinusn(double sqrts_sqrts0)
Sigma0 Sigma- <-> Xi- n cross section parametrization Two hyperon exchange, based on effective model ...
double sigmaplussigmaminus_xi0p(double sqrts_sqrts0)
Sigma+ Sigma- <-> Xi0 p cross section parametrization Two hyperon exchange, based on effective model ...
const std::initializer_list< double > PIMINUSP_LAMBDAK0_SIG
PDG data on pi- p to Lambda K0 cross section: cross section.
Hash a pair of integers.