14 #include "Pythia8/Pythia.h"
32 const double string_formation_time,
33 const double box_length,
34 const bool is_total_parametrized,
36 :
Action({in_part_a, in_part_b}, time),
37 sum_of_partial_cross_sections_(0.),
38 isotropic_(isotropic),
39 string_formation_time_(string_formation_time),
40 is_total_parametrized_(is_total_parametrized),
41 spin_interaction_type_(spin_interaction_type) {
42 box_length_ = box_length;
43 if (is_total_parametrized_) {
44 parametrized_total_cross_section_ = smash_NaN<double>;
111 "ScatterAction::generate_final_state: Invalid process type " +
117 const bool core_in_incoming =
123 new_particle.boost_momentum(
128 new_particle.set_4position(middle_point);
129 if (core_in_incoming) {
130 new_particle.fluidize();
132 if (new_particle.type().pdgcode().is_heavy_flavor()) {
134 const double perturbative_weight = std::accumulate(
137 return w * p.perturbative_weight();
139 new_particle.set_perturbative_weight(perturbative_weight);
149 throw std::logic_error(
150 "add_all_scatterings should be called only once per ScatterAction "
166 CollisionBranchList processes =
180 const double xs_diff =
189 bool suppress_pseudoresonances_for_T_matrix_channels =
false;
196 suppress_pseudoresonances_for_T_matrix_channels =
true;
203 if (pseudoresonance && finder_parameters.
two_to_one &&
204 !suppress_pseudoresonances_for_T_matrix_channels) {
212 auto pseudoresonance_branch = std::make_unique<CollisionBranch>(
218 << pseudoresonance->
name() <<
" with cross section " << xs_gap
231 <<
"Trying to rescale branches before adding processes.";
232 throw std::logic_error(
233 "This function can only be called after having added processes.");
240 const std::set<ParticleTypePtr> pair{type_a, type_b};
243 <<
"Total cross section between " << type_a->
name() <<
" and "
244 << type_b->
name() <<
" is roughly zero at sqrt(s) = " <<
sqrt_s()
245 <<
" GeV, and no rescaling to match the parametrized value will be "
246 "done.\nAn elastic process will be added, instead, to match the "
247 "total cross section.\nFor this pair of particles, this warning "
248 "will be subsequently suppressed.";
251 auto elastic_branch = std::make_unique<CollisionBranch>(
256 const double reweight =
261 proc->set_weight(proc->weight() * reweight);
271 const double desired_mass =
sqrt_s();
280 if (nucleon_and_pion) {
282 }
else if (two_nucleons) {
284 }
else if (two_pions) {
286 }
else if (nucleon_and_kaon) {
310 if (std::empty(list)) {
316 auto largest = *std::max_element(list.begin(), list.end(),
318 return a->mass() < b->mass();
324 return std::abs(a->
mass() - desired_mass) <
325 std::abs(b->mass() - desired_mass);
327 auto closest = *std::min_element(list.begin(), list.end(), comparison);
330 throw std::logic_error(
"Unknown method for selecting pseudoresonance.");
344 <<
"Trying to parametrize total cross section when it shouldn't be.";
345 throw std::logic_error(
346 "This function can only be called on ScatterAction objects with "
347 "parametrized cross section.");
367 return (1. / std::sqrt(1.0 -
beta_cm().sqr()));
388 const double lamb =
lambda_tilde(m_s, m1 * m1, m2 * m2);
407 " position difference [fm]: ", pos_diff,
408 ", momentum difference [GeV]: ", mom_diff);
410 const double dp2 = mom_diff.
sqr();
411 const double dr2 = pos_diff.
sqr();
416 const double dpdr = pos_diff * mom_diff;
425 const double result = dr2 - dpdr * dpdr / dp2;
426 return result > 0.0 ? result : 0.0;
435 const double mom_diff_sqr =
437 const double x_sqr = delta_x.
sqr();
445 const double p_a_dot_x = p_a.
momentum().
Dot(delta_x);
446 const double p_b_dot_x = p_b.
momentum().
Dot(delta_x);
451 (p_a_sqr * std::pow(p_b_dot_x, 2) + p_b_sqr * std::pow(p_a_dot_x, 2) -
452 2 * p_a_dot_p_b * p_a_dot_x * p_b_dot_x) /
453 (std::pow(p_a_dot_p_b, 2) - p_a_sqr * p_b_sqr);
454 return b_sqr > 0.0 ? b_sqr : 0.0;
467 return 7.6 + 0.66 * std::log(mandelstam_s);
485 return 5.5 * p8 / (7.7 + p8);
504 }
else if (plab < 0.6) {
505 return 16.53 * (plab - 0.225);
506 }
else if (plab < 1.6) {
507 return -1.63 * plab + 7.16;
514 double kinetic_energy_cm) {
536 const double mass_a = masses.first;
537 const double mass_b = masses.second;
539 const std::array<double, 2> t_range = get_t_range<double>(
540 kinetic_energy_cm, mass_in_a, mass_in_b, mass_a, mass_b);
546 double mandelstam_s_new = 0.;
562 double bb, a, plab =
plab_from_s(mandelstam_s_new);
569 a = (plab < 0.8) ? 1. : 0.64 / (plab * plab);
579 t = t_range[0] + t_range[1] - t;
583 1. - 2. * (t - t_range[0]) / (t_range[1] - t_range[0]));
596 t = t_range[0] + t_range[1] - t;
599 1. - 2. * (t - t_range[0]) / (t_range[1] - t_range[0]));
603 const std::array<double, 4>
p{1.46434, 5.80311, -6.89358, 1.94302};
604 const double a =
p[0] + mass_a * (
p[1] + mass_a * (
p[2] + mass_a *
p[3]));
608 double t = t_range[0];
613 t = t_range[0] + t_range[1] - t;
616 1. - 2. * (t - t_range[0]) / (t_range[1] - t_range[0]));
629 const double p_f =
pCM(kinetic_energy_cm, mass_a, mass_b);
632 " radial momentum: ", p_f);
678 "resonance_formation: "
679 "Incorrect number of particles in final state: ";
706 out_mom += data.momentum();
709 logg[
LPythia].debug(
"Outgoing momenta string:", out_mom);
724 bool success =
false;
726 const int ntry_max = 10000;
727 while (!success && ntry < ntry_max) {
732 if (ntry == ntry_max) {
737 bool success_newtry =
false;
753 while (!success_newtry && ntry_new < ntry_max) {
758 if (success_newtry) {
762 if (!success_newtry) {
820 if (has_lambda && has_pion) {
828 FourVector final_spin_vector = lambda.spin_vector();
830 if (random_int <= 7) {
842 final_spin_vector[1] = -final_spin_vector[1];
843 final_spin_vector[2] = -final_spin_vector[2];
844 final_spin_vector[3] = -final_spin_vector[3];
851 sigma_star.set_spin_vector(final_spin_vector);
864 const bool is_AB_to_AX =
866 const bool is_AB_to_XB =
874 if (is_AB_to_AX || is_AB_to_XB) {
875 const std::size_t idx_hadron_in = is_AB_to_AX ? 0 : 1;
888 it->set_unpolarized_spin_vector();
892 particle.set_unpolarized_spin_vector();
900 out <<
" (not performed)";
Action is the base class for a generic process that takes a number of incoming particles and transfor...
virtual void sample_2body_phasespace()
Sample the full 2-body phase-space (masses, momenta, angles) in the center-of-mass frame for the fina...
FourVector total_momentum_of_outgoing_particles() const
Calculate the total kinetic momentum of the outgoing particles.
void assign_formation_time_to_outgoing_particles()
Assign the formation time to the outgoing particles.
std::pair< FourVector, FourVector > get_potential_at_interaction_point() const
Get the skyrme and asymmetry potential at the interaction point.
ParticleList outgoing_particles_
Initially this stores only the PDG codes of final-state particles.
FourVector total_momentum() const
Sum of 4-momenta of incoming particles.
virtual void sample_manybody_phasespace()
Sample the full n-body phase-space (masses, momenta, angles) in the center-of-mass frame for the fina...
const double time_of_execution_
Time at which the action is supposed to be performed (absolute time in the lab frame in fm).
void assign_unpolarized_spin_vector_to_outgoing_particles()
Assign an unpolarized spin vector to all outgoing particles.
const ParticleList & incoming_particles() const
Get the list of particles that go into the action.
double sqrt_s() const
Determine the total energy in the center-of-mass frame [GeV].
ParticleList incoming_particles_
List with data of incoming particles.
FourVector get_interaction_point() const
Get the interaction point.
static double lambda_tilde(double a, double b, double c)
Little helper function that calculates the lambda function (sometimes written with a tilde to better ...
ProcessType process_type_
type of process
Angles provides a common interface for generating directions: i.e., two angles that should be interpr...
ThreeVector threevec() const
void distribute_isotropically()
Populate the object with a new direction.
CollisionBranch is a derivative of ProcessBranch, which is used to represent particular final-state c...
ProcessType get_type() const override
The CrossSections class assembles everything that is needed to calculate cross sections and gathers a...
double high_energy(const ScatterActionsFinderParameters &finder_parameters) const
Determine the parametrized total cross section at high energies for the given collision,...
double string_probability(const ScatterActionsFinderParameters &finder_parameters) const
CollisionBranchList string_excitation(double total_string_xs, StringProcess *string_process, const ScatterActionsFinderParameters &finder_parameters) const
Determine the cross section for string excitations, which is given by the difference between the para...
double parametrized_total(const ScatterActionsFinderParameters &finder_parameters) const
Select the parametrization for the total cross section, given the types of incoming particles.
CollisionBranchList generate_collision_list(const ScatterActionsFinderParameters &finder_parameters, StringProcess *string_process) const
Generate a list of all possible collisions between the incoming particles with the given c....
Guard type that safely disables floating point traps for the scope in which it is placed.
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
double sqr() const
calculate the square of the vector (which is a scalar)
FourVector lorentz_boost(const ThreeVector &v) const
Returns the FourVector boosted with velocity v.
ThreeVector threevec() const
double Dot(const FourVector &a) const
calculate the scalar product with another four-vector
ThreeVector velocity() const
Get the velocity (3-vector divided by zero component).
ParticleData contains the dynamic information of a certain particle.
PdgCode pdgcode() const
Get the pdgcode of the particle.
void set_4momentum(const FourVector &momentum_vector)
Set the particle's 4-momentum directly.
const ParticleType & type() const
Get the type of the particle.
const FourVector & momentum() const
Get the particle's 4-momentum.
ThreeVector velocity() const
Get the velocity 3-vector.
const FourVector & spin_vector() const
Get the mean spin 4-vector (Pauli–Lubanski vector) of the particle (const reference,...
void set_spin_vector(const FourVector &s)
Set the mean spin 4-vector (Pauli–Lubanski vector) of the particle.
void boost(const ThreeVector &v)
Apply a full Lorentz boost of momentum and position.
const FourVector & position() const
Get the particle's position in Minkowski space.
A pointer-like interface to global references to ParticleType objects.
const std::string & name() const
int32_t charge() const
The charge of the particle.
bool is_Deltastar() const
PdgCode stores a Particle Data Group Particle Numbering Scheme particle type number.
int antiparticle_sign() const
int baryon_number() const
bool is_Dstar2007() const
double frac_charm() const
ParticleList particle_list() const
Thrown when ScatterAction is called to perform with unknown ProcessType.
SpinInteractionType spin_interaction_type_
What kind of spin interaction to use.
bool isotropic_
Do this collision isotropically?
std::optional< double > parametrized_total_cross_section_
If cross section is parametrized, store the value.
void string_spin_interaction()
Perform spin interaction in string excitations.
void rescale_outgoing_branches()
Loop over the possible branches and rescales their weight according to the desired total cross sectio...
void add_collision(CollisionBranchPtr p)
Add a new collision channel.
ScatterAction(const ParticleData &in_part1, const ParticleData &in_part2, double time, bool isotropic=false, double string_formation_time=1.0, double box_length=-1.0, bool is_total_parametrized=false, const SpinInteractionType spin_interaction_type=SpinInteractionType::Off)
Construct a ScatterAction object.
void resonance_formation()
Perform a 2->1 resonance-formation process.
ThreeVector beta_cm() const
Get the velocity of the center of mass of the scattering/incoming particles in the calculation frame.
double partial_cross_section_
Partial cross-section to the chosen outgoing channel.
double relative_velocity() const
Get the relative velocity of the two incoming particles.
double mandelstam_s() const
Determine the Mandelstam s variable,.
void set_parametrized_total_cross_section(const ScatterActionsFinderParameters &finder_parameters)
Given the incoming particles, assigns the correct parametrization of the total cross section.
double get_partial_weight() const override
Get the partial cross section of the chosen channel.
StringProcess * string_process_
Pointer to interface class for strings.
bool is_total_parametrized_
Whether the total cross section is parametrized.
void create_string_final_state()
Creates the final states for string-processes after they are performed.
double sum_of_partial_cross_sections_
Current sum of partial hadronic cross sections.
double cm_momentum_squared() const
Get the squared momentum of the center of mass of the incoming particles in the calculation frame.
void generate_final_state() override
Generate the final-state of the scattering process.
void add_all_scatterings(const ScatterActionsFinderParameters &finder_parameters)
Add all possible scattering subprocesses for this action object.
void two_to_many_scattering()
Perform an inelastic two-to-many-body scattering (more than 2)
double get_total_weight() const override
Get the total cross section of scattering particles.
void string_excitation()
Todo(ryu): document better - it is not really UrQMD-based, isn't it? Perform the UrQMD-based string e...
void elastic_scattering()
Perform an elastic two-body scattering, i.e. just exchange momentum.
void inelastic_scattering()
Perform an inelastic two-body scattering, i.e. new particles are formed.
void spin_interaction()
Perform spin interaction in binary interactions.
void sample_angles(std::pair< double, double > masses, double kinetic_energy_cm) override
Sample final-state angles in a 2->2 collision (possibly anisotropic).
void add_collisions(CollisionBranchList pv)
Add several new collision channels at once.
double gamma_cm() const
Get the gamma factor corresponding to a boost to the center of mass frame of the colliding particles.
double cm_momentum() const
Get the momentum of the center of mass of the incoming particles in the calculation frame.
bool were_processes_added_
Lock for calling add_all_scatterings only once.
static std::set< std::set< ParticleTypePtr > > warned_no_rescaling_available
Warn about zero cross section only once per particle type pair.
double cov_transverse_distance_sqr() const
Calculate the transverse distance of the two incoming particles in their local rest frame written in ...
ParticleTypePtr try_find_pseudoresonance(const PseudoResonance method, const StringTransitionParameters &transition) const
Try to find a pseudo-resonance that can be created from the incoming particles using a given method.
CollisionBranchList collision_channels_
List of possible collisions.
double transverse_distance_sqr() const
Calculate the transverse distance of the two incoming particles in their local rest frame.
Helper class for ScatterActionsFinder.
const bool strings_with_probability
This indicates whether the string fragmentation is swiched on with a probability smoothly increasing ...
const StringTransitionParameters transition_high_energy
Constants related to transition between low collision energies - mediated via resonances - and high c...
const CharmRescattering charm_rescattering
Specifies kind of charm rescattering.
const PseudoResonance pseudoresonance_method
Which pseudo-resonance to choose.
const bool two_to_one
Enables resonance production.
ParticleList get_final_state()
bool next(ProcessType type)
Generate the next string process for a given process type.
void init(const ParticleList &incoming, double tcoll)
initialization feed intial particles, time of collision and gamma factor of the center of mass.
The ThreeVector class represents a physical three-vector with the components .
void rotate_z_axis_to(ThreeVector &r)
Rotate the z-axis onto the vector r.
Collection of useful constants that are known at compile time.
@ T_Matrix
Charm interactions via T-matrix approach.
@ None
Disable charm interactions.
PseudoResonance
Which pseudo-resonance fills the inelastic gap in the transition to string region of cross sections.
@ Closest
Resonance with the pole mass closest from the invariant mass of incoming particles for all processes.
@ ClosestFromUnstable
Closest resonance for a given mass from processes with at least one resonance in the incoming particl...
@ None
No pseudo-resonance is created.
@ LargestFromUnstable
Heaviest possible resonance from processes with at least one resonance in the incoming particles.
@ Largest
Resonance of largest mass for all processes.
SpinInteractionType
Possible spin interaction types.
@ Off
No spin interactions.
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > & logg
An array that stores all pre-configured Logger objects.
void format_debug_output(std::ostream &out) const override
Writes information about this scatter action to the out stream.
T power(T n, T xMin, T xMax)
Sample from a power-law probability density proportional to |x|^n.
T expo(T A, T x1, T x2)
Draws a random number x from an exponential distribution exp(A*x), where A is assumed to be positive,...
T uniform_int(T min, T max)
double plab_from_s(double mandelstam_s, double mass)
Convert Mandelstam-s to p_lab in a fixed-target collision.
static double Cugnon_bnp(double plab)
Computes the B coefficients from the Cugnon parametrization of the angular distribution in elastic np...
T pCM(const T sqrts, const T mass_a, const T mass_b) noexcept
ParticleTypePtrList list_possible_resonances(const ParticleTypePtr type_a, const ParticleTypePtr type_b)
Lists the possible resonances that decay into two particles.
T pCM_sqr(const T sqrts, const T mass_a, const T mass_b) noexcept
@ FailedString
See here for a short description.
@ TwoToOne
See here for a short description.
@ StringHardSingleDiffractiveAX
See here for a short description.
@ StringSoftDoubleDiffractive
See here for a short description.
@ TwoToFive
See here for a short description.
@ StringSoftSingleDiffractiveXB
See here for a short description.
@ TwoToTwo
See here for a short description.
@ Elastic
See here for a short description.
@ TwoToFour
See here for a short description.
@ StringHardNonDiffractive
See here for a short description.
@ StringSoftAnnihilation
See here for a short description.
@ StringSoftNonDiffractive
See here for a short description.
@ StringSoftSingleDiffractiveAX
See here for a short description.
@ StringHardSingleDiffractiveXB
See here for a short description.
@ StringHardDoubleDiffractive
See here for a short description.
@ TwoToThree
See here for a short description.
static double high_energy_bpp(double plab)
Computes the B coefficients from the STAR fit, see fig.
std::string to_string(ThermodynamicQuantity quantity)
Convert a ThermodynamicQuantity enum value to its corresponding string.
constexpr double nucleon_mass
Nucleon mass in GeV.
constexpr T pow_int(const T base, unsigned const exponent)
Efficient template for calculating integer powers using squaring.
constexpr double pion_mass
Pion mass in GeV.
T pCM_from_s(const T s, const T mass_a, const T mass_b) noexcept
constexpr double really_small
Numerical error tolerance.
static constexpr int LScatterAction
static constexpr int LPythia
double s_from_plab(double plab, double m_P, double m_T)
Convert p_lab to Mandelstam-s for a fixed-target setup, with a projectile of mass m_P and momentum pl...
bool is_string_process(ProcessType p)
Check if a given process type is a string excitation.
static void boost_spin_vectors_after_elastic_scattering(ParticleData &outgoing_particle_a, ParticleData &outgoing_particle_b)
static double Cugnon_bpp(double plab)
Computes the B coefficients from the Cugnon parametrization of the angular distribution in elastic pp...
Constants related to transition between low and high collision energies.
const std::pair< double, double > sqrts_range_Npi
Transition range in N collisions.
const double pipi_offset
Constant offset as to where to turn on the strings and elastic processes for reactions (this is an e...
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 double KN_offset
Constant offset as to where to shift from 2to2 to string processes (in GeV) in the case of KN reactio...
const std::pair< double, double > sqrts_range_NN
Transition range in NN collisions.