32 double spin_factor = (c.
spin() + 1) * (d.
spin() + 1);
33 spin_factor /= (a.
spin() + 1) * (b.
spin() + 1);
34 double symmetry_factor = (1 + (a == b));
35 symmetry_factor /= (1 + (c == d));
38 return spin_factor * symmetry_factor * momentum_factor;
54 double spin_factor = (c.
spin() + 1) * (d.
spin() + 1);
55 spin_factor /= (a.
spin() + 1) * (b.
spin() + 1);
56 double symmetry_factor = (1 + (a == b));
57 symmetry_factor /= (1 + (c == d));
58 const double momentum_factor =
61 return spin_factor * symmetry_factor * momentum_factor;
77 double spin_factor = (c.
spin() + 1) * (d.
spin() + 1);
78 spin_factor /= (a.
spin() + 1) * (b.
spin() + 1);
79 double symmetry_factor = (1 + (a == b));
80 symmetry_factor /= (1 + (c == d));
81 const double momentum_factor =
84 return spin_factor * symmetry_factor * momentum_factor;
92 CollisionBranchList in_list,
double weight = 1.) {
93 main_list.reserve(main_list.size() + in_list.size());
94 for (
auto& proc : in_list) {
95 proc->set_weight(proc->weight() * weight);
96 main_list.emplace_back(std::move(proc));
106 for (
auto& proc : list) {
107 xs_sum += proc->weight();
114 const std::pair<FourVector, FourVector> potentials)
115 : incoming_particles_(incoming_particles),
117 potentials_(potentials),
118 is_BBbar_pair_(incoming_particles_[0].type().is_baryon() &&
119 incoming_particles_[1].type().is_baryon() &&
120 incoming_particles_[0].type().antiparticle_sign() ==
121 -incoming_particles_[1].type().antiparticle_sign()) {}
124 double elastic_parameter,
bool two_to_one_switch,
125 ReactionsBitSet included_2to2,
double low_snn_cut,
bool strings_switch,
126 bool use_AQM,
bool strings_with_probability,
NNbarTreatment nnbar_treatment,
128 CollisionBranchList process_list;
132 double p_pythia = 0.;
133 if (strings_with_probability) {
141 const bool reject_by_nucleon_elastic_cutoff =
145 if (incl_elastic && !reject_by_nucleon_elastic_cutoff) {
146 process_list.emplace_back(
elastic(elastic_parameter, use_AQM));
152 const double sig_current =
sum_xs_of(process_list);
153 const double sig_string = std::max(0.,
high_energy() - sig_current);
160 if (two_to_one_switch) {
164 if (included_2to2.any()) {
174 throw std::runtime_error(
175 "'NNbar' has to be in the list of allowed 2 to 2 processes " 176 "to enable annihilation to go through resonances");
192 bool use_AQM)
const {
193 double elastic_xs = 0.;
194 if (elast_par >= 0.) {
196 elastic_xs = elast_par;
207 CollisionBranchList process_list;
210 const auto& pdg_a = data_a.
pdgcode();
211 const auto& pdg_b = data_b.
pdgcode();
212 if ((pdg_a.is_nucleon() && pdg_b.is_pion()) ||
213 (pdg_b.is_nucleon() && pdg_a.is_pion())) {
222 double elastic_xs = 0.0;
230 elastic_xs =
nk_el();
234 elastic_xs =
nn_el();
242 const bool is_deuteron =
244 if (is_deuteron && pdg_other.
is_pion()) {
247 }
else if (is_deuteron && pdg_other.
is_nucleon()) {
251 }
else if (use_AQM) {
256 elastic_xs =
nn_el();
301 std::stringstream ss;
304 ss <<
"problem in CrossSections::elastic: a=" << name_a <<
" b=" << name_b
305 <<
" j_a=" << pdg_a.
spin() <<
" j_b=" << pdg_b.
spin()
306 <<
" sigma=" << sig_el <<
" s=" << s;
307 throw std::runtime_error(ss.str());
317 assert(pion != nucleon);
322 switch (nucleon.
code()) {
324 switch (pion.
code()) {
337 switch (pion.
code()) {
350 switch (pion.
code()) {
363 switch (pion.
code()) {
376 throw std::runtime_error(
377 "only the elastic cross section for proton-pion " 384 std::stringstream ss;
387 ss <<
"problem in CrossSections::elastic: a=" << name_a <<
" b=" << name_b
388 <<
" j_a=" << pdg_a.
spin() <<
" j_b=" << pdg_b.
spin()
389 <<
" sigma=" << sig_el <<
" s=" << s;
390 throw std::runtime_error(ss.str());
400 const auto pdg_nucleon = type_nucleon.
pdgcode().
code();
409 CollisionBranchList process_list;
410 switch (pdg_nucleon) {
418 type_K_p, type_Sigma_p);
429 type_K_p, type_Sigma_m);
431 sqrt_s_, type_K_z, type_Sigma_z);
433 sqrt_s_, type_K_z, type_Lambda);
448 sqrt_s_, type_K_p, type_Sigma_z);
450 sqrt_s_, type_K_z, type_Sigma_p);
453 type_K_p, type_Lambda);
469 type_K_z, type_Sigma_p);
471 sqrt_s_, type_K_p, type_Sigma_z);
473 sqrt_s_, type_K_p, type_Lambda);
481 type_K_z, type_Sigma_m);
496 sqrt_s_, type_K_z, type_Sigma_z);
498 sqrt_s_, type_K_p, type_Sigma_m);
501 type_K_z, type_Lambda);
517 type_K_m, type_Sigma_m_bar);
519 sqrt_s_, type_Kbar_z, type_Sigma_z_bar);
521 sqrt_s_, type_Kbar_z, type_Lambda_bar);
529 type_K_m, type_Sigma_p_bar);
544 sqrt_s_, type_K_m, type_Sigma_z_bar);
546 sqrt_s_, type_Kbar_z, type_Sigma_p_bar);
549 type_K_m, type_Lambda_bar);
562 type_Kbar_z, type_Sigma_m_bar);
573 type_Kbar_z, type_Sigma_p_bar);
575 sqrt_s_, type_K_m, type_Sigma_z_bar);
577 sqrt_s_, type_K_m, type_Lambda_bar);
592 sqrt_s_, type_Kbar_z, type_Sigma_z_bar);
594 sqrt_s_, type_K_m, type_Sigma_m_bar);
597 type_Kbar_z, type_Lambda_bar);
614 assert(kaon != nucleon);
619 switch (nucleon.
code()) {
621 switch (kaon.
code()) {
637 switch (kaon.
code()) {
653 switch (kaon.
code()) {
669 switch (kaon.
code()) {
685 throw std::runtime_error(
686 "elastic cross section for antinucleon-kaon " 693 std::stringstream ss;
696 ss <<
"problem in CrossSections::elastic: a=" << name_a <<
" b=" << name_b
697 <<
" j_a=" << pdg_a.
spin() <<
" j_b=" << pdg_b.
spin()
698 <<
" sigma=" << sig_el <<
" s=" << s;
699 throw std::runtime_error(ss.str());
704 const auto& log = logger<LogArea::CrossSections>();
705 CollisionBranchList resonance_process_list;
716 if (type_resonance.is_stable()) {
722 type_resonance.pdgcode() == type_particle_a.
pdgcode()) ||
724 type_resonance.pdgcode() == type_particle_b.
pdgcode())) {
728 double resonance_xsection =
formation(type_resonance, p_cm_sqr);
732 resonance_process_list.push_back(make_unique<CollisionBranch>(
734 log.debug(
"Found resonance: ", type_resonance);
735 log.debug(type_particle_a.
name(), type_particle_b.
name(),
"->",
736 type_resonance.name(),
" at sqrt(s)[GeV] = ",
sqrt_s_,
737 " with xs[mb] = ", resonance_xsection);
740 return resonance_process_list;
744 double cm_momentum_sqr)
const {
748 if (type_resonance.
charge() !=
762 if (partial_width <= 0.) {
767 const double spinfactor =
768 static_cast<double>(type_resonance.
spin() + 1) /
769 ((type_particle_a.
spin() + 1) * (type_particle_b.
spin() + 1));
770 const int sym_factor =
775 return spinfactor * sym_factor * 2. * M_PI * M_PI / cm_momentum_sqr *
782 CollisionBranchList process_list;
787 const auto& pdg_a = data_a.
pdgcode();
788 const auto& pdg_b = data_b.
pdgcode();
790 if (pdg_a.is_nucleon() && pdg_b.is_nucleon() &&
791 pdg_a.antiparticle_sign() == pdg_b.antiparticle_sign()) {
793 process_list =
nn_xx(included_2to2);
801 if ((pdg_a.is_nucleon() && pdg_b.is_kaon()) ||
802 (pdg_b.is_nucleon() && pdg_a.is_kaon())) {
804 process_list =
nk_xx(included_2to2);
805 }
else if ((pdg_a.is_hyperon() && pdg_b.is_pion()) ||
806 (pdg_b.is_hyperon() && pdg_a.is_pion())) {
808 process_list =
ypi_xx(included_2to2);
809 }
else if ((pdg_a.is_Delta() && pdg_b.is_kaon()) ||
810 (pdg_b.is_Delta() && pdg_a.is_kaon())) {
818 process_list =
dn_xx(included_2to2);
824 process_list =
dpi_xx(included_2to2);
832 CollisionBranchList process_list;
838 if (!same_sign && !any_nucleus) {
858 CollisionBranchList process_list, channel_list;
864 bool both_antinucleons =
867 const ParticleTypePtrList& nuc_or_anti_nuc =
870 const ParticleTypePtrList& delta_or_anti_delta =
880 process_list.reserve(process_list.size() + channel_list.size());
881 std::move(channel_list.begin(), channel_list.end(),
882 std::inserter(process_list, process_list.end()));
883 channel_list.clear();
894 process_list.reserve(process_list.size() + channel_list.size());
895 std::move(channel_list.begin(), channel_list.end(),
896 std::inserter(process_list, process_list.end()));
897 channel_list.clear();
909 if (deutron && antideutron && pim && pi0 && pip &&
911 const ParticleTypePtrList deutron_list = {deutron};
912 const ParticleTypePtrList antideutron_list = {antideutron};
913 const ParticleTypePtrList pion_list = {pim, pi0, pip};
915 (both_antinucleons ? antideutron_list : deutron_list), pion_list,
918 return pCM(sqrts, type_res_1.
mass(), type_res_2.
mass());
920 process_list.reserve(process_list.size() + channel_list.size());
921 std::move(channel_list.begin(), channel_list.end(),
922 std::inserter(process_list, process_list.end()));
923 channel_list.clear();
935 const auto pdg_nucleon = type_nucleon.
pdgcode().
code();
953 bool incl_KN_to_KDelta =
955 sqrt_s_ < KN_to_KDelta_cutoff;
956 bool incl_Strangeness_exchange =
959 CollisionBranchList process_list;
964 switch (pdg_nucleon) {
966 if (incl_Strangeness_exchange) {
976 sqrt_s_, type_pi_m, type_Sigma_p);
979 sqrt_s_, type_pi_p, type_Sigma_m);
982 type_pi_z, type_Sigma_z);
985 type_pi_z, type_Lambda);
996 if (incl_Strangeness_exchange) {
1004 type_pi_m, type_Sigma_z);
1007 type_pi_z, type_Sigma_m);
1010 type_pi_m, type_Lambda);
1015 if (incl_KN_to_KDelta) {
1023 type_nucleon, type_kaon,
1027 sqrt_s_, type_Kbar_z, type_Delta_pp_bar);
1031 type_nucleon, type_kaon,
1032 type_K_m, type_Delta_p_bar);
1034 sqrt_s_, type_K_m, type_Delta_p_bar);
1039 if (incl_KN_to_KDelta) {
1047 type_nucleon, type_kaon,
1051 sqrt_s_, type_Kbar_z, type_Delta_p_bar);
1055 type_nucleon, type_kaon,
1056 type_K_m, type_Delta_z_bar);
1058 sqrt_s_, type_K_m, type_Delta_z_bar);
1060 if (incl_KN_to_KN) {
1064 type_Kbar_z, type_p_bar);
1074 switch (pdg_nucleon) {
1076 if (incl_KN_to_KDelta) {
1084 type_nucleon, type_kaon,
1085 type_K_z, type_Delta_pp);
1087 sqrt_s_, type_K_z, type_Delta_pp);
1091 type_nucleon, type_kaon,
1092 type_K_p, type_Delta_p);
1094 sqrt_s_, type_K_p, type_Delta_p);
1099 if (incl_KN_to_KDelta) {
1107 type_nucleon, type_kaon,
1108 type_K_z, type_Delta_p);
1110 sqrt_s_, type_K_z, type_Delta_p);
1114 type_nucleon, type_kaon,
1115 type_K_p, type_Delta_z);
1117 sqrt_s_, type_K_p, type_Delta_z);
1119 if (incl_KN_to_KN) {
1128 if (incl_Strangeness_exchange) {
1138 sqrt_s_, type_pi_p, type_Sigma_p_bar);
1141 sqrt_s_, type_pi_m, type_Sigma_m_bar);
1144 type_pi_z, type_Sigma_z_bar);
1147 type_pi_z, type_Lambda_bar);
1149 if (incl_KN_to_KN) {
1153 sqrt_s_, type_K_z, type_n_bar);
1158 if (incl_Strangeness_exchange) {
1166 type_pi_p, type_Sigma_z_bar);
1169 type_pi_z, type_Sigma_m_bar);
1172 type_pi_p, type_Lambda_bar);
1185 switch (pdg_nucleon) {
1187 if (incl_KN_to_KDelta) {
1195 type_nucleon, type_kaon,
1196 type_K_z, type_Delta_p);
1198 sqrt_s_, type_K_z, type_Delta_p);
1202 type_nucleon, type_kaon,
1203 type_K_p, type_Delta_z);
1205 sqrt_s_, type_K_p, type_Delta_z);
1207 if (incl_KN_to_KN) {
1221 if (incl_KN_to_KDelta) {
1229 type_nucleon, type_kaon,
1230 type_K_z, type_Delta_z);
1232 sqrt_s_, type_K_z, type_Delta_z);
1236 type_nucleon, type_kaon,
1237 type_K_p, type_Delta_m);
1239 sqrt_s_, type_K_p, type_Delta_m);
1244 if (incl_Strangeness_exchange) {
1252 type_pi_m, type_Sigma_z_bar);
1255 type_pi_z, type_Sigma_p_bar);
1258 type_pi_m, type_Lambda_bar);
1263 if (incl_Strangeness_exchange) {
1273 sqrt_s_, type_pi_m, type_Sigma_m_bar);
1276 sqrt_s_, type_pi_p, type_Sigma_p_bar);
1279 type_pi_z, type_Sigma_z_bar);
1282 type_pi_z, type_Lambda_bar);
1284 if (incl_KN_to_KN) {
1288 sqrt_s_, type_K_p, type_p_bar);
1296 switch (pdg_nucleon) {
1298 if (incl_Strangeness_exchange) {
1306 type_pi_z, type_Sigma_p);
1309 type_pi_p, type_Sigma_z);
1312 type_pi_p, type_Lambda);
1317 if (incl_Strangeness_exchange) {
1327 sqrt_s_, type_pi_p, type_Sigma_m);
1330 sqrt_s_, type_pi_m, type_Sigma_p);
1333 type_pi_z, type_Sigma_z);
1336 type_pi_z, type_Lambda);
1338 if (incl_KN_to_KN) {
1347 if (incl_KN_to_KDelta) {
1349 const auto& type_Kbar_z = type_kaon;
1355 type_nucleon, type_kaon,
1359 sqrt_s_, type_Kbar_z, type_Delta_bar_m);
1363 type_nucleon, type_kaon,
1364 type_K_m, type_Delta_bar_z);
1366 sqrt_s_, type_K_m, type_Delta_bar_z);
1368 if (incl_KN_to_KN) {
1377 sqrt_s_, type_K_m, type_n_bar);
1382 if (incl_KN_to_KDelta) {
1390 type_nucleon, type_kaon,
1394 sqrt_s_, type_Kbar_z, type_Delta_z_bar);
1398 type_nucleon, type_kaon,
1399 type_K_m, type_Delta_m_bar);
1401 sqrt_s_, type_K_m, type_Delta_m_bar);
1409 return process_list;
1414 CollisionBranchList process_list;
1416 return process_list;
1423 const auto pdg_delta = type_delta.
pdgcode().
code();
1431 switch (
pack(pdg_delta, pdg_kaon)) {
1442 type_p, type_K_p, type_kaon, type_delta) *
1455 type_kaon, type_p_bar,
1458 type_p_bar, type_K_m, type_kaon, type_delta) *
1461 sqrt_s_, type_p_bar, type_K_m);
1476 type_n, type_K_p, type_kaon, type_delta) *
1487 type_p, type_K_z, type_kaon, type_delta) *
1502 type_kaon, type_n_bar,
1505 type_n_bar, type_K_m, type_kaon, type_delta) *
1508 sqrt_s_, type_n_bar, type_K_m);
1513 type_kaon, type_p_bar,
1516 type_p_bar, type_Kbar_z, type_kaon, type_delta) *
1519 sqrt_s_, type_p_bar, type_Kbar_z);
1532 type_n, type_K_z, type_kaon, type_delta) *
1545 type_kaon, type_n_bar,
1548 type_n_bar, type_Kbar_z, type_kaon, type_delta) *
1551 sqrt_s_, type_n_bar, type_Kbar_z);
1558 return process_list;
1562 CollisionBranchList process_list;
1564 return process_list;
1571 const auto pdg_hyperon = type_hyperon.
pdgcode().
code();
1576 switch (
pack(pdg_hyperon, pdg_pion)) {
1583 s, type_hyperon, type_pion, type_n, type_K_m) *
1599 sqrt_s_, type_p, type_Kbar_z);
1608 type_pion, type_n_bar,
1612 sqrt_s_, type_n_bar, type_K_p);
1621 type_pion, type_p_bar,
1625 sqrt_s_, type_p_bar, type_K_z);
1634 s, type_hyperon, type_pion, type_n, type_K_m) *
1650 sqrt_s_, type_p, type_Kbar_z);
1659 type_pion, type_n_bar,
1663 sqrt_s_, type_n_bar, type_K_p);
1672 type_pion, type_p_bar,
1676 sqrt_s_, type_p_bar, type_K_z);
1685 s, type_hyperon, type_pion, type_n, type_K_m) *
1701 sqrt_s_, type_p, type_Kbar_z);
1710 type_pion, type_n_bar,
1714 sqrt_s_, type_n_bar, type_K_p);
1723 type_pion, type_p_bar,
1727 sqrt_s_, type_p_bar, type_K_z);
1738 s, type_hyperon, type_pion, type_p, type_K_m) *
1749 sqrt_s_, type_n, type_Kbar_z);
1760 type_pion, type_p_bar,
1764 sqrt_s_, type_p_bar, type_K_p);
1768 type_pion, type_n_bar,
1772 sqrt_s_, type_n_bar, type_K_z);
1783 s, type_hyperon, type_pion, type_p, type_K_m) *
1794 sqrt_s_, type_n, type_Kbar_z);
1805 type_pion, type_p_bar,
1809 sqrt_s_, type_p_bar, type_K_p);
1813 type_pion, type_n_bar,
1817 sqrt_s_, type_n_bar, type_K_z);
1828 s, type_hyperon, type_pion, type_p, type_K_m) *
1839 sqrt_s_, type_n, type_Kbar_z);
1850 type_pion, type_p_bar,
1854 sqrt_s_, type_p_bar, type_K_p);
1858 type_pion, type_n_bar,
1862 sqrt_s_, type_n_bar, type_K_z);
1873 s, type_hyperon, type_pion, type_p, type_K_m) *
1884 sqrt_s_, type_n, type_Kbar_z);
1895 type_pion, type_p_bar,
1899 sqrt_s_, type_p_bar, type_K_p);
1903 type_pion, type_n_bar,
1907 sqrt_s_, type_n_bar, type_K_z);
1914 return process_list;
1918 const auto& log = logger<LogArea::ScatterAction>();
1919 CollisionBranchList process_list;
1929 ParticleTypePtrList nuc = (baryon_number > 0)
1936 nuc_a->charge() + nuc_b->charge()) {
1940 for (
const int twoI :
I_tot_range(*nuc_a, *nuc_b)) {
1942 type_a, type_b, *nuc_a, *nuc_b, twoI);
1949 const double matrix_element =
1951 if (matrix_element <= 0.) {
1955 const double spin_factor = (nuc_a->spin() + 1) * (nuc_b->spin() + 1);
1956 const int sym_fac_in =
1958 const int sym_fac_out =
1959 (nuc_a->iso_multiplet() == nuc_b->iso_multiplet()) ? 2 : 1;
1960 double p_cm_final =
pCM_from_s(s, nuc_a->mass(), nuc_b->mass());
1961 const double xsection = isospin_factor * spin_factor * sym_fac_in /
1962 sym_fac_out * p_cm_final * matrix_element /
1966 process_list.push_back(make_unique<CollisionBranch>(
1968 log.debug(type_a.
name(), type_b.
name(),
"->", nuc_a->name(),
1969 nuc_b->name(),
" at sqrts [GeV] = ", sqrts,
1970 " with cs[mb] = ", xsection);
1982 if (is_pid_or_pidprime &&
1990 if (produced_nucleus == &type_nucleus ||
1992 produced_nucleus->baryon_number() != type_nucleus.
baryon_number()) {
1999 const double matrix_element =
2000 295.5 + 2.862 / (0.00283735 +
pow_int(sqrts - 2.181, 2)) +
2001 0.0672 /
pow_int(tmp, 2) - 6.61753 / tmp;
2002 const double spin_factor =
2003 (produced_nucleus->spin() + 1) * (type_pi.
spin() + 1);
2008 double xsection = matrix_element * spin_factor / (s *
cm_momentum());
2009 if (produced_nucleus->is_stable()) {
2011 xsection *=
pCM_from_s(s, type_pi.
mass(), produced_nucleus->mass());
2014 const double resonance_integral =
2015 produced_nucleus->iso_multiplet()->get_integral_piR(sqrts);
2016 xsection *= resonance_integral;
2017 log.debug(
"Resonance integral ", resonance_integral,
2018 ", matrix element: ", matrix_element,
2021 process_list.push_back(make_unique<CollisionBranch>(
2023 log.debug(type_pi.
name(), type_nucleus.
name(),
"→ ", type_pi.
name(),
2024 produced_nucleus->name(),
" at ", sqrts,
2025 " GeV, xs[mb] = ", xsection);
2028 return process_list;
2036 CollisionBranchList process_list;
2038 return process_list;
2046 if (produced_nucleus == &type_nucleus ||
2048 produced_nucleus->baryon_number() != type_nucleus.
baryon_number()) {
2051 double matrix_element = 0.0;
2059 matrix_element = 79.0474 / std::pow(tmp, 0.7897) + 654.596 * tmp;
2064 matrix_element = 342.572 / std::pow(tmp, 0.6);
2066 const double spin_factor =
2067 (produced_nucleus->spin() + 1) * (type_N.
spin() + 1);
2071 double xsection = matrix_element * spin_factor / (s *
cm_momentum());
2072 if (produced_nucleus->is_stable()) {
2074 xsection *=
pCM_from_s(s, type_N.
mass(), produced_nucleus->mass());
2077 const double resonance_integral =
2078 produced_nucleus->iso_multiplet()->get_integral_NR(sqrts);
2079 xsection *= resonance_integral;
2081 process_list.push_back(make_unique<CollisionBranch>(
2083 const auto& log = logger<LogArea::ScatterAction>();
2084 log.debug(type_N.
name(), type_nucleus.
name(),
"→ ", type_N.
name(),
2085 produced_nucleus->name(),
" at ", sqrts,
2086 " GeV, xs[mb] = ", xsection);
2088 return process_list;
2092 double total_string_xs,
StringProcess* string_process,
bool use_AQM)
const {
2093 const auto& log = logger<LogArea::CrossSections>();
2095 if (!string_process) {
2096 throw std::runtime_error(
"string_process should be initialized.");
2099 CollisionBranchList channel_list;
2100 if (total_string_xs <= 0.) {
2101 return channel_list;
2110 std::array<int, 2> pdgid;
2111 double AQM_factor = 1.;
2112 for (
int i = 0; i < 2; i++) {
2120 bool can_annihilate =
false;
2123 for (
int iq = 1; iq <= n_q_types; iq++) {
2124 std::array<int, 2> nquark;
2125 for (
int i = 0; i < 2; i++) {
2129 if (nquark[0] != 0 && nquark[1] != 0) {
2130 can_annihilate =
true;
2146 std::array<double, 3> xs =
2149 for (
int ip = 0; ip < 3; ip++) {
2150 xs[ip] *= AQM_factor;
2153 double single_diffr_AX = xs[0], single_diffr_XB = xs[1], double_diffr = xs[2];
2154 double single_diffr = single_diffr_AX + single_diffr_XB;
2155 double diffractive = single_diffr + double_diffr;
2161 double sig_annihilation = 0.0;
2162 if (can_annihilate) {
2168 xs_param *= AQM_factor;
2170 sig_annihilation = std::min(total_string_xs, xs_param);
2173 const double nondiffractive_all =
2174 std::max(0., total_string_xs - sig_annihilation - diffractive);
2175 diffractive = total_string_xs - sig_annihilation - nondiffractive_all;
2176 double_diffr = std::max(0., diffractive - single_diffr);
2177 const double a = (diffractive - double_diffr) / single_diffr;
2178 single_diffr_AX *= a;
2179 single_diffr_XB *= a;
2180 assert(std::abs(single_diffr_AX + single_diffr_XB + double_diffr +
2181 sig_annihilation + nondiffractive_all - total_string_xs) <
2184 double nondiffractive_soft = 0.;
2185 double nondiffractive_hard = 0.;
2186 if (nondiffractive_all > 0.) {
2191 nondiffractive_soft =
2192 nondiffractive_all * std::exp(-hard_xsec / nondiffractive_all);
2193 nondiffractive_hard = nondiffractive_all - nondiffractive_soft;
2195 log.debug(
"String cross sections [mb] are");
2196 log.debug(
"Single-diffractive AB->AX: ", single_diffr_AX);
2197 log.debug(
"Single-diffractive AB->XB: ", single_diffr_XB);
2198 log.debug(
"Double-diffractive AB->XX: ", double_diffr);
2199 log.debug(
"Soft non-diffractive: ", nondiffractive_soft);
2200 log.debug(
"Hard non-diffractive: ", nondiffractive_hard);
2201 log.debug(
"B-Bbar annihilation: ", sig_annihilation);
2204 const double sig_string_soft = total_string_xs - nondiffractive_hard;
2207 if (sig_string_soft > 0.) {
2208 channel_list.push_back(make_unique<CollisionBranch>(
2210 channel_list.push_back(make_unique<CollisionBranch>(
2212 channel_list.push_back(make_unique<CollisionBranch>(
2214 channel_list.push_back(make_unique<CollisionBranch>(
2216 if (can_annihilate) {
2217 channel_list.push_back(make_unique<CollisionBranch>(
2221 if (nondiffractive_hard > 0.) {
2222 channel_list.push_back(make_unique<CollisionBranch>(
2225 return channel_list;
2237 if (pdg_a == pdg_b) {
2257 xs = xs_l * (1. - prob_high) + xs_h * prob_high;
2272 }
else if ((pdg_a.is_meson() && pdg_b.
is_baryon()) ||
2273 (pdg_b.
is_meson() && pdg_a.is_baryon())) {
2279 if (pdg_a.is_meson() && pdg_b.
is_meson()) {
2286 xs *= (1. - 0.4 * pdg_a.frac_strange()) * (1. - 0.4 * pdg_b.
frac_strange());
2292 double cross_sec = 0.;
2316 const double current_xs)
const {
2317 const auto& log = logger<LogArea::CrossSections>();
2321 double nnbar_xsec = std::max(0.,
ppbar_total(s) - current_xs);
2322 log.debug(
"NNbar cross section is: ", nnbar_xsec);
2330 const auto& log = logger<LogArea::CrossSections>();
2331 CollisionBranchList channel_list;
2341 if (sqrt_s_ - 2 * type_N.mass() < 0) {
2342 return channel_list;
2349 log.debug(
"NNbar reverse cross section is: ", xsection);
2350 channel_list.push_back(make_unique<CollisionBranch>(
2352 channel_list.push_back(make_unique<CollisionBranch>(
2355 return channel_list;
2359 const bool is_anti_particles)
const {
2362 CollisionBranchList process_list;
2368 ParticleTypePtrList nuc_or_anti_nuc;
2369 if (is_anti_particles) {
2380 nuc_a->charge() + nuc_b->charge()) {
2384 for (
const int twoI :
I_tot_range(*nuc_a, *nuc_b)) {
2386 type_a, type_b, *nuc_a, *nuc_b, twoI);
2393 const double matrix_element =
2395 if (matrix_element <= 0.) {
2403 const double spin_factor = (nuc_a->spin() + 1) * (nuc_b->spin() + 1);
2404 const int sym_fac_in =
2406 const int sym_fac_out =
2407 (nuc_a->iso_multiplet() == nuc_b->iso_multiplet()) ? 2 : 1;
2408 const double xsection = isospin_factor * spin_factor * sym_fac_in /
2409 sym_fac_out * p_cm_final * matrix_element /
2413 process_list.push_back(make_unique<CollisionBranch>(
2415 const auto& log = logger<LogArea::CrossSections>();
2416 log.debug(
"2->2 absorption with original particles: ", type_a,
2422 return process_list;
2429 const double m_a = type_a.
mass();
2430 const double m_b = type_b.
mass();
2431 const double msqr = 2. * (m_a * m_a + m_b * m_b);
2441 const double uplmt = m_a + m_b + 3.0 * (w_a + w_b) + 3.0;
2442 if (sqrts > uplmt) {
2449 return 68. / std::pow(sqrts - 1.104, 1.951);
2458 }
else if (twoI == 0) {
2459 const double parametrization = 14. / msqr;
2466 return 6.5 * parametrization;
2468 return parametrization;
2481 }
else if (twoI == 0) {
2495 }
else if (twoI == 0) {
2505 (1.0 - std::exp(-(sqrts - 2.0) * 20.0));
2512 template <
class IntegrationMethod>
2514 const ParticleTypePtrList& list_res_1,
2515 const ParticleTypePtrList& list_res_2,
2516 const IntegrationMethod integrator)
const {
2520 const auto& log = logger<LogArea::CrossSections>();
2521 CollisionBranchList channel_list;
2529 if (type_res_1->charge() + type_res_2->charge() !=
2535 for (
const int twoI :
I_tot_range(type_particle_a, type_particle_b)) {
2537 type_particle_a, type_particle_b, *type_res_1, *type_res_2, twoI);
2544 const double lower_limit = type_res_1->min_mass_kinematic();
2545 const double upper_limit = sqrt_s_ - type_res_2->mass();
2549 if (upper_limit - lower_limit < 1E-3) {
2555 sqrt_s_, *type_res_1, *type_res_2, twoI);
2556 if (matrix_element <= 0.) {
2563 const double resonance_integral = integrator(*type_res_1, *type_res_2);
2568 const double spin_factor =
2569 (type_res_1->spin() + 1) * (type_res_2->spin() + 1);
2570 const double xsection = isospin_factor * spin_factor * matrix_element *
2574 channel_list.push_back(make_unique<CollisionBranch>(
2576 log.debug(
"Found 2->2 creation process for resonance ", type_res_1,
2578 log.debug(
"2->2 with original particles: ", type_particle_a,
2584 return channel_list;
2588 bool use_transition_probability,
2590 bool treat_BBbar_with_strings)
const {
2593 if (!strings_switch) {
2600 const bool is_NN_scattering =
2603 const bool is_BBbar_scattering =
2611 const bool is_AQM_scattering =
2617 const double mass_sum =
2620 if (!is_NN_scattering && !is_BBbar_scattering && !is_Npi_scattering &&
2621 !is_AQM_scattering) {
2623 }
else if (is_BBbar_scattering) {
2630 const bool is_KplusP =
2642 }
else if (pdg1.
is_pion() && pdg2.is_pion()) {
2647 if (!use_transition_probability) {
2648 return static_cast<double>(
sqrt_s_ > mass_sum + aqm_offset);
2652 double region_lower, region_upper;
2653 if (is_Npi_scattering) {
2656 }
else if (is_NN_scattering) {
2662 region_lower = mass_sum + aqm_offset;
2668 }
else if (
sqrt_s_ < region_lower) {
2678 const double region_lower,
const double region_upper)
const {
2687 double x = (
sqrt_s_ - 0.5 * (region_lower + region_upper)) /
2688 (region_upper - region_lower);
2689 assert(x >= -0.5 && x <= 0.5);
2690 double prob = 0.5 * (std::sin(M_PI * x) + 1.0);
2691 assert(prob >= 0. && prob <= 1.);
static PdgCode from_decimal(const int pdgcode_decimal)
Construct PDG code from decimal number.
double piminusp_elastic(double mandelstam_s)
pi-p elastic cross section parametrization Source: GiBUU:parametrizationBarMes_HighEnergy.f90
PdgCode pdgcode() const
Get the pdgcode of the particle.
const bool is_BBbar_pair_
Whether incoming particles are a baryon-antibaryon pair.
double kminusp_kbar0n(double mandelstam_s)
K- p <-> Kbar0 n cross section parametrization.
const double sqrt_s_
Total energy in the center-of-mass frame.
double kminusp_elastic_background(double mandelstam_s)
K- p elastic background cross section parametrization Source: Buss:2011mx, B.3.9. ...
static ParticleTypePtrList & list_baryon_resonances()
static double detailed_balance_factor_RR(double sqrts, double pcm, const ParticleType &a, const ParticleType &b, const ParticleType &c, const ParticleType &d)
Helper function: Calculate the detailed balance factor R such that where and are unstable...
static ParticleTypePtrList & list_Deltas()
double string_probability(bool strings_switch, bool use_transition_probability, bool use_AQM, bool treat_nnbar_with_strings) const
double diffractive. Two strings are formed, one from A and one from B.
constexpr double really_small
Numerical error tolerance.
double deuteron_nucleon_elastic(double mandelstam_s)
Deuteron nucleon elastic cross-section [mb] parametrized by Oh:2009gx.
double piplusp_high_energy(double mandelstam_s)
pi+p total cross section at high energies
double piminusp_lambdak0_pdg(double mandelstam_s)
pi- p -> Lambda K0 cross section parametrization, PDG data.
double ppbar_elastic(double mandelstam_s)
ppbar elastic cross section parametrization Source: Bass:1998ca
double piminusp_sigma0k0_res(double mandelstam_s)
pi- p -> Sigma0 K0 cross section parametrization, resonance contribution.
String excitation processes used in SMASH.
double piminusp_sigmaminuskplus_pdg(double mandelstam_s)
pi- p -> Sigma- K+ cross section parametrization, PDG data.
double kminusp_piminussigmaplus(double sqrts)
K- p <-> pi- Sigma+ cross section parametrization Taken from UrQMD (Graef:2014mra).
CollisionBranchList deltak_xx(ReactionsBitSet included_2to2) const
Find all inelastic 2->2 processes for Delta-Kaon (DeltaK) Scattering.
constexpr uint64_t pack(int32_t x, int32_t y)
Pack two int32_t into an uint64_t.
int baryon_number() const
double kplusp_elastic_background(double mandelstam_s)
K+ p elastic background cross section parametrization.
static ParticleTypePtrList & list_light_nuclei()
Collection of useful constants that are known at compile time.
static ParticleTypePtrList & list_anti_nucleons()
double pp_high_energy(double mandelstam_s)
pp total cross section at high energies
const std::array< double, 2 > sqrts_range_NN
transition range in N-N collisions: Tuned to reproduce experimental exclusive cross section data...
double kminusn_piminussigma0(double sqrts)
K- n <-> pi- Sigma0 cross section parametrization Follow from the parametrization with the same stran...
double k0n_elastic_background(double mandelstam_s)
K0 n elastic background cross section parametrization Source: Buss:2011mx, B.3.9. ...
a special case of baryon-antibaryon annihilation.
static int pdg_map_for_pythia(PdgCode &pdg)
Take pdg code and map onto particle specie which can be handled by PYTHIA.
T pCM_sqr(const T sqrts, const T mass_a, const T mass_b) noexcept
T pCM_from_s(const T s, const T mass_a, const T mass_b) noexcept
unsigned int spin() const
constexpr T pow_int(const T base, unsigned const exponent)
Efficient template for calculating integer powers using squaring.
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...
CollisionBranchList generate_collision_list(double elastic_parameter, bool two_to_one_switch, ReactionsBitSet included_2to2, double low_snn_cut, bool strings_switch, bool use_AQM, bool strings_with_probability, NNbarTreatment nnbar_treatment, StringProcess *string_process) const
Generate a list of all possible collisions between the incoming particles with the given c...
constexpr double fm2_mb
mb <-> fm^2 conversion factor.
2->2 inelastic scattering
double get_integral_RR(const ParticleType &type_res_2, double sqrts)
Look up the tabulated resonance integral for the XX -> RR cross section.
double NN_string_hard(double mandelstam_s)
nucleon-nucleon hard scattering cross section (with partonic scattering)
double ppbar_high_energy(double mandelstam_s)
ppbar total cross section at high energies
CollisionBranchList dpi_xx(ReactionsBitSet included_2to2) const
Find all inelastic 2->2 processes involving Pion and (anti-) Deuteron (dpi), specifically dπ→ NN...
constexpr double nucleon_mass
Nucleon mass in GeV.
double k0p_elastic_background(double mandelstam_s)
K0 p elastic background cross section parametrization Source: Buss:2011mx, B.3.9. ...
T pCM_sqr_from_s(const T s, const T mass_a, const T mass_b) noexcept
CollisionBranchList npi_yk() const
Find all processes for Nucleon-Pion to Hyperon-Kaon Scattering.
double spectral_function(double m) const
Full spectral function of the resonance (relativistic Breit-Wigner distribution with mass-dependent ...
double nn_el() const
Determine the (parametrized) elastic cross section for a nucleon-nucleon (NN) collision.
constexpr double hbarc
GeV <-> fm conversion factor.
static double sum_xs_of(CollisionBranchList &list)
Helper function: Sum all cross sections of the given process list.
CollisionBranchPtr elastic(double elast_par, bool use_AQM) const
Determine the elastic cross section for this collision.
NNbarTreatment
Treatment of N Nbar Annihilation.
CollisionBranchList two_to_one() const
Find all resonances that can be produced in a 2->1 collision of the two input particles and the produ...
double get_integral_NR(double sqrts)
Look up the tabulated resonance integral for the XX -> NR cross section.
double get_integral_RK(double sqrts)
Look up the tabulated resonance integral for the XX -> RK cross section.
CollisionBranchPtr NNbar_annihilation(const double current_xs) const
Determine the cross section for NNbar annihilation, which is given by the difference between the para...
double kplusn_k0p(double mandelstam_s)
K+ n charge exchange cross section parametrization.
KaonNucleonRatios kaon_nucleon_ratios
CollisionBranchList nn_xx(ReactionsBitSet included_2to2) const
Find all inelastic 2->2 processes for Nucelon-Nucelon Scattering.
constexpr double pion_mass
Pion mass in GeV.
Range of total isospin for reaction of particle a with particle b.
double kbar0n_elastic_background(double mandelstam_s)
Kbar0 n elastic background cross section parametrization Source: Buss:2011mx, B.3.9.
CrossSections(const ParticleList &incoming_particles, const double sqrt_s, const std::pair< FourVector, FourVector > potentials)
Construct CrossSections instance.
static const ParticleType & find(PdgCode pdgcode)
Returns the ParticleType object for the given pdgcode.
double npi_el() const
Determine the elastic cross section for a nucleon-pion (Npi) collision.
CollisionBranchList rare_two_to_two() const
Find all 2->2 processes which are suppressed at high energies when strings are turned on with probabi...
double string_hard_cross_section() const
Determine the (parametrized) hard non-diffractive string cross section for this collision.
constexpr int h1
h₁(1170).
double nk_el() const
Determine the elastic cross section for a nucleon-kaon (NK) collision.
std::array< double, 3 > cross_sections_diffractive(int pdg_a, int pdg_b, double sqrt_s)
Interface to pythia_sigmatot_ to compute cross-sections of A+B-> different final states Schuler:1993w...
double kminusn_piminuslambda(double sqrts)
K- n <-> pi- Lambda cross section parametrization Follow from the parametrization with the same stran...
CollisionBranchList NNbar_creation() const
Determine the cross section for NNbar creation, which is given by detailed balance from the reverse r...
int antiparticle_sign() const
IsoParticleType * iso_multiplet() const
static const ParticleTypeList & list_all()
elastic scattering: particles remain the same, only momenta change
CollisionBranchList dn_xx(ReactionsBitSet included_2to2) const
Find all inelastic 2->2 processes involving Nucleon and (anti-) Deuteron (dN), specifically Nd → Nd'...
CollisionBranchList bb_xx_except_nn(ReactionsBitSet included_2to2) const
Find all inelastic 2->2 processes for Baryon-Baryon (BB) Scattering except the more specific Nucleon-...
double pipi_string_hard(double mandelstam_s)
pion-pion hard scattering cross section (with partonic scattering)
double kminusp_pi0sigma0(double sqrts)
K- p <-> pi0 Sigma0 cross section parametrization Fit to Landolt-Börnstein instead of UrQMD values...
const std::string & name() const
void add_channel(CollisionBranchList &process_list, F &&get_xsection, double sqrts, const ParticleType &type_a, const ParticleType &type_b) const
Helper function: Add a 2-to-2 channel to a collision branch list given a cross section.
constexpr int decimal_d
Deuteron in decimal digits.
constexpr int Delta_pp
Δ⁺⁺.
Particle type contains the static properties of a particle species.
constexpr double minimum_sqrts_pythia_can_handle
Energy in GeV, below which hard reactions via pythia are impossible.
CollisionBranchList two_to_two(ReactionsBitSet included_2to2) const
Find all inelastic 2->2 processes for the given scattering.
constexpr int decimal_antid
Anti-deuteron in decimal digits.
double piminusp_high_energy(double mandelstam_s)
pi-p total cross section at high energies
double np_elastic(double mandelstam_s)
np elastic cross section parametrization Source: Weil:2013mya, eq.
double kplusn_elastic_background(double mandelstam_s)
K+ n elastic background cross section parametrization sigma(K+n->K+n) = sigma(K+n->K0p) = 0...
hard string process involving 2->2 QCD process by PYTHIA.
const double KN_offset
Constant offset as to where to shift from 2to2 to string processes (in GeV) in the case of KN reactio...
constexpr double deuteron_mass
Deuteron mass in GeV.
PdgCode stores a Particle Data Group Particle Numbering Scheme particle type number.
const double sqrts_range
constant for the range of transition region in the case of AQM this is added to the sum of masses + s...
double piplusp_elastic(double mandelstam_s)
pi+p elastic cross section parametrization, PDG data.
static double detailed_balance_factor_RK(double sqrts, double pcm, const ParticleType &a, const ParticleType &b, const ParticleType &c, const ParticleType &d)
Helper function: Calculate the detailed balance factor R such that where is unstable, is a kaon and are stable.
const ParticleType & type() const
Get the type of the particle.
CollisionBranchList nk_xx(ReactionsBitSet included_2to2) const
Find all inelastic 2->2 background processes for Nucleon-Kaon (NK) Scattering.
CollisionBranchList bar_bar_to_nuc_nuc(const bool is_anti_particles) const
Calculate cross sections for resonance absorption (i.e.
std::bitset< 10 > ReactionsBitSet
Container for the 2 to 2 reactions in the code.
CollisionBranchList string_excitation(double total_string_xs, StringProcess *string_process, bool use_AQM) const
Determine the cross section for string excitations, which is given by the difference between the para...
ParticleTypePtr get_antiparticle() const
int32_t charge() const
The charge of the particle.
const double sqrts_add_lower
constant for the lower end of transition region in the case of AQM this is added to the sum of masses...
const ParticleList incoming_particles_
List with data of scattering particles.
double pp_elastic(double mandelstam_s)
pp elastic cross section parametrization Source: Weil:2013mya, eq.
double kminusp_piplussigmaminus(double sqrts)
K- p <-> pi+ Sigma- cross section parametrization Taken from UrQMD (Graef:2014mra).
static double detailed_balance_factor_stable(double s, const ParticleType &a, const ParticleType &b, const ParticleType &c, const ParticleType &d)
Helper function: Calculate the detailed balance factor R such that where are stable.
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.
double kminusn_elastic_background(double mandelstam_s)
K- n elastic background cross section parametrization Source: Buss:2011mx, B.3.9. ...
CollisionBranchList find_nn_xsection_from_type(const ParticleTypePtrList &type_res_1, const ParticleTypePtrList &type_res_2, const IntegrationMethod integrator) const
Utility function to avoid code replication in nn_xx().
Use string fragmentation.
bool is_Nstar1535() const
Use intermediate Resonances.
int antiparticle_sign() const
double formation(const ParticleType &type_resonance, double cm_momentum_sqr) const
Return the 2-to-1 resonance production cross section for a given resonance.
std::int32_t code() const
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...
CollisionBranchList ypi_xx(ReactionsBitSet included_2to2) const
Find all inelastic 2->2 processes for Hyperon-Pion (Ypi) Scattering.
double kplusn_inelastic_background(double mandelstam_s)
K+ n inelastic background cross section parametrization Source: Buss:2011mx, B.3.8.
const double pipi_offset
Constant offset as to where to turn on the strings and elastic processes for pi pi reactions (this is...
double width_at_pole() const
bool is_antiparticle_of(const PdgCode rhs) const
static const ParticleTypePtr try_find(PdgCode pdgcode)
Returns the ParticleTypePtr for the given pdgcode.
double high_energy() const
Determine the parametrized total cross section at high energies for the given collision, which is non-zero for Baryon-Baryon and Nucleon-Pion scatterings currently.
resonance formation (2->1)
double ppbar_total(double mandelstam_s)
ppbar total cross section parametrization Source: Bass:1998ca
single diffractive AB->XB.
double kminusp_pi0lambda(double sqrts)
K- p <-> pi0 Lambda cross section parametrization Fit to Landolt-Börnstein instead of UrQMD values...
double elastic_parametrization(bool use_AQM) const
Choose the appropriate parametrizations for given incoming particles and return the (parametrized) el...
double piplusp_sigmapluskplus_pdg(double mandelstam_s)
pi+ p to Sigma+ K+ cross section parametrization, PDG data.
A pointer-like interface to global references to ParticleType objects.
double npbar_high_energy(double mandelstam_s)
npbar total cross section at high energies
double piplusp_elastic_high_energy(double mandelstam_s, double m1, double m2)
pi+p elactic cross section parametrization.
double deuteron_pion_elastic(double mandelstam_s)
Deuteron pion elastic cross-section [mb] parametrized to fit pi-d elastic scattering data (the data c...
double probability_transit_high(const double region_lower, const double region_upper) const
static ParticleTypePtrList & list_nucleons()
double get_partial_in_width(const double m, const ParticleData &p_a, const ParticleData &p_b) const
Get the mass-dependent partial in-width of a resonance with mass m, decaying into two given daughter ...
double cm_momentum() const
Determine the momenta of the incoming particles in the center-of-mass system.
double kbar0p_elastic_background(double mandelstam_s)
Kbar0 p elastic background cross section parametrization Source: Buss:2011mx, B.3.9.
non-diffractive. Two strings are formed both have ends in A and B.
T pCM(const T sqrts, const T mass_a, const T mass_b) noexcept
const std::array< double, 2 > sqrts_range_Npi
transition range in N-pi collisions
int32_t get_decimal() const
static void append_list(CollisionBranchList &main_list, CollisionBranchList in_list, double weight=1.)
Helper function: Append a list of processes to another (main) list of processes.
static double nn_to_resonance_matrix_element(double sqrts, const ParticleType &type_a, const ParticleType &type_b, const int twoI)
Scattering matrix amplitude squared (divided by 16π) for resonance production processes like NN → NR...
double np_high_energy(double mandelstam_s)
np total cross section at high energies
unsigned int spin() const
ParticleData contains the dynamic information of a certain particle.
(41-45) soft string excitations.
static ParticleTypePtrList & list_anti_Deltas()
bool is_Deltastar() const
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 kplusp_inelastic_background(double mandelstam_s)
K+ p inelastic background cross section parametrization Source: Buss:2011mx, B.3.8.
double frac_strange() const
double Npi_string_hard(double mandelstam_s)
nucleon-pion 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 ...