 |
Version: SMASH-1.8
|
|
#include <processstring.h>
String excitation processes used in SMASH.
Only one instance of this class should be created.
This class implements string excitation processes based on the UrQMD model Bass:1998ca [4], Bleicher:1999xi [8] and subsequent fragmentation according to the LUND/PYTHIA fragmentation scheme Andersson:1983ia [2], Sjostrand:2014zea [41].
The class implements the following functionality:
- given two colliding initial state particles it provides hadronic final state after single diffractive, double diffractive and non-diffractive string excitation
- owns a Pythia8::SigmaTotal object to compute corresponding cross-sections
- owns a Pythia object, that allows to fragment strings
Definition at line 47 of file processstring.h.
|
| StringProcess (double string_tension, double time_formation, double gluon_beta, double gluon_pmin, double quark_alpha, double quark_beta, double strange_supp, double diquark_supp, double sigma_perp, double stringz_a_leading, double stringz_b_leading, double stringz_a, double stringz_b, double string_sigma_T, double factor_t_form, bool mass_dependent_formation_times, double prob_proton_to_d_uu, bool separate_fragment_baryon, double popcorn_rate) |
| Constructor, initializes pythia. More...
|
|
void | common_setup_pythia (Pythia8::Pythia *pythia_in, double strange_supp, double diquark_supp, double popcorn_rate, double stringz_a, double stringz_b, double string_sigma_T) |
| Common setup of PYTHIA objects for soft and hard string routines. More...
|
|
void | init_pythia_hadron_rndm () |
| Set PYTHIA random seeds to be desired values. More...
|
|
Pythia8::Pythia * | get_ptr_pythia_parton () |
| Function to get the PYTHIA object for hard string routine. More...
|
|
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:1993wr [39]. More...
|
|
void | set_pmin_gluon_lightcone (double p_light_cone_min) |
| set the minimum lightcone momentum scale carried by gluon. More...
|
|
void | set_pow_fgluon (double betapow) |
| lightcone momentum fraction of gluon is sampled according to probability distribution P(x) = 1/x * (1 - x)^{1 + pow_fgluon_beta_} in double-diffractive processes. More...
|
|
void | set_pow_fquark (double alphapow, double betapow) |
| lightcone momentum fraction of quark is sampled according to probability distribution \( P(x) = x^{pow_fquark_alpha_ - 1} * (1 - x)^{pow_fquark_beta_ - 1} \) in non-diffractive processes. More...
|
|
void | set_sigma_qperp_ (double sigma_qperp) |
| set the average amount of transverse momentum transfer sigma_qperp_. More...
|
|
void | set_tension_string (double kappa_string) |
| set the string tension, which is used in append_final_state. More...
|
|
void | init (const ParticleList &incoming, double tcoll) |
| initialization feed intial particles, time of collision and gamma factor of the center of mass. More...
|
|
void | compute_incoming_lightcone_momenta () |
| compute the lightcone momenta of incoming particles where the longitudinal direction is set to be same as that of the three-momentum of particle A. More...
|
|
bool | set_mass_and_direction_2strings (const std::array< std::array< int, 2 >, 2 > &quarks, const std::array< FourVector, 2 > &pstr_com, std::array< double, 2 > &m_str, std::array< ThreeVector, 2 > &evec_str) |
| Determine string masses and directions in which strings are stretched. More...
|
|
bool | make_final_state_2strings (const std::array< std::array< int, 2 >, 2 > &quarks, const std::array< FourVector, 2 > &pstr_com, const std::array< double, 2 > &m_str, const std::array< ThreeVector, 2 > &evec_str, bool flip_string_ends, bool separate_fragment_baryon) |
| Prepare kinematics of two strings, fragment them and append to final_state. More...
|
|
bool | next_SDiff (bool is_AB_to_AX) |
| Single-diffractive process is based on single pomeron exchange described in Ingelman:1984ns [22]. More...
|
|
bool | next_DDiff () |
| Double-diffractive process ( A + B -> X + X ) is similar to the single-diffractive process, but lightcone momenta of gluons are sampled in the same was as the UrQMD model Bass:1998ca [4], Bleicher:1999xi [8]. More...
|
|
bool | next_NDiffSoft () |
| Soft Non-diffractive process is modelled in accordance with dual-topological approach Capella:1978ig [12]. More...
|
|
bool | next_NDiffHard () |
| Hard Non-diffractive process is based on PYTHIA 8 with partonic showers and interactions. More...
|
|
bool | next_BBbarAnn () |
| Baryon-antibaryon annihilation process Based on what UrQMD Bass:1998ca [4], Bleicher:1999xi [8] does, it create two mesonic strings after annihilating one quark-antiquark pair. More...
|
|
void | replace_constituent (Pythia8::Particle &particle, std::array< int, 5 > &excess_constituent) |
| Convert a partonic PYTHIA particle into the desired species and update the excess of constituents. More...
|
|
void | find_total_number_constituent (Pythia8::Event &event_intermediate, std::array< int, 5 > &nquark_total, std::array< int, 5 > &nantiq_total) |
| Compute how many quarks and antiquarks we have in the system, and update the correspoing arrays with size 5. More...
|
|
bool | splitting_gluon_qqbar (Pythia8::Event &event_intermediate, std::array< int, 5 > &nquark_total, std::array< int, 5 > &nantiq_total, bool sign_constituent, std::array< std::array< int, 5 >, 2 > &excess_constituent) |
| Take total number of quarks and check if the system has enough constituents that need to be converted into other flavors. More...
|
|
void | rearrange_excess (std::array< int, 5 > &nquark_total, std::array< std::array< int, 5 >, 2 > &excess_quark, std::array< std::array< int, 5 >, 2 > &excess_antiq) |
| Take total number of quarks and check if the system has enough constituents that need to be converted into other flavors. More...
|
|
bool | restore_constituent (Pythia8::Event &event_intermediate, std::array< std::array< int, 5 >, 2 > &excess_quark, std::array< std::array< int, 5 >, 2 > &excess_antiq) |
| Take the intermediate partonic state from PYTHIA event with mapped hadrons and convert constituents into the desired ones according to the excess of quarks and anti-quarks. More...
|
|
void | compose_string_parton (bool find_forward_string, Pythia8::Event &event_intermediate, Pythia8::Event &event_hadronize) |
| Identify a set of partons, which are connected to form a color-neutral string, from a given PYTHIA event record. More...
|
|
void | compose_string_junction (bool &find_forward_string, Pythia8::Event &event_intermediate, Pythia8::Event &event_hadronize) |
| Identify a set of partons and junction(s), which are connected to form a color-neutral string, from a given PYTHIA event record. More...
|
|
void | find_junction_leg (bool sign_color, std::vector< int > &col, Pythia8::Event &event_intermediate, Pythia8::Event &event_hadronize) |
| Identify partons, which are associated with junction legs, from a given PYTHIA event record. More...
|
|
int | get_index_forward (bool find_forward, int np_end, Pythia8::Event &event) |
| Obtain index of the most forward or backward particle in a given PYTHIA event record. More...
|
|
ParticleList | get_final_state () |
| a function to get the final state particle list which is called after the collision More...
|
|
int | append_final_state (ParticleList &intermediate_particles, const FourVector &uString, const ThreeVector &evecLong) |
| compute the formation time and fill the arrays with final-state particles as described in Andersson:1983ia [2]. More...
|
|
int | fragment_string (int idq1, int idq2, double mString, ThreeVector &evecLong, bool flip_string_ends, bool separate_fragment_baryon, ParticleList &intermediate_particles) |
| perform string fragmentation to determine species and momenta of hadrons by implementing PYTHIA 8.2 Andersson:1983ia [2], Sjostrand:2014zea [41]. More...
|
|
int | fragment_off_hadron (bool from_forward, bool separate_fragment_baryon, std::array< ThreeVector, 3 > &evec_basis, double &ppos_string, double &pneg_string, double &QTrx_string_pos, double &QTrx_string_neg, double &QTry_string_pos, double &QTry_string_neg, Pythia8::FlavContainer &flav_string_pos, Pythia8::FlavContainer &flav_string_neg, std::vector< int > &pdgid_frag, std::vector< FourVector > &momentum_frag) |
| Fragment one hadron from a given string configuration if the string mass is above threshold (given by the consituent masses). More...
|
|
int | get_hadrontype_from_quark (int idq1, int idq2) |
| Determines hadron type from valence quark constituents. More...
|
|
int | get_resonance_from_quark (int idq1, int idq2, double mass) |
|
bool | make_lightcone_final_two (bool separate_fragment_hadron, double ppos_string, double pneg_string, double mTrn_had_forward, double mTrn_had_backward, double &ppos_had_forward, double &ppos_had_backward, double &pneg_had_forward, double &pneg_had_backward) |
| Determines lightcone momenta of two final hadrons fragmented from a string in the same way as StringFragmentation::finalTwo in StringFragmentation.cc of PYTHIA 8. More...
|
|
bool | remake_kinematics_fragments (Pythia8::Event &event_fragments, std::array< ThreeVector, 3 > &evec_basis, double ppos_string, double pneg_string, double QTrx_string, double QTry_string, double QTrx_add_pos, double QTry_add_pos, double QTrx_add_neg, double QTry_add_neg) |
|
void | shift_rapidity_event (Pythia8::Event &event, std::array< ThreeVector, 3 > &evec_basis, double factor_yrapid, double diff_yrapid) |
| Shift the momentum rapidity of all particles in a given event record. More...
|
|
double | getPPosA () |
|
double | getPNegA () |
|
double | getPPosB () |
|
double | getPnegB () |
|
double | get_massA () |
|
double | get_massB () |
|
double | get_sqrts () |
|
std::array< PdgCode, 2 > | get_PDGs () |
|
std::array< FourVector, 2 > | get_plab () |
|
std::array< FourVector, 2 > | get_pcom () |
|
FourVector | get_ucom () |
|
ThreeVector | get_vcom () |
|
double | get_tcoll () |
|
|
static void | make_orthonormal_basis (ThreeVector &evec_polar, std::array< ThreeVector, 3 > &evec_basis) |
| compute three orthonormal basis vectors from unit vector in the longitudinal direction More...
|
|
static void | find_excess_constituent (PdgCode &pdg_actual, PdgCode &pdg_mapped, std::array< int, 5 > &excess_quark, std::array< int, 5 > &excess_antiq) |
| Compare the valence quark contents of the actual and mapped hadrons and evaluate how many more constituents the actual hadron has compared to the mapped one. More...
|
|
static bool | append_intermediate_list (int pdgid, FourVector momentum, ParticleList &intermediate_particles) |
| append new particle from PYTHIA to a specific particle list More...
|
|
static void | convert_KaonLS (int &pythia_id) |
| convert Kaon-L or Kaon-S into K0 or Anti-K0 More...
|
|
static void | quarks_from_diquark (int diquark, int &q1, int &q2, int °_spin) |
| find two quarks from a diquark. More...
|
|
static int | diquark_from_quarks (int q1, int q2) |
| Construct diquark from two quarks. More...
|
|
static void | make_string_ends (const PdgCode &pdgcode_in, int &idq1, int &idq2, double xi) |
| make a random selection to determine partonic contents at the string ends. More...
|
|
static Pythia8::Vec4 | set_Vec4 (double energy, const ThreeVector &mom) |
| Easy setter of Pythia Vec4 from SMASH. More...
|
|
static FourVector | reorient (Pythia8::Particle &particle, std::array< ThreeVector, 3 > &evec_basis) |
| compute the four-momentum properly oriented in the lab frame. More...
|
|
static double | sample_zLund (double a, double b, double mTrn) |
| Sample lightcone momentum fraction according to the LUND fragmentation function. More...
|
|
static void | assign_all_scaling_factors (int baryon_string, ParticleList &outgoing_particles, const ThreeVector &evecLong, double suppression_factor) |
| Assign a cross section scaling factor to all outgoing particles. More...
|
|
static std::pair< int, int > | find_leading (int nq1, int nq2, ParticleList &list) |
| Find the leading string fragments. More...
|
|
static void | assign_scaling_factor (int nquark, ParticleData &data, double suppression_factor) |
| Assign a cross section scaling factor to the given particle. More...
|
|
static int | pdg_map_for_pythia (PdgCode &pdg) |
| Take pdg code and map onto particle specie which can be handled by PYTHIA. More...
|
|
◆ StringProcess()
smash::StringProcess::StringProcess |
( |
double |
string_tension, |
|
|
double |
time_formation, |
|
|
double |
gluon_beta, |
|
|
double |
gluon_pmin, |
|
|
double |
quark_alpha, |
|
|
double |
quark_beta, |
|
|
double |
strange_supp, |
|
|
double |
diquark_supp, |
|
|
double |
sigma_perp, |
|
|
double |
stringz_a_leading, |
|
|
double |
stringz_b_leading, |
|
|
double |
stringz_a, |
|
|
double |
stringz_b, |
|
|
double |
string_sigma_T, |
|
|
double |
factor_t_form, |
|
|
bool |
mass_dependent_formation_times, |
|
|
double |
prob_proton_to_d_uu, |
|
|
bool |
separate_fragment_baryon, |
|
|
double |
popcorn_rate |
|
) |
| |
Constructor, initializes pythia.
Should only be called once.
- Parameters
-
[in] | string_tension | value of kappa_tension_string_ [GeV/fm] |
[in] | time_formation | value of time_formation_const_ [fm] |
[in] | gluon_beta | value of pow_fgluon_beta_ |
[in] | gluon_pmin | value of pmin_gluon_lightcone_ |
[in] | quark_alpha | value of pow_fquark_alpha_ |
[in] | quark_beta | value of pow_fquark_beta_ |
[in] | strange_supp | strangeness suppression factor (StringFlav:probStoUD) in fragmentation |
[in] | diquark_supp | diquark suppression factor (StringFlav:probQQtoQ) in fragmentation |
[in] | sigma_perp | value of sigma_qperp_ [GeV] |
[in] | stringz_a_leading | Parameter a in Lund fragmentation function for leading baryons. |
[in] | stringz_b_leading | Parameter b in Lund fragmentation function for leading baryons. |
[in] | stringz_a | parameter (StringZ:aLund) for the fragmentation function |
[in] | stringz_b | parameter (StringZ:bLund) for the fragmentation function [GeV^-2] |
[in] | string_sigma_T | transverse momentum spread (StringPT:sigma) in fragmentation [GeV] |
[in] | factor_t_form | to be multiplied to soft string formation times |
[in] | mass_dependent_formation_times | Whether the formation times of string fragments should depend on their mass. |
[in] | prob_proton_to_d_uu | Probability of a nucleon to be split into the quark it contains once and a diquark another flavour. |
[in] | separate_fragment_baryon | whether to use a separate fragmentation function for leading baryons in non-diffractive string processes. |
[in] | popcorn_rate | parameter (StringFlav:popcornRate) to determine the production rate of popcorn mesons from the diquark end of a string. |
- See also
- StringProcess::common_setup_pythia(Pythia8::Pythia *, double, double, double, double, double)
-
pythia8235/share/Pythia8/xmldoc/FlavourSelection.xml
-
pythia8235/share/Pythia8/xmldoc/Fragmentation.xml
-
pythia8235/share/Pythia8/xmldoc/MasterSwitches.xml
-
pythia8235/share/Pythia8/xmldoc/MultipartonInteractions.xml
Definition at line 21 of file processstring.cc.
47 pythia_parton_ = make_unique<Pythia8::Pythia>(PYTHIA_XML_DIR,
false);
54 popcorn_rate, stringz_a, stringz_b, string_sigma_T);
57 pythia_hadron_ = make_unique<Pythia8::Pythia>(PYTHIA_XML_DIR,
false);
61 popcorn_rate, stringz_a, stringz_b, string_sigma_T);
73 for (
int imu = 0; imu < 3; imu++) {
◆ common_setup_pythia()
void smash::StringProcess::common_setup_pythia |
( |
Pythia8::Pythia * |
pythia_in, |
|
|
double |
strange_supp, |
|
|
double |
diquark_supp, |
|
|
double |
popcorn_rate, |
|
|
double |
stringz_a, |
|
|
double |
stringz_b, |
|
|
double |
string_sigma_T |
|
) |
| |
Common setup of PYTHIA objects for soft and hard string routines.
- Parameters
-
[out] | pythia_in | pointer to the PYTHIA object |
[in] | strange_supp | strangeness suppression factor (StringFlav:probStoUD) in fragmentation |
[in] | diquark_supp | diquark suppression factor (StringFlav:probQQtoQ) in fragmentation |
[in] | popcorn_rate | parameter (StringFlav:popcornRate) to determine the production rate of popcorn mesons from the diquark end of a string. |
[in] | stringz_a | parameter (StringZ:aLund) for the fragmentation function |
[in] | stringz_b | parameter (StringZ:bLund) for the fragmentation function |
[in] | string_sigma_T | transverse momentum spread (StringPT:sigma) in fragmentation [GeV] |
- See also
- pythia8235/share/Pythia8/xmldoc/FlavourSelection.xml
-
pythia8235/share/Pythia8/xmldoc/Fragmentation.xml
Definition at line 80 of file processstring.cc.
87 pythia_in->readString(
"ParticleData:modeBreitWigner = 4");
90 pythia_in->readString(
"MultipartonInteractions:pTmin = 1.5");
91 pythia_in->readString(
"MultipartonInteractions:nSample = 10000");
93 pythia_in->readString(
"StringPT:sigma = " + std::to_string(string_sigma_T));
95 pythia_in->readString(
"StringFlav:probQQtoQ = " +
96 std::to_string(diquark_supp));
98 pythia_in->readString(
"StringFlav:probStoUD = " +
99 std::to_string(strange_supp));
100 pythia_in->readString(
"StringFlav:popcornRate = " +
101 std::to_string(popcorn_rate));
103 pythia_in->readString(
"StringZ:aLund = " + std::to_string(stringz_a));
104 pythia_in->readString(
"StringZ:bLund = " + std::to_string(stringz_b));
107 pythia_in->readString(
"PDF:pSet = 13");
108 pythia_in->readString(
"PDF:pSetB = 13");
109 pythia_in->readString(
"PDF:piSet = 1");
110 pythia_in->readString(
"PDF:piSetB = 1");
111 pythia_in->readString(
"Beams:idA = 2212");
112 pythia_in->readString(
"Beams:idB = 2212");
113 pythia_in->readString(
"Beams:eCM = 10.");
116 pythia_in->readString(
"Random:setSeed = on");
118 pythia_in->readString(
"Print:quiet = on");
120 pythia_in->readString(
"HadronLevel:Decay = off");
123 int pdgid = ptype.pdgcode().get_decimal();
124 double mass_pole = ptype.mass();
125 double width_pole = ptype.width_at_pole();
127 if (pythia_in->particleData.isParticle(pdgid)) {
129 pythia_in->particleData.m0(pdgid, mass_pole);
130 pythia_in->particleData.mWidth(pdgid, width_pole);
131 }
else if (pdgid == 310 || pdgid == 130) {
133 pythia_in->particleData.m0(pdgid,
kaon_mass);
134 pythia_in->particleData.mWidth(pdgid, 0.);
139 pythia_in->readString(
"Check:epTolErr = 1e-6");
140 pythia_in->readString(
"Check:epTolWarn = 1e-8");
◆ init_pythia_hadron_rndm()
void smash::StringProcess::init_pythia_hadron_rndm |
( |
| ) |
|
|
inline |
◆ get_ptr_pythia_parton()
Pythia8::Pythia* smash::StringProcess::get_ptr_pythia_parton |
( |
| ) |
|
|
inline |
Function to get the PYTHIA object for hard string routine.
- Returns
- pointer to the PYTHIA object used in hard string routine
Definition at line 291 of file processstring.h.
◆ cross_sections_diffractive()
std::array<double, 3> smash::StringProcess::cross_sections_diffractive |
( |
int |
pdg_a, |
|
|
int |
pdg_b, |
|
|
double |
sqrt_s |
|
) |
| |
|
inline |
Interface to pythia_sigmatot_ to compute cross-sections of A+B-> different final states Schuler:1993wr [39].
- Parameters
-
[in] | pdg_a | pdg code of incoming particle A |
[in] | pdg_b | pdg code of incoming particle B |
[in] | sqrt_s | collision energy in the center of mass frame [GeV] |
- Returns
- array with single diffractive cross-sections AB->AX, AB->XB and double diffractive AB->XX.
Definition at line 302 of file processstring.h.
305 double sqrts_threshold = 2. * (1. + 1.0e-6);
308 const int pdg_a_mod =
309 (std::abs(pdg_a) > 1000) ? pdg_a : 10 * (std::abs(pdg_a) / 10) + 3;
310 const int pdg_b_mod =
311 (std::abs(pdg_b) > 1000) ? pdg_b : 10 * (std::abs(pdg_b) / 10) + 3;
316 if (sqrt_s < sqrts_threshold) {
317 sqrt_s = sqrts_threshold;
◆ set_pmin_gluon_lightcone()
void smash::StringProcess::set_pmin_gluon_lightcone |
( |
double |
p_light_cone_min | ) |
|
|
inline |
set the minimum lightcone momentum scale carried by gluon.
- Todo:
- The following set_ functions are replaced with constructor with arguments.
Must be cleaned up if necessary. This is relevant for the double-diffractive process. The minimum lightcone momentum fraction is set to be pmin_gluon_lightcone_/sqrtsAB.
- Parameters
-
p_light_cone_min | a value that we want to use for pmin_gluon_lightcone_. |
Definition at line 338 of file processstring.h.
◆ set_pow_fgluon()
void smash::StringProcess::set_pow_fgluon |
( |
double |
betapow | ) |
|
|
inline |
lightcone momentum fraction of gluon is sampled according to probability distribution P(x) = 1/x * (1 - x)^{1 + pow_fgluon_beta_} in double-diffractive processes.
- Parameters
-
betapow | is a value that we want to use for pow_fgluon_beta_. |
Definition at line 348 of file processstring.h.
◆ set_pow_fquark()
void smash::StringProcess::set_pow_fquark |
( |
double |
alphapow, |
|
|
double |
betapow |
|
) |
| |
|
inline |
lightcone momentum fraction of quark is sampled according to probability distribution \( P(x) = x^{pow_fquark_alpha_ - 1} * (1 - x)^{pow_fquark_beta_ - 1} \) in non-diffractive processes.
- Parameters
-
alphapow | is a value that we want to use for pow_fquark_alpha_. |
betapow | is a value that we want to use for pow_fquark_beta_. |
Definition at line 357 of file processstring.h.
◆ set_sigma_qperp_()
void smash::StringProcess::set_sigma_qperp_ |
( |
double |
sigma_qperp | ) |
|
|
inline |
set the average amount of transverse momentum transfer sigma_qperp_.
- Parameters
-
sigma_qperp | is a value that we want to use for sigma_qperp_. |
Definition at line 365 of file processstring.h.
◆ set_tension_string()
void smash::StringProcess::set_tension_string |
( |
double |
kappa_string | ) |
|
|
inline |
set the string tension, which is used in append_final_state.
- Parameters
-
kappa_string | is a value that we want to use for string tension. |
Definition at line 370 of file processstring.h.
◆ init()
void smash::StringProcess::init |
( |
const ParticleList & |
incoming, |
|
|
double |
tcoll |
|
) |
| |
initialization feed intial particles, time of collision and gamma factor of the center of mass.
- Parameters
-
[in] | incoming | is the list of initial state particles. |
[in] | tcoll | is time of collision. |
Definition at line 200 of file processstring.cc.
203 massA_ = incoming[0].effective_mass();
204 massB_ = incoming[1].effective_mass();
206 plab_[0] = incoming[0].momentum();
207 plab_[1] = incoming[1].momentum();
218 ThreeVector evec_coll =
pcom_[0].threevec() / pabscomAB;
◆ make_orthonormal_basis()
void smash::StringProcess::make_orthonormal_basis |
( |
ThreeVector & |
evec_polar, |
|
|
std::array< ThreeVector, 3 > & |
evec_basis |
|
) |
| |
|
static |
compute three orthonormal basis vectors from unit vector in the longitudinal direction
- Parameters
-
[in] | evec_polar | unit three-vector in the longitudinal direction |
[out] | evec_basis | orthonormal basis vectors of which evec_basis[0] is in the longitudinal direction while evec_basis[1] and evec_basis[2] span the transverse plane. |
Definition at line 1615 of file processstring.cc.
1617 assert(std::fabs(evec_polar.sqr() - 1.) <
really_small);
1619 if (std::abs(evec_polar.x3()) < (1. - 1.0e-8)) {
1624 evec_basis[0] = evec_polar;
1626 theta = std::acos(evec_basis[0].x3());
1628 ex = evec_basis[0].x1();
1629 ey = evec_basis[0].x2();
1630 et = std::sqrt(ex * ex + ey * ey);
1632 phi = std::acos(ex / et);
1634 phi = -std::acos(ex / et);
1639 evec_basis[1].set_x1(std::cos(theta) * std::cos(phi));
1640 evec_basis[1].set_x2(std::cos(theta) * std::sin(phi));
1641 evec_basis[1].set_x3(-std::sin(theta));
1643 evec_basis[2].set_x1(-std::sin(phi));
1644 evec_basis[2].set_x2(std::cos(phi));
1645 evec_basis[2].set_x3(0.);
1648 if (evec_polar.x3() > 0.) {
1649 evec_basis[1] = ThreeVector(1., 0., 0.);
1650 evec_basis[2] = ThreeVector(0., 1., 0.);
1651 evec_basis[0] = ThreeVector(0., 0., 1.);
1653 evec_basis[1] = ThreeVector(0., 1., 0.);
1654 evec_basis[2] = ThreeVector(1., 0., 0.);
1655 evec_basis[0] = ThreeVector(0., 0., -1.);
1659 assert(std::fabs(evec_basis[1] * evec_basis[2]) <
really_small);
1660 assert(std::fabs(evec_basis[2] * evec_basis[0]) <
really_small);
1661 assert(std::fabs(evec_basis[0] * evec_basis[1]) <
really_small);
◆ compute_incoming_lightcone_momenta()
void smash::StringProcess::compute_incoming_lightcone_momenta |
( |
| ) |
|
compute the lightcone momenta of incoming particles where the longitudinal direction is set to be same as that of the three-momentum of particle A.
Definition at line 1664 of file processstring.cc.
◆ set_mass_and_direction_2strings()
bool smash::StringProcess::set_mass_and_direction_2strings |
( |
const std::array< std::array< int, 2 >, 2 > & |
quarks, |
|
|
const std::array< FourVector, 2 > & |
pstr_com, |
|
|
std::array< double, 2 > & |
m_str, |
|
|
std::array< ThreeVector, 2 > & |
evec_str |
|
) |
| |
Determine string masses and directions in which strings are stretched.
- Parameters
-
[in] | quarks | pdg ids of string ends |
[in] | pstr_com | 4-momenta of strings in the C.o.m. frame [GeV] |
[out] | m_str | masses of strings [GeV] |
[out] | evec_str | are directions in which strings are stretched. |
- Returns
- whether masses are above the threshold
Definition at line 311 of file processstring.cc.
315 std::array<bool, 2> found_mass;
316 for (
int i = 0; i < 2; i++) {
317 found_mass[i] =
false;
319 m_str[i] = pstr_com[i].sqr();
320 m_str[i] = (m_str[i] > 0.) ? std::sqrt(m_str[i]) : 0.;
321 const double threshold =
pythia_hadron_->particleData.m0(quarks[i][0]) +
324 if (m_str[i] > threshold) {
325 found_mass[i] =
true;
338 const ThreeVector mom =
pcom_[i].threevec();
339 const FourVector pnull(mom.abs(), mom);
340 const FourVector prs = pnull.lorentz_boost(pstr_com[i].velocity());
341 evec_str[i] = prs.threevec() / prs.threevec().abs();
345 return found_mass[0] && found_mass[1];
◆ make_final_state_2strings()
bool smash::StringProcess::make_final_state_2strings |
( |
const std::array< std::array< int, 2 >, 2 > & |
quarks, |
|
|
const std::array< FourVector, 2 > & |
pstr_com, |
|
|
const std::array< double, 2 > & |
m_str, |
|
|
const std::array< ThreeVector, 2 > & |
evec_str, |
|
|
bool |
flip_string_ends, |
|
|
bool |
separate_fragment_baryon |
|
) |
| |
Prepare kinematics of two strings, fragment them and append to final_state.
- Parameters
-
[in] | quarks | pdg ids of string ends |
[in] | pstr_com | 4-momenta of strings in the C.o.m. frame [GeV] |
[in] | m_str | masses of strings [GeV] |
[out] | evec_str | are directions in which strings are stretched. |
[in] | flip_string_ends | is whether or not we randomly switch string ends. |
[in] | separate_fragment_baryon | is whether to fragment leading baryons (or anti-baryons) with a separate fragmentation function. |
- Returns
- whether fragmentations and final state creation was successful
Definition at line 348 of file processstring.cc.
354 const std::array<FourVector, 2> ustr_com = {pstr_com[0] / m_str[0],
355 pstr_com[1] / m_str[1]};
356 for (
int i = 0; i < 2; i++) {
357 ParticleList new_intermediate_particles;
360 ThreeVector evec = evec_str[i];
362 int nfrag =
fragment_string(quarks[i][0], quarks[i][1], m_str[i], evec,
363 flip_string_ends, separate_fragment_baryon,
364 new_intermediate_particles);
◆ next_SDiff()
bool smash::StringProcess::next_SDiff |
( |
bool |
is_AB_to_AX | ) |
|
Single-diffractive process is based on single pomeron exchange described in Ingelman:1984ns [22].
- Parameters
-
[in] | is_AB_to_AX | specifies which hadron to excite into a string. true : A + B -> A + X, false : A + B -> X + B |
- Returns
- whether the process is successfully implemented.
Definition at line 229 of file processstring.cc.
240 double QTrn, QTrx, QTry;
241 double pabscomHX_sqr, massX;
250 if (mstrMin > mstrMax) {
256 QTrn = std::sqrt(QTrx * QTrx + QTry * QTry);
263 const bool foundPabsX = pabscomHX_sqr > QTrn * QTrn;
268 double sign_direction = is_AB_to_AX ? 1. : -1.;
270 const ThreeVector cm_momentum =
272 (
evecBasisAB_[0] * std::sqrt(pabscomHX_sqr - QTrn * QTrn) +
274 const FourVector pstrHcom(std::sqrt(pabscomHX_sqr + massH * massH),
276 const FourVector pstrXcom(std::sqrt(pabscomHX_sqr + massX * massX),
279 const FourVector ustrXcom = pstrXcom / massX;
283 const ThreeVector threeMomentum =
284 is_AB_to_AX ?
pcom_[1].threevec() :
pcom_[0].threevec();
285 const FourVector pnull = FourVector(threeMomentum.abs(), threeMomentum);
286 const FourVector prs = pnull.lorentz_boost(ustrXcom.velocity());
287 ThreeVector evec = prs.threevec() / prs.threevec().abs();
289 ParticleList new_intermediate_particles;
291 new_intermediate_particles);
302 new_particle.set_4momentum(pstrHcom);
303 new_particle.set_cross_section_scaling_factor(1.);
◆ next_DDiff()
bool smash::StringProcess::next_DDiff |
( |
| ) |
|
Double-diffractive process ( A + B -> X + X ) is similar to the single-diffractive process, but lightcone momenta of gluons are sampled in the same was as the UrQMD model Bass:1998ca [4], Bleicher:1999xi [8].
String masses are computed after pomeron exchange aquiring transverse momentum transfer.
- Returns
- whether the process is successfully implemented.
Definition at line 381 of file processstring.cc.
387 std::array<std::array<int, 2>, 2> quarks;
388 std::array<FourVector, 2> pstr_com;
389 std::array<double, 2> m_str;
390 std::array<ThreeVector, 2> evec_str;
391 ThreeVector threeMomentum;
400 const double xfracA =
402 const double xfracB =
407 const double QTrn = std::sqrt(QTrx * QTrx + QTry * QTry);
409 const double QPos = -QTrn * QTrn / (2. * xfracB *
PNegB_);
410 const double QNeg = QTrn * QTrn / (2. * xfracA *
PPosA_);
416 FourVector((
PPosA_ + QPos +
PNegA_ + QNeg) * M_SQRT1_2, threeMomentum);
422 FourVector((
PPosB_ - QPos +
PNegB_ - QNeg) * M_SQRT1_2, threeMomentum);
424 const bool found_masses =
429 const bool flip_string_ends =
true;
431 quarks, pstr_com, m_str, evec_str, flip_string_ends,
false);
◆ next_NDiffSoft()
bool smash::StringProcess::next_NDiffSoft |
( |
| ) |
|
Soft Non-diffractive process is modelled in accordance with dual-topological approach Capella:1978ig [12].
This involves a parton exchange in conjunction with momentum transfer. Probability distribution function of the lightcone momentum fraction carried by quark is based on the UrQMD model Bass:1998ca [4], Bleicher:1999xi [8].
- Returns
- whether the process is successfully implemented.
- Exceptions
-
std::runtime_error | if incoming particles are neither mesonic nor baryonic |
Definition at line 436 of file processstring.cc.
442 std::array<std::array<int, 2>, 2> quarks;
443 std::array<FourVector, 2> pstr_com;
444 std::array<double, 2> m_str;
445 std::array<ThreeVector, 2> evec_str;
448 int idqA1, idqA2, idqB1, idqB2;
452 const int bar_a =
PDGcodes_[0].baryon_number(),
455 (bar_a == 0 && bar_b == 1) ||
456 (bar_a == 0 && bar_b == 0)) {
457 quarks[0][0] = idqB1;
458 quarks[0][1] = idqA2;
459 quarks[1][0] = idqA1;
460 quarks[1][1] = idqB2;
461 }
else if (((bar_a == 0) && (bar_b == -1)) ||
464 quarks[0][0] = idqA1;
465 quarks[0][1] = idqB2;
466 quarks[1][0] = idqB1;
467 quarks[1][1] = idqA2;
469 std::stringstream ss;
470 ss <<
" StringProcess::next_NDiff : baryonA = " << bar_a
471 <<
", baryonB = " << bar_b;
472 throw std::runtime_error(ss.str());
480 const double QTrn = std::sqrt(QTrx * QTrx + QTry * QTry);
482 const double QPos = -QTrn * QTrn / (2. * xfracB *
PNegB_);
483 const double QNeg = QTrn * QTrn / (2. * xfracA *
PPosA_);
484 const double dPPos = -xfracA *
PPosA_ - QPos;
485 const double dPNeg = xfracB *
PNegB_ - QNeg;
487 ThreeVector threeMomentum =
491 FourVector((
PPosA_ + dPPos +
PNegA_ + dPNeg) * M_SQRT1_2, threeMomentum);
492 m_str[0] = pstr_com[0].sqr();
498 FourVector((
PPosB_ - dPPos +
PNegB_ - dPNeg) * M_SQRT1_2, threeMomentum);
500 const bool found_masses =
505 const bool flip_string_ends =
false;
◆ next_NDiffHard()
bool smash::StringProcess::next_NDiffHard |
( |
| ) |
|
Hard Non-diffractive process is based on PYTHIA 8 with partonic showers and interactions.
- Returns
- whether the process is successfully implemented.
Definition at line 513 of file processstring.cc.
520 std::array<int, 2> pdg_for_pythia;
521 std::array<std::array<int, 5>, 2> excess_quark;
522 std::array<std::array<int, 5>, 2> excess_antiq;
523 for (
int i = 0; i < 2; i++) {
524 for (
int j = 0; j < 5; j++) {
525 excess_quark[i][j] = 0;
526 excess_antiq[i][j] = 0;
532 " is mapped onto ", pdg_for_pythia[i]);
534 PdgCode pdgcode_for_pythia(std::to_string(pdg_for_pythia[i]));
539 logg[
LPythia].debug(
" excess_quark[", i,
"] = (", excess_quark[i][0],
540 ", ", excess_quark[i][1],
", ", excess_quark[i][2],
541 ", ", excess_quark[i][3],
", ", excess_quark[i][4],
543 logg[
LPythia].debug(
" excess_antiq[", i,
"] = (", excess_antiq[i][0],
544 ", ", excess_antiq[i][1],
", ", excess_antiq[i][2],
545 ", ", excess_antiq[i][3],
", ", excess_antiq[i][4],
553 bool same_initial_state = previous_idA == pdg_for_pythia[0] &&
554 previous_idB == pdg_for_pythia[1] &&
565 logg[
LPythia].debug(
"Pythia initialized with ", pdg_for_pythia[0],
" + ",
566 pdg_for_pythia[1],
" at CM energy [GeV] ",
sqrtsAB_);
568 throw std::runtime_error(
"Pythia failed to initialize.");
577 logg[
LPythia].debug(
"pythia_parton_ : rndm is initialized with seed ",
584 logg[
LPythia].debug(
"Pythia final state computed, success = ",
585 final_state_success);
586 if (!final_state_success) {
590 ParticleList new_intermediate_particles;
591 ParticleList new_non_hadron_particles;
593 Pythia8::Vec4 pSum = 0.;
616 std::array<int, 3> col;
617 for (
int j = 0; j < 3; j++) {
630 bool correct_constituents =
632 if (!correct_constituents) {
633 logg[
LPythia].debug(
"failed to find correct partonic constituents.");
639 while (ipart < npart) {
644 logg[
LPythia].debug(
"PDG ID from Pythia: ", pdgid);
646 logg[
LPythia].debug(
"4-momentum from Pythia: ", momentum);
651 " does not exist in ParticleType - start over.");
652 final_state_success =
false;
661 bool hadronize_success =
false;
662 bool find_forward_string =
true;
663 logg[
LPythia].debug(
"Hard non-diff: partonic process gives ",
670 logg[
LPythia].debug(
" Dummy event in hard string routine failed.");
671 hadronize_success =
false;
688 logg[
LPythia].debug(
"Pythia hadronized, success = ", hadronize_success);
690 new_intermediate_particles.clear();
691 if (hadronize_success) {
692 for (
int i = 0; i < event_hadron.size(); i++) {
693 if (event_hadron[i].isFinal()) {
694 int pythia_id = event_hadron[i].id();
695 logg[
LPythia].debug(
"PDG ID from Pythia: ", pythia_id);
708 logg[
LPythia].debug(
"4-momentum from Pythia: ", momentum);
709 logg[
LPythia].debug(
"appending the particle ", pythia_id,
710 " to the intermediate particle list.");
711 bool found_ptype =
false;
712 if (event_hadron[i].isHadron()) {
714 new_intermediate_particles);
717 new_non_hadron_particles);
721 " does not exist in ParticleType - start over.");
722 hadronize_success =
false;
730 if (!hadronize_success) {
734 FourVector uString = FourVector(1., 0., 0., 0.);
739 find_forward_string = !find_forward_string;
742 if (hadronize_success) {
744 for (ParticleData data : new_non_hadron_particles) {
745 data.set_cross_section_scaling_factor(1.);
753 return hadronize_success;
◆ next_BBbarAnn()
bool smash::StringProcess::next_BBbarAnn |
( |
| ) |
|
Baryon-antibaryon annihilation process Based on what UrQMD Bass:1998ca [4], Bleicher:1999xi [8] does, it create two mesonic strings after annihilating one quark-antiquark pair.
Each string has mass equal to half of sqrts.
- Returns
- whether the process is successfully implemented.
- Exceptions
-
std::invalid_argument | if incoming particles are not baryon-antibaryon pair |
Definition at line 1504 of file processstring.cc.
1505 const std::array<FourVector, 2> ustrcom = {FourVector(1., 0., 0., 0.),
1506 FourVector(1., 0., 0., 0.)};
1518 if (baryon.baryon_number() == -1) {
1519 std::swap(baryon, antibaryon);
1521 if (baryon.baryon_number() != 1 || antibaryon.baryon_number() != -1) {
1522 throw std::invalid_argument(
"Expected baryon-antibaryon pair.");
1526 constexpr
int n_q_types = 5;
1527 std::vector<int> qcount_bar, qcount_antibar;
1528 std::vector<int> n_combinations;
1529 bool no_combinations =
true;
1530 for (
int i = 0; i < n_q_types; i++) {
1531 qcount_bar.push_back(baryon.net_quark_number(i + 1));
1532 qcount_antibar.push_back(-antibaryon.net_quark_number(i + 1));
1533 const int n_i = qcount_bar[i] * qcount_antibar[i];
1534 n_combinations.push_back(n_i);
1536 no_combinations =
false;
1542 if (no_combinations) {
1543 for (
int i = 0; i < 2; i++) {
1546 new_particle.set_4momentum(
pcom_[i]);
1547 new_particle.set_cross_section_scaling_factor(1.);
1556 auto discrete_distr = random::discrete_dist<int>(n_combinations);
1557 const int q_annihilate = discrete_distr() + 1;
1558 qcount_bar[q_annihilate - 1]--;
1559 qcount_antibar[q_annihilate - 1]--;
1562 std::vector<int> remaining_quarks, remaining_antiquarks;
1563 for (
int i = 0; i < n_q_types; i++) {
1564 for (
int j = 0; j < qcount_bar[i]; j++) {
1565 remaining_quarks.push_back(i + 1);
1567 for (
int j = 0; j < qcount_antibar[i]; j++) {
1568 remaining_antiquarks.push_back(-(i + 1));
1571 assert(remaining_quarks.size() == 2);
1572 assert(remaining_antiquarks.size() == 2);
1578 std::swap(remaining_quarks[0], remaining_quarks[1]);
1581 std::swap(remaining_antiquarks[0], remaining_antiquarks[1]);
1584 bool kin_threshold_satisfied =
true;
1585 for (
int i = 0; i < 2; i++) {
1586 const double mstr_min =
1589 if (mstr_min > mstr[i]) {
1590 kin_threshold_satisfied =
false;
1593 if (!kin_threshold_satisfied) {
1597 for (
int i = 0; i < 2; i++) {
1598 ParticleList new_intermediate_particles;
1600 ThreeVector evec =
pcom_[i].threevec() /
pcom_[i].threevec().abs();
1602 fragment_string(remaining_quarks[i], remaining_antiquarks[i], mstr[i],
1603 evec,
true,
false, new_intermediate_particles);
◆ find_excess_constituent()
void smash::StringProcess::find_excess_constituent |
( |
PdgCode & |
pdg_actual, |
|
|
PdgCode & |
pdg_mapped, |
|
|
std::array< int, 5 > & |
excess_quark, |
|
|
std::array< int, 5 > & |
excess_antiq |
|
) |
| |
|
static |
Compare the valence quark contents of the actual and mapped hadrons and evaluate how many more constituents the actual hadron has compared to the mapped one.
excess_quark[i - 1] is how many more quarks with flavor i (PDG id i) pdg_actual has compared to pdg_mapped. excess_antiq[i - 1] is how many more antiquarks with flavor i (PDG id -i) pdg_actual has compared to pdg_mapped.
- Parameters
-
[in] | pdg_actual | PDG code of actual incoming particle. |
[in] | pdg_mapped | PDG code of mapped particles used in PYTHIA event generation. |
[out] | excess_quark | excess of quarks. |
[out] | excess_antiq | excess of anti-quarks. |
Definition at line 756 of file processstring.cc.
762 std::array<int, 3> qcontent_actual = pdg_actual.quark_content();
763 std::array<int, 3> qcontent_mapped = pdg_mapped.quark_content();
765 excess_quark = {0, 0, 0, 0, 0};
766 excess_antiq = {0, 0, 0, 0, 0};
767 for (
int i = 0; i < 3; i++) {
768 if (qcontent_actual[i] > 0) {
769 int j = qcontent_actual[i] - 1;
770 excess_quark[j] += 1;
773 if (qcontent_mapped[i] > 0) {
774 int j = qcontent_mapped[i] - 1;
775 excess_quark[j] -= 1;
778 if (qcontent_actual[i] < 0) {
779 int j = std::abs(qcontent_actual[i]) - 1;
780 excess_antiq[j] += 1;
783 if (qcontent_mapped[i] < 0) {
784 int j = std::abs(qcontent_mapped[i]) - 1;
785 excess_antiq[j] -= 1;
◆ replace_constituent()
void smash::StringProcess::replace_constituent |
( |
Pythia8::Particle & |
particle, |
|
|
std::array< int, 5 > & |
excess_constituent |
|
) |
| |
Convert a partonic PYTHIA particle into the desired species and update the excess of constituents.
If the quark flavor i is converted into another flavor j, excess_constituent[i - 1] increases by 1 and excess_constituent[j - 1] decreases by 1. Note that this happens only if excess_constituent[i - 1] < 0 and excess_constituent[j - 1] > 0 (i.e., the incoming hadron has more constituents with flavor j and less constituents with flavor i, compared to the mapped hadron), so they get closer to 0 after the function call.
- Parameters
-
[out] | particle | PYTHIA particle object to be converted. |
[out] | excess_constituent | excess in the number of quark constituents. If the particle has positive (negative) quark number, excess of quarks (anti-quarks) should be used. |
- See also
- StringProcess::restore_constituent(Pythia8::Event &, std::array<std::array<int, 5>, 2> &, std::array<std::array<int, 5>, 2> &)
Definition at line 790 of file processstring.cc.
793 if (!particle.isQuark() && !particle.isDiquark()) {
798 const std::array<int, 5> excess_null = {0, 0, 0, 0, 0};
799 if (excess_constituent == excess_null) {
804 std::array<int, 2> pdgid = {0, 0};
807 if (particle.isQuark()) {
809 pdgid[0] = particle.id();
810 }
else if (particle.isDiquark()) {
815 for (
int iq = 0; iq < nq; iq++) {
816 int jq = std::abs(pdgid[iq]) - 1;
818 std::vector<int> k_found;
821 if (excess_constituent[jq] < 0) {
822 for (
int k = 0; k < 5; k++) {
824 if (k != jq && excess_constituent[k] > 0) {
825 k_found.push_back(k);
831 if (k_found.size() > 0) {
834 k_select = k_found[l];
837 pdgid[iq] = pdgid[iq] > 0 ? k_select + 1 : -(k_select + 1);
838 excess_constituent[jq] += 1;
839 excess_constituent[k_select] -= 1;
844 if (particle.isQuark()) {
845 pdgid_new = pdgid[0];
846 }
else if (particle.isDiquark()) {
847 if (std::abs(pdgid[0]) < std::abs(pdgid[1])) {
848 std::swap(pdgid[0], pdgid[1]);
851 pdgid_new = std::abs(pdgid[0]) * 1000 + std::abs(pdgid[1]) * 100;
852 if (std::abs(pdgid[0]) == std::abs(pdgid[1])) {
855 pdgid_new += spin_deg;
858 if (particle.id() < 0) {
862 logg[
LPythia].debug(
" parton id = ", particle.id(),
" is converted to ",
866 Pythia8::Vec4 pquark = particle.p();
868 double e_new = std::sqrt(mass_new * mass_new + pquark.pAbs() * pquark.pAbs());
870 particle.id(pdgid_new);
872 particle.m(mass_new);
◆ find_total_number_constituent()
void smash::StringProcess::find_total_number_constituent |
( |
Pythia8::Event & |
event_intermediate, |
|
|
std::array< int, 5 > & |
nquark_total, |
|
|
std::array< int, 5 > & |
nantiq_total |
|
) |
| |
Compute how many quarks and antiquarks we have in the system, and update the correspoing arrays with size 5.
Note that elements of the array (0, 1, 2, 3, 4) correspond to d, u, s, c, b flavors.
- Parameters
-
[in] | event_intermediate | PYTHIA partonic event record which contains output from PYTHIA (hard) event generation. |
[out] | nquark_total | total number of quarks in the system. This is computed based on event_intermediate. |
[out] | nantiq_total | total number of antiquarks in the system. This is computed based on event_intermediate. |
Definition at line 875 of file processstring.cc.
878 for (
int iflav = 0; iflav < 5; iflav++) {
879 nquark_total[iflav] = 0;
880 nantiq_total[iflav] = 0;
883 for (
int ip = 1; ip < event_intermediate.size(); ip++) {
884 if (!event_intermediate[ip].isFinal()) {
887 const int pdgid = event_intermediate[ip].id();
890 for (
int iflav = 0; iflav < 5; iflav++) {
891 nquark_total[iflav] +=
896 for (
int iflav = 0; iflav < 5; iflav++) {
897 nantiq_total[iflav] +=
pythia_hadron_->particleData.nQuarksInCode(
898 std::abs(pdgid), iflav + 1);
◆ splitting_gluon_qqbar()
bool smash::StringProcess::splitting_gluon_qqbar |
( |
Pythia8::Event & |
event_intermediate, |
|
|
std::array< int, 5 > & |
nquark_total, |
|
|
std::array< int, 5 > & |
nantiq_total, |
|
|
bool |
sign_constituent, |
|
|
std::array< std::array< int, 5 >, 2 > & |
excess_constituent |
|
) |
| |
Take total number of quarks and check if the system has enough constituents that need to be converted into other flavors.
If that is not the case, a gluon is splitted into a quark-antiquark pair with desired flavor, so that their flavor can be changed afterwards. For example, if there is no antiquark in the system and we have excess_antiq = (1, -1, 0, 0, 0) (i.e., one ubar has to be converted into dbar), a gluon will be splitted into u-ubar pair.
- Parameters
-
[out] | event_intermediate | PYTHIA partonic event record to be updated when a gluon happens to split into a qqbar pair. |
[out] | nquark_total | total number of quarks in the system. This is computed based on event_intermediate. |
[out] | nantiq_total | total number of antiquarks in the system. This is computed based on event_intermediate. |
[in] | sign_constituent | true (false) if want to check quarks (antiquarks) and their excesses. |
[in] | excess_constituent | excess in the number of quark constituents. If sign_constituent is true (false), excess of quarks (anti-quarks) should be used. |
- Returns
- false if there are not enough constituents and there is no gluon to split into desired quark-antiquark pair. Otherwise, it gives true.
Definition at line 904 of file processstring.cc.
908 Pythia8::Vec4 pSum = event_intermediate[0].p();
914 for (
int iflav = 0; iflav < 5; iflav++) {
921 excess_constituent[0][iflav] + excess_constituent[1][iflav];
922 if (sign_constituent) {
923 nquark_final += nquark_total[iflav];
925 nquark_final += nantiq_total[iflav];
930 bool enough_quark = nquark_final >= 0;
934 logg[
LPythia].debug(
" not enough constituents with flavor ", iflav + 1,
935 " : try to split a gluon to qqbar.");
936 for (
int ic = 0; ic < std::abs(nquark_final); ic++) {
940 if (excess_constituent[0][iflav] < 0) {
949 for (
int ip = 2; ip < event_intermediate.size(); ip++) {
950 if (!event_intermediate[ip].isFinal() ||
951 !event_intermediate[ip].isGluon()) {
955 const double y_gluon_current = event_intermediate[ip].y();
956 const double y_gluon_forward = event_intermediate[iforward].y();
957 if ((ih_mod == 0 && y_gluon_current > y_gluon_forward) ||
958 (ih_mod == 1 && y_gluon_current < y_gluon_forward)) {
963 if (!event_intermediate[iforward].isGluon()) {
964 logg[
LPythia].debug(
"There is no gluon to split into qqbar.");
969 Pythia8::Vec4 pgluon = event_intermediate[iforward].p();
971 const int pdgid = iflav + 1;
973 const int status = event_intermediate[iforward].status();
977 const int col = event_intermediate[iforward].col();
978 const int acol = event_intermediate[iforward].acol();
981 std::array<double, 2> px_quark;
982 std::array<double, 2> py_quark;
983 std::array<double, 2> pz_quark;
985 std::array<double, 2> e_quark;
987 std::array<Pythia8::Vec4, 2> pquark;
989 const double sigma_qt_frag =
pythia_hadron_->parm(
"StringPT:sigma");
994 for (
int isign = 0; isign < 2; isign++) {
998 px_quark[isign] = 0.5 * pgluon.px() + (isign == 0 ? 1. : -1.) * qx;
999 py_quark[isign] = 0.5 * pgluon.py() + (isign == 0 ? 1. : -1.) * qy;
1000 pz_quark[isign] = 0.5 * pgluon.pz();
1002 std::sqrt(mass * mass + px_quark[isign] * px_quark[isign] +
1003 py_quark[isign] * py_quark[isign] +
1004 pz_quark[isign] * pz_quark[isign]);
1005 pquark[isign] = Pythia8::Vec4(px_quark[isign], py_quark[isign],
1006 pz_quark[isign], e_quark[isign]);
1011 pSum += pquark[0] + pquark[1] - pgluon;
1013 event_intermediate.append(pdgid, status, col, 0, pquark[0], mass);
1014 event_intermediate.append(-pdgid, status, 0, acol, pquark[1], mass);
1016 event_intermediate.remove(iforward, iforward);
1018 logg[
LPythia].debug(
" gluon at iforward = ", iforward,
1019 " is splitted into ", pdgid,
",", -pdgid,
1023 nquark_total[iflav] += 1;
1024 nantiq_total[iflav] += 1;
1031 event_intermediate[0].p(pSum);
1032 event_intermediate[0].m(pSum.mCalc());
◆ rearrange_excess()
void smash::StringProcess::rearrange_excess |
( |
std::array< int, 5 > & |
nquark_total, |
|
|
std::array< std::array< int, 5 >, 2 > & |
excess_quark, |
|
|
std::array< std::array< int, 5 >, 2 > & |
excess_antiq |
|
) |
| |
Take total number of quarks and check if the system has enough constituents that need to be converted into other flavors.
If that is not the case, excesses of quarks and antiquarks are modified such that the net quark number of each flavor is conserved. For example, if there is no antiquark in the system and we have excess_antiq = (1, -1, 0, 0, 0) (i.e., one ubar has to be converted into dbar), excess_antiq will be changed into (0, 0, 0, 0, 0) and (-1, 1, 0, 0, 0) will be added to excess_quark (i.e., one d quark has to be converted into u quark instead).
Number of quarks is checked if the first argument is the total number of quarks, and the second and third arguments are respectively excesses of quarks and antiquarks. Number of antiquarks is checked if the first argument is the total number of antiquarks, and the second and third arguments are respectively excesses of antiquarks and quarks.
- Parameters
-
[in] | nquark_total | total number of quarks (antiquarks) in the system. |
[out] | excess_quark | excess of quarks (antiquarks) in incoming particles, compared to the mapped ones. |
[out] | excess_antiq | excess of anti-quarks (quarks) in incoming particles, compared to the mapped ones. |
Definition at line 1037 of file processstring.cc.
1041 for (
int iflav = 0; iflav < 5; iflav++) {
1048 nquark_total[iflav] + excess_quark[0][iflav] + excess_quark[1][iflav];
1052 bool enough_quark = nquark_final >= 0;
1054 if (!enough_quark) {
1055 logg[
LPythia].debug(
" not enough constituents with flavor ", iflav + 1,
1056 " : try to modify excess of constituents.");
1057 for (
int ic = 0; ic < std::abs(nquark_final); ic++) {
1061 if (excess_quark[0][iflav] < 0) {
1069 excess_quark[ih_mod][iflav] += 1;
1070 excess_antiq[ih_mod][iflav] += 1;
1077 for (
int jflav = 0; jflav < 5; jflav++) {
1079 if (jflav != iflav && excess_quark[ih_mod][jflav] > 0) {
1082 excess_quark[ih_mod][jflav] -= 1;
1083 excess_antiq[ih_mod][jflav] -= 1;
◆ restore_constituent()
bool smash::StringProcess::restore_constituent |
( |
Pythia8::Event & |
event_intermediate, |
|
|
std::array< std::array< int, 5 >, 2 > & |
excess_quark, |
|
|
std::array< std::array< int, 5 >, 2 > & |
excess_antiq |
|
) |
| |
Take the intermediate partonic state from PYTHIA event with mapped hadrons and convert constituents into the desired ones according to the excess of quarks and anti-quarks.
Quark (antiquark) flavor is changed and excess of quark (antiquark) is also updated by calling StringProcess::replace_constituent. Beginning with the most forward (or backward) constituent, conversion is done until the total net quark number of each flavor is same with that of incoming hadrons. (i.e., excess_quark minus excess_antiq of incoming hadrons becomes zero.)
However, note that there are some circumstances where this procedure is not directly carried out. For example, a proton-kaon(+) collision mapped onto a proton-pion(+) might be an issue if it involves d + dbar -> g g partonic interaction, given that we anticipate to change dbar to sbar. If such case occurs, we first try to split gluon into quark-antiquark pair with desired flavor. If there are not enough gluons to split, we try to modify the excesses of constituents such that the net quark number is conserved.
- Parameters
-
[out] | event_intermediate | PYTHIA partonic event record to be updated according to the valence quark contents of incoming hadrons. |
[out] | excess_quark | excess of quarks in incoming particles, compared to the mapped ones. |
[out] | excess_antiq | excess of anti-quarks in incoming particles, compared to the mapped ones. |
- See also
- StringProcess::replace_constituent(Pythia8::Particle &, std::array<int, 5> &)
-
StringProcess::splitting_gluon_qqbar(Pythia8::Event &, std::array<int, 5> &, std::array<int, 5> &, bool, std::array<std::array<int, 5>, 2> &)
-
StringProcess::rearrange_excess(std::array<int, 5> &, std::array<std::array<int, 5>, 2> &, std::array<std::array<int, 5>, 2> &)
Definition at line 1094 of file processstring.cc.
1098 Pythia8::Vec4 pSum = event_intermediate[0].p();
1099 const double energy_init = pSum.e();
1100 logg[
LPythia].debug(
" initial total energy [GeV] : ", energy_init);
1103 std::array<int, 5> nquark_total;
1104 std::array<int, 5> nantiq_total;
1109 event_intermediate, nquark_total, nantiq_total,
true, excess_quark);
1111 event_intermediate, nquark_total, nantiq_total,
false, excess_antiq);
1115 if (!split_for_quark || !split_for_antiq) {
1121 for (
int iflav = 0; iflav < 5; iflav++) {
1122 if (nquark_total[iflav] + excess_quark[0][iflav] + excess_quark[1][iflav] <
1124 logg[
LPythia].debug(
"Not enough quark constituents of flavor ",
1129 if (nantiq_total[iflav] + excess_antiq[0][iflav] + excess_antiq[1][iflav] <
1131 logg[
LPythia].debug(
"Not enough antiquark constituents of flavor ",
1137 for (
int ih = 0; ih < 2; ih++) {
1138 logg[
LPythia].debug(
" initial excess_quark[", ih,
"] = (",
1139 excess_quark[ih][0],
", ", excess_quark[ih][1],
", ",
1140 excess_quark[ih][2],
", ", excess_quark[ih][3],
", ",
1141 excess_quark[ih][4],
")");
1142 logg[
LPythia].debug(
" initial excess_antiq[", ih,
"] = (",
1143 excess_antiq[ih][0],
", ", excess_antiq[ih][1],
", ",
1144 excess_antiq[ih][2],
", ", excess_antiq[ih][3],
", ",
1145 excess_antiq[ih][4],
")");
1148 bool recovered_quarks =
false;
1149 while (!recovered_quarks) {
1152 std::array<bool, 2> find_forward = {
true,
false};
1153 const std::array<int, 5> excess_null = {0, 0, 0, 0, 0};
1154 std::array<int, 5> excess_total = excess_null;
1156 for (
int ih = 0; ih < 2; ih++) {
1157 int nfrag = event_intermediate.size();
1158 for (
int np_end = 0; np_end < nfrag - 1; np_end++) {
1165 pSum -= event_intermediate[iforward].p();
1167 if (event_intermediate[iforward].
id() > 0) {
1170 " excess_quark[", ih,
"] = (", excess_quark[ih][0],
", ",
1171 excess_quark[ih][1],
", ", excess_quark[ih][2],
", ",
1172 excess_quark[ih][3],
", ", excess_quark[ih][4],
")");
1176 " excess_antiq[", ih,
"] = (", excess_antiq[ih][0],
", ",
1177 excess_antiq[ih][1],
", ", excess_antiq[ih][2],
", ",
1178 excess_antiq[ih][3],
", ", excess_antiq[ih][4],
")");
1181 const int pdgid = event_intermediate[iforward].id();
1182 Pythia8::Vec4 pquark = event_intermediate[iforward].p();
1185 const int status = event_intermediate[iforward].status();
1186 const int color = event_intermediate[iforward].col();
1187 const int anticolor = event_intermediate[iforward].acol();
1190 event_intermediate.append(pdgid, status, color, anticolor, pquark,
1193 event_intermediate.remove(iforward, iforward);
1199 for (
int j = 0; j < 5; j++) {
1200 excess_total[j] += (excess_quark[ih][j] - excess_antiq[ih][j]);
1206 recovered_quarks = excess_total == excess_null;
1208 logg[
LPythia].debug(
" valence quark contents of hadons are recovered.");
1210 logg[
LPythia].debug(
" current total energy [GeV] : ", pSum.e());
1214 if (std::abs(pSum.e() - energy_init) <
really_small * energy_init) {
1218 double energy_current = pSum.e();
1220 for (
int i = 1; i < event_intermediate.size(); i++) {
1221 slope += event_intermediate[i].pAbs2() / event_intermediate[i].e();
1224 const double rescale_factor = 1. + (energy_init - energy_current) / slope;
1226 for (
int i = 1; i < event_intermediate.size(); i++) {
1227 const double px = rescale_factor * event_intermediate[i].px();
1228 const double py = rescale_factor * event_intermediate[i].py();
1229 const double pz = rescale_factor * event_intermediate[i].pz();
1230 const double pabs = rescale_factor * event_intermediate[i].pAbs();
1231 const double mass = event_intermediate[i].m();
1233 event_intermediate[i].px(px);
1234 event_intermediate[i].py(py);
1235 event_intermediate[i].pz(pz);
1236 event_intermediate[i].e(std::sqrt(mass * mass + pabs * pabs));
1237 pSum += event_intermediate[i].p();
1239 logg[
LPythia].debug(
" parton momenta are rescaled by factor of ",
1243 logg[
LPythia].debug(
" final total energy [GeV] : ", pSum.e());
1246 event_intermediate[0].p(pSum);
1247 event_intermediate[0].m(pSum.mCalc());
◆ compose_string_parton()
void smash::StringProcess::compose_string_parton |
( |
bool |
find_forward_string, |
|
|
Pythia8::Event & |
event_intermediate, |
|
|
Pythia8::Event & |
event_hadronize |
|
) |
| |
Identify a set of partons, which are connected to form a color-neutral string, from a given PYTHIA event record.
All partons found are moved into a new event record for the further hadronization process. Note that col and acol of Pythia8::Particle contain information on the color flow. This function begins with the most forward (or backward) parton.
For example, quark (col = 1, acol = 0), gluon (col = 2, acol = 1) and antiquark (col = 0, acol = 2) correspond to a \( \bar{q} \, g \, q \) mesonic string. quark (col = 1, acol = 0) and diquark (col = 0, acol = 1) correspond to a \( qq \, q\) baryonic string.
- Parameters
-
[in] | find_forward_string | If it is set to be true (false), it begins with forward (backward) parton. |
[out] | event_intermediate | PYTHIA event record from which a string is identified. All partons found here are removed. |
[out] | event_hadronize | PYTHIA event record to which partons in a string are added. |
Definition at line 1252 of file processstring.cc.
1255 Pythia8::Vec4 pSum = 0.;
1256 event_hadronize.reset();
1260 logg[
LPythia].debug(
"Hard non-diff: iforward = ", iforward,
"(",
1261 event_intermediate[iforward].
id(),
")");
1263 pSum += event_intermediate[iforward].p();
1264 event_hadronize.append(event_intermediate[iforward]);
1266 int col_to_find = event_intermediate[iforward].acol();
1267 int acol_to_find = event_intermediate[iforward].col();
1268 event_intermediate.remove(iforward, iforward);
1269 logg[
LPythia].debug(
"Hard non-diff: event_intermediate reduces in size to ",
1270 event_intermediate.size());
1273 while (col_to_find != 0 || acol_to_find != 0) {
1274 logg[
LPythia].debug(
" col_to_find = ", col_to_find,
1275 ", acol_to_find = ", acol_to_find);
1278 for (
int i = 1; i < event_intermediate.size(); i++) {
1279 const int pdgid = event_intermediate[i].id();
1281 col_to_find != 0 && col_to_find == event_intermediate[i].col();
1283 acol_to_find != 0 && acol_to_find == event_intermediate[i].acol();
1285 logg[
LPythia].debug(
" col_to_find ", col_to_find,
" from i ", i,
"(",
1289 logg[
LPythia].debug(
" acol_to_find ", acol_to_find,
" from i ", i,
"(",
1293 if (found_col && !found_acol) {
1295 col_to_find = event_intermediate[i].acol();
1297 }
else if (!found_col && found_acol) {
1299 acol_to_find = event_intermediate[i].col();
1301 }
else if (found_col && found_acol) {
1310 event_intermediate.list();
1311 event_intermediate.listJunctions();
1312 event_hadronize.list();
1313 event_hadronize.listJunctions();
1314 if (col_to_find != 0) {
1315 logg[
LPythia].error(
"No parton with col = ", col_to_find);
1317 if (acol_to_find != 0) {
1318 logg[
LPythia].error(
"No parton with acol = ", acol_to_find);
1320 throw std::runtime_error(
"Hard string could not be identified.");
1322 pSum += event_intermediate[ifound].p();
1324 event_hadronize.append(event_intermediate[ifound]);
1326 event_intermediate.remove(ifound, ifound);
1328 "Hard non-diff: event_intermediate reduces in size to ",
1329 event_intermediate.size());
1335 event_hadronize[0].p(pSum);
1336 event_hadronize[0].m(pSum.mCalc());
◆ compose_string_junction()
void smash::StringProcess::compose_string_junction |
( |
bool & |
find_forward_string, |
|
|
Pythia8::Event & |
event_intermediate, |
|
|
Pythia8::Event & |
event_hadronize |
|
) |
| |
Identify a set of partons and junction(s), which are connected to form a color-neutral string, from a given PYTHIA event record.
All partons found are moved into a new event record for the further hadronization process. Junction topology in PYTHIA combines three quarks (antiquarks) to make a color-neutral baryonic (anti-baryonic) configuration. A junction (anti-junction) carries three color (anti-color) indices which are connected with quarks (antiquarks). This function begins with the first junction.
For example, if there is a kind-1 junction with legs (col = 1, 2 and 3), it will first look for three partons with color indices col = 1, 2 and 3 and trace color indices until each leg is `‘closed’' with quark. If there is no quark in the end, there should be an anti-junction and its legs are connected to partons with corresponding anti-colors.
- Parameters
-
[out] | find_forward_string | If it is set to be true (false), it is a string in the forward (backward) direction. |
[out] | event_intermediate | PYTHIA event record from which a string is identified. All partons and junction(s) found here are removed. |
[out] | event_hadronize | PYTHIA event record to which partons in a string are added. |
- See also
- StringProcess::find_junction_leg(bool, std::vector<int> &, Pythia8::Event &, Pythia8::Event &)
Definition at line 1339 of file processstring.cc.
1342 event_hadronize.reset();
1350 const int kind = event_intermediate.kindJunction(0);
1351 bool sign_color = kind % 2 == 1;
1352 std::vector<int> col;
1353 for (
int j = 0; j < 3; j++) {
1354 col.push_back(event_intermediate.colJunction(0, j));
1356 event_hadronize.appendJunction(kind, col[0], col[1], col[2]);
1357 event_intermediate.eraseJunction(0);
1358 logg[
LPythia].debug(
"junction (", col[0],
", ", col[1],
", ", col[2],
1359 ") with kind ", kind,
" will be handled.");
1361 bool found_string =
false;
1362 while (!found_string) {
1365 found_string =
true;
1366 for (
unsigned int j = 0; j < col.size(); j++) {
1367 found_string = found_string && col[j] == 0;
1369 if (!found_string) {
1372 logg[
LPythia].debug(
" still has leg(s) unfinished.");
1373 sign_color = !sign_color;
1374 std::vector<int> junction_to_move;
1375 for (
int i = 0; i < event_intermediate.sizeJunction(); i++) {
1376 const int kind_new = event_intermediate.kindJunction(i);
1380 if (sign_color != (kind_new % 2 == 1)) {
1384 std::array<int, 3> col_new;
1385 for (
int k = 0; k < 3; k++) {
1386 col_new[k] = event_intermediate.colJunction(i, k);
1389 int n_legs_connected = 0;
1391 for (
unsigned int j = 0; j < col.size(); j++) {
1395 for (
int k = 0; k < 3; k++) {
1396 if (col[j] == col_new[k]) {
1397 n_legs_connected += 1;
1405 if (n_legs_connected > 0) {
1406 for (
int k = 0; k < 3; k++) {
1407 if (col_new[k] != 0) {
1408 col.push_back(col_new[k]);
1412 event_intermediate.colJunction(i, 0),
", ",
1413 event_intermediate.colJunction(i, 1),
", ",
1414 event_intermediate.colJunction(i, 2),
1415 ") with kind ", kind_new,
" will be added.");
1416 junction_to_move.push_back(i);
1422 for (
unsigned int i = 0; i < junction_to_move.size(); i++) {
1423 unsigned int imove = junction_to_move[i] - i;
1424 const int kind_add = event_intermediate.kindJunction(imove);
1425 std::array<int, 3> col_add;
1426 for (
int k = 0; k < 3; k++) {
1427 col_add[k] = event_intermediate.colJunction(imove, k);
1430 event_hadronize.appendJunction(kind_add, col_add[0], col_add[1],
1433 event_intermediate.eraseJunction(imove);
1438 Pythia8::Vec4 pSum = event_hadronize[0].p();
1439 find_forward_string = pSum.pz() > 0.;
◆ find_junction_leg()
void smash::StringProcess::find_junction_leg |
( |
bool |
sign_color, |
|
|
std::vector< int > & |
col, |
|
|
Pythia8::Event & |
event_intermediate, |
|
|
Pythia8::Event & |
event_hadronize |
|
) |
| |
Identify partons, which are associated with junction legs, from a given PYTHIA event record.
All partons found are moved into a new event record for the further hadronization process.
- Parameters
-
[in] | sign_color | true (false) if the junction is associated with color (anti-color) indices, corresponding baryonic (anti-baryonic) string |
[out] | col | set of color indices that need to be found. The value is set to be zero once the corresponding partons are found. |
[out] | event_intermediate | PYTHIA event record from which a string is identified. All partons and junction(s) found here are removed. |
[out] | event_hadronize | PYTHIA event record to which partons in a string are added. |
- See also
- StringProcess::compose_string_junction(bool &, Pythia8::Event &, Pythia8::Event &)
Definition at line 1442 of file processstring.cc.
1445 Pythia8::Vec4 pSum = event_hadronize[0].p();
1446 for (
unsigned int j = 0; j < col.size(); j++) {
1450 bool found_leg =
false;
1451 while (!found_leg) {
1453 for (
int i = 1; i < event_intermediate.size(); i++) {
1454 const int pdgid = event_intermediate[i].id();
1455 if (sign_color && col[j] == event_intermediate[i].col()) {
1456 logg[
LPythia].debug(
" col[", j,
"] = ", col[j],
" from i ", i,
"(",
1459 col[j] = event_intermediate[i].acol();
1461 }
else if (!sign_color && col[j] == event_intermediate[i].acol()) {
1462 logg[
LPythia].debug(
" acol[", j,
"] = ", col[j],
" from i ", i,
"(",
1465 col[j] = event_intermediate[i].col();
1472 if (event_intermediate.sizeJunction() == 0) {
1473 event_intermediate.list();
1474 event_intermediate.listJunctions();
1475 event_hadronize.list();
1476 event_hadronize.listJunctions();
1477 logg[
LPythia].error(
"No parton with col = ", col[j],
1478 " connected with junction leg ", j);
1479 throw std::runtime_error(
"Hard string could not be identified.");
1482 pSum += event_intermediate[ifound].p();
1484 event_hadronize.append(event_intermediate[ifound]);
1486 event_intermediate.remove(ifound, ifound);
1488 "Hard non-diff: event_intermediate reduces in size to ",
1489 event_intermediate.size());
1499 event_hadronize[0].p(pSum);
1500 event_hadronize[0].m(pSum.mCalc());
◆ get_index_forward()
int smash::StringProcess::get_index_forward |
( |
bool |
find_forward, |
|
|
int |
np_end, |
|
|
Pythia8::Event & |
event |
|
) |
| |
|
inline |
Obtain index of the most forward or backward particle in a given PYTHIA event record.
- Parameters
-
[in] | find_forward | if it looks for the most forward or backward particle. |
[in] | np_end | number of the last particle entries to be excluded in lookup. In other words, it finds the most forward (or backward) particle among event[1, ... , event.size() - 1 - np_end]. |
[in] | event | PYTHIA event record which contains particle entries. Note that event[0] is reserved for information on the entire system. |
- Returns
- index of the selected particle, which is used to access the specific particle entry in the event record.
Definition at line 747 of file processstring.h.
750 for (
int ip = 2; ip <
event.size() - np_end; ip++) {
751 const double y_quark_current =
event[ip].y();
752 const double y_quark_forward =
event[iforward].y();
753 if ((find_forward && y_quark_current > y_quark_forward) ||
754 (!find_forward && y_quark_current < y_quark_forward)) {
◆ get_final_state()
ParticleList smash::StringProcess::get_final_state |
( |
| ) |
|
|
inline |
a function to get the final state particle list which is called after the collision
- Returns
- ParticleList filled with the final state particles.
Definition at line 766 of file processstring.h.
◆ append_final_state()
int smash::StringProcess::append_final_state |
( |
ParticleList & |
intermediate_particles, |
|
|
const FourVector & |
uString, |
|
|
const ThreeVector & |
evecLong |
|
) |
| |
compute the formation time and fill the arrays with final-state particles as described in Andersson:1983ia [2].
- Parameters
-
[out] | intermediate_particles | list of fragmented particles to be appended |
[in] | uString | is velocity four vector of the string. |
[in] | evecLong | is unit 3-vector in which string is stretched. |
- Returns
- number of hadrons fragmented out of string.
- Exceptions
-
std::invalid_argument | if fragmented particle is not hadron |
std::invalid_argument | if string is neither mesonic nor baryonic |
Definition at line 144 of file processstring.cc.
150 for (ParticleData &data : intermediate_particles) {
152 bstring += data.pdgcode().baryon_number();
162 const ThreeVector vstring = uString.velocity();
165 for (
int i = 0; i < nfrag; i++) {
166 ThreeVector velocity = intermediate_particles[i].momentum().velocity();
167 double gamma = 1. / intermediate_particles[i].inverse_gamma();
169 FourVector momentum =
170 intermediate_particles[i].momentum().lorentz_boost(-vstring);
171 intermediate_particles[i].set_4momentum(momentum);
175 double tau_prod = M_SQRT2 * intermediate_particles[i].effective_mass() /
177 double t_prod = tau_prod * gamma;
178 FourVector fragment_position = FourVector(t_prod, t_prod * velocity);
181 fragment_position = fragment_position.lorentz_boost(-vstring);
182 fragment_position = fragment_position.lorentz_boost(-
vcomAB_);
183 intermediate_particles[i].set_slow_formation_times(
187 ThreeVector v_calc = momentum.lorentz_boost(-
vcomAB_).velocity();
188 double gamma_factor = 1.0 / std::sqrt(1 - (v_calc).sqr());
189 intermediate_particles[i].set_slow_formation_times(
◆ append_intermediate_list()
static bool smash::StringProcess::append_intermediate_list |
( |
int |
pdgid, |
|
|
FourVector |
momentum, |
|
|
ParticleList & |
intermediate_particles |
|
) |
| |
|
inlinestatic |
append new particle from PYTHIA to a specific particle list
- Parameters
-
[in] | pdgid | PDG id of particle |
[in] | momentum | four-momentum of particle |
[out] | intermediate_particles | particle list to which the new particle is added. |
- Returns
- whether PDG id exists in ParticleType table.
Definition at line 792 of file processstring.h.
794 const std::string s = std::to_string(pdgid);
795 PdgCode pythia_code(s);
797 new_particle.set_4momentum(momentum);
798 intermediate_particles.push_back(new_particle);
◆ convert_KaonLS()
static void smash::StringProcess::convert_KaonLS |
( |
int & |
pythia_id | ) |
|
|
inlinestatic |
convert Kaon-L or Kaon-S into K0 or Anti-K0
- Parameters
-
[out] | pythia_id | is PDG id to be converted. |
Definition at line 806 of file processstring.h.
807 if (pythia_id == 310 || pythia_id == 130) {
◆ quarks_from_diquark()
void smash::StringProcess::quarks_from_diquark |
( |
int |
diquark, |
|
|
int & |
q1, |
|
|
int & |
q2, |
|
|
int & |
deg_spin |
|
) |
| |
|
static |
find two quarks from a diquark.
Order does not matter.
- Parameters
-
[in] | diquark | PDG id of diquark |
[out] | q1 | PDG id of quark 1 |
[out] | q2 | PDG id of quark 2 |
[out] | deg_spin | spin degeneracy |
Definition at line 1671 of file processstring.cc.
1674 assert((std::abs(diquark) > 1000) && (std::abs(diquark) < 5510) &&
1675 (std::abs(diquark) % 100 < 10));
1678 deg_spin = std::abs(diquark) % 10;
1680 const int sign_anti = diquark > 0 ? 1 : -1;
1683 q1 = sign_anti * (std::abs(diquark) - (std::abs(diquark) % 1000)) / 1000;
1684 q2 = sign_anti * (std::abs(diquark) % 1000 - deg_spin) / 100;
◆ diquark_from_quarks()
int smash::StringProcess::diquark_from_quarks |
( |
int |
q1, |
|
|
int |
q2 |
|
) |
| |
|
static |
Construct diquark from two quarks.
Order does not matter.
- Parameters
-
[in] | q1 | PDG code of quark 1 |
[in] | q2 | PDG code of quark 2 |
- Returns
- PDG code of diquark composed of q1 and q2
Definition at line 1687 of file processstring.cc.
1688 assert((q1 > 0 && q2 > 0) || (q1 < 0 && q2 < 0));
1689 if (std::abs(q1) < std::abs(q2)) {
1692 int diquark = std::abs(q1 * 1000 + q2 * 100);
1697 return (q1 < 0) ? -diquark : diquark;
◆ make_string_ends()
void smash::StringProcess::make_string_ends |
( |
const PdgCode & |
pdgcode_in, |
|
|
int & |
idq1, |
|
|
int & |
idq2, |
|
|
double |
xi |
|
) |
| |
|
static |
make a random selection to determine partonic contents at the string ends.
- Parameters
-
[in] | pdgcode_in | is PdgCode of hadron which transforms into a string. |
[out] | idq1 | is PDG id of quark or anti-diquark. |
[out] | idq2 | is PDG id of anti-quark or diquark. |
[in] | xi | probability to split a nucleon into the quark it has only once and a diquark of another flavour. |
Definition at line 1700 of file processstring.cc.
1702 std::array<int, 3> quarks = pdg.quark_content();
1703 if (pdg.is_nucleon()) {
1706 if (pdg.charge() == 0) {
1724 if (pdg.is_meson()) {
1735 assert(pdg.is_baryon());
1744 std::swap(idq1, idq2);
◆ set_Vec4()
static Pythia8::Vec4 smash::StringProcess::set_Vec4 |
( |
double |
energy, |
|
|
const ThreeVector & |
mom |
|
) |
| |
|
inlinestatic |
Easy setter of Pythia Vec4 from SMASH.
- Parameters
-
[in] | energy | time component |
[in] | mom | spatial three-vector |
- Returns
- Pythia Vec4 from energy and ThreeVector
Definition at line 844 of file processstring.h.
845 return Pythia8::Vec4(mom.x1(), mom.x2(), mom.x3(), energy);
◆ reorient()
static FourVector smash::StringProcess::reorient |
( |
Pythia8::Particle & |
particle, |
|
|
std::array< ThreeVector, 3 > & |
evec_basis |
|
) |
| |
|
inlinestatic |
compute the four-momentum properly oriented in the lab frame.
While PYTHIA assumes that the collision axis is in z-direction, this is not necessarly the case in SMASH.
- Parameters
-
[in] | particle | particle object from PYTHIA event generation where z-axis is set to be the collision axis |
[in] | evec_basis | three basis vectors in the lab frame evec_basis[0] is unit vector in the collision axis and other two span the transverse plane |
- Returns
- four-momentum of particle in the lab frame
Definition at line 859 of file processstring.h.
861 ThreeVector three_momentum = evec_basis[0] * particle.pz() +
862 evec_basis[1] * particle.px() +
863 evec_basis[2] * particle.py();
864 return FourVector(particle.e(), three_momentum);
◆ fragment_string()
int smash::StringProcess::fragment_string |
( |
int |
idq1, |
|
|
int |
idq2, |
|
|
double |
mString, |
|
|
ThreeVector & |
evecLong, |
|
|
bool |
flip_string_ends, |
|
|
bool |
separate_fragment_baryon, |
|
|
ParticleList & |
intermediate_particles |
|
) |
| |
perform string fragmentation to determine species and momenta of hadrons by implementing PYTHIA 8.2 Andersson:1983ia [2], Sjostrand:2014zea [41].
- Parameters
-
[in] | idq1 | PDG id of quark or anti-diquark (carrying color index). |
[in] | idq2 | PDG id of diquark or anti-quark (carrying anti-color index). |
[in] | mString | the string mass. [GeV] |
[out] | evecLong | unit 3-vector specifying the direction of diquark or anti-diquark. |
[in] | flip_string_ends | is whether or not we randomly switch string ends. |
[in] | separate_fragment_baryon | is whether fragment leading baryon (or anti-baryon) with separate fragmentation function. |
[out] | intermediate_particles | list of fragmented particles |
- Returns
- number of hadrons fragmented out of string.
- Exceptions
-
std::runtime_error | if string mass is lower than threshold set by PYTHIA |
Definition at line 1748 of file processstring.cc.
1753 intermediate_particles.clear();
1755 logg[
LPythia].debug(
"initial quark content for fragment_string : ", idq1,
1757 logg[
LPythia].debug(
"initial string mass (GeV) for fragment_string : ",
1760 std::array<int, 2> idqIn;
1766 std::array<double, 2> m_const;
1768 for (
int i = 0; i < 2; i++) {
1770 bstring +=
pythia_hadron_->particleData.baryonNumberType(idqIn[i]);
1774 logg[
LPythia].debug(
"baryon number of string times 3 : ", bstring);
1781 evecLong = -evecLong;
1784 if (m_const[0] + m_const[1] > mString) {
1785 throw std::runtime_error(
"String fragmentation: m1 + m2 > mString");
1787 Pythia8::Vec4 pSum = 0.;
1789 int number_of_fragments = 0;
1790 bool do_string_fragmentation =
false;
1794 double ppos_string_new, pneg_string_new;
1797 double QTrx_string_new, QTry_string_new, QTrn_string_new;
1799 double mTrn_string_new;
1801 double mass_string_new;
1805 double QTrx_add_pos, QTry_add_pos;
1808 double QTrx_add_neg, QTry_add_neg;
1820 std::array<ThreeVector, 3> evec_basis;
1823 if (separate_fragment_baryon && (std::abs(bstring) == 3) &&
1824 (mString > m_const[0] + m_const[1] + 1.)) {
1831 std::vector<int> pdgid_frag_prior;
1834 std::vector<FourVector> momentum_frag_prior;
1837 double QTrx_string_pos;
1839 double QTrx_string_neg;
1841 double QTry_string_pos;
1843 double QTry_string_neg;
1846 double QTrn_string_pos;
1849 double QTrn_string_neg;
1851 std::array<double, 2> m_trans;
1854 const int niter_max = 10000;
1855 bool found_leading_baryon =
false;
1856 for (
int iiter = 0; iiter < niter_max; iiter++) {
1858 pdgid_frag_prior.clear();
1859 momentum_frag_prior.clear();
1861 std::vector<int> pdgid_frag;
1862 std::vector<FourVector> momentum_frag;
1864 ppos_string_new = mString * M_SQRT1_2;
1865 pneg_string_new = mString * M_SQRT1_2;
1867 QTrx_string_pos = 0.;
1868 QTrx_string_neg = 0.;
1869 QTrx_string_new = 0.;
1870 QTry_string_pos = 0.;
1871 QTry_string_neg = 0.;
1872 QTry_string_new = 0.;
1874 Pythia8::FlavContainer flav_string_pos =
1875 bstring > 0 ? Pythia8::FlavContainer(idq2)
1876 : Pythia8::FlavContainer(idq1);
1878 Pythia8::FlavContainer flav_string_neg =
1879 bstring > 0 ? Pythia8::FlavContainer(idq1)
1880 : Pythia8::FlavContainer(idq2);
1882 bool found_forward_baryon =
false;
1884 bool done_forward_end =
false;
1887 bool energy_used_up =
false;
1888 while (!found_forward_baryon && !energy_used_up) {
1899 separate_fragment_baryon && from_forward && !done_forward_end,
1900 evec_basis, ppos_string_new, pneg_string_new, QTrx_string_pos,
1901 QTrx_string_neg, QTry_string_pos, QTry_string_neg, flav_string_pos,
1902 flav_string_neg, pdgid_frag, momentum_frag);
1908 QTrx_string_new = QTrx_string_pos + QTrx_string_neg;
1909 QTry_string_new = QTry_string_pos + QTry_string_neg;
1913 idqIn[0] = bstring > 0 ? flav_string_neg.id : flav_string_pos.id;
1914 idqIn[1] = bstring > 0 ? flav_string_pos.id : flav_string_neg.id;
1915 for (
int i = 0; i < 2; i++) {
1918 QTrn_string_pos = std::sqrt(QTrx_string_pos * QTrx_string_pos +
1919 QTry_string_pos * QTry_string_pos);
1920 QTrn_string_neg = std::sqrt(QTrx_string_neg * QTrx_string_neg +
1921 QTry_string_neg * QTry_string_neg);
1926 m_trans[0] = std::sqrt(m_const[0] * m_const[0] +
1927 QTrn_string_neg * QTrn_string_neg);
1931 m_trans[1] = std::sqrt(m_const[1] * m_const[1] +
1932 QTrn_string_pos * QTrn_string_pos);
1937 m_trans[0] = std::sqrt(m_const[0] * m_const[0] +
1938 QTrn_string_pos * QTrn_string_pos);
1942 m_trans[1] = std::sqrt(m_const[1] * m_const[1] +
1943 QTrn_string_neg * QTrn_string_neg);
1945 done_forward_end = done_forward_end || from_forward;
1946 found_forward_baryon =
1947 found_forward_baryon ||
1952 energy_used_up =
true;
1956 n_frag_prior += n_frag;
1957 for (
int i_frag = 0; i_frag < n_frag; i_frag++) {
1958 pdgid_frag_prior.push_back(pdgid_frag[i_frag]);
1959 momentum_frag_prior.push_back(momentum_frag[i_frag]);
1967 double mTsqr_string = 2. * ppos_string_new * pneg_string_new;
1968 mTrn_string_new = std::sqrt(mTsqr_string);
1969 QTrn_string_new = std::sqrt(QTrx_string_new * QTrx_string_new +
1970 QTry_string_new * QTry_string_new);
1971 if (mTrn_string_new < QTrn_string_new) {
1974 found_leading_baryon =
false;
1978 std::sqrt(mTsqr_string - QTrn_string_new * QTrn_string_new);
1982 if (mass_string_new > m_const[0] + m_const[1]) {
1983 do_string_fragmentation =
true;
1984 found_leading_baryon =
true;
1985 QTrx_add_pos = QTrx_string_pos;
1986 QTry_add_pos = QTry_string_pos;
1987 QTrx_add_neg = QTrx_string_neg;
1988 QTry_add_neg = QTry_string_neg;
1990 found_leading_baryon =
false;
1993 }
else if (n_frag == 2) {
1996 do_string_fragmentation =
false;
1997 found_leading_baryon =
true;
2001 if (found_leading_baryon) {
2005 if (found_leading_baryon) {
2008 for (
int i_frag = 0; i_frag < n_frag_prior; i_frag++) {
2009 logg[
LPythia].debug(
"appending the the fragmented hadron ",
2010 pdgid_frag_prior[i_frag],
2011 " to the intermediate particle list.");
2014 momentum_frag_prior[i_frag],
2015 intermediate_particles);
2017 logg[
LPythia].error(
"PDG ID ", pdgid_frag_prior[i_frag],
2018 " should exist in ParticleType.");
2019 throw std::runtime_error(
"string fragmentation failed.");
2021 number_of_fragments++;
2029 if (do_string_fragmentation) {
2030 mTrn_string_new = std::sqrt(2. * ppos_string_new * pneg_string_new);
2032 std::array<double, 2> ppos_parton;
2034 std::array<double, 2> pneg_parton;
2042 const double pb_const =
2043 (mTrn_string_new * mTrn_string_new + m_trans[0] * m_trans[0] -
2044 m_trans[1] * m_trans[1]) /
2045 (4. * pneg_string_new);
2046 const double pc_const =
2047 0.5 * m_trans[0] * m_trans[0] * ppos_string_new / pneg_string_new;
2048 ppos_parton[0] = pb_const + (bstring > 0 ? -1. : 1.) *
2049 std::sqrt(pb_const * pb_const - pc_const);
2050 ppos_parton[1] = ppos_string_new - ppos_parton[0];
2054 for (
int i = 0; i < 2; i++) {
2055 pneg_parton[i] = 0.5 * m_trans[i] * m_trans[i] / ppos_parton[i];
2058 const int status = 1;
2059 int color, anticolor;
2060 ThreeVector three_mom;
2061 ThreeVector transverse_mom;
2062 Pythia8::Vec4 pquark;
2082 bstring > 0 ? evec_basis[1] * (QTrx_string_neg - QTrx_add_neg) +
2083 evec_basis[2] * (QTry_string_neg - QTry_add_neg)
2084 : evec_basis[1] * (QTrx_string_pos - QTrx_add_pos) +
2085 evec_basis[2] * (QTry_string_pos - QTry_add_pos);
2087 evec_basis[0] * (ppos_parton[0] - pneg_parton[0]) * M_SQRT1_2 +
2089 const double E_quark =
2090 std::sqrt(m_const[0] * m_const[0] + three_mom.sqr());
2091 pquark =
set_Vec4(E_quark, three_mom);
2093 pythia_hadron_->event.append(idqIn[0], status, color, anticolor, pquark,
2114 bstring > 0 ? evec_basis[1] * (QTrx_string_pos - QTrx_add_pos) +
2115 evec_basis[2] * (QTry_string_pos - QTry_add_pos)
2116 : evec_basis[1] * (QTrx_string_neg - QTrx_add_neg) +
2117 evec_basis[2] * (QTry_string_neg - QTry_add_neg);
2119 evec_basis[0] * (ppos_parton[1] - pneg_parton[1]) * M_SQRT1_2 +
2121 const double E_antiq =
2122 std::sqrt(m_const[1] * m_const[1] + three_mom.sqr());
2123 pquark =
set_Vec4(E_antiq, three_mom);
2125 pythia_hadron_->event.append(idqIn[1], status, color, anticolor, pquark,
2129 do_string_fragmentation =
true;
2131 ppos_string_new = mString * M_SQRT1_2;
2132 pneg_string_new = mString * M_SQRT1_2;
2133 QTrx_string_new = 0.;
2134 QTry_string_new = 0.;
2135 QTrn_string_new = 0.;
2136 mTrn_string_new = mString;
2137 mass_string_new = mString;
2142 double sign_direction = 1.;
2143 if (bstring == -3) {
2147 sign_direction = -1;
2151 const double pCMquark =
pCM(mString, m_const[0], m_const[1]);
2152 const double E1 = std::sqrt(m_const[0] * m_const[0] + pCMquark * pCMquark);
2153 const double E2 = std::sqrt(m_const[1] * m_const[1] + pCMquark * pCMquark);
2155 ThreeVector direction = sign_direction * evecLong;
2158 const int status1 = 1, color1 = 1, anticolor1 = 0;
2159 Pythia8::Vec4 pquark =
set_Vec4(E1, -direction * pCMquark);
2161 pythia_hadron_->event.append(idqIn[0], status1, color1, anticolor1, pquark,
2164 const int status2 = 1, color2 = 0, anticolor2 = 1;
2165 pquark =
set_Vec4(E2, direction * pCMquark);
2167 pythia_hadron_->event.append(idqIn[1], status2, color2, anticolor2, pquark,
2171 if (do_string_fragmentation) {
2172 logg[
LPythia].debug(
"fragmenting a string with ", idqIn[0],
", ", idqIn[1]);
2177 if (!successful_hadronization) {
2184 pythia_hadron_->event, evec_basis, ppos_string_new, pneg_string_new,
2185 QTrx_string_new, QTry_string_new, QTrx_add_pos, QTry_add_pos,
2186 QTrx_add_neg, QTry_add_neg);
2187 if (!successful_kinematics) {
2191 for (
int ipyth = 0; ipyth <
pythia_hadron_->event.size(); ipyth++) {
2199 FourVector momentum(
2202 logg[
LPythia].debug(
"appending the fragmented hadron ", pythia_id,
2203 " to the intermediate particle list.");
2208 " does not exist in ParticleType - start over.");
2209 intermediate_particles.clear();
2213 number_of_fragments++;
2216 return number_of_fragments;
◆ fragment_off_hadron()
int smash::StringProcess::fragment_off_hadron |
( |
bool |
from_forward, |
|
|
bool |
separate_fragment_baryon, |
|
|
std::array< ThreeVector, 3 > & |
evec_basis, |
|
|
double & |
ppos_string, |
|
|
double & |
pneg_string, |
|
|
double & |
QTrx_string_pos, |
|
|
double & |
QTrx_string_neg, |
|
|
double & |
QTry_string_pos, |
|
|
double & |
QTry_string_neg, |
|
|
Pythia8::FlavContainer & |
flav_string_pos, |
|
|
Pythia8::FlavContainer & |
flav_string_neg, |
|
|
std::vector< int > & |
pdgid_frag, |
|
|
std::vector< FourVector > & |
momentum_frag |
|
) |
| |
Fragment one hadron from a given string configuration if the string mass is above threshold (given by the consituent masses).
Otherwise the entire string breaks down into (final) two hadrons.
- Parameters
-
[in] | from_forward | whether a hadron is fragmented from the forward end of the string |
[in] | separate_fragment_baryon | whether a separate fragmentation function is used for the leading baryon from the diquark end of string. |
[in] | evec_basis | three orthonormal basis vectors of which evec_basis[0] is in the longitudinal direction while evec_basis[1] and evec_basis[2] span the transverse plane. |
[out] | ppos_string | lightcone momentum p^+ of the string. This will be changed according to that of the remaining string. |
[out] | pneg_string | lightcone momentum p^- of the string. This will be changed according to that of the remaining string. |
[out] | QTrx_string_pos | transverse momentum px carried by the forward end of the string. This will be changed according to that of the remaining string. |
[out] | QTrx_string_neg | transverse momentum px carried by the backward end of the string. This will be changed according to that of the remaining string. |
[out] | QTry_string_pos | transverse momentum py carried by the forward end of the string. This will be changed according to that of the remaining string. |
[out] | QTry_string_neg | transverse momentum py carried by the backward end of the string. This will be changed according to that of the remaining string. |
[out] | flav_string_pos | constituent flavor at the forward end of the string. This will be changed according to that of the remaining string. |
[out] | flav_string_neg | constituent flavor at the backward end of the string. This will be changed according to that of the remaining string. |
[out] | pdgid_frag | PDG id of fragmented hadron(s) |
[out] | momentum_frag | four-momenta of fragmented hadrons(s) |
- Returns
- number of fragmented hadron(s). It can be 1 or 2 depending on the string mass. If it fails to fragment, returns 0.
Definition at line 2219 of file processstring.cc.
2229 const int n_try = 10;
2231 momentum_frag.clear();
2233 if (ppos_string < 0. || pneg_string < 0.) {
2234 throw std::runtime_error(
"string has a negative lightcone momentum.");
2236 double mTsqr_string = 2. * ppos_string * pneg_string;
2238 double mTrn_string = std::sqrt(mTsqr_string);
2240 double QTrx_string_tot = QTrx_string_pos + QTrx_string_neg;
2241 double QTry_string_tot = QTry_string_pos + QTry_string_neg;
2242 double QTsqr_string_tot = std::fabs(QTrx_string_tot * QTrx_string_tot) +
2243 std::fabs(QTry_string_tot * QTry_string_tot);
2244 double QTrn_string_tot = std::sqrt(QTsqr_string_tot);
2245 if (mTrn_string < QTrn_string_tot) {
2249 double mass_string = std::sqrt(mTsqr_string - QTsqr_string_tot);
2250 logg[
LPythia].debug(
" Fragment off one hadron from a string ( ",
2251 flav_string_pos.id,
" , ", flav_string_neg.id,
2252 " ) with mass ", mass_string,
" GeV.");
2255 const double sigma_qt_frag =
pythia_hadron_->parm(
"StringPT:sigma");
2256 const double stop_string_mass =
2258 const double stop_string_smear =
2262 const double prob_enhance_qt =
2264 double fac_enhance_qt;
2268 fac_enhance_qt = 1.;
2282 logg[
LPythia].debug(
" Transverse momentum (", QTrx_new,
", ", QTry_new,
2283 ") GeV selected for the new qqbar pair.");
2292 double QTrx_had_1st =
2293 from_forward ? QTrx_string_pos + QTrx_new : QTrx_string_neg + QTrx_new;
2294 double QTry_had_1st =
2295 from_forward ? QTry_string_pos + QTry_new : QTry_string_neg + QTry_new;
2296 double QTrn_had_1st =
2297 std::sqrt(QTrx_had_1st * QTrx_had_1st + QTry_had_1st * QTry_had_1st);
2300 int pdgid_had_1st = 0;
2302 double mass_had_1st = 0.;
2305 Pythia8::FlavContainer flav_old =
2306 from_forward ? flav_string_pos : flav_string_neg;
2311 Pythia8::FlavContainer flav_new = Pythia8::FlavContainer(0);
2315 for (
int i_try = 0; i_try < n_try; i_try++) {
2320 if (pdgid_had_1st != 0) {
2323 logg[
LPythia].debug(
" number of tries of flavor selection : ",
2324 i_try + 1,
" in StringProcess::fragment_off_hadron.");
2328 if (pdgid_had_1st == 0) {
2332 " selected for the string end with ", flav_old.id);
2334 " selected for the (first) fragmented hadron.");
2335 bool had_1st_baryon =
pythia_hadron_->particleData.isBaryon(pdgid_had_1st);
2337 double mTrn_had_1st =
2338 std::sqrt(mass_had_1st * mass_had_1st + QTrn_had_1st * QTrn_had_1st);
2339 logg[
LPythia].debug(
" Transverse momentum (", QTrx_had_1st,
", ",
2341 ") GeV selected for the (first) fragmented hadron.");
2346 const double mass_min_to_continue =
2347 (stop_string_mass +
pythia_hadron_->particleData.m0(flav_new.id) +
2353 bool string_into_final_two = mass_string < mass_min_to_continue;
2354 if (string_into_final_two) {
2355 logg[
LPythia].debug(
" The string mass is below the mass threshold ",
2356 mass_min_to_continue,
2357 " GeV : finishing with two hadrons.");
2361 double ppos_had_1st = 0.;
2362 double pneg_had_1st = 0.;
2366 bool from_diquark_end =
2367 from_forward ?
pythia_hadron_->particleData.isDiquark(flav_string_pos.id)
2370 bool has_diquark_pos =
2374 if (string_into_final_two) {
2378 int pdgid_had_2nd = 0.;
2380 double mass_had_2nd = 0.;
2383 Pythia8::FlavContainer flav_new2 = Pythia8::FlavContainer(0);
2384 flav_new2.anti(flav_new);
2387 if (
pythia_hadron_->particleData.isDiquark(flav_string_neg.id) &&
2388 pythia_hadron_->particleData.isDiquark(flav_new2.id) && from_forward) {
2391 if (
pythia_hadron_->particleData.isDiquark(flav_string_pos.id) &&
2392 pythia_hadron_->particleData.isDiquark(flav_new2.id) && !from_forward) {
2395 for (
int i_try = 0; i_try < n_try; i_try++) {
2400 if (pdgid_had_2nd != 0) {
2406 if (pdgid_had_2nd == 0) {
2410 " selected for the (second) fragmented hadron.");
2411 bool had_2nd_baryon =
pythia_hadron_->particleData.isBaryon(pdgid_had_2nd);
2419 double QTrx_had_2nd =
2420 from_forward ? QTrx_string_neg - QTrx_new : QTrx_string_pos - QTrx_new;
2421 double QTry_had_2nd =
2422 from_forward ? QTry_string_neg - QTry_new : QTry_string_pos - QTry_new;
2423 double QTrn_had_2nd =
2424 std::sqrt(QTrx_had_2nd * QTrx_had_2nd + QTry_had_2nd * QTry_had_2nd);
2425 double mTrn_had_2nd =
2426 std::sqrt(mass_had_2nd * mass_had_2nd + QTrn_had_2nd * QTrn_had_2nd);
2427 logg[
LPythia].debug(
" Transverse momentum (", QTrx_had_2nd,
", ",
2429 ") GeV selected for the (second) fragmented hadron.");
2431 double ppos_had_2nd = 0.;
2432 double pneg_had_2nd = 0.;
2438 bool found_kinematics =
2441 separate_fragment_baryon && has_diquark_pos && had_1st_baryon,
2442 ppos_string, pneg_string, mTrn_had_1st, mTrn_had_2nd,
2443 ppos_had_1st, ppos_had_2nd, pneg_had_1st, pneg_had_2nd)
2445 separate_fragment_baryon && has_diquark_pos && had_2nd_baryon,
2446 ppos_string, pneg_string, mTrn_had_2nd, mTrn_had_1st,
2447 ppos_had_2nd, ppos_had_1st, pneg_had_2nd, pneg_had_1st);
2448 if (!found_kinematics) {
2455 QTrx_string_pos = 0.;
2456 QTry_string_pos = 0.;
2459 pdgid_frag.push_back(pdgid_had_1st);
2460 FourVector mom_had_1st = FourVector(
2461 (ppos_had_1st + pneg_had_1st) * M_SQRT1_2,
2462 evec_basis[0] * (ppos_had_1st - pneg_had_1st) * M_SQRT1_2 +
2463 evec_basis[1] * QTrx_had_1st + evec_basis[2] * QTry_had_1st);
2464 momentum_frag.push_back(mom_had_1st);
2467 pdgid_frag.push_back(pdgid_had_2nd);
2468 FourVector mom_had_2nd = FourVector(
2469 (ppos_had_2nd + pneg_had_2nd) * M_SQRT1_2,
2470 evec_basis[0] * (ppos_had_2nd - pneg_had_2nd) * M_SQRT1_2 +
2471 evec_basis[1] * QTrx_had_2nd + evec_basis[2] * QTry_had_2nd);
2472 momentum_frag.push_back(mom_had_2nd);
2481 double stringz_a_use, stringz_b_use;
2484 if (separate_fragment_baryon && from_diquark_end && had_1st_baryon) {
2494 double xfrac =
sample_zLund(stringz_a_use, stringz_b_use, mTrn_had_1st);
2498 ppos_had_1st = xfrac * ppos_string;
2499 pneg_had_1st = 0.5 * mTrn_had_1st * mTrn_had_1st / ppos_had_1st;
2500 if (pneg_had_1st > pneg_string) {
2506 pneg_had_1st = xfrac * pneg_string;
2507 ppos_had_1st = 0.5 * mTrn_had_1st * mTrn_had_1st / pneg_had_1st;
2508 if (ppos_had_1st > ppos_string) {
2514 pdgid_frag.push_back(pdgid_had_1st);
2515 FourVector mom_had_1st = FourVector(
2516 (ppos_had_1st + pneg_had_1st) * M_SQRT1_2,
2517 evec_basis[0] * (ppos_had_1st - pneg_had_1st) * M_SQRT1_2 +
2518 evec_basis[1] * QTrx_had_1st + evec_basis[2] * QTry_had_1st);
2519 momentum_frag.push_back(mom_had_1st);
2522 ppos_string -= ppos_had_1st;
2523 pneg_string -= pneg_had_1st;
2533 flav_string_pos.anti(flav_new);
2534 QTrx_string_pos = -QTrx_new;
2535 QTry_string_pos = -QTry_new;
2539 flav_string_neg.anti(flav_new);
2540 QTrx_string_neg = -QTrx_new;
2541 QTry_string_neg = -QTry_new;
◆ get_hadrontype_from_quark()
int smash::StringProcess::get_hadrontype_from_quark |
( |
int |
idq1, |
|
|
int |
idq2 |
|
) |
| |
Determines hadron type from valence quark constituents.
First, try with PYTHIA routine. If it does not work, select a resonance with the same quantum numbers. The probability to pick each resonance in this case is proportional to spin degeneracy / mass, which is inspired by UrQMD.
- Parameters
-
[in] | idq1 | PDG id of a valence quark constituent. |
[in] | idq2 | PDG id of another valence quark constituent. |
- Returns
- PDG id of selected hadronic species.
Definition at line 2550 of file processstring.cc.
2551 const int baryon_number =
2555 int pdgid_hadron = 0;
2558 Pythia8::FlavContainer flav1 = Pythia8::FlavContainer(idq1);
2559 Pythia8::FlavContainer flav2 = Pythia8::FlavContainer(idq2);
2560 const int n_try = 10;
2561 for (
int i_try = 0; i_try < n_try; i_try++) {
2563 if (pdgid_hadron != 0) {
2564 return pdgid_hadron;
2572 std::array<int, 5> frag_net_q;
2575 for (
int iq = 0; iq < 5; iq++) {
2577 pythia_hadron_->particleData.nQuarksInCode(std::abs(idq1), iq + 1);
2579 pythia_hadron_->particleData.nQuarksInCode(std::abs(idq2), iq + 1);
2580 nq1 = idq1 > 0 ? nq1 : -nq1;
2581 nq2 = idq2 > 0 ? nq2 : -nq2;
2582 frag_net_q[iq] = nq1 + nq2;
2584 const int frag_iso3 = frag_net_q[1] - frag_net_q[0];
2585 const int frag_strange = -frag_net_q[2];
2586 const int frag_charm = frag_net_q[3];
2587 const int frag_bottom = -frag_net_q[4];
2588 logg[
LPythia].debug(
" conserved charges : iso3 = ", frag_iso3,
2589 ", strangeness = ", frag_strange,
2590 ", charmness = ", frag_charm,
2591 ", bottomness = ", frag_bottom);
2593 std::vector<int> pdgid_possible;
2594 std::vector<double> weight_possible;
2595 std::vector<double> weight_summed;
2600 if (!ptype.is_hadron()) {
2603 const int pdgid = ptype.pdgcode().get_decimal();
2605 (baryon_number == 3 * ptype.pdgcode().baryon_number()) &&
2606 (frag_iso3 == ptype.pdgcode().isospin3()) &&
2607 (frag_strange == ptype.pdgcode().strangeness()) &&
2608 (frag_charm == ptype.pdgcode().charmness()) &&
2609 (frag_bottom == ptype.pdgcode().bottomness())) {
2610 const int spin_degeneracy = ptype.pdgcode().spin_degeneracy();
2611 const double mass_pole = ptype.mass();
2612 const double weight = static_cast<double>(spin_degeneracy) / mass_pole;
2613 pdgid_possible.push_back(pdgid);
2614 weight_possible.push_back(weight);
2616 logg[
LPythia].debug(
" PDG id ", pdgid,
" is possible with weight ",
2620 const int n_possible = pdgid_possible.size();
2621 weight_summed.push_back(0.);
2622 for (
int i = 0; i < n_possible; i++) {
2623 weight_summed.push_back(weight_summed[i] + weight_possible[i]);
2629 for (
int i = 0; i < n_possible; i++) {
2630 if ((uspc >= weight_summed[i]) && (uspc < weight_summed[i + 1])) {
2631 return pdgid_possible[i];
◆ get_resonance_from_quark()
int smash::StringProcess::get_resonance_from_quark |
( |
int |
idq1, |
|
|
int |
idq2, |
|
|
double |
mass |
|
) |
| |
- Parameters
-
[in] | idq1 | id of the valence quark (anti-diquark) |
[in] | idq2 | id of the valence anti-quark (diquark) |
[in] | mass | mass of the resonance. |
- Returns
- PDG id of resonance with the closest mass. If the mass is below the threshold or the input PDG id is invalid, 0 is returned.
Definition at line 2638 of file processstring.cc.
2648 bool end1_is_quark = idq1 > 0 &&
pythia_hadron_->particleData.isQuark(idq1);
2649 bool end1_is_antidiq =
2652 bool end2_is_antiq = idq2 < 0 &&
pythia_hadron_->particleData.isQuark(idq2);
2653 bool end2_is_diquark =
2657 if (end1_is_quark) {
2658 if (end2_is_antiq) {
2661 }
else if (end2_is_diquark) {
2667 }
else if (end1_is_antidiq) {
2668 if (end2_is_antiq) {
2681 std::array<int, 5> net_qnumber;
2682 for (
int iflav = 0; iflav < 5; iflav++) {
2683 net_qnumber[iflav] = 0;
2686 pythia_hadron_->particleData.nQuarksInCode(std::abs(idq1), iflav + 1);
2689 qnumber1 = -qnumber1;
2691 net_qnumber[iflav] += qnumber1;
2694 pythia_hadron_->particleData.nQuarksInCode(std::abs(idq2), iflav + 1);
2697 qnumber2 = -qnumber2;
2699 net_qnumber[iflav] += qnumber2;
2703 std::vector<int> pdgid_possible;
2705 std::vector<double> mass_diff;
2707 if (!ptype.is_hadron() || ptype.is_stable() ||
2708 ptype.pdgcode().baryon_number() != baryon) {
2712 const int pdgid = ptype.pdgcode().get_decimal();
2713 const double mass_min = ptype.min_mass_spectral();
2714 if (mass < mass_min) {
2719 if (ptype.pdgcode().isospin3() != net_qnumber[1] - net_qnumber[0]) {
2723 if (ptype.pdgcode().strangeness() != -net_qnumber[2]) {
2727 if (ptype.pdgcode().charmness() != net_qnumber[3]) {
2731 if (ptype.pdgcode().bottomness() != -net_qnumber[4]) {
2736 const double mass_pole = ptype.mass();
2738 pdgid_possible.push_back(pdgid);
2739 mass_diff.push_back(mass - mass_pole);
2742 const int n_res = pdgid_possible.size();
2748 int ires_closest = 0;
2749 double mass_diff_min = std::fabs(mass_diff[0]);
2752 for (
int ires = 1; ires < n_res; ires++) {
2753 if (std::fabs(mass_diff[ires]) < mass_diff_min) {
2754 ires_closest = ires;
2755 mass_diff_min = mass_diff[ires];
2758 logg[
LPythia].debug(
"Quark constituents ", idq1,
" and ", idq2,
" with mass ",
2759 mass,
" (GeV) turned into a resonance ",
2760 pdgid_possible[ires_closest]);
2761 return pdgid_possible[ires_closest];
◆ make_lightcone_final_two()
bool smash::StringProcess::make_lightcone_final_two |
( |
bool |
separate_fragment_hadron, |
|
|
double |
ppos_string, |
|
|
double |
pneg_string, |
|
|
double |
mTrn_had_forward, |
|
|
double |
mTrn_had_backward, |
|
|
double & |
ppos_had_forward, |
|
|
double & |
ppos_had_backward, |
|
|
double & |
pneg_had_forward, |
|
|
double & |
pneg_had_backward |
|
) |
| |
Determines lightcone momenta of two final hadrons fragmented from a string in the same way as StringFragmentation::finalTwo in StringFragmentation.cc of PYTHIA 8.
- Parameters
-
[in] | separate_fragment_hadron | whether a separate fragmentation function is used for the forward hadron |
[in] | ppos_string | lightcone momentum p^+ of the string |
[in] | pneg_string | ligntcone momentum p^- of the string |
[in] | mTrn_had_forward | transverse mass of the forward hadron |
[in] | mTrn_had_backward | transverse mass of the backward hadron |
[out] | ppos_had_forward | lightcone momentum p^+ of the forward hadron |
[out] | ppos_had_backward | lightcone momentum p^+ of the backward hadron |
[out] | pneg_had_forward | lightcone momentum p^- of the forward hadron |
[out] | pneg_had_backward | lightcone momentum p^- of the backward hadron |
- Returns
- if the lightcone momenta are properly determined such that energy and momentum are conserved.
Definition at line 2764 of file processstring.cc.
2769 const double mTsqr_string = 2. * ppos_string * pneg_string;
2770 if (mTsqr_string < 0.) {
2773 const double mTrn_string = std::sqrt(mTsqr_string);
2774 if (mTrn_string < mTrn_had_forward + mTrn_had_backward) {
2779 const double mTsqr_had_forward = mTrn_had_forward * mTrn_had_forward;
2781 const double mTsqr_had_backward = mTrn_had_backward * mTrn_had_backward;
2795 const double xm_diff =
2796 (mTsqr_had_forward - mTsqr_had_backward) / mTsqr_string;
2797 const double xe_pos = 0.5 * (1. + xm_diff);
2798 const double xe_neg = 0.5 * (1. - xm_diff);
2801 const double lambda_sqr =
2802 pow_int(mTsqr_string - mTsqr_had_forward - mTsqr_had_backward, 2) -
2803 4. * mTsqr_had_forward * mTsqr_had_backward;
2804 if (lambda_sqr <= 0.) {
2807 const double lambda = std::sqrt(lambda_sqr);
2808 const double b_lund =
2813 const double prob_reverse =
2814 std::exp(-b_lund * lambda) / (1. + std::exp(-b_lund * lambda));
2815 double xpz_pos = 0.5 * lambda / mTsqr_string;
2820 ppos_had_forward = (xe_pos + xpz_pos) * ppos_string;
2821 ppos_had_backward = (xe_neg - xpz_pos) * ppos_string;
2823 pneg_had_forward = 0.5 * mTsqr_had_forward / ppos_had_forward;
2824 pneg_had_backward = 0.5 * mTsqr_had_backward / ppos_had_backward;
◆ sample_zLund()
double smash::StringProcess::sample_zLund |
( |
double |
a, |
|
|
double |
b, |
|
|
double |
mTrn |
|
) |
| |
|
static |
Sample lightcone momentum fraction according to the LUND fragmentation function.
\( f(z) = \frac{1}{z} (1 - z)^a \exp{ \left(- \frac{b m_T^2}{z} \right) } \)
- Parameters
-
[in] | a | parameter for the fragmentation function |
[in] | b | parameter for the fragmentation function |
[in] | mTrn | transverse mass of the fragmented hadron |
- Returns
- sampled lightcone momentum fraction
Definition at line 2829 of file processstring.cc.
2832 bool xfrac_accepted =
false;
2840 while (!xfrac_accepted) {
2841 const double fac_env = b * mTrn * mTrn;
2845 const double xfrac_inv = 1. - std::log(u_aux) / fac_env;
2846 assert(xfrac_inv >= 1.);
2849 const double xf_ratio = std::pow(1. - 1. / xfrac_inv, a) / xfrac_inv;
2854 xfrac = 1. / xfrac_inv;
2855 xfrac_accepted =
true;
◆ remake_kinematics_fragments()
bool smash::StringProcess::remake_kinematics_fragments |
( |
Pythia8::Event & |
event_fragments, |
|
|
std::array< ThreeVector, 3 > & |
evec_basis, |
|
|
double |
ppos_string, |
|
|
double |
pneg_string, |
|
|
double |
QTrx_string, |
|
|
double |
QTry_string, |
|
|
double |
QTrx_add_pos, |
|
|
double |
QTry_add_pos, |
|
|
double |
QTrx_add_neg, |
|
|
double |
QTry_add_neg |
|
) |
| |
- Parameters
-
[out] | event_fragments | event record which contains information of particles |
[in] | evec_basis | three orthonormal basis vectors of which evec_basis[0] is in the longitudinal direction while evec_basis[1] and evec_basis[2] span the transverse plane. |
[in] | ppos_string | lightcone momentum p^+ of the string |
[in] | pneg_string | ligntcone momentum p^- of the string |
[in] | QTrx_string | transverse momentum px of the string |
[in] | QTry_string | transverse momentum py of the string |
[in] | QTrx_add_pos | transverse momentum px to be added to the most forward hadron |
[in] | QTry_add_pos | transverse momentum py to be added to the most forward hadron |
[in] | QTrx_add_neg | transverse momentum px to be added to the most backward hadron |
[in] | QTry_add_neg | transverse momentum py to be added to the most backward hadron |
Definition at line 2861 of file processstring.cc.
2866 logg[
LPythia].debug(
"Correcting the kinematics of fragmented hadrons...");
2868 if (ppos_string < 0. || pneg_string < 0.) {
2870 " wrong lightcone momenta of string : ppos_string (GeV) = ",
2871 ppos_string,
" pneg_string (GeV) = ", pneg_string);
2875 const double yrapid_string = 0.5 * std::log(ppos_string / pneg_string);
2876 logg[
LOutput].debug(
"Momentum-space rapidity of the string should be ",
2880 const double mTrn_string = std::sqrt(2. * ppos_string * pneg_string);
2881 logg[
LOutput].debug(
"Transvere mass (GeV) of the string should be ",
2884 const double QTrn_string =
2885 std::sqrt(QTrx_string * QTrx_string + QTry_string * QTry_string);
2886 if (mTrn_string < QTrn_string) {
2888 " wrong transverse mass of string : mTrn_string (GeV) = ", mTrn_string,
2889 " QTrn_string (GeV) = ", QTrn_string);
2892 const double msqr_string =
2893 mTrn_string * mTrn_string - QTrn_string * QTrn_string;
2895 const double mass_string = std::sqrt(msqr_string);
2896 logg[
LOutput].debug(
"The string mass (GeV) should be ", mass_string);
2900 if (std::fabs(QTrx_add_pos) <
small_number * mass_string &&
2901 std::fabs(QTry_add_pos) <
small_number * mass_string &&
2902 std::fabs(QTrx_add_neg) <
small_number * mass_string &&
2903 std::fabs(QTry_add_neg) <
small_number * mass_string) {
2904 logg[
LOutput].debug(
" no need to add transverse momenta - skipping.");
2908 FourVector ptot_string_ini = FourVector(0., 0., 0., 0.);
2910 for (
int ipyth = 1; ipyth < event_fragments.size(); ipyth++) {
2911 if (!event_fragments[ipyth].isFinal()) {
2916 FourVector(event_fragments[ipyth].e(), event_fragments[ipyth].px(),
2917 event_fragments[ipyth].py(), event_fragments[ipyth].pz());
2918 ptot_string_ini += p_frag;
2920 const double E_string_ini = ptot_string_ini.x0();
2921 const double pz_string_ini = ptot_string_ini.threevec() * evec_basis[0];
2922 const double ppos_string_ini = (E_string_ini + pz_string_ini) * M_SQRT1_2;
2923 const double pneg_string_ini = (E_string_ini - pz_string_ini) * M_SQRT1_2;
2925 const double yrapid_string_ini =
2926 0.5 * std::log(ppos_string_ini / pneg_string_ini);
2932 int ip_backward = 0;
2933 double y_forward = 0.;
2934 double y_backward = 0.;
2935 ptot_string_ini = FourVector(0., 0., 0., 0.);
2937 for (
int ipyth = 1; ipyth < event_fragments.size(); ipyth++) {
2938 if (!event_fragments[ipyth].isFinal()) {
2943 FourVector(event_fragments[ipyth].e(), event_fragments[ipyth].px(),
2944 event_fragments[ipyth].py(), event_fragments[ipyth].pz());
2945 ptot_string_ini += p_frag;
2947 const double E_frag = p_frag.x0();
2948 const double pl_frag = p_frag.threevec() * evec_basis[0];
2949 double y_current = 0.5 * std::log((E_frag + pl_frag) / (E_frag - pl_frag));
2950 if (y_current > y_forward) {
2952 y_forward = y_current;
2954 if (y_current < y_backward) {
2955 ip_backward = ipyth;
2956 y_backward = y_current;
2959 logg[
LOutput].debug(
" The most forward hadron is ip_forward = ", ip_forward,
2960 " with rapidity ", y_forward);
2961 logg[
LOutput].debug(
" The most backward hadron is ip_backward = ",
2962 ip_backward,
" with rapidity ", y_backward);
2964 const double px_string_ini = ptot_string_ini.threevec() * evec_basis[1];
2965 const double py_string_ini = ptot_string_ini.threevec() * evec_basis[2];
2969 bool correct_px = std::fabs(px_string_ini + QTrx_add_pos + QTrx_add_neg -
2973 " input transverse momenta in x-axis are not consistent.");
2978 bool correct_py = std::fabs(py_string_ini + QTry_add_pos + QTry_add_neg -
2982 " input transverse momenta in y-axis are not consistent.");
2986 Pythia8::Vec4 pvec_string_now =
2987 set_Vec4(ptot_string_ini.x0(), ptot_string_ini.threevec());
2990 " Adding transverse momentum to the most forward hadron.");
2991 pvec_string_now -= event_fragments[ip_forward].p();
2992 const double mass_frag_pos = event_fragments[ip_forward].p().mCalc();
2994 FourVector p_old_frag_pos = FourVector(
2995 event_fragments[ip_forward].e(), event_fragments[ip_forward].px(),
2996 event_fragments[ip_forward].py(), event_fragments[ip_forward].pz());
2998 ThreeVector mom_new_frag_pos = p_old_frag_pos.threevec() +
2999 QTrx_add_pos * evec_basis[1] +
3000 QTry_add_pos * evec_basis[2];
3002 double E_new_frag_pos =
3003 std::sqrt(mom_new_frag_pos.sqr() + mass_frag_pos * mass_frag_pos);
3004 Pythia8::Vec4 pvec_new_frag_pos =
set_Vec4(E_new_frag_pos, mom_new_frag_pos);
3005 pvec_string_now += pvec_new_frag_pos;
3007 event_fragments[ip_forward].p(pvec_new_frag_pos);
3010 " Adding transverse momentum to the most backward hadron.");
3011 pvec_string_now -= event_fragments[ip_backward].p();
3012 const double mass_frag_neg = event_fragments[ip_backward].p().mCalc();
3014 FourVector p_old_frag_neg = FourVector(
3015 event_fragments[ip_backward].e(), event_fragments[ip_backward].px(),
3016 event_fragments[ip_backward].py(), event_fragments[ip_backward].pz());
3018 ThreeVector mom_new_frag_neg = p_old_frag_neg.threevec() +
3019 QTrx_add_neg * evec_basis[1] +
3020 QTry_add_neg * evec_basis[2];
3022 double E_new_frag_neg =
3023 std::sqrt(mom_new_frag_neg.sqr() + mass_frag_neg * mass_frag_neg);
3024 Pythia8::Vec4 pvec_new_frag_neg =
set_Vec4(E_new_frag_neg, mom_new_frag_neg);
3025 pvec_string_now += pvec_new_frag_neg;
3027 event_fragments[ip_backward].p(pvec_new_frag_neg);
3030 event_fragments[0].p(pvec_string_now);
3031 event_fragments[0].m(pvec_string_now.mCalc());
3035 double mTrn_frag_all = 0.;
3036 for (
int ipyth = 1; ipyth < event_fragments.size(); ipyth++) {
3037 if (!event_fragments[ipyth].isFinal()) {
3043 FourVector(event_fragments[ipyth].e(), event_fragments[ipyth].px(),
3044 event_fragments[ipyth].py(), event_fragments[ipyth].pz());
3045 ptot_string_ini += p_frag;
3047 const double E_frag = p_frag.x0();
3048 const double pl_frag = p_frag.threevec() * evec_basis[0];
3049 const double ppos_frag = (E_frag + pl_frag) * M_SQRT1_2;
3050 const double pneg_frag = (E_frag - pl_frag) * M_SQRT1_2;
3051 const double mTrn_frag = std::sqrt(2. * ppos_frag * pneg_frag);
3052 mTrn_frag_all += mTrn_frag;
3055 "Sum of transverse masses (GeV) of all fragmented hadrons : ",
3059 if (mTrn_string < mTrn_frag_all) {
3060 logg[
LOutput].debug(
" which is larger than mT of the actual string ",
3065 double mass_string_now = pvec_string_now.mCalc();
3066 double msqr_string_now = mass_string_now * mass_string_now;
3068 FourVector p_string_now =
3069 FourVector(pvec_string_now.e(), pvec_string_now.px(),
3070 pvec_string_now.py(), pvec_string_now.pz());
3071 double E_string_now = p_string_now.x0();
3072 double pz_string_now = p_string_now.threevec() * evec_basis[0];
3073 logg[
LOutput].debug(
"The string mass (GeV) at this point : ",
3075 double ppos_string_now = (E_string_now + pz_string_now) * M_SQRT1_2;
3076 double pneg_string_now = (E_string_now - pz_string_now) * M_SQRT1_2;
3078 double yrapid_string_now = 0.5 * std::log(ppos_string_now / pneg_string_now);
3079 logg[
LOutput].debug(
"The momentum-space rapidity of string at this point : ",
3082 "The momentum-space rapidities of hadrons will be changed.");
3083 const int niter_max = 10000;
3084 bool accepted =
false;
3085 double fac_all_yrapid = 1.;
3090 for (
int iiter = 0; iiter < niter_max; iiter++) {
3091 if (std::fabs(mass_string_now - mass_string) <
really_small * mass_string) {
3095 double E_deriv = 0.;
3096 double pz_deriv = 0.;
3100 for (
int ipyth = 1; ipyth < event_fragments.size(); ipyth++) {
3101 if (!event_fragments[ipyth].isFinal()) {
3106 FourVector(event_fragments[ipyth].e(), event_fragments[ipyth].px(),
3107 event_fragments[ipyth].py(), event_fragments[ipyth].pz());
3108 const double E_frag = p_frag.x0();
3109 const double pl_frag = p_frag.threevec() * evec_basis[0];
3110 const double ppos_frag = (E_frag + pl_frag) * M_SQRT1_2;
3111 const double pneg_frag = (E_frag - pl_frag) * M_SQRT1_2;
3112 const double mTrn_frag = std::sqrt(2. * ppos_frag * pneg_frag);
3113 const double y_frag = 0.5 * std::log(ppos_frag / pneg_frag);
3115 E_deriv += mTrn_frag * (y_frag - yrapid_string_now) * std::sinh(y_frag);
3116 pz_deriv += mTrn_frag * (y_frag - yrapid_string_now) * std::cosh(y_frag);
3118 double slope = 2. * (E_string_now * E_deriv - pz_string_now * pz_deriv);
3119 double fac_yrapid = 1. + std::tanh((msqr_string - msqr_string_now) / slope);
3120 fac_all_yrapid *= fac_yrapid;
3124 (1. - fac_yrapid) * yrapid_string_now);
3126 pvec_string_now = event_fragments[0].p();
3127 mass_string_now = pvec_string_now.mCalc();
3128 msqr_string_now = mass_string_now * mass_string_now;
3129 p_string_now = FourVector(pvec_string_now.e(), pvec_string_now.px(),
3130 pvec_string_now.py(), pvec_string_now.pz());
3131 E_string_now = p_string_now.x0();
3132 pz_string_now = p_string_now.threevec() * evec_basis[0];
3133 ppos_string_now = (E_string_now + pz_string_now) * M_SQRT1_2;
3134 pneg_string_now = (E_string_now - pz_string_now) * M_SQRT1_2;
3135 yrapid_string_now = 0.5 * std::log(ppos_string_now / pneg_string_now);
3136 logg[
LOutput].debug(
" step ", iiter + 1,
" : fac_yrapid = ", fac_yrapid,
3137 " , string mass (GeV) = ", mass_string_now,
3138 " , string rapidity = ", yrapid_string_now);
3142 logg[
LOutput].debug(
" Too many iterations in rapidity rescaling.");
3146 "The overall factor multiplied to the rapidities of hadrons = ",
3148 logg[
LOutput].debug(
"The momentum-space rapidity of string at this point : ",
3150 const double y_diff = yrapid_string - yrapid_string_now;
3151 logg[
LOutput].debug(
"The hadrons will be boosted by rapidity ", y_diff,
3152 " for the longitudinal momentum conservation.");
◆ shift_rapidity_event()
void smash::StringProcess::shift_rapidity_event |
( |
Pythia8::Event & |
event, |
|
|
std::array< ThreeVector, 3 > & |
evec_basis, |
|
|
double |
factor_yrapid, |
|
|
double |
diff_yrapid |
|
) |
| |
|
inline |
Shift the momentum rapidity of all particles in a given event record.
y to factor_yrapid * y + diff_yrapid
- Parameters
-
[out] | event | event record which contains information of particles |
[in] | evec_basis | three orthonormal basis vectors of which evec_basis[0] is in the longitudinal direction while evec_basis[1] and evec_basis[2] span the transverse plane. |
[in] | factor_yrapid | factor multiplied to the old rapidity |
[in] | diff_yrapid | rapidity difference added to the old one |
Definition at line 1028 of file processstring.h.
1031 Pythia8::Vec4 pvec_string_now = Pythia8::Vec4(0., 0., 0., 0.);
1033 for (
int ipyth = 1; ipyth <
event.size(); ipyth++) {
1034 if (!event[ipyth].isFinal()) {
1038 FourVector p_frag = FourVector(
1039 event[ipyth].e(), event[ipyth].px(),
1040 event[ipyth].py(), event[ipyth].pz());
1041 const double E_frag = p_frag.x0();
1042 const double pl_frag = p_frag.threevec() * evec_basis[0];
1043 const double ppos_frag = (E_frag + pl_frag) * M_SQRT1_2;
1044 const double pneg_frag = (E_frag - pl_frag) * M_SQRT1_2;
1045 const double mTrn_frag = std::sqrt(2. * ppos_frag * pneg_frag);
1047 const double y_frag = 0.5 * std::log(ppos_frag / pneg_frag);
1050 const double y_new_frag = factor_yrapid * y_frag + diff_yrapid;
1052 const double E_new_frag = mTrn_frag * std::cosh(y_new_frag);
1053 const double pl_new_frag = mTrn_frag * std::sinh(y_new_frag);
1054 ThreeVector mom_new_frag =
1055 p_frag.threevec() + (pl_new_frag - pl_frag) * evec_basis[0];
1056 Pythia8::Vec4 pvec_new_frag =
set_Vec4(E_new_frag, mom_new_frag);
1057 event[ipyth].p(pvec_new_frag);
1058 pvec_string_now += pvec_new_frag;
1060 event[0].p(pvec_string_now);
1061 event[0].m(pvec_string_now.mCalc());
◆ assign_all_scaling_factors()
void smash::StringProcess::assign_all_scaling_factors |
( |
int |
baryon_string, |
|
|
ParticleList & |
outgoing_particles, |
|
|
const ThreeVector & |
evecLong, |
|
|
double |
suppression_factor |
|
) |
| |
|
static |
Assign a cross section scaling factor to all outgoing particles.
The factor is only non-zero, when the outgoing particle carries a valence quark from the excited hadron. The assigned cross section scaling factor is equal to the number of the valence quarks from the fragmented hadron contained in the fragment divided by the total number of valence quarks of that fragment multiplied by a coherence factor
- Parameters
-
[in] | baryon_string | baryon number of the string |
[out] | outgoing_particles | list of string fragments to which scaling factors are assigned |
[in] | evecLong | direction in which the string is stretched |
[in] | suppression_factor | additional coherence factor to be multiplied with scaling factor |
Definition at line 3192 of file processstring.cc.
3197 for (ParticleData &data : outgoing_particles) {
3198 data.set_cross_section_scaling_factor(0.0);
3201 std::sort(outgoing_particles.begin(), outgoing_particles.end(),
3202 [&](ParticleData i, ParticleData j) {
3203 return i.momentum().velocity() * evecLong >
3204 j.momentum().velocity() * evecLong;
3207 switch (baryon_string) {
3221 throw std::runtime_error(
"string is neither mesonic nor baryonic");
3226 std::pair<int, int> i =
find_leading(nq1, nq2, outgoing_particles);
3227 std::pair<int, int> j =
find_leading(nq2, nq1, outgoing_particles);
3228 if (baryon_string == 0 && i.second - i.first < j.second - j.first) {
3231 suppression_factor);
3235 suppression_factor);
◆ find_leading()
std::pair< int, int > smash::StringProcess::find_leading |
( |
int |
nq1, |
|
|
int |
nq2, |
|
|
ParticleList & |
list |
|
) |
| |
|
static |
Find the leading string fragments.
Find the first particle, which can carry nq1, and the last particle, which can carry nq2 valence quarks and return their indices in the given list.
- Parameters
-
[in] | nq1 | number of valence quarks from excited hadron at forward end of the string |
[in] | nq2 | number of valance quarks from excited hadron at backward end of the string |
[in] | list | list of string fragments |
- Returns
- indices of the leading hadrons in
list
Definition at line 3175 of file processstring.cc.
3177 assert(list.size() >= 2);
3178 int end = list.size() - 1;
3181 i1 <= end && !list[i1].pdgcode().contains_enough_valence_quarks(nq1);
3185 i2 >= 0 && !list[i2].pdgcode().contains_enough_valence_quarks(nq2);
3188 std::pair<int, int> indices(i1, i2);
◆ assign_scaling_factor()
void smash::StringProcess::assign_scaling_factor |
( |
int |
nquark, |
|
|
ParticleData & |
data, |
|
|
double |
suppression_factor |
|
) |
| |
|
static |
Assign a cross section scaling factor to the given particle.
The scaling factor is the number of quarks from the excited hadron, that the fragment carries devided by the total number of quarks in this fragment multiplied by coherence factor.
- Parameters
-
[in] | nquark | number of valence quarks from the excited hadron contained in the given string fragment data |
[out] | data | particle to assign a scaling factor to |
[in] | suppression_factor | coherence factor to decrease scaling factor |
Definition at line 3160 of file processstring.cc.
3162 int nbaryon = data.pdgcode().baryon_number();
3166 data.set_cross_section_scaling_factor(0.5 * suppression_factor);
3167 }
else if (data.is_baryon()) {
3170 data.set_cross_section_scaling_factor(suppression_factor * nquark /
◆ pdg_map_for_pythia()
int smash::StringProcess::pdg_map_for_pythia |
( |
PdgCode & |
pdg | ) |
|
|
static |
Take pdg code and map onto particle specie which can be handled by PYTHIA.
Positively charged baryons are mapped onto proton and other baryons are mapped onto neutrons. Same rule applies for anti-baryons. Positively (negatively) charged mesons are mapped onto pi+ (pi-). Negatively and positively charged leptons are mapped respectivly onto electron and positron. Currently, we do not have cross sections for leptons and photons with high energy, so such collisions should not happen.
- Parameters
-
- Returns
- mapped PDG id to be used in PYTHIA
- Exceptions
-
std::runtime_error | if the incoming particle is neither hadron nor lepton. |
Definition at line 3239 of file processstring.cc.
3240 PdgCode pdg_mapped(0x0);
3242 if (pdg.baryon_number() == 1) {
3243 pdg_mapped = pdg.charge() > 0 ? PdgCode(
pdg::p) : PdgCode(pdg::
n);
3244 }
else if (pdg.baryon_number() == -1) {
3245 pdg_mapped = pdg.charge() < 0 ? PdgCode(-
pdg::p) : PdgCode(-pdg::
n);
3246 }
else if (pdg.is_hadron()) {
3247 if (pdg.charge() >= 0) {
3252 }
else if (pdg.is_lepton()) {
3253 pdg_mapped = pdg.charge() < 0 ? PdgCode(0x11) : PdgCode(-0x11);
3255 throw std::runtime_error(
"StringProcess::pdg_map_for_pythia failed.");
3258 return pdg_mapped.get_decimal();
◆ getPPosA()
double smash::StringProcess::getPPosA |
( |
| ) |
|
|
inline |
- Returns
- forward lightcone momentum incoming particle A in CM-frame [GeV]
- See also
- PPosA_
Definition at line 1139 of file processstring.h.
◆ getPNegA()
double smash::StringProcess::getPNegA |
( |
| ) |
|
|
inline |
- Returns
- backward lightcone momentum incoming particle Af in CM-frame [GeV]
- See also
- PNegA_
Definition at line 1145 of file processstring.h.
◆ getPPosB()
double smash::StringProcess::getPPosB |
( |
| ) |
|
|
inline |
- Returns
- forward lightcone momentum incoming particle B in CM-frame [GeV]
- See also
- PPosB_
Definition at line 1151 of file processstring.h.
◆ getPnegB()
double smash::StringProcess::getPnegB |
( |
| ) |
|
|
inline |
- Returns
- backward lightcone momentum incoming particle B in CM-frame [GeV]
- See also
- PNegB_
Definition at line 1157 of file processstring.h.
◆ get_massA()
double smash::StringProcess::get_massA |
( |
| ) |
|
|
inline |
◆ get_massB()
double smash::StringProcess::get_massB |
( |
| ) |
|
|
inline |
◆ get_sqrts()
double smash::StringProcess::get_sqrts |
( |
| ) |
|
|
inline |
◆ get_PDGs()
std::array<PdgCode, 2> smash::StringProcess::get_PDGs |
( |
| ) |
|
|
inline |
◆ get_plab()
std::array<FourVector, 2> smash::StringProcess::get_plab |
( |
| ) |
|
|
inline |
◆ get_pcom()
std::array<FourVector, 2> smash::StringProcess::get_pcom |
( |
| ) |
|
|
inline |
- Returns
- momenta of incoming particles in center of mass frame [GeV]
- See also
- pcom_
Definition at line 1193 of file processstring.h.
◆ get_ucom()
◆ get_vcom()
◆ get_tcoll()
double smash::StringProcess::get_tcoll |
( |
| ) |
|
|
inline |
◆ PPosA_
double smash::StringProcess::PPosA_ |
|
private |
forward lightcone momentum p^{+} of incoming particle A in CM-frame [GeV]
Definition at line 51 of file processstring.h.
◆ PPosB_
double smash::StringProcess::PPosB_ |
|
private |
forward lightcone momentum p^{+} of incoming particle B in CM-frame [GeV]
Definition at line 53 of file processstring.h.
◆ PNegA_
double smash::StringProcess::PNegA_ |
|
private |
backward lightcone momentum p^{-} of incoming particle A in CM-frame [GeV]
Definition at line 55 of file processstring.h.
◆ PNegB_
double smash::StringProcess::PNegB_ |
|
private |
backward lightcone momentum p^{-} of incoming particle B in CM-frame [GeV]
Definition at line 57 of file processstring.h.
◆ massA_
double smash::StringProcess::massA_ |
|
private |
◆ massB_
double smash::StringProcess::massB_ |
|
private |
◆ sqrtsAB_
double smash::StringProcess::sqrtsAB_ |
|
private |
sqrt of Mandelstam variable s of collision [GeV]
Definition at line 63 of file processstring.h.
◆ PDGcodes_
std::array<PdgCode, 2> smash::StringProcess::PDGcodes_ |
|
private |
◆ plab_
std::array<FourVector, 2> smash::StringProcess::plab_ |
|
private |
momenta of incoming particles in the lab frame [GeV]
Definition at line 67 of file processstring.h.
◆ pcom_
std::array<FourVector, 2> smash::StringProcess::pcom_ |
|
private |
momenta of incoming particles in the center of mass frame [GeV]
Definition at line 69 of file processstring.h.
◆ ucomAB_
velocity four vector of the center of mass in the lab frame
Definition at line 71 of file processstring.h.
◆ vcomAB_
velocity three vector of the center of mass in the lab frame
Definition at line 73 of file processstring.h.
◆ evecBasisAB_
std::array<ThreeVector, 3> smash::StringProcess::evecBasisAB_ |
|
private |
Orthonormal basis vectors in the center of mass frame, where the 0th one is parallel to momentum of incoming particle A.
Definition at line 78 of file processstring.h.
◆ NpartFinal_
int smash::StringProcess::NpartFinal_ |
|
private |
◆ NpartString_
std::array<int, 2> smash::StringProcess::NpartString_ |
|
private |
number of particles fragmented from strings
Definition at line 82 of file processstring.h.
◆ pmin_gluon_lightcone_
double smash::StringProcess::pmin_gluon_lightcone_ |
|
private |
the minimum lightcone momentum scale carried by a gluon [GeV]
Definition at line 84 of file processstring.h.
◆ pow_fgluon_beta_
double smash::StringProcess::pow_fgluon_beta_ |
|
private |
parameter \(\beta\) for the gluon distribution function \( P(x) = x^{-1} (1 - x)^{1 + \beta} \)
Definition at line 89 of file processstring.h.
◆ pow_fquark_alpha_
double smash::StringProcess::pow_fquark_alpha_ |
|
private |
parameter \(\alpha\) for the quark distribution function \( P(x) = x^{\alpha - 1} (1 - x)^{\beta - 1} \)
Definition at line 94 of file processstring.h.
◆ pow_fquark_beta_
double smash::StringProcess::pow_fquark_beta_ |
|
private |
parameter \(\beta\) for the quark distribution function \( P(x) = x^{\alpha - 1} (1 - x)^{\beta - 1} \)
Definition at line 99 of file processstring.h.
◆ sigma_qperp_
double smash::StringProcess::sigma_qperp_ |
|
private |
Transverse momentum spread of the excited strings.
[GeV] Transverse momenta of strings are sampled according to gaussian distribution with width sigma_qperp_
Definition at line 105 of file processstring.h.
◆ stringz_a_leading_
double smash::StringProcess::stringz_a_leading_ |
|
private |
parameter (StringZ:aLund) for the fragmentation function of leading baryon in soft non-diffractive string processes
Definition at line 110 of file processstring.h.
◆ stringz_b_leading_
double smash::StringProcess::stringz_b_leading_ |
|
private |
parameter (StringZ:bLund) for the fragmentation function of leading baryon in soft non-diffractive string processes
Definition at line 115 of file processstring.h.
◆ stringz_a_produce_
double smash::StringProcess::stringz_a_produce_ |
|
private |
parameter (StringZ:aLund) for the fragmentation function of other (produced) hadrons in soft non-diffractive string processes
Definition at line 120 of file processstring.h.
◆ stringz_b_produce_
double smash::StringProcess::stringz_b_produce_ |
|
private |
parameter (StringZ:bLund) for the fragmentation function of other (produced) hadrons in soft non-diffractive string processes
Definition at line 125 of file processstring.h.
◆ kappa_tension_string_
double smash::StringProcess::kappa_tension_string_ |
|
private |
◆ additional_xsec_supp_
double smash::StringProcess::additional_xsec_supp_ |
|
private |
additional cross-section suppression factor to take coherence effect into account.
Definition at line 132 of file processstring.h.
◆ time_formation_const_
double smash::StringProcess::time_formation_const_ |
|
private |
constant proper time in the case of constant formation time [fm]
Definition at line 134 of file processstring.h.
◆ soft_t_form_
double smash::StringProcess::soft_t_form_ |
|
private |
factor to be multiplied to formation times in soft strings
Definition at line 136 of file processstring.h.
◆ time_collision_
double smash::StringProcess::time_collision_ |
|
private |
time of collision in the computational frame [fm]
Definition at line 138 of file processstring.h.
◆ mass_dependent_formation_times_
bool smash::StringProcess::mass_dependent_formation_times_ |
|
private |
Whether the formation time should depend on the mass of the fragment according to Andersson:1983ia [2] eq.
2.45:
\( \tau = \sqrt{2}\frac{m}{\kappa} \)
The formation time and position is not calculated directly using the yoyo model because the spacetime rapidity where a string fragment forms is not equal to the fragment's momentum space rapidity. This cannot be easily combined with possible interactions before the formation time.
Definition at line 150 of file processstring.h.
◆ prob_proton_to_d_uu_
double smash::StringProcess::prob_proton_to_d_uu_ |
|
private |
Probability of splitting a nucleon into the quark flavour it has only once and a diquark it has twice.
Definition at line 155 of file processstring.h.
◆ separate_fragment_baryon_
bool smash::StringProcess::separate_fragment_baryon_ |
|
private |
Whether to use a separate fragmentation function for leading baryons.
Definition at line 158 of file processstring.h.
◆ pythia_parton_initialized_
bool smash::StringProcess::pythia_parton_initialized_ = false |
|
private |
Remembers if Pythia is initialized or not.
Definition at line 160 of file processstring.h.
◆ final_state_
ParticleList smash::StringProcess::final_state_ |
|
private |
final state array which must be accessed after the collision
Definition at line 166 of file processstring.h.
◆ pythia_parton_
std::unique_ptr<Pythia8::Pythia> smash::StringProcess::pythia_parton_ |
|
private |
PYTHIA object used in hard string routine.
Definition at line 169 of file processstring.h.
◆ pythia_hadron_
std::unique_ptr<Pythia8::Pythia> smash::StringProcess::pythia_hadron_ |
|
private |
◆ pythia_sigmatot_
Pythia8::SigmaTotal smash::StringProcess::pythia_sigmatot_ |
|
private |
◆ pythia_stringflav_
Pythia8::StringFlav smash::StringProcess::pythia_stringflav_ |
|
private |
An object for the flavor selection in string fragmentation in the case of separate fragmentation function for leading baryon.
Definition at line 181 of file processstring.h.
◆ event_intermediate_
Pythia8::Event smash::StringProcess::event_intermediate_ |
|
private |
event record for intermediate partonic state in the hard string routine
Definition at line 187 of file processstring.h.
The documentation for this class was generated from the following files:
std::array< int, 2 > NpartString_
number of particles fragmented from strings
int NpartFinal_
total number of final state particles
double normal(const T &mean, const T &sigma)
Returns a random number drawn from a normal distribution.
std::array< ThreeVector, 3 > evecBasisAB_
Orthonormal basis vectors in the center of mass frame, where the 0th one is parallel to momentum of i...
static constexpr int LOutput
double stringz_b_produce_
parameter (StringZ:bLund) for the fragmentation function of other (produced) hadrons in soft non-diff...
int append_final_state(ParticleList &intermediate_particles, const FourVector &uString, const ThreeVector &evecLong)
compute the formation time and fill the arrays with final-state particles as described in Andersson:1...
double stringz_b_leading_
parameter (StringZ:bLund) for the fragmentation function of leading baryon in soft non-diffractive st...
T beta_a0(T xmin, T b)
Draws a random number from a beta-distribution with a = 0.
void compose_string_parton(bool find_forward_string, Pythia8::Event &event_intermediate, Pythia8::Event &event_hadronize)
Identify a set of partons, which are connected to form a color-neutral string, from a given PYTHIA ev...
double massB_
mass of incoming particle B [GeV]
static void make_string_ends(const PdgCode &pdgcode_in, int &idq1, int &idq2, double xi)
make a random selection to determine partonic contents at the string ends.
std::array< FourVector, 2 > plab_
momenta of incoming particles in the lab frame [GeV]
static Pythia8::Vec4 set_Vec4(double energy, const ThreeVector &mom)
Easy setter of Pythia Vec4 from SMASH.
Pythia8::SigmaTotal pythia_sigmatot_
An object to compute cross-sections.
static std::pair< int, int > find_leading(int nq1, int nq2, ParticleList &list)
Find the leading string fragments.
std::array< FourVector, 2 > pcom_
momenta of incoming particles in the center of mass frame [GeV]
double sqrtsAB_
sqrt of Mandelstam variable s of collision [GeV]
double prob_proton_to_d_uu_
Probability of splitting a nucleon into the quark flavour it has only once and a diquark it has twice...
bool separate_fragment_baryon_
Whether to use a separate fragmentation function for leading baryons.
void find_total_number_constituent(Pythia8::Event &event_intermediate, std::array< int, 5 > &nquark_total, std::array< int, 5 > &nantiq_total)
Compute how many quarks and antiquarks we have in the system, and update the correspoing arrays with ...
constexpr double small_number
Physical error tolerance.
void rearrange_excess(std::array< int, 5 > &nquark_total, std::array< std::array< int, 5 >, 2 > &excess_quark, std::array< std::array< int, 5 >, 2 > &excess_antiq)
Take total number of quarks and check if the system has enough constituents that need to be converted...
void replace_constituent(Pythia8::Particle &particle, std::array< int, 5 > &excess_constituent)
Convert a partonic PYTHIA particle into the desired species and update the excess of constituents.
double time_formation_const_
constant proper time in the case of constant formation time [fm]
std::unique_ptr< Pythia8::Pythia > pythia_hadron_
PYTHIA object used in fragmentation.
bool pythia_parton_initialized_
Remembers if Pythia is initialized or not.
T uniform_int(T min, T max)
bool set_mass_and_direction_2strings(const std::array< std::array< int, 2 >, 2 > &quarks, const std::array< FourVector, 2 > &pstr_com, std::array< double, 2 > &m_str, std::array< ThreeVector, 2 > &evec_str)
Determine string masses and directions in which strings are stretched.
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
T beta(T a, T b)
Draws a random number from a beta-distribution, where probability density of is .
double PNegA_
backward lightcone momentum p^{-} of incoming particle A in CM-frame [GeV]
double pmin_gluon_lightcone_
the minimum lightcone momentum scale carried by a gluon [GeV]
double soft_t_form_
factor to be multiplied to formation times in soft strings
std::array< PdgCode, 2 > PDGcodes_
PdgCodes of incoming particles.
T pCM(const T sqrts, const T mass_a, const T mass_b) noexcept
constexpr double really_small
Numerical error tolerance.
static const ParticleType & find(PdgCode pdgcode)
Returns the ParticleType object for the given pdgcode.
double PPosB_
forward lightcone momentum p^{+} of incoming particle B in CM-frame [GeV]
void compute_incoming_lightcone_momenta()
compute the lightcone momenta of incoming particles where the longitudinal direction is set to be sam...
void shift_rapidity_event(Pythia8::Event &event, std::array< ThreeVector, 3 > &evec_basis, double factor_yrapid, double diff_yrapid)
Shift the momentum rapidity of all particles in a given event record.
static void quarks_from_diquark(int diquark, int &q1, int &q2, int °_spin)
find two quarks from a diquark.
int fragment_string(int idq1, int idq2, double mString, ThreeVector &evecLong, bool flip_string_ends, bool separate_fragment_baryon, ParticleList &intermediate_particles)
perform string fragmentation to determine species and momenta of hadrons by implementing PYTHIA 8....
static int diquark_from_quarks(int q1, int q2)
Construct diquark from two quarks.
static void assign_scaling_factor(int nquark, ParticleData &data, double suppression_factor)
Assign a cross section scaling factor to the given particle.
static void make_orthonormal_basis(ThreeVector &evec_polar, std::array< ThreeVector, 3 > &evec_basis)
compute three orthonormal basis vectors from unit vector in the longitudinal direction
Pythia8::Event event_intermediate_
event record for intermediate partonic state in the hard string routine
std::unique_ptr< Pythia8::Pythia > pythia_parton_
PYTHIA object used in hard string routine.
static constexpr int LPythia
void find_junction_leg(bool sign_color, std::vector< int > &col, Pythia8::Event &event_intermediate, Pythia8::Event &event_hadronize)
Identify partons, which are associated with junction legs, from a given PYTHIA event record.
bool mass_dependent_formation_times_
Whether the formation time should depend on the mass of the fragment according to Andersson:1983ia e...
int get_index_forward(bool find_forward, int np_end, Pythia8::Event &event)
Obtain index of the most forward or backward particle in a given PYTHIA event record.
static int pdg_map_for_pythia(PdgCode &pdg)
Take pdg code and map onto particle specie which can be handled by PYTHIA.
double PNegB_
backward lightcone momentum p^{-} of incoming particle B in CM-frame [GeV]
static void convert_KaonLS(int &pythia_id)
convert Kaon-L or Kaon-S into K0 or Anti-K0
static void assign_all_scaling_factors(int baryon_string, ParticleList &outgoing_particles, const ThreeVector &evecLong, double suppression_factor)
Assign a cross section scaling factor to all outgoing particles.
double pow_fquark_beta_
parameter for the quark distribution function
ThreeVector velocity() const
Get the velocity (3-vector divided by zero component).
double stringz_a_produce_
parameter (StringZ:aLund) for the fragmentation function of other (produced) hadrons in soft non-diff...
static void find_excess_constituent(PdgCode &pdg_actual, PdgCode &pdg_mapped, std::array< int, 5 > &excess_quark, std::array< int, 5 > &excess_antiq)
Compare the valence quark contents of the actual and mapped hadrons and evaluate how many more consti...
double sigma_qperp_
Transverse momentum spread of the excited strings.
void common_setup_pythia(Pythia8::Pythia *pythia_in, double strange_supp, double diquark_supp, double popcorn_rate, double stringz_a, double stringz_b, double string_sigma_T)
Common setup of PYTHIA objects for soft and hard string routines.
bool splitting_gluon_qqbar(Pythia8::Event &event_intermediate, std::array< int, 5 > &nquark_total, std::array< int, 5 > &nantiq_total, bool sign_constituent, std::array< std::array< int, 5 >, 2 > &excess_constituent)
Take total number of quarks and check if the system has enough constituents that need to be converted...
FourVector ucomAB_
velocity four vector of the center of mass in the lab frame
constexpr T pow_int(const T base, unsigned const exponent)
Efficient template for calculating integer powers using squaring.
static FourVector reorient(Pythia8::Particle &particle, std::array< ThreeVector, 3 > &evec_basis)
compute the four-momentum properly oriented in the lab frame.
T power(T n, T xMin, T xMax)
Draws a random number according to a power-law distribution ~ x^n.
static double sample_zLund(double a, double b, double mTrn)
Sample lightcone momentum fraction according to the LUND fragmentation function.
Pythia8::StringFlav pythia_stringflav_
An object for the flavor selection in string fragmentation in the case of separate fragmentation func...
double additional_xsec_supp_
additional cross-section suppression factor to take coherence effect into account.
bool make_final_state_2strings(const std::array< std::array< int, 2 >, 2 > &quarks, const std::array< FourVector, 2 > &pstr_com, const std::array< double, 2 > &m_str, const std::array< ThreeVector, 2 > &evec_str, bool flip_string_ends, bool separate_fragment_baryon)
Prepare kinematics of two strings, fragment them and append to final_state.
bool remake_kinematics_fragments(Pythia8::Event &event_fragments, std::array< ThreeVector, 3 > &evec_basis, double ppos_string, double pneg_string, double QTrx_string, double QTry_string, double QTrx_add_pos, double QTry_add_pos, double QTrx_add_neg, double QTry_add_neg)
static bool append_intermediate_list(int pdgid, FourVector momentum, ParticleList &intermediate_particles)
append new particle from PYTHIA to a specific particle list
void compose_string_junction(bool &find_forward_string, Pythia8::Event &event_intermediate, Pythia8::Event &event_hadronize)
Identify a set of partons and junction(s), which are connected to form a color-neutral string,...
double stringz_a_leading_
parameter (StringZ:aLund) for the fragmentation function of leading baryon in soft non-diffractive st...
double time_collision_
time of collision in the computational frame [fm]
ThreeVector vcomAB_
velocity three vector of the center of mass in the lab frame
double PPosA_
forward lightcone momentum p^{+} of incoming particle A in CM-frame [GeV]
double pow_fgluon_beta_
parameter for the gluon distribution function
bool make_lightcone_final_two(bool separate_fragment_hadron, double ppos_string, double pneg_string, double mTrn_had_forward, double mTrn_had_backward, double &ppos_had_forward, double &ppos_had_backward, double &pneg_had_forward, double &pneg_had_backward)
Determines lightcone momenta of two final hadrons fragmented from a string in the same way as StringF...
double pow_fquark_alpha_
parameter for the quark distribution function
double kappa_tension_string_
string tension [GeV/fm]
bool restore_constituent(Pythia8::Event &event_intermediate, std::array< std::array< int, 5 >, 2 > &excess_quark, std::array< std::array< int, 5 >, 2 > &excess_antiq)
Take the intermediate partonic state from PYTHIA event with mapped hadrons and convert constituents i...
constexpr double kaon_mass
Kaon mass in GeV.
int fragment_off_hadron(bool from_forward, bool separate_fragment_baryon, std::array< ThreeVector, 3 > &evec_basis, double &ppos_string, double &pneg_string, double &QTrx_string_pos, double &QTrx_string_neg, double &QTry_string_pos, double &QTry_string_neg, Pythia8::FlavContainer &flav_string_pos, Pythia8::FlavContainer &flav_string_neg, std::vector< int > &pdgid_frag, std::vector< FourVector > &momentum_frag)
Fragment one hadron from a given string configuration if the string mass is above threshold (given by...
constexpr int maximum_rndm_seed_in_pythia
The maximum value of the random seed used in PYTHIA.
constexpr double pion_mass
Pion mass in GeV.
ParticleList final_state_
final state array which must be accessed after the collision
static const ParticleTypeList & list_all()
double massA_
mass of incoming particle A [GeV]
T pCM_sqr(const T sqrts, const T mass_a, const T mass_b) noexcept