 |
Version: SMASH-2.0
|
|
#include <stringprocess.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 [46].
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 45 of file stringprocess.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...
|
|
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 [43]. 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 [24]. 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...
|
|
void | clear_final_state () |
| a function that clears the final state particle list which is used for testing mainly 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 [46]. 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...
|
|
|
typedef std::map< std::pair< int, int >, std::unique_ptr< Pythia8::Pythia > > | pythia_map |
| Map containing PYTHIA objects for hard string routines. More...
|
|
◆ pythia_map
Map containing PYTHIA objects for hard string routines.
Particle IDs are used as the keys to obtain the respective object. This was introduced to reduce the amount of Pythia init() calls.
Definition at line 178 of file stringprocess.h.
◆ 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)
-
pythia8302/share/Pythia8/xmldoc/FlavourSelection.xml
-
pythia8302/share/Pythia8/xmldoc/Fragmentation.xml
-
pythia8302/share/Pythia8/xmldoc/MasterSwitches.xml
-
pythia8302/share/Pythia8/xmldoc/MultipartonInteractions.xml
Definition at line 21 of file stringprocess.cc.
51 pythia_hadron_ = make_unique<Pythia8::Pythia>(PYTHIA_XML_DIR,
false);
55 popcorn_rate, stringz_a, stringz_b, string_sigma_T);
80 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
- pythia8302/share/Pythia8/xmldoc/FlavourSelection.xml
-
pythia8302/share/Pythia8/xmldoc/Fragmentation.xml
Definition at line 87 of file stringprocess.cc.
94 pythia_in->readString(
"ParticleData:modeBreitWigner = 4");
97 pythia_in->readString(
"MultipartonInteractions:pTmin = 1.5");
98 pythia_in->readString(
"MultipartonInteractions:nSample = 10000");
100 pythia_in->readString(
"StringPT:sigma = " + std::to_string(string_sigma_T));
102 pythia_in->readString(
"StringFlav:probQQtoQ = " +
103 std::to_string(diquark_supp));
105 pythia_in->readString(
"StringFlav:probStoUD = " +
106 std::to_string(strange_supp));
107 pythia_in->readString(
"StringFlav:popcornRate = " +
108 std::to_string(popcorn_rate));
110 pythia_in->readString(
"StringZ:aLund = " + std::to_string(stringz_a));
111 pythia_in->readString(
"StringZ:bLund = " + std::to_string(stringz_b));
114 pythia_in->readString(
"PDF:pSet = 13");
115 pythia_in->readString(
"PDF:pSetB = 13");
116 pythia_in->readString(
"PDF:piSet = 1");
117 pythia_in->readString(
"PDF:piSetB = 1");
118 pythia_in->readString(
"Beams:idA = 2212");
119 pythia_in->readString(
"Beams:idB = 2212");
120 pythia_in->readString(
"Beams:eCM = 10.");
123 pythia_in->readString(
"Random:setSeed = on");
125 pythia_in->readString(
"Print:quiet = on");
127 pythia_in->readString(
"HadronLevel:Decay = off");
130 int pdgid = ptype.pdgcode().get_decimal();
131 double mass_pole = ptype.mass();
132 double width_pole = ptype.width_at_pole();
134 if (pythia_in->particleData.isParticle(pdgid)) {
136 pythia_in->particleData.m0(pdgid, mass_pole);
137 pythia_in->particleData.mWidth(pdgid, width_pole);
138 }
else if (pdgid == 310 || pdgid == 130) {
140 pythia_in->particleData.m0(pdgid,
kaon_mass);
141 pythia_in->particleData.mWidth(pdgid, 0.);
146 pythia_in->readString(
"Check:epTolErr = 1e-6");
147 pythia_in->readString(
"Check:epTolWarn = 1e-8");
◆ init_pythia_hadron_rndm()
void smash::StringProcess::init_pythia_hadron_rndm |
( |
| ) |
|
|
inline |
◆ 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 [43].
- 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 309 of file stringprocess.h.
312 double sqrts_threshold = 2. * (1. + 1.0e-6);
315 const int pdg_a_mod =
316 (std::abs(pdg_a) > 1000) ? pdg_a : 10 * (std::abs(pdg_a) / 10) + 3;
317 const int pdg_b_mod =
318 (std::abs(pdg_b) > 1000) ? pdg_b : 10 * (std::abs(pdg_b) / 10) + 3;
323 if (sqrt_s < sqrts_threshold) {
324 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 345 of file stringprocess.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 355 of file stringprocess.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 364 of file stringprocess.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 372 of file stringprocess.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 377 of file stringprocess.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 207 of file stringprocess.cc.
210 massA_ = incoming[0].effective_mass();
211 massB_ = incoming[1].effective_mass();
213 plab_[0] = incoming[0].momentum();
214 plab_[1] = incoming[1].momentum();
225 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 1630 of file stringprocess.cc.
1632 assert(std::fabs(evec_polar.sqr() - 1.) <
really_small);
1634 if (std::abs(evec_polar.x3()) < (1. - 1.0e-8)) {
1639 evec_basis[0] = evec_polar;
1641 theta = std::acos(evec_basis[0].x3());
1643 ex = evec_basis[0].x1();
1644 ey = evec_basis[0].x2();
1645 et = std::sqrt(ex * ex + ey * ey);
1647 phi = std::acos(ex / et);
1649 phi = -std::acos(ex / et);
1654 evec_basis[1].set_x1(std::cos(theta) * std::cos(phi));
1655 evec_basis[1].set_x2(std::cos(theta) * std::sin(phi));
1656 evec_basis[1].set_x3(-std::sin(theta));
1658 evec_basis[2].set_x1(-std::sin(phi));
1659 evec_basis[2].set_x2(std::cos(phi));
1660 evec_basis[2].set_x3(0.);
1663 if (evec_polar.x3() > 0.) {
1664 evec_basis[1] = ThreeVector(1., 0., 0.);
1665 evec_basis[2] = ThreeVector(0., 1., 0.);
1666 evec_basis[0] = ThreeVector(0., 0., 1.);
1668 evec_basis[1] = ThreeVector(0., 1., 0.);
1669 evec_basis[2] = ThreeVector(1., 0., 0.);
1670 evec_basis[0] = ThreeVector(0., 0., -1.);
1674 assert(std::fabs(evec_basis[1] * evec_basis[2]) <
really_small);
1675 assert(std::fabs(evec_basis[2] * evec_basis[0]) <
really_small);
1676 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 1679 of file stringprocess.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 318 of file stringprocess.cc.
322 std::array<bool, 2> found_mass;
323 for (
int i = 0; i < 2; i++) {
324 found_mass[i] =
false;
326 m_str[i] = pstr_com[i].sqr();
327 m_str[i] = (m_str[i] > 0.) ? std::sqrt(m_str[i]) : 0.;
328 const double threshold =
pythia_hadron_->particleData.m0(quarks[i][0]) +
331 if (m_str[i] > threshold) {
332 found_mass[i] =
true;
345 const ThreeVector mom =
pcom_[i].threevec();
346 const FourVector pnull(mom.abs(), mom);
347 const FourVector prs = pnull.lorentz_boost(pstr_com[i].velocity());
348 evec_str[i] = prs.threevec() / prs.threevec().abs();
352 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 355 of file stringprocess.cc.
361 const std::array<FourVector, 2> ustr_com = {pstr_com[0] / m_str[0],
362 pstr_com[1] / m_str[1]};
363 for (
int i = 0; i < 2; i++) {
364 ParticleList new_intermediate_particles;
367 ThreeVector evec = evec_str[i];
369 int nfrag =
fragment_string(quarks[i][0], quarks[i][1], m_str[i], evec,
370 flip_string_ends, separate_fragment_baryon,
371 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 [24].
- 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 236 of file stringprocess.cc.
247 double QTrn, QTrx, QTry;
248 double pabscomHX_sqr, massX;
257 if (mstrMin > mstrMax) {
263 QTrn = std::sqrt(QTrx * QTrx + QTry * QTry);
270 const bool foundPabsX = pabscomHX_sqr > QTrn * QTrn;
275 double sign_direction = is_AB_to_AX ? 1. : -1.;
277 const ThreeVector cm_momentum =
279 (
evecBasisAB_[0] * std::sqrt(pabscomHX_sqr - QTrn * QTrn) +
281 const FourVector pstrHcom(std::sqrt(pabscomHX_sqr + massH * massH),
283 const FourVector pstrXcom(std::sqrt(pabscomHX_sqr + massX * massX),
286 const FourVector ustrXcom = pstrXcom / massX;
290 const ThreeVector threeMomentum =
291 is_AB_to_AX ?
pcom_[1].threevec() :
pcom_[0].threevec();
292 const FourVector pnull = FourVector(threeMomentum.abs(), threeMomentum);
293 const FourVector prs = pnull.lorentz_boost(ustrXcom.velocity());
294 ThreeVector evec = prs.threevec() / prs.threevec().abs();
296 ParticleList new_intermediate_particles;
298 new_intermediate_particles);
309 new_particle.set_4momentum(pstrHcom);
310 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 388 of file stringprocess.cc.
394 std::array<std::array<int, 2>, 2> quarks;
395 std::array<FourVector, 2> pstr_com;
396 std::array<double, 2> m_str;
397 std::array<ThreeVector, 2> evec_str;
398 ThreeVector threeMomentum;
407 const double xfracA =
409 const double xfracB =
414 const double QTrn = std::sqrt(QTrx * QTrx + QTry * QTry);
416 const double QPos = -QTrn * QTrn / (2. * xfracB *
PNegB_);
417 const double QNeg = QTrn * QTrn / (2. * xfracA *
PPosA_);
423 FourVector((
PPosA_ + QPos +
PNegA_ + QNeg) * M_SQRT1_2, threeMomentum);
429 FourVector((
PPosB_ - QPos +
PNegB_ - QNeg) * M_SQRT1_2, threeMomentum);
431 const bool found_masses =
436 const bool flip_string_ends =
true;
438 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 443 of file stringprocess.cc.
449 std::array<std::array<int, 2>, 2> quarks;
450 std::array<FourVector, 2> pstr_com;
451 std::array<double, 2> m_str;
452 std::array<ThreeVector, 2> evec_str;
455 int idqA1, idqA2, idqB1, idqB2;
459 const int bar_a =
PDGcodes_[0].baryon_number(),
462 (bar_a == 0 && bar_b == 1) ||
463 (bar_a == 0 && bar_b == 0)) {
464 quarks[0][0] = idqB1;
465 quarks[0][1] = idqA2;
466 quarks[1][0] = idqA1;
467 quarks[1][1] = idqB2;
468 }
else if (((bar_a == 0) && (bar_b == -1)) ||
471 quarks[0][0] = idqA1;
472 quarks[0][1] = idqB2;
473 quarks[1][0] = idqB1;
474 quarks[1][1] = idqA2;
476 std::stringstream ss;
477 ss <<
" StringProcess::next_NDiff : baryonA = " << bar_a
478 <<
", baryonB = " << bar_b;
479 throw std::runtime_error(ss.str());
487 const double QTrn = std::sqrt(QTrx * QTrx + QTry * QTry);
489 const double QPos = -QTrn * QTrn / (2. * xfracB *
PNegB_);
490 const double QNeg = QTrn * QTrn / (2. * xfracA *
PPosA_);
491 const double dPPos = -xfracA *
PPosA_ - QPos;
492 const double dPNeg = xfracB *
PNegB_ - QNeg;
494 ThreeVector threeMomentum =
498 FourVector((
PPosA_ + dPPos +
PNegA_ + dPNeg) * M_SQRT1_2, threeMomentum);
499 m_str[0] = pstr_com[0].sqr();
505 FourVector((
PPosB_ - dPPos +
PNegB_ - dPNeg) * M_SQRT1_2, threeMomentum);
507 const bool found_masses =
512 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 520 of file stringprocess.cc.
527 std::array<int, 2> pdg_for_pythia;
528 std::array<std::array<int, 5>, 2> excess_quark;
529 std::array<std::array<int, 5>, 2> excess_antiq;
530 for (
int i = 0; i < 2; i++) {
531 for (
int j = 0; j < 5; j++) {
532 excess_quark[i][j] = 0;
533 excess_antiq[i][j] = 0;
539 " is mapped onto ", pdg_for_pythia[i]);
541 PdgCode pdgcode_for_pythia(std::to_string(pdg_for_pythia[i]));
546 logg[
LPythia].debug(
" excess_quark[", i,
"] = (", excess_quark[i][0],
547 ", ", excess_quark[i][1],
", ", excess_quark[i][2],
548 ", ", excess_quark[i][3],
", ", excess_quark[i][4],
550 logg[
LPythia].debug(
" excess_antiq[", i,
"] = (", excess_antiq[i][0],
551 ", ", excess_antiq[i][1],
", ", excess_antiq[i][2],
552 ", ", excess_antiq[i][3],
", ", excess_antiq[i][4],
556 std::pair<int, int> idAB{pdg_for_pythia[0], pdg_for_pythia[1]};
561 hard_map_[idAB] = make_unique<Pythia8::Pythia>(PYTHIA_XML_DIR,
false);
562 hard_map_[idAB]->readString(
"SoftQCD:nonDiffractive = on");
563 hard_map_[idAB]->readString(
"MultipartonInteractions:pTmin = 1.5");
564 hard_map_[idAB]->readString(
"HadronLevel:all = off");
570 hard_map_[idAB]->settings.flag(
"Beams:allowVariableEnergy",
true);
572 hard_map_[idAB]->settings.mode(
"Beams:idA", idAB.first);
573 hard_map_[idAB]->settings.mode(
"Beams:idB", idAB.second);
576 logg[
LPythia].debug(
"Pythia object initialized with ", pdg_for_pythia[0],
577 " + ", pdg_for_pythia[1],
" at CM energy [GeV] ",
581 throw std::runtime_error(
"Pythia failed to initialize.");
589 logg[
LPythia].debug(
"hard_map_[", idAB.first,
"][", idAB.second,
590 "] : rndm is initialized with seed ", seed_new);
598 logg[
LPythia].debug(
"Pythia final state computed, success = ",
599 final_state_success);
600 if (!final_state_success) {
604 ParticleList new_intermediate_particles;
605 ParticleList new_non_hadron_particles;
607 Pythia8::Vec4 pSum = 0.;
612 for (
int i = 0; i <
hard_map_[idAB]->event.size(); i++) {
613 if (
hard_map_[idAB]->event[i].isFinal()) {
614 const int pdgid =
hard_map_[idAB]->event[i].id();
615 Pythia8::Vec4 pquark =
hard_map_[idAB]->event[i].p();
616 const double mass =
hard_map_[idAB]->particleData.m0(pdgid);
618 const int status =
hard_map_[idAB]->event[i].status();
619 const int color =
hard_map_[idAB]->event[i].col();
620 const int anticolor =
hard_map_[idAB]->event[i].acol();
628 for (
int i = 0; i <
hard_map_[idAB]->event.sizeJunction(); i++) {
629 const int kind =
hard_map_[idAB]->event.kindJunction(i);
630 std::array<int, 3> col;
631 for (
int j = 0; j < 3; j++) {
632 col[j] =
hard_map_[idAB]->event.colJunction(i, j);
644 bool correct_constituents =
646 if (!correct_constituents) {
647 logg[
LPythia].debug(
"failed to find correct partonic constituents.");
653 while (ipart < npart) {
657 !
hard_map_[idAB]->particleData.isOctetHadron(pdgid)) {
658 logg[
LPythia].debug(
"PDG ID from Pythia: ", pdgid);
660 logg[
LPythia].debug(
"4-momentum from Pythia: ", momentum);
665 " does not exist in ParticleType - start over.");
666 final_state_success =
false;
675 bool hadronize_success =
false;
676 bool find_forward_string =
true;
677 logg[
LPythia].debug(
"Hard non-diff: partonic process gives ",
684 logg[
LPythia].debug(
" Dummy event in hard string routine failed.");
685 hadronize_success =
false;
702 logg[
LPythia].debug(
"Pythia hadronized, success = ", hadronize_success);
704 new_intermediate_particles.clear();
705 if (hadronize_success) {
706 for (
int i = 0; i < event_hadron.size(); i++) {
707 if (event_hadron[i].isFinal()) {
708 int pythia_id = event_hadron[i].id();
709 logg[
LPythia].debug(
"PDG ID from Pythia: ", pythia_id);
722 logg[
LPythia].debug(
"4-momentum from Pythia: ", momentum);
723 logg[
LPythia].debug(
"appending the particle ", pythia_id,
724 " to the intermediate particle list.");
725 bool found_ptype =
false;
726 if (event_hadron[i].isHadron()) {
728 new_intermediate_particles);
731 new_non_hadron_particles);
735 " does not exist in ParticleType - start over.");
736 hadronize_success =
false;
744 if (!hadronize_success) {
748 FourVector uString = FourVector(1., 0., 0., 0.);
753 find_forward_string = !find_forward_string;
756 if (hadronize_success) {
758 for (ParticleData data : new_non_hadron_particles) {
759 data.set_cross_section_scaling_factor(1.);
767 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 1519 of file stringprocess.cc.
1520 const std::array<FourVector, 2> ustrcom = {FourVector(1., 0., 0., 0.),
1521 FourVector(1., 0., 0., 0.)};
1533 if (baryon.baryon_number() == -1) {
1534 std::swap(baryon, antibaryon);
1536 if (baryon.baryon_number() != 1 || antibaryon.baryon_number() != -1) {
1537 throw std::invalid_argument(
"Expected baryon-antibaryon pair.");
1541 constexpr
int n_q_types = 5;
1542 std::vector<int> qcount_bar, qcount_antibar;
1543 std::vector<int> n_combinations;
1544 bool no_combinations =
true;
1545 for (
int i = 0; i < n_q_types; i++) {
1546 qcount_bar.push_back(baryon.net_quark_number(i + 1));
1547 qcount_antibar.push_back(-antibaryon.net_quark_number(i + 1));
1548 const int n_i = qcount_bar[i] * qcount_antibar[i];
1549 n_combinations.push_back(n_i);
1551 no_combinations =
false;
1557 if (no_combinations) {
1558 for (
int i = 0; i < 2; i++) {
1561 new_particle.set_4momentum(
pcom_[i]);
1562 new_particle.set_cross_section_scaling_factor(1.);
1571 auto discrete_distr = random::discrete_dist<int>(n_combinations);
1572 const int q_annihilate = discrete_distr() + 1;
1573 qcount_bar[q_annihilate - 1]--;
1574 qcount_antibar[q_annihilate - 1]--;
1577 std::vector<int> remaining_quarks, remaining_antiquarks;
1578 for (
int i = 0; i < n_q_types; i++) {
1579 for (
int j = 0; j < qcount_bar[i]; j++) {
1580 remaining_quarks.push_back(i + 1);
1582 for (
int j = 0; j < qcount_antibar[i]; j++) {
1583 remaining_antiquarks.push_back(-(i + 1));
1586 assert(remaining_quarks.size() == 2);
1587 assert(remaining_antiquarks.size() == 2);
1593 std::swap(remaining_quarks[0], remaining_quarks[1]);
1596 std::swap(remaining_antiquarks[0], remaining_antiquarks[1]);
1599 bool kin_threshold_satisfied =
true;
1600 for (
int i = 0; i < 2; i++) {
1601 const double mstr_min =
1604 if (mstr_min > mstr[i]) {
1605 kin_threshold_satisfied =
false;
1608 if (!kin_threshold_satisfied) {
1612 for (
int i = 0; i < 2; i++) {
1613 ParticleList new_intermediate_particles;
1615 ThreeVector evec =
pcom_[i].threevec() /
pcom_[i].threevec().abs();
1617 fragment_string(remaining_quarks[i], remaining_antiquarks[i], mstr[i],
1618 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 770 of file stringprocess.cc.
776 std::array<int, 3> qcontent_actual = pdg_actual.quark_content();
777 std::array<int, 3> qcontent_mapped = pdg_mapped.quark_content();
779 excess_quark = {0, 0, 0, 0, 0};
780 excess_antiq = {0, 0, 0, 0, 0};
781 for (
int i = 0; i < 3; i++) {
782 if (qcontent_actual[i] > 0) {
783 int j = qcontent_actual[i] - 1;
784 excess_quark[j] += 1;
787 if (qcontent_mapped[i] > 0) {
788 int j = qcontent_mapped[i] - 1;
789 excess_quark[j] -= 1;
792 if (qcontent_actual[i] < 0) {
793 int j = std::abs(qcontent_actual[i]) - 1;
794 excess_antiq[j] += 1;
797 if (qcontent_mapped[i] < 0) {
798 int j = std::abs(qcontent_mapped[i]) - 1;
799 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 804 of file stringprocess.cc.
807 if (!particle.isQuark() && !particle.isDiquark()) {
812 const std::array<int, 5> excess_null = {0, 0, 0, 0, 0};
813 if (excess_constituent == excess_null) {
818 std::array<int, 2> pdgid = {0, 0};
821 if (particle.isQuark()) {
823 pdgid[0] = particle.id();
824 }
else if (particle.isDiquark()) {
829 for (
int iq = 0; iq < nq; iq++) {
830 int jq = std::abs(pdgid[iq]) - 1;
832 std::vector<int> k_found;
835 if (excess_constituent[jq] < 0) {
836 for (
int k = 0; k < 5; k++) {
838 if (k != jq && excess_constituent[k] > 0) {
839 k_found.push_back(k);
845 if (k_found.size() > 0) {
848 k_select = k_found[l];
851 pdgid[iq] = pdgid[iq] > 0 ? k_select + 1 : -(k_select + 1);
852 excess_constituent[jq] += 1;
853 excess_constituent[k_select] -= 1;
858 if (particle.isQuark()) {
859 pdgid_new = pdgid[0];
860 }
else if (particle.isDiquark()) {
861 if (std::abs(pdgid[0]) < std::abs(pdgid[1])) {
862 std::swap(pdgid[0], pdgid[1]);
865 pdgid_new = std::abs(pdgid[0]) * 1000 + std::abs(pdgid[1]) * 100;
866 if (std::abs(pdgid[0]) == std::abs(pdgid[1])) {
869 pdgid_new += spin_deg;
872 if (particle.id() < 0) {
876 logg[
LPythia].debug(
" parton id = ", particle.id(),
" is converted to ",
880 Pythia8::Vec4 pquark = particle.p();
882 double e_new = std::sqrt(mass_new * mass_new + pquark.pAbs() * pquark.pAbs());
884 particle.id(pdgid_new);
886 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 889 of file stringprocess.cc.
892 for (
int iflav = 0; iflav < 5; iflav++) {
893 nquark_total[iflav] = 0;
894 nantiq_total[iflav] = 0;
897 for (
int ip = 1; ip < event_intermediate.size(); ip++) {
898 if (!event_intermediate[ip].isFinal()) {
901 const int pdgid = event_intermediate[ip].id();
904 for (
int iflav = 0; iflav < 5; iflav++) {
905 nquark_total[iflav] +=
910 for (
int iflav = 0; iflav < 5; iflav++) {
911 nantiq_total[iflav] +=
pythia_hadron_->particleData.nQuarksInCode(
912 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 918 of file stringprocess.cc.
922 Pythia8::Vec4 pSum = event_intermediate[0].p();
928 for (
int iflav = 0; iflav < 5; iflav++) {
935 excess_constituent[0][iflav] + excess_constituent[1][iflav];
936 if (sign_constituent) {
937 nquark_final += nquark_total[iflav];
939 nquark_final += nantiq_total[iflav];
944 bool enough_quark = nquark_final >= 0;
948 logg[
LPythia].debug(
" not enough constituents with flavor ", iflav + 1,
949 " : try to split a gluon to qqbar.");
950 for (
int ic = 0; ic < std::abs(nquark_final); ic++) {
954 if (excess_constituent[0][iflav] < 0) {
963 for (
int ip = 2; ip < event_intermediate.size(); ip++) {
964 if (!event_intermediate[ip].isFinal() ||
965 !event_intermediate[ip].isGluon()) {
969 const double y_gluon_current = event_intermediate[ip].y();
970 const double y_gluon_forward = event_intermediate[iforward].y();
971 if ((ih_mod == 0 && y_gluon_current > y_gluon_forward) ||
972 (ih_mod == 1 && y_gluon_current < y_gluon_forward)) {
977 if (!event_intermediate[iforward].isGluon()) {
978 logg[
LPythia].debug(
"There is no gluon to split into qqbar.");
983 Pythia8::Vec4 pgluon = event_intermediate[iforward].p();
985 const int pdgid = iflav + 1;
987 const int status = event_intermediate[iforward].status();
991 const int col = event_intermediate[iforward].col();
992 const int acol = event_intermediate[iforward].acol();
995 std::array<double, 2> px_quark;
996 std::array<double, 2> py_quark;
997 std::array<double, 2> pz_quark;
999 std::array<double, 2> e_quark;
1001 std::array<Pythia8::Vec4, 2> pquark;
1003 const double sigma_qt_frag =
pythia_hadron_->parm(
"StringPT:sigma");
1008 for (
int isign = 0; isign < 2; isign++) {
1012 px_quark[isign] = 0.5 * pgluon.px() + (isign == 0 ? 1. : -1.) * qx;
1013 py_quark[isign] = 0.5 * pgluon.py() + (isign == 0 ? 1. : -1.) * qy;
1014 pz_quark[isign] = 0.5 * pgluon.pz();
1016 std::sqrt(mass * mass + px_quark[isign] * px_quark[isign] +
1017 py_quark[isign] * py_quark[isign] +
1018 pz_quark[isign] * pz_quark[isign]);
1019 pquark[isign] = Pythia8::Vec4(px_quark[isign], py_quark[isign],
1020 pz_quark[isign], e_quark[isign]);
1025 pSum += pquark[0] + pquark[1] - pgluon;
1027 event_intermediate.append(pdgid, status, col, 0, pquark[0], mass);
1028 event_intermediate.append(-pdgid, status, 0, acol, pquark[1], mass);
1030 event_intermediate.remove(iforward, iforward);
1032 logg[
LPythia].debug(
" gluon at iforward = ", iforward,
1033 " is splitted into ", pdgid,
",", -pdgid,
1037 nquark_total[iflav] += 1;
1038 nantiq_total[iflav] += 1;
1045 event_intermediate[0].p(pSum);
1046 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 1051 of file stringprocess.cc.
1055 for (
int iflav = 0; iflav < 5; iflav++) {
1062 nquark_total[iflav] + excess_quark[0][iflav] + excess_quark[1][iflav];
1066 bool enough_quark = nquark_final >= 0;
1068 if (!enough_quark) {
1069 logg[
LPythia].debug(
" not enough constituents with flavor ", iflav + 1,
1070 " : try to modify excess of constituents.");
1071 for (
int ic = 0; ic < std::abs(nquark_final); ic++) {
1075 if (excess_quark[0][iflav] < 0) {
1083 excess_quark[ih_mod][iflav] += 1;
1084 excess_antiq[ih_mod][iflav] += 1;
1091 for (
int jflav = 0; jflav < 5; jflav++) {
1093 if (jflav != iflav && excess_quark[ih_mod][jflav] > 0) {
1096 excess_quark[ih_mod][jflav] -= 1;
1097 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 1108 of file stringprocess.cc.
1112 Pythia8::Vec4 pSum = event_intermediate[0].p();
1113 const double energy_init = pSum.e();
1114 logg[
LPythia].debug(
" initial total energy [GeV] : ", energy_init);
1117 std::array<int, 5> nquark_total;
1118 std::array<int, 5> nantiq_total;
1123 event_intermediate, nquark_total, nantiq_total,
true, excess_quark);
1125 event_intermediate, nquark_total, nantiq_total,
false, excess_antiq);
1129 if (!split_for_quark || !split_for_antiq) {
1135 for (
int iflav = 0; iflav < 5; iflav++) {
1136 if (nquark_total[iflav] + excess_quark[0][iflav] + excess_quark[1][iflav] <
1138 logg[
LPythia].debug(
"Not enough quark constituents of flavor ",
1143 if (nantiq_total[iflav] + excess_antiq[0][iflav] + excess_antiq[1][iflav] <
1145 logg[
LPythia].debug(
"Not enough antiquark constituents of flavor ",
1151 for (
int ih = 0; ih < 2; ih++) {
1152 logg[
LPythia].debug(
" initial excess_quark[", ih,
"] = (",
1153 excess_quark[ih][0],
", ", excess_quark[ih][1],
", ",
1154 excess_quark[ih][2],
", ", excess_quark[ih][3],
", ",
1155 excess_quark[ih][4],
")");
1156 logg[
LPythia].debug(
" initial excess_antiq[", ih,
"] = (",
1157 excess_antiq[ih][0],
", ", excess_antiq[ih][1],
", ",
1158 excess_antiq[ih][2],
", ", excess_antiq[ih][3],
", ",
1159 excess_antiq[ih][4],
")");
1162 bool recovered_quarks =
false;
1163 while (!recovered_quarks) {
1166 std::array<bool, 2> find_forward = {
true,
false};
1167 const std::array<int, 5> excess_null = {0, 0, 0, 0, 0};
1168 std::array<int, 5> excess_total = excess_null;
1170 for (
int ih = 0; ih < 2; ih++) {
1171 int nfrag = event_intermediate.size();
1172 for (
int np_end = 0; np_end < nfrag - 1; np_end++) {
1179 pSum -= event_intermediate[iforward].p();
1181 if (event_intermediate[iforward].
id() > 0) {
1184 " excess_quark[", ih,
"] = (", excess_quark[ih][0],
", ",
1185 excess_quark[ih][1],
", ", excess_quark[ih][2],
", ",
1186 excess_quark[ih][3],
", ", excess_quark[ih][4],
")");
1190 " excess_antiq[", ih,
"] = (", excess_antiq[ih][0],
", ",
1191 excess_antiq[ih][1],
", ", excess_antiq[ih][2],
", ",
1192 excess_antiq[ih][3],
", ", excess_antiq[ih][4],
")");
1195 const int pdgid = event_intermediate[iforward].id();
1196 Pythia8::Vec4 pquark = event_intermediate[iforward].p();
1199 const int status = event_intermediate[iforward].status();
1200 const int color = event_intermediate[iforward].col();
1201 const int anticolor = event_intermediate[iforward].acol();
1204 event_intermediate.append(pdgid, status, color, anticolor, pquark,
1207 event_intermediate.remove(iforward, iforward);
1213 for (
int j = 0; j < 5; j++) {
1214 excess_total[j] += (excess_quark[ih][j] - excess_antiq[ih][j]);
1220 recovered_quarks = excess_total == excess_null;
1222 logg[
LPythia].debug(
" valence quark contents of hadons are recovered.");
1224 logg[
LPythia].debug(
" current total energy [GeV] : ", pSum.e());
1228 if (std::abs(pSum.e() - energy_init) <=
1233 double energy_current = pSum.e();
1235 for (
int i = 1; i < event_intermediate.size(); i++) {
1236 slope += event_intermediate[i].pAbs2() / event_intermediate[i].e();
1239 const double rescale_factor = 1. + (energy_init - energy_current) / slope;
1241 for (
int i = 1; i < event_intermediate.size(); i++) {
1242 const double px = rescale_factor * event_intermediate[i].px();
1243 const double py = rescale_factor * event_intermediate[i].py();
1244 const double pz = rescale_factor * event_intermediate[i].pz();
1245 const double pabs = rescale_factor * event_intermediate[i].pAbs();
1246 const double mass = event_intermediate[i].m();
1248 event_intermediate[i].px(px);
1249 event_intermediate[i].py(py);
1250 event_intermediate[i].pz(pz);
1251 event_intermediate[i].e(std::sqrt(mass * mass + pabs * pabs));
1252 pSum += event_intermediate[i].p();
1254 logg[
LPythia].debug(
" parton momenta are rescaled by factor of ",
1258 logg[
LPythia].debug(
" final total energy [GeV] : ", pSum.e());
1261 event_intermediate[0].p(pSum);
1262 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 1267 of file stringprocess.cc.
1270 Pythia8::Vec4 pSum = 0.;
1271 event_hadronize.reset();
1275 logg[
LPythia].debug(
"Hard non-diff: iforward = ", iforward,
"(",
1276 event_intermediate[iforward].
id(),
")");
1278 pSum += event_intermediate[iforward].p();
1279 event_hadronize.append(event_intermediate[iforward]);
1281 int col_to_find = event_intermediate[iforward].acol();
1282 int acol_to_find = event_intermediate[iforward].col();
1283 event_intermediate.remove(iforward, iforward);
1284 logg[
LPythia].debug(
"Hard non-diff: event_intermediate reduces in size to ",
1285 event_intermediate.size());
1288 while (col_to_find != 0 || acol_to_find != 0) {
1289 logg[
LPythia].debug(
" col_to_find = ", col_to_find,
1290 ", acol_to_find = ", acol_to_find);
1293 for (
int i = 1; i < event_intermediate.size(); i++) {
1294 const int pdgid = event_intermediate[i].id();
1296 col_to_find != 0 && col_to_find == event_intermediate[i].col();
1298 acol_to_find != 0 && acol_to_find == event_intermediate[i].acol();
1300 logg[
LPythia].debug(
" col_to_find ", col_to_find,
" from i ", i,
"(",
1304 logg[
LPythia].debug(
" acol_to_find ", acol_to_find,
" from i ", i,
"(",
1308 if (found_col && !found_acol) {
1310 col_to_find = event_intermediate[i].acol();
1312 }
else if (!found_col && found_acol) {
1314 acol_to_find = event_intermediate[i].col();
1316 }
else if (found_col && found_acol) {
1325 event_intermediate.list();
1326 event_intermediate.listJunctions();
1327 event_hadronize.list();
1328 event_hadronize.listJunctions();
1329 if (col_to_find != 0) {
1330 logg[
LPythia].error(
"No parton with col = ", col_to_find);
1332 if (acol_to_find != 0) {
1333 logg[
LPythia].error(
"No parton with acol = ", acol_to_find);
1335 throw std::runtime_error(
"Hard string could not be identified.");
1337 pSum += event_intermediate[ifound].p();
1339 event_hadronize.append(event_intermediate[ifound]);
1341 event_intermediate.remove(ifound, ifound);
1343 "Hard non-diff: event_intermediate reduces in size to ",
1344 event_intermediate.size());
1350 event_hadronize[0].p(pSum);
1351 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 1354 of file stringprocess.cc.
1357 event_hadronize.reset();
1365 const int kind = event_intermediate.kindJunction(0);
1366 bool sign_color = kind % 2 == 1;
1367 std::vector<int> col;
1368 for (
int j = 0; j < 3; j++) {
1369 col.push_back(event_intermediate.colJunction(0, j));
1371 event_hadronize.appendJunction(kind, col[0], col[1], col[2]);
1372 event_intermediate.eraseJunction(0);
1373 logg[
LPythia].debug(
"junction (", col[0],
", ", col[1],
", ", col[2],
1374 ") with kind ", kind,
" will be handled.");
1376 bool found_string =
false;
1377 while (!found_string) {
1380 found_string =
true;
1381 for (
unsigned int j = 0; j < col.size(); j++) {
1382 found_string = found_string && col[j] == 0;
1384 if (!found_string) {
1387 logg[
LPythia].debug(
" still has leg(s) unfinished.");
1388 sign_color = !sign_color;
1389 std::vector<int> junction_to_move;
1390 for (
int i = 0; i < event_intermediate.sizeJunction(); i++) {
1391 const int kind_new = event_intermediate.kindJunction(i);
1395 if (sign_color != (kind_new % 2 == 1)) {
1399 std::array<int, 3> col_new;
1400 for (
int k = 0; k < 3; k++) {
1401 col_new[k] = event_intermediate.colJunction(i, k);
1404 int n_legs_connected = 0;
1406 for (
unsigned int j = 0; j < col.size(); j++) {
1410 for (
int k = 0; k < 3; k++) {
1411 if (col[j] == col_new[k]) {
1412 n_legs_connected += 1;
1420 if (n_legs_connected > 0) {
1421 for (
int k = 0; k < 3; k++) {
1422 if (col_new[k] != 0) {
1423 col.push_back(col_new[k]);
1427 event_intermediate.colJunction(i, 0),
", ",
1428 event_intermediate.colJunction(i, 1),
", ",
1429 event_intermediate.colJunction(i, 2),
1430 ") with kind ", kind_new,
" will be added.");
1431 junction_to_move.push_back(i);
1437 for (
unsigned int i = 0; i < junction_to_move.size(); i++) {
1438 unsigned int imove = junction_to_move[i] - i;
1439 const int kind_add = event_intermediate.kindJunction(imove);
1440 std::array<int, 3> col_add;
1441 for (
int k = 0; k < 3; k++) {
1442 col_add[k] = event_intermediate.colJunction(imove, k);
1445 event_hadronize.appendJunction(kind_add, col_add[0], col_add[1],
1448 event_intermediate.eraseJunction(imove);
1453 Pythia8::Vec4 pSum = event_hadronize[0].p();
1454 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 1457 of file stringprocess.cc.
1460 Pythia8::Vec4 pSum = event_hadronize[0].p();
1461 for (
unsigned int j = 0; j < col.size(); j++) {
1465 bool found_leg =
false;
1466 while (!found_leg) {
1468 for (
int i = 1; i < event_intermediate.size(); i++) {
1469 const int pdgid = event_intermediate[i].id();
1470 if (sign_color && col[j] == event_intermediate[i].col()) {
1471 logg[
LPythia].debug(
" col[", j,
"] = ", col[j],
" from i ", i,
"(",
1474 col[j] = event_intermediate[i].acol();
1476 }
else if (!sign_color && col[j] == event_intermediate[i].acol()) {
1477 logg[
LPythia].debug(
" acol[", j,
"] = ", col[j],
" from i ", i,
"(",
1480 col[j] = event_intermediate[i].col();
1487 if (event_intermediate.sizeJunction() == 0) {
1488 event_intermediate.list();
1489 event_intermediate.listJunctions();
1490 event_hadronize.list();
1491 event_hadronize.listJunctions();
1492 logg[
LPythia].error(
"No parton with col = ", col[j],
1493 " connected with junction leg ", j);
1494 throw std::runtime_error(
"Hard string could not be identified.");
1497 pSum += event_intermediate[ifound].p();
1499 event_hadronize.append(event_intermediate[ifound]);
1501 event_intermediate.remove(ifound, ifound);
1503 "Hard non-diff: event_intermediate reduces in size to ",
1504 event_intermediate.size());
1514 event_hadronize[0].p(pSum);
1515 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 754 of file stringprocess.h.
757 for (
int ip = 2; ip <
event.size() - np_end; ip++) {
758 const double y_quark_current =
event[ip].y();
759 const double y_quark_forward =
event[iforward].y();
760 if ((find_forward && y_quark_current > y_quark_forward) ||
761 (!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 773 of file stringprocess.h.
◆ clear_final_state()
void smash::StringProcess::clear_final_state |
( |
| ) |
|
|
inline |
a function that clears the final state particle list which is used for testing mainly
Definition at line 779 of file stringprocess.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 151 of file stringprocess.cc.
157 for (ParticleData &data : intermediate_particles) {
159 bstring += data.pdgcode().baryon_number();
169 const ThreeVector vstring = uString.velocity();
172 for (
int i = 0; i < nfrag; i++) {
173 ThreeVector velocity = intermediate_particles[i].momentum().velocity();
174 double gamma = 1. / intermediate_particles[i].inverse_gamma();
176 FourVector momentum =
177 intermediate_particles[i].momentum().lorentz_boost(-vstring);
178 intermediate_particles[i].set_4momentum(momentum);
182 double tau_prod = M_SQRT2 * intermediate_particles[i].effective_mass() /
184 double t_prod = tau_prod * gamma;
185 FourVector fragment_position = FourVector(t_prod, t_prod * velocity);
188 fragment_position = fragment_position.lorentz_boost(-vstring);
189 fragment_position = fragment_position.lorentz_boost(-
vcomAB_);
190 intermediate_particles[i].set_slow_formation_times(
194 ThreeVector v_calc = momentum.lorentz_boost(-
vcomAB_).velocity();
195 double gamma_factor = 1.0 / std::sqrt(1 - (v_calc).sqr());
196 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 805 of file stringprocess.h.
807 const std::string s = std::to_string(pdgid);
808 PdgCode pythia_code(s);
812 new_particle.set_4momentum(momentum);
813 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 825 of file stringprocess.h.
826 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 1686 of file stringprocess.cc.
1689 assert((std::abs(diquark) > 1000) && (std::abs(diquark) < 5510) &&
1690 (std::abs(diquark) % 100 < 10));
1693 deg_spin = std::abs(diquark) % 10;
1695 const int sign_anti = diquark > 0 ? 1 : -1;
1698 q1 = sign_anti * (std::abs(diquark) - (std::abs(diquark) % 1000)) / 1000;
1699 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 1702 of file stringprocess.cc.
1703 assert((q1 > 0 && q2 > 0) || (q1 < 0 && q2 < 0));
1704 if (std::abs(q1) < std::abs(q2)) {
1707 int diquark = std::abs(q1 * 1000 + q2 * 100);
1712 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 1715 of file stringprocess.cc.
1717 std::array<int, 3> quarks = pdg.quark_content();
1718 if (pdg.is_nucleon()) {
1721 if (pdg.charge() == 0) {
1739 if (pdg.is_meson()) {
1750 assert(pdg.is_baryon());
1759 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 865 of file stringprocess.h.
866 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 880 of file stringprocess.h.
882 ThreeVector three_momentum = evec_basis[0] * particle.pz() +
883 evec_basis[1] * particle.px() +
884 evec_basis[2] * particle.py();
885 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 [46].
- 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 1763 of file stringprocess.cc.
1768 intermediate_particles.clear();
1770 logg[
LPythia].debug(
"initial quark content for fragment_string : ", idq1,
1772 logg[
LPythia].debug(
"initial string mass (GeV) for fragment_string : ",
1775 std::array<int, 2> idqIn;
1781 std::array<double, 2> m_const;
1783 for (
int i = 0; i < 2; i++) {
1785 bstring +=
pythia_hadron_->particleData.baryonNumberType(idqIn[i]);
1789 logg[
LPythia].debug(
"baryon number of string times 3 : ", bstring);
1796 evecLong = -evecLong;
1799 if (m_const[0] + m_const[1] > mString) {
1800 throw std::runtime_error(
"String fragmentation: m1 + m2 > mString");
1802 Pythia8::Vec4 pSum = 0.;
1804 int number_of_fragments = 0;
1805 bool do_string_fragmentation =
false;
1809 double ppos_string_new, pneg_string_new;
1812 double QTrx_string_new, QTry_string_new, QTrn_string_new;
1814 double mTrn_string_new;
1816 double mass_string_new;
1820 double QTrx_add_pos, QTry_add_pos;
1823 double QTrx_add_neg, QTry_add_neg;
1835 std::array<ThreeVector, 3> evec_basis;
1838 if (separate_fragment_baryon && (std::abs(bstring) == 3) &&
1839 (mString > m_const[0] + m_const[1] + 1.)) {
1846 std::vector<int> pdgid_frag_prior;
1849 std::vector<FourVector> momentum_frag_prior;
1852 double QTrx_string_pos;
1854 double QTrx_string_neg;
1856 double QTry_string_pos;
1858 double QTry_string_neg;
1861 double QTrn_string_pos;
1864 double QTrn_string_neg;
1866 std::array<double, 2> m_trans;
1869 const int niter_max = 10000;
1870 bool found_leading_baryon =
false;
1871 for (
int iiter = 0; iiter < niter_max; iiter++) {
1873 pdgid_frag_prior.clear();
1874 momentum_frag_prior.clear();
1876 std::vector<int> pdgid_frag;
1877 std::vector<FourVector> momentum_frag;
1879 ppos_string_new = mString * M_SQRT1_2;
1880 pneg_string_new = mString * M_SQRT1_2;
1882 QTrx_string_pos = 0.;
1883 QTrx_string_neg = 0.;
1884 QTrx_string_new = 0.;
1885 QTry_string_pos = 0.;
1886 QTry_string_neg = 0.;
1887 QTry_string_new = 0.;
1889 Pythia8::FlavContainer flav_string_pos =
1890 bstring > 0 ? Pythia8::FlavContainer(idq2)
1891 : Pythia8::FlavContainer(idq1);
1893 Pythia8::FlavContainer flav_string_neg =
1894 bstring > 0 ? Pythia8::FlavContainer(idq1)
1895 : Pythia8::FlavContainer(idq2);
1897 bool found_forward_baryon =
false;
1899 bool done_forward_end =
false;
1902 bool energy_used_up =
false;
1903 while (!found_forward_baryon && !energy_used_up) {
1914 separate_fragment_baryon && from_forward && !done_forward_end,
1915 evec_basis, ppos_string_new, pneg_string_new, QTrx_string_pos,
1916 QTrx_string_neg, QTry_string_pos, QTry_string_neg, flav_string_pos,
1917 flav_string_neg, pdgid_frag, momentum_frag);
1923 QTrx_string_new = QTrx_string_pos + QTrx_string_neg;
1924 QTry_string_new = QTry_string_pos + QTry_string_neg;
1928 idqIn[0] = bstring > 0 ? flav_string_neg.id : flav_string_pos.id;
1929 idqIn[1] = bstring > 0 ? flav_string_pos.id : flav_string_neg.id;
1930 for (
int i = 0; i < 2; i++) {
1933 QTrn_string_pos = std::sqrt(QTrx_string_pos * QTrx_string_pos +
1934 QTry_string_pos * QTry_string_pos);
1935 QTrn_string_neg = std::sqrt(QTrx_string_neg * QTrx_string_neg +
1936 QTry_string_neg * QTry_string_neg);
1941 m_trans[0] = std::sqrt(m_const[0] * m_const[0] +
1942 QTrn_string_neg * QTrn_string_neg);
1946 m_trans[1] = std::sqrt(m_const[1] * m_const[1] +
1947 QTrn_string_pos * QTrn_string_pos);
1952 m_trans[0] = std::sqrt(m_const[0] * m_const[0] +
1953 QTrn_string_pos * QTrn_string_pos);
1957 m_trans[1] = std::sqrt(m_const[1] * m_const[1] +
1958 QTrn_string_neg * QTrn_string_neg);
1960 done_forward_end = done_forward_end || from_forward;
1961 found_forward_baryon =
1962 found_forward_baryon ||
1967 energy_used_up =
true;
1971 n_frag_prior += n_frag;
1972 for (
int i_frag = 0; i_frag < n_frag; i_frag++) {
1973 pdgid_frag_prior.push_back(pdgid_frag[i_frag]);
1974 momentum_frag_prior.push_back(momentum_frag[i_frag]);
1982 double mTsqr_string = 2. * ppos_string_new * pneg_string_new;
1983 mTrn_string_new = std::sqrt(mTsqr_string);
1984 QTrn_string_new = std::sqrt(QTrx_string_new * QTrx_string_new +
1985 QTry_string_new * QTry_string_new);
1986 if (mTrn_string_new < QTrn_string_new) {
1989 found_leading_baryon =
false;
1993 std::sqrt(mTsqr_string - QTrn_string_new * QTrn_string_new);
1997 if (mass_string_new > m_const[0] + m_const[1]) {
1998 do_string_fragmentation =
true;
1999 found_leading_baryon =
true;
2000 QTrx_add_pos = QTrx_string_pos;
2001 QTry_add_pos = QTry_string_pos;
2002 QTrx_add_neg = QTrx_string_neg;
2003 QTry_add_neg = QTry_string_neg;
2005 found_leading_baryon =
false;
2008 }
else if (n_frag == 2) {
2011 do_string_fragmentation =
false;
2012 found_leading_baryon =
true;
2016 if (found_leading_baryon) {
2020 if (found_leading_baryon) {
2023 for (
int i_frag = 0; i_frag < n_frag_prior; i_frag++) {
2024 logg[
LPythia].debug(
"appending the the fragmented hadron ",
2025 pdgid_frag_prior[i_frag],
2026 " to the intermediate particle list.");
2029 momentum_frag_prior[i_frag],
2030 intermediate_particles);
2032 logg[
LPythia].error(
"PDG ID ", pdgid_frag_prior[i_frag],
2033 " should exist in ParticleType.");
2034 throw std::runtime_error(
"string fragmentation failed.");
2036 number_of_fragments++;
2044 if (do_string_fragmentation) {
2045 mTrn_string_new = std::sqrt(2. * ppos_string_new * pneg_string_new);
2047 std::array<double, 2> ppos_parton;
2049 std::array<double, 2> pneg_parton;
2057 const double pb_const =
2058 (mTrn_string_new * mTrn_string_new + m_trans[0] * m_trans[0] -
2059 m_trans[1] * m_trans[1]) /
2060 (4. * pneg_string_new);
2061 const double pc_const =
2062 0.5 * m_trans[0] * m_trans[0] * ppos_string_new / pneg_string_new;
2063 ppos_parton[0] = pb_const + (bstring > 0 ? -1. : 1.) *
2064 std::sqrt(pb_const * pb_const - pc_const);
2065 ppos_parton[1] = ppos_string_new - ppos_parton[0];
2069 for (
int i = 0; i < 2; i++) {
2070 pneg_parton[i] = 0.5 * m_trans[i] * m_trans[i] / ppos_parton[i];
2073 const int status = 1;
2074 int color, anticolor;
2075 ThreeVector three_mom;
2076 ThreeVector transverse_mom;
2077 Pythia8::Vec4 pquark;
2097 bstring > 0 ? evec_basis[1] * (QTrx_string_neg - QTrx_add_neg) +
2098 evec_basis[2] * (QTry_string_neg - QTry_add_neg)
2099 : evec_basis[1] * (QTrx_string_pos - QTrx_add_pos) +
2100 evec_basis[2] * (QTry_string_pos - QTry_add_pos);
2102 evec_basis[0] * (ppos_parton[0] - pneg_parton[0]) * M_SQRT1_2 +
2104 const double E_quark =
2105 std::sqrt(m_const[0] * m_const[0] + three_mom.sqr());
2106 pquark =
set_Vec4(E_quark, three_mom);
2108 pythia_hadron_->event.append(idqIn[0], status, color, anticolor, pquark,
2129 bstring > 0 ? evec_basis[1] * (QTrx_string_pos - QTrx_add_pos) +
2130 evec_basis[2] * (QTry_string_pos - QTry_add_pos)
2131 : evec_basis[1] * (QTrx_string_neg - QTrx_add_neg) +
2132 evec_basis[2] * (QTry_string_neg - QTry_add_neg);
2134 evec_basis[0] * (ppos_parton[1] - pneg_parton[1]) * M_SQRT1_2 +
2136 const double E_antiq =
2137 std::sqrt(m_const[1] * m_const[1] + three_mom.sqr());
2138 pquark =
set_Vec4(E_antiq, three_mom);
2140 pythia_hadron_->event.append(idqIn[1], status, color, anticolor, pquark,
2144 do_string_fragmentation =
true;
2146 ppos_string_new = mString * M_SQRT1_2;
2147 pneg_string_new = mString * M_SQRT1_2;
2148 QTrx_string_new = 0.;
2149 QTry_string_new = 0.;
2150 QTrn_string_new = 0.;
2151 mTrn_string_new = mString;
2152 mass_string_new = mString;
2157 double sign_direction = 1.;
2158 if (bstring == -3) {
2162 sign_direction = -1;
2166 const double pCMquark =
pCM(mString, m_const[0], m_const[1]);
2167 const double E1 = std::sqrt(m_const[0] * m_const[0] + pCMquark * pCMquark);
2168 const double E2 = std::sqrt(m_const[1] * m_const[1] + pCMquark * pCMquark);
2170 ThreeVector direction = sign_direction * evecLong;
2173 const int status1 = 1, color1 = 1, anticolor1 = 0;
2174 Pythia8::Vec4 pquark =
set_Vec4(E1, -direction * pCMquark);
2176 pythia_hadron_->event.append(idqIn[0], status1, color1, anticolor1, pquark,
2179 const int status2 = 1, color2 = 0, anticolor2 = 1;
2180 pquark =
set_Vec4(E2, direction * pCMquark);
2182 pythia_hadron_->event.append(idqIn[1], status2, color2, anticolor2, pquark,
2186 if (do_string_fragmentation) {
2187 logg[
LPythia].debug(
"fragmenting a string with ", idqIn[0],
", ", idqIn[1]);
2193 if (!successful_hadronization) {
2200 pythia_hadron_->event, evec_basis, ppos_string_new, pneg_string_new,
2201 QTrx_string_new, QTry_string_new, QTrx_add_pos, QTry_add_pos,
2202 QTrx_add_neg, QTry_add_neg);
2203 if (!successful_kinematics) {
2207 for (
int ipyth = 0; ipyth <
pythia_hadron_->event.size(); ipyth++) {
2215 FourVector momentum(
2218 logg[
LPythia].debug(
"appending the fragmented hadron ", pythia_id,
2219 " to the intermediate particle list.");
2224 " does not exist in ParticleType - start over.");
2225 intermediate_particles.clear();
2229 number_of_fragments++;
2232 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 2235 of file stringprocess.cc.
2245 const int n_try = 10;
2247 momentum_frag.clear();
2249 if (ppos_string < 0. || pneg_string < 0.) {
2250 throw std::runtime_error(
"string has a negative lightcone momentum.");
2252 double mTsqr_string = 2. * ppos_string * pneg_string;
2254 double mTrn_string = std::sqrt(mTsqr_string);
2256 double QTrx_string_tot = QTrx_string_pos + QTrx_string_neg;
2257 double QTry_string_tot = QTry_string_pos + QTry_string_neg;
2258 double QTsqr_string_tot = std::fabs(QTrx_string_tot * QTrx_string_tot) +
2259 std::fabs(QTry_string_tot * QTry_string_tot);
2260 double QTrn_string_tot = std::sqrt(QTsqr_string_tot);
2261 if (mTrn_string < QTrn_string_tot) {
2265 double mass_string = std::sqrt(mTsqr_string - QTsqr_string_tot);
2266 logg[
LPythia].debug(
" Fragment off one hadron from a string ( ",
2267 flav_string_pos.id,
" , ", flav_string_neg.id,
2268 " ) with mass ", mass_string,
" GeV.");
2271 const double sigma_qt_frag =
pythia_hadron_->parm(
"StringPT:sigma");
2272 const double stop_string_mass =
2274 const double stop_string_smear =
2278 const double prob_enhance_qt =
2280 double fac_enhance_qt;
2284 fac_enhance_qt = 1.;
2298 logg[
LPythia].debug(
" Transverse momentum (", QTrx_new,
", ", QTry_new,
2299 ") GeV selected for the new qqbar pair.");
2308 double QTrx_had_1st =
2309 from_forward ? QTrx_string_pos + QTrx_new : QTrx_string_neg + QTrx_new;
2310 double QTry_had_1st =
2311 from_forward ? QTry_string_pos + QTry_new : QTry_string_neg + QTry_new;
2312 double QTrn_had_1st =
2313 std::sqrt(QTrx_had_1st * QTrx_had_1st + QTry_had_1st * QTry_had_1st);
2316 int pdgid_had_1st = 0;
2318 double mass_had_1st = 0.;
2321 Pythia8::FlavContainer flav_old =
2322 from_forward ? flav_string_pos : flav_string_neg;
2327 Pythia8::FlavContainer flav_new = Pythia8::FlavContainer(0);
2331 for (
int i_try = 0; i_try < n_try; i_try++) {
2336 if (pdgid_had_1st != 0) {
2339 logg[
LPythia].debug(
" number of tries of flavor selection : ",
2340 i_try + 1,
" in StringProcess::fragment_off_hadron.");
2344 if (pdgid_had_1st == 0) {
2348 " selected for the string end with ", flav_old.id);
2350 " selected for the (first) fragmented hadron.");
2351 bool had_1st_baryon =
pythia_hadron_->particleData.isBaryon(pdgid_had_1st);
2353 double mTrn_had_1st =
2354 std::sqrt(mass_had_1st * mass_had_1st + QTrn_had_1st * QTrn_had_1st);
2355 logg[
LPythia].debug(
" Transverse momentum (", QTrx_had_1st,
", ",
2357 ") GeV selected for the (first) fragmented hadron.");
2362 const double mass_min_to_continue =
2363 (stop_string_mass +
pythia_hadron_->particleData.m0(flav_new.id) +
2369 bool string_into_final_two = mass_string < mass_min_to_continue;
2370 if (string_into_final_two) {
2371 logg[
LPythia].debug(
" The string mass is below the mass threshold ",
2372 mass_min_to_continue,
2373 " GeV : finishing with two hadrons.");
2377 double ppos_had_1st = 0.;
2378 double pneg_had_1st = 0.;
2382 bool from_diquark_end =
2383 from_forward ?
pythia_hadron_->particleData.isDiquark(flav_string_pos.id)
2386 bool has_diquark_pos =
2390 if (string_into_final_two) {
2394 int pdgid_had_2nd = 0.;
2396 double mass_had_2nd = 0.;
2399 Pythia8::FlavContainer flav_new2 = Pythia8::FlavContainer(0);
2400 flav_new2.anti(flav_new);
2403 if (
pythia_hadron_->particleData.isDiquark(flav_string_neg.id) &&
2404 pythia_hadron_->particleData.isDiquark(flav_new2.id) && from_forward) {
2407 if (
pythia_hadron_->particleData.isDiquark(flav_string_pos.id) &&
2408 pythia_hadron_->particleData.isDiquark(flav_new2.id) && !from_forward) {
2411 for (
int i_try = 0; i_try < n_try; i_try++) {
2416 if (pdgid_had_2nd != 0) {
2422 if (pdgid_had_2nd == 0) {
2426 " selected for the (second) fragmented hadron.");
2427 bool had_2nd_baryon =
pythia_hadron_->particleData.isBaryon(pdgid_had_2nd);
2435 double QTrx_had_2nd =
2436 from_forward ? QTrx_string_neg - QTrx_new : QTrx_string_pos - QTrx_new;
2437 double QTry_had_2nd =
2438 from_forward ? QTry_string_neg - QTry_new : QTry_string_pos - QTry_new;
2439 double QTrn_had_2nd =
2440 std::sqrt(QTrx_had_2nd * QTrx_had_2nd + QTry_had_2nd * QTry_had_2nd);
2441 double mTrn_had_2nd =
2442 std::sqrt(mass_had_2nd * mass_had_2nd + QTrn_had_2nd * QTrn_had_2nd);
2443 logg[
LPythia].debug(
" Transverse momentum (", QTrx_had_2nd,
", ",
2445 ") GeV selected for the (second) fragmented hadron.");
2447 double ppos_had_2nd = 0.;
2448 double pneg_had_2nd = 0.;
2454 bool found_kinematics =
2457 separate_fragment_baryon && has_diquark_pos && had_1st_baryon,
2458 ppos_string, pneg_string, mTrn_had_1st, mTrn_had_2nd,
2459 ppos_had_1st, ppos_had_2nd, pneg_had_1st, pneg_had_2nd)
2461 separate_fragment_baryon && has_diquark_pos && had_2nd_baryon,
2462 ppos_string, pneg_string, mTrn_had_2nd, mTrn_had_1st,
2463 ppos_had_2nd, ppos_had_1st, pneg_had_2nd, pneg_had_1st);
2464 if (!found_kinematics) {
2471 QTrx_string_pos = 0.;
2472 QTry_string_pos = 0.;
2475 pdgid_frag.push_back(pdgid_had_1st);
2476 FourVector mom_had_1st = FourVector(
2477 (ppos_had_1st + pneg_had_1st) * M_SQRT1_2,
2478 evec_basis[0] * (ppos_had_1st - pneg_had_1st) * M_SQRT1_2 +
2479 evec_basis[1] * QTrx_had_1st + evec_basis[2] * QTry_had_1st);
2480 momentum_frag.push_back(mom_had_1st);
2483 pdgid_frag.push_back(pdgid_had_2nd);
2484 FourVector mom_had_2nd = FourVector(
2485 (ppos_had_2nd + pneg_had_2nd) * M_SQRT1_2,
2486 evec_basis[0] * (ppos_had_2nd - pneg_had_2nd) * M_SQRT1_2 +
2487 evec_basis[1] * QTrx_had_2nd + evec_basis[2] * QTry_had_2nd);
2488 momentum_frag.push_back(mom_had_2nd);
2497 double stringz_a_use, stringz_b_use;
2500 if (separate_fragment_baryon && from_diquark_end && had_1st_baryon) {
2510 double xfrac =
sample_zLund(stringz_a_use, stringz_b_use, mTrn_had_1st);
2514 ppos_had_1st = xfrac * ppos_string;
2515 pneg_had_1st = 0.5 * mTrn_had_1st * mTrn_had_1st / ppos_had_1st;
2516 if (pneg_had_1st > pneg_string) {
2522 pneg_had_1st = xfrac * pneg_string;
2523 ppos_had_1st = 0.5 * mTrn_had_1st * mTrn_had_1st / pneg_had_1st;
2524 if (ppos_had_1st > ppos_string) {
2530 pdgid_frag.push_back(pdgid_had_1st);
2531 FourVector mom_had_1st = FourVector(
2532 (ppos_had_1st + pneg_had_1st) * M_SQRT1_2,
2533 evec_basis[0] * (ppos_had_1st - pneg_had_1st) * M_SQRT1_2 +
2534 evec_basis[1] * QTrx_had_1st + evec_basis[2] * QTry_had_1st);
2535 momentum_frag.push_back(mom_had_1st);
2538 ppos_string -= ppos_had_1st;
2539 pneg_string -= pneg_had_1st;
2549 flav_string_pos.anti(flav_new);
2550 QTrx_string_pos = -QTrx_new;
2551 QTry_string_pos = -QTry_new;
2555 flav_string_neg.anti(flav_new);
2556 QTrx_string_neg = -QTrx_new;
2557 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 2566 of file stringprocess.cc.
2567 const int baryon_number =
2571 int pdgid_hadron = 0;
2574 Pythia8::FlavContainer flav1 = Pythia8::FlavContainer(idq1);
2575 Pythia8::FlavContainer flav2 = Pythia8::FlavContainer(idq2);
2576 const int n_try = 10;
2577 for (
int i_try = 0; i_try < n_try; i_try++) {
2579 if (pdgid_hadron != 0) {
2580 return pdgid_hadron;
2588 std::array<int, 5> frag_net_q;
2591 for (
int iq = 0; iq < 5; iq++) {
2593 pythia_hadron_->particleData.nQuarksInCode(std::abs(idq1), iq + 1);
2595 pythia_hadron_->particleData.nQuarksInCode(std::abs(idq2), iq + 1);
2596 nq1 = idq1 > 0 ? nq1 : -nq1;
2597 nq2 = idq2 > 0 ? nq2 : -nq2;
2598 frag_net_q[iq] = nq1 + nq2;
2600 const int frag_iso3 = frag_net_q[1] - frag_net_q[0];
2601 const int frag_strange = -frag_net_q[2];
2602 const int frag_charm = frag_net_q[3];
2603 const int frag_bottom = -frag_net_q[4];
2604 logg[
LPythia].debug(
" conserved charges : iso3 = ", frag_iso3,
2605 ", strangeness = ", frag_strange,
2606 ", charmness = ", frag_charm,
2607 ", bottomness = ", frag_bottom);
2609 std::vector<int> pdgid_possible;
2610 std::vector<double> weight_possible;
2611 std::vector<double> weight_summed;
2616 if (!ptype.is_hadron()) {
2619 const int pdgid = ptype.pdgcode().get_decimal();
2621 (baryon_number == 3 * ptype.pdgcode().baryon_number()) &&
2622 (frag_iso3 == ptype.pdgcode().isospin3()) &&
2623 (frag_strange == ptype.pdgcode().strangeness()) &&
2624 (frag_charm == ptype.pdgcode().charmness()) &&
2625 (frag_bottom == ptype.pdgcode().bottomness())) {
2626 const int spin_degeneracy = ptype.pdgcode().spin_degeneracy();
2627 const double mass_pole = ptype.mass();
2628 const double weight = static_cast<double>(spin_degeneracy) / mass_pole;
2629 pdgid_possible.push_back(pdgid);
2630 weight_possible.push_back(weight);
2632 logg[
LPythia].debug(
" PDG id ", pdgid,
" is possible with weight ",
2636 const int n_possible = pdgid_possible.size();
2637 weight_summed.push_back(0.);
2638 for (
int i = 0; i < n_possible; i++) {
2639 weight_summed.push_back(weight_summed[i] + weight_possible[i]);
2645 for (
int i = 0; i < n_possible; i++) {
2646 if ((uspc >= weight_summed[i]) && (uspc < weight_summed[i + 1])) {
2647 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 2654 of file stringprocess.cc.
2664 bool end1_is_quark = idq1 > 0 &&
pythia_hadron_->particleData.isQuark(idq1);
2665 bool end1_is_antidiq =
2668 bool end2_is_antiq = idq2 < 0 &&
pythia_hadron_->particleData.isQuark(idq2);
2669 bool end2_is_diquark =
2673 if (end1_is_quark) {
2674 if (end2_is_antiq) {
2677 }
else if (end2_is_diquark) {
2683 }
else if (end1_is_antidiq) {
2684 if (end2_is_antiq) {
2697 std::array<int, 5> net_qnumber;
2698 for (
int iflav = 0; iflav < 5; iflav++) {
2699 net_qnumber[iflav] = 0;
2702 pythia_hadron_->particleData.nQuarksInCode(std::abs(idq1), iflav + 1);
2705 qnumber1 = -qnumber1;
2707 net_qnumber[iflav] += qnumber1;
2710 pythia_hadron_->particleData.nQuarksInCode(std::abs(idq2), iflav + 1);
2713 qnumber2 = -qnumber2;
2715 net_qnumber[iflav] += qnumber2;
2719 std::vector<int> pdgid_possible;
2721 std::vector<double> mass_diff;
2723 if (!ptype.is_hadron() || ptype.is_stable() ||
2724 ptype.pdgcode().baryon_number() != baryon) {
2728 const int pdgid = ptype.pdgcode().get_decimal();
2729 const double mass_min = ptype.min_mass_spectral();
2730 if (mass < mass_min) {
2735 if (ptype.pdgcode().isospin3() != net_qnumber[1] - net_qnumber[0]) {
2739 if (ptype.pdgcode().strangeness() != -net_qnumber[2]) {
2743 if (ptype.pdgcode().charmness() != net_qnumber[3]) {
2747 if (ptype.pdgcode().bottomness() != -net_qnumber[4]) {
2752 const double mass_pole = ptype.mass();
2754 pdgid_possible.push_back(pdgid);
2755 mass_diff.push_back(mass - mass_pole);
2758 const int n_res = pdgid_possible.size();
2764 int ires_closest = 0;
2765 double mass_diff_min = std::fabs(mass_diff[0]);
2768 for (
int ires = 1; ires < n_res; ires++) {
2769 if (std::fabs(mass_diff[ires]) < mass_diff_min) {
2770 ires_closest = ires;
2771 mass_diff_min = mass_diff[ires];
2774 logg[
LPythia].debug(
"Quark constituents ", idq1,
" and ", idq2,
" with mass ",
2775 mass,
" (GeV) turned into a resonance ",
2776 pdgid_possible[ires_closest]);
2777 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 2780 of file stringprocess.cc.
2785 const double mTsqr_string = 2. * ppos_string * pneg_string;
2786 if (mTsqr_string < 0.) {
2789 const double mTrn_string = std::sqrt(mTsqr_string);
2790 if (mTrn_string < mTrn_had_forward + mTrn_had_backward) {
2795 const double mTsqr_had_forward = mTrn_had_forward * mTrn_had_forward;
2797 const double mTsqr_had_backward = mTrn_had_backward * mTrn_had_backward;
2811 const double xm_diff =
2812 (mTsqr_had_forward - mTsqr_had_backward) / mTsqr_string;
2813 const double xe_pos = 0.5 * (1. + xm_diff);
2814 const double xe_neg = 0.5 * (1. - xm_diff);
2817 const double lambda_sqr =
2818 pow_int(mTsqr_string - mTsqr_had_forward - mTsqr_had_backward, 2) -
2819 4. * mTsqr_had_forward * mTsqr_had_backward;
2820 if (lambda_sqr <= 0.) {
2823 const double lambda = std::sqrt(lambda_sqr);
2824 const double b_lund =
2829 const double prob_reverse =
2830 std::exp(-b_lund * lambda) / (1. + std::exp(-b_lund * lambda));
2831 double xpz_pos = 0.5 * lambda / mTsqr_string;
2836 ppos_had_forward = (xe_pos + xpz_pos) * ppos_string;
2837 ppos_had_backward = (xe_neg - xpz_pos) * ppos_string;
2839 pneg_had_forward = 0.5 * mTsqr_had_forward / ppos_had_forward;
2840 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 2845 of file stringprocess.cc.
2848 bool xfrac_accepted =
false;
2856 while (!xfrac_accepted) {
2857 const double fac_env = b * mTrn * mTrn;
2861 const double xfrac_inv = 1. - std::log(u_aux) / fac_env;
2862 assert(xfrac_inv >= 1.);
2865 const double xf_ratio = std::pow(1. - 1. / xfrac_inv, a) / xfrac_inv;
2870 xfrac = 1. / xfrac_inv;
2871 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 2877 of file stringprocess.cc.
2882 logg[
LPythia].debug(
"Correcting the kinematics of fragmented hadrons...");
2884 if (ppos_string < 0. || pneg_string < 0.) {
2886 " wrong lightcone momenta of string : ppos_string (GeV) = ",
2887 ppos_string,
" pneg_string (GeV) = ", pneg_string);
2891 const double yrapid_string = 0.5 * std::log(ppos_string / pneg_string);
2892 logg[
LOutput].debug(
"Momentum-space rapidity of the string should be ",
2896 const double mTrn_string = std::sqrt(2. * ppos_string * pneg_string);
2897 logg[
LOutput].debug(
"Transvere mass (GeV) of the string should be ",
2900 const double QTrn_string =
2901 std::sqrt(QTrx_string * QTrx_string + QTry_string * QTry_string);
2902 if (mTrn_string < QTrn_string) {
2904 " wrong transverse mass of string : mTrn_string (GeV) = ", mTrn_string,
2905 " QTrn_string (GeV) = ", QTrn_string);
2908 const double msqr_string =
2909 mTrn_string * mTrn_string - QTrn_string * QTrn_string;
2911 const double mass_string = std::sqrt(msqr_string);
2912 logg[
LOutput].debug(
"The string mass (GeV) should be ", mass_string);
2916 if (std::fabs(QTrx_add_pos) <
small_number * mass_string &&
2917 std::fabs(QTry_add_pos) <
small_number * mass_string &&
2918 std::fabs(QTrx_add_neg) <
small_number * mass_string &&
2919 std::fabs(QTry_add_neg) <
small_number * mass_string) {
2920 logg[
LOutput].debug(
" no need to add transverse momenta - skipping.");
2924 FourVector ptot_string_ini = FourVector(0., 0., 0., 0.);
2926 for (
int ipyth = 1; ipyth < event_fragments.size(); ipyth++) {
2927 if (!event_fragments[ipyth].isFinal()) {
2932 FourVector(event_fragments[ipyth].e(), event_fragments[ipyth].px(),
2933 event_fragments[ipyth].py(), event_fragments[ipyth].pz());
2934 ptot_string_ini += p_frag;
2936 const double E_string_ini = ptot_string_ini.x0();
2937 const double pz_string_ini = ptot_string_ini.threevec() * evec_basis[0];
2938 const double ppos_string_ini = (E_string_ini + pz_string_ini) * M_SQRT1_2;
2939 const double pneg_string_ini = (E_string_ini - pz_string_ini) * M_SQRT1_2;
2941 const double yrapid_string_ini =
2942 0.5 * std::log(ppos_string_ini / pneg_string_ini);
2948 int ip_backward = 0;
2949 double y_forward = 0.;
2950 double y_backward = 0.;
2951 ptot_string_ini = FourVector(0., 0., 0., 0.);
2953 for (
int ipyth = 1; ipyth < event_fragments.size(); ipyth++) {
2954 if (!event_fragments[ipyth].isFinal()) {
2959 FourVector(event_fragments[ipyth].e(), event_fragments[ipyth].px(),
2960 event_fragments[ipyth].py(), event_fragments[ipyth].pz());
2961 ptot_string_ini += p_frag;
2963 const double E_frag = p_frag.x0();
2964 const double pl_frag = p_frag.threevec() * evec_basis[0];
2965 double y_current = 0.5 * std::log((E_frag + pl_frag) / (E_frag - pl_frag));
2966 if (y_current > y_forward) {
2968 y_forward = y_current;
2970 if (y_current < y_backward) {
2971 ip_backward = ipyth;
2972 y_backward = y_current;
2975 logg[
LOutput].debug(
" The most forward hadron is ip_forward = ", ip_forward,
2976 " with rapidity ", y_forward);
2977 logg[
LOutput].debug(
" The most backward hadron is ip_backward = ",
2978 ip_backward,
" with rapidity ", y_backward);
2980 const double px_string_ini = ptot_string_ini.threevec() * evec_basis[1];
2981 const double py_string_ini = ptot_string_ini.threevec() * evec_basis[2];
2985 bool correct_px = std::fabs(px_string_ini + QTrx_add_pos + QTrx_add_neg -
2989 " input transverse momenta in x-axis are not consistent.");
2994 bool correct_py = std::fabs(py_string_ini + QTry_add_pos + QTry_add_neg -
2998 " input transverse momenta in y-axis are not consistent.");
3002 Pythia8::Vec4 pvec_string_now =
3003 set_Vec4(ptot_string_ini.x0(), ptot_string_ini.threevec());
3006 " Adding transverse momentum to the most forward hadron.");
3007 pvec_string_now -= event_fragments[ip_forward].p();
3008 const double mass_frag_pos = event_fragments[ip_forward].p().mCalc();
3010 FourVector p_old_frag_pos = FourVector(
3011 event_fragments[ip_forward].e(), event_fragments[ip_forward].px(),
3012 event_fragments[ip_forward].py(), event_fragments[ip_forward].pz());
3014 ThreeVector mom_new_frag_pos = p_old_frag_pos.threevec() +
3015 QTrx_add_pos * evec_basis[1] +
3016 QTry_add_pos * evec_basis[2];
3018 double E_new_frag_pos =
3019 std::sqrt(mom_new_frag_pos.sqr() + mass_frag_pos * mass_frag_pos);
3020 Pythia8::Vec4 pvec_new_frag_pos =
set_Vec4(E_new_frag_pos, mom_new_frag_pos);
3021 pvec_string_now += pvec_new_frag_pos;
3023 event_fragments[ip_forward].p(pvec_new_frag_pos);
3026 " Adding transverse momentum to the most backward hadron.");
3027 pvec_string_now -= event_fragments[ip_backward].p();
3028 const double mass_frag_neg = event_fragments[ip_backward].p().mCalc();
3030 FourVector p_old_frag_neg = FourVector(
3031 event_fragments[ip_backward].e(), event_fragments[ip_backward].px(),
3032 event_fragments[ip_backward].py(), event_fragments[ip_backward].pz());
3034 ThreeVector mom_new_frag_neg = p_old_frag_neg.threevec() +
3035 QTrx_add_neg * evec_basis[1] +
3036 QTry_add_neg * evec_basis[2];
3038 double E_new_frag_neg =
3039 std::sqrt(mom_new_frag_neg.sqr() + mass_frag_neg * mass_frag_neg);
3040 Pythia8::Vec4 pvec_new_frag_neg =
set_Vec4(E_new_frag_neg, mom_new_frag_neg);
3041 pvec_string_now += pvec_new_frag_neg;
3043 event_fragments[ip_backward].p(pvec_new_frag_neg);
3046 event_fragments[0].p(pvec_string_now);
3047 event_fragments[0].m(pvec_string_now.mCalc());
3051 double mTrn_frag_all = 0.;
3052 for (
int ipyth = 1; ipyth < event_fragments.size(); ipyth++) {
3053 if (!event_fragments[ipyth].isFinal()) {
3059 FourVector(event_fragments[ipyth].e(), event_fragments[ipyth].px(),
3060 event_fragments[ipyth].py(), event_fragments[ipyth].pz());
3061 ptot_string_ini += p_frag;
3063 const double E_frag = p_frag.x0();
3064 const double pl_frag = p_frag.threevec() * evec_basis[0];
3065 const double ppos_frag = (E_frag + pl_frag) * M_SQRT1_2;
3066 const double pneg_frag = (E_frag - pl_frag) * M_SQRT1_2;
3067 const double mTrn_frag = std::sqrt(2. * ppos_frag * pneg_frag);
3068 mTrn_frag_all += mTrn_frag;
3071 "Sum of transverse masses (GeV) of all fragmented hadrons : ",
3075 if (mTrn_string < mTrn_frag_all) {
3076 logg[
LOutput].debug(
" which is larger than mT of the actual string ",
3081 double mass_string_now = pvec_string_now.mCalc();
3082 double msqr_string_now = mass_string_now * mass_string_now;
3084 FourVector p_string_now =
3085 FourVector(pvec_string_now.e(), pvec_string_now.px(),
3086 pvec_string_now.py(), pvec_string_now.pz());
3087 double E_string_now = p_string_now.x0();
3088 double pz_string_now = p_string_now.threevec() * evec_basis[0];
3089 logg[
LOutput].debug(
"The string mass (GeV) at this point : ",
3091 double ppos_string_now = (E_string_now + pz_string_now) * M_SQRT1_2;
3092 double pneg_string_now = (E_string_now - pz_string_now) * M_SQRT1_2;
3094 double yrapid_string_now = 0.5 * std::log(ppos_string_now / pneg_string_now);
3095 logg[
LOutput].debug(
"The momentum-space rapidity of string at this point : ",
3098 "The momentum-space rapidities of hadrons will be changed.");
3099 const int niter_max = 10000;
3100 bool accepted =
false;
3101 double fac_all_yrapid = 1.;
3106 for (
int iiter = 0; iiter < niter_max; iiter++) {
3107 if (std::fabs(mass_string_now - mass_string) <
really_small * mass_string) {
3111 double E_deriv = 0.;
3112 double pz_deriv = 0.;
3116 for (
int ipyth = 1; ipyth < event_fragments.size(); ipyth++) {
3117 if (!event_fragments[ipyth].isFinal()) {
3122 FourVector(event_fragments[ipyth].e(), event_fragments[ipyth].px(),
3123 event_fragments[ipyth].py(), event_fragments[ipyth].pz());
3124 const double E_frag = p_frag.x0();
3125 const double pl_frag = p_frag.threevec() * evec_basis[0];
3126 const double ppos_frag = (E_frag + pl_frag) * M_SQRT1_2;
3127 const double pneg_frag = (E_frag - pl_frag) * M_SQRT1_2;
3128 const double mTrn_frag = std::sqrt(2. * ppos_frag * pneg_frag);
3129 const double y_frag = 0.5 * std::log(ppos_frag / pneg_frag);
3131 E_deriv += mTrn_frag * (y_frag - yrapid_string_now) * std::sinh(y_frag);
3132 pz_deriv += mTrn_frag * (y_frag - yrapid_string_now) * std::cosh(y_frag);
3134 double slope = 2. * (E_string_now * E_deriv - pz_string_now * pz_deriv);
3135 double fac_yrapid = 1. + std::tanh((msqr_string - msqr_string_now) / slope);
3136 fac_all_yrapid *= fac_yrapid;
3140 (1. - fac_yrapid) * yrapid_string_now);
3142 pvec_string_now = event_fragments[0].p();
3143 mass_string_now = pvec_string_now.mCalc();
3144 msqr_string_now = mass_string_now * mass_string_now;
3145 p_string_now = FourVector(pvec_string_now.e(), pvec_string_now.px(),
3146 pvec_string_now.py(), pvec_string_now.pz());
3147 E_string_now = p_string_now.x0();
3148 pz_string_now = p_string_now.threevec() * evec_basis[0];
3149 ppos_string_now = (E_string_now + pz_string_now) * M_SQRT1_2;
3150 pneg_string_now = (E_string_now - pz_string_now) * M_SQRT1_2;
3151 yrapid_string_now = 0.5 * std::log(ppos_string_now / pneg_string_now);
3152 logg[
LOutput].debug(
" step ", iiter + 1,
" : fac_yrapid = ", fac_yrapid,
3153 " , string mass (GeV) = ", mass_string_now,
3154 " , string rapidity = ", yrapid_string_now);
3158 logg[
LOutput].debug(
" Too many iterations in rapidity rescaling.");
3162 "The overall factor multiplied to the rapidities of hadrons = ",
3164 logg[
LOutput].debug(
"The momentum-space rapidity of string at this point : ",
3166 const double y_diff = yrapid_string - yrapid_string_now;
3167 logg[
LOutput].debug(
"The hadrons will be boosted by rapidity ", y_diff,
3168 " 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 1049 of file stringprocess.h.
1052 Pythia8::Vec4 pvec_string_now = Pythia8::Vec4(0., 0., 0., 0.);
1054 for (
int ipyth = 1; ipyth <
event.size(); ipyth++) {
1055 if (!event[ipyth].isFinal()) {
1059 FourVector p_frag = FourVector(
1060 event[ipyth].e(), event[ipyth].px(),
1061 event[ipyth].py(), event[ipyth].pz());
1062 const double E_frag = p_frag.x0();
1063 const double pl_frag = p_frag.threevec() * evec_basis[0];
1064 const double ppos_frag = (E_frag + pl_frag) * M_SQRT1_2;
1065 const double pneg_frag = (E_frag - pl_frag) * M_SQRT1_2;
1066 const double mTrn_frag = std::sqrt(2. * ppos_frag * pneg_frag);
1068 const double y_frag = 0.5 * std::log(ppos_frag / pneg_frag);
1071 const double y_new_frag = factor_yrapid * y_frag + diff_yrapid;
1073 const double E_new_frag = mTrn_frag * std::cosh(y_new_frag);
1074 const double pl_new_frag = mTrn_frag * std::sinh(y_new_frag);
1075 ThreeVector mom_new_frag =
1076 p_frag.threevec() + (pl_new_frag - pl_frag) * evec_basis[0];
1077 Pythia8::Vec4 pvec_new_frag =
set_Vec4(E_new_frag, mom_new_frag);
1078 event[ipyth].p(pvec_new_frag);
1079 pvec_string_now += pvec_new_frag;
1081 event[0].p(pvec_string_now);
1082 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 3208 of file stringprocess.cc.
3213 for (ParticleData &data : outgoing_particles) {
3214 data.set_cross_section_scaling_factor(0.0);
3217 std::sort(outgoing_particles.begin(), outgoing_particles.end(),
3218 [&](ParticleData i, ParticleData j) {
3219 return i.momentum().velocity() * evecLong >
3220 j.momentum().velocity() * evecLong;
3223 switch (baryon_string) {
3237 throw std::runtime_error(
"string is neither mesonic nor baryonic");
3242 std::pair<int, int> i =
find_leading(nq1, nq2, outgoing_particles);
3243 std::pair<int, int> j =
find_leading(nq2, nq1, outgoing_particles);
3244 if (baryon_string == 0 && i.second - i.first < j.second - j.first) {
3247 suppression_factor);
3251 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 3191 of file stringprocess.cc.
3193 assert(list.size() >= 2);
3194 int end = list.size() - 1;
3197 i1 <= end && !list[i1].pdgcode().contains_enough_valence_quarks(nq1);
3201 i2 >= 0 && !list[i2].pdgcode().contains_enough_valence_quarks(nq2);
3204 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 3176 of file stringprocess.cc.
3178 int nbaryon = data.pdgcode().baryon_number();
3182 data.set_cross_section_scaling_factor(0.5 * suppression_factor);
3183 }
else if (data.is_baryon()) {
3186 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 3255 of file stringprocess.cc.
3256 PdgCode pdg_mapped(0x0);
3258 if (pdg.baryon_number() == 1) {
3259 pdg_mapped = pdg.charge() > 0 ? PdgCode(
pdg::p) : PdgCode(pdg::
n);
3260 }
else if (pdg.baryon_number() == -1) {
3261 pdg_mapped = pdg.charge() < 0 ? PdgCode(-
pdg::p) : PdgCode(-pdg::
n);
3262 }
else if (pdg.is_hadron()) {
3263 if (pdg.charge() >= 0) {
3268 }
else if (pdg.is_lepton()) {
3269 pdg_mapped = pdg.charge() < 0 ? PdgCode(0x11) : PdgCode(-0x11);
3271 throw std::runtime_error(
"StringProcess::pdg_map_for_pythia failed.");
3274 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 1160 of file stringprocess.h.
◆ getPNegA()
double smash::StringProcess::getPNegA |
( |
| ) |
|
|
inline |
- Returns
- backward lightcone momentum incoming particle Af in CM-frame [GeV]
- See also
- PNegA_
Definition at line 1166 of file stringprocess.h.
◆ getPPosB()
double smash::StringProcess::getPPosB |
( |
| ) |
|
|
inline |
- Returns
- forward lightcone momentum incoming particle B in CM-frame [GeV]
- See also
- PPosB_
Definition at line 1172 of file stringprocess.h.
◆ getPnegB()
double smash::StringProcess::getPnegB |
( |
| ) |
|
|
inline |
- Returns
- backward lightcone momentum incoming particle B in CM-frame [GeV]
- See also
- PNegB_
Definition at line 1178 of file stringprocess.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 1214 of file stringprocess.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 49 of file stringprocess.h.
◆ PPosB_
double smash::StringProcess::PPosB_ |
|
private |
forward lightcone momentum p^{+} of incoming particle B in CM-frame [GeV]
Definition at line 51 of file stringprocess.h.
◆ PNegA_
double smash::StringProcess::PNegA_ |
|
private |
backward lightcone momentum p^{-} of incoming particle A in CM-frame [GeV]
Definition at line 53 of file stringprocess.h.
◆ PNegB_
double smash::StringProcess::PNegB_ |
|
private |
backward lightcone momentum p^{-} of incoming particle B in CM-frame [GeV]
Definition at line 55 of file stringprocess.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 61 of file stringprocess.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 65 of file stringprocess.h.
◆ pcom_
std::array<FourVector, 2> smash::StringProcess::pcom_ |
|
private |
momenta of incoming particles in the center of mass frame [GeV]
Definition at line 67 of file stringprocess.h.
◆ ucomAB_
velocity four vector of the center of mass in the lab frame
Definition at line 69 of file stringprocess.h.
◆ vcomAB_
velocity three vector of the center of mass in the lab frame
Definition at line 71 of file stringprocess.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 76 of file stringprocess.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 80 of file stringprocess.h.
◆ pmin_gluon_lightcone_
double smash::StringProcess::pmin_gluon_lightcone_ |
|
private |
the minimum lightcone momentum scale carried by a gluon [GeV]
Definition at line 82 of file stringprocess.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 87 of file stringprocess.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 92 of file stringprocess.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 97 of file stringprocess.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 103 of file stringprocess.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 108 of file stringprocess.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 113 of file stringprocess.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 118 of file stringprocess.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 123 of file stringprocess.h.
◆ strange_supp_
double smash::StringProcess::strange_supp_ |
|
private |
◆ diquark_supp_
double smash::StringProcess::diquark_supp_ |
|
private |
◆ popcorn_rate_
double smash::StringProcess::popcorn_rate_ |
|
private |
◆ string_sigma_T_
double smash::StringProcess::string_sigma_T_ |
|
private |
transverse momentum spread in string fragmentation
Definition at line 131 of file stringprocess.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 138 of file stringprocess.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 140 of file stringprocess.h.
◆ soft_t_form_
double smash::StringProcess::soft_t_form_ |
|
private |
factor to be multiplied to formation times in soft strings
Definition at line 142 of file stringprocess.h.
◆ time_collision_
double smash::StringProcess::time_collision_ |
|
private |
time of collision in the computational frame [fm]
Definition at line 144 of file stringprocess.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 156 of file stringprocess.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 161 of file stringprocess.h.
◆ separate_fragment_baryon_
bool smash::StringProcess::separate_fragment_baryon_ |
|
private |
Whether to use a separate fragmentation function for leading baryons.
Definition at line 164 of file stringprocess.h.
◆ final_state_
ParticleList smash::StringProcess::final_state_ |
|
private |
final state array which must be accessed after the collision
Definition at line 170 of file stringprocess.h.
◆ hard_map_
Map object to contain the different pythia objects.
Definition at line 181 of file stringprocess.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 193 of file stringprocess.h.
◆ event_intermediate_
Pythia8::Event smash::StringProcess::event_intermediate_ |
|
private |
event record for intermediate partonic state in the hard string routine
Definition at line 199 of file stringprocess.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 string_sigma_T_
transverse momentum spread in string fragmentation
double stringz_b_produce_
parameter (StringZ:bLund) for the fragmentation function of other (produced) hadrons in soft non-diff...
void init(const ParticleList &incoming, double tcoll)
initialization feed intial particles, time of collision and gamma factor of the center of mass.
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...
pythia_map hard_map_
Map object to contain the different pythia objects.
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.
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.
double strange_supp_
strange quark suppression factor
double diquark_supp_
diquark suppression factor
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
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 popcorn_rate_
popcorn rate
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...
static const ParticleTypePtr try_find(PdgCode pdgcode)
Returns the ParticleTypePtr for the given pdgcode.
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