Version: SMASH-3.4
stringprocess.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2017-2020,2022,2024-2026
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
10 #ifndef SRC_INCLUDE_SMASH_STRINGPROCESS_H_
11 #define SRC_INCLUDE_SMASH_STRINGPROCESS_H_
12 
13 #include <map>
14 #include <memory>
15 #include <string>
16 #include <utility>
17 #include <vector>
18 
19 #include "Pythia8/Pythia.h"
20 
21 #include "constants.h"
22 #include "logging.h"
23 #include "particledata.h"
24 #include "smash/processbranch.h"
25 
26 namespace smash {
27 static constexpr int LPythia = LogArea::Pythia::id;
28 
29 /**
30  * \brief String excitation processes used in SMASH
31  *
32  * Only one instance of this class should be created.
33  *
34  * This class implements string excitation processes based on the UrQMD model
35  * \iref{Bass:1998ca}, \iref{Bleicher:1999xi} and subsequent fragmentation
36  * according to the LUND/PYTHIA fragmentation scheme
37  * \iref{Andersson:1983ia}, \iref{Sjostrand:2014zea}, \iref{Bierlich:2022pfr}.
38  *
39  * The class implements the following functionality:
40  * - given two colliding initial state particles it provides hadronic final
41  * state after single diffractive, double diffractive and non-diffractive
42  * string excitation
43  * - owns a Pythia8::SigmaTotal object to compute corresponding cross-sections
44  * - owns a Pythia object, that allows to fragment strings
45  */
47  private:
48  // The following 4 variables are in the center of mass frame
49  /// forward lightcone momentum p^{+} of incoming particle A in CM-frame
50  /// [GeV]
51  double PPosA_;
52  /// forward lightcone momentum p^{+} of incoming particle B in CM-frame
53  /// [GeV]
54  double PPosB_;
55  /// backward lightcone momentum p^{-} of incoming particle A in CM-frame
56  /// [GeV]
57  double PNegA_;
58  /// backward lightcone momentum p^{-} of incoming particle B in CM-frame
59  /// [GeV]
60  double PNegB_;
61  /// mass of incoming particle A [GeV]
62  double massA_;
63  /// mass of incoming particle B [GeV]
64  double massB_;
65  /// sqrt of Mandelstam variable s of collision [GeV]
66  double sqrtsAB_;
67  /// PdgCodes of incoming particles
68  std::array<PdgCode, 2> PDGcodes_;
69  /// momenta of incoming particles in the lab frame [GeV]
70  std::array<FourVector, 2> plab_;
71  /// momenta of incoming particles in the center of mass frame [GeV]
72  std::array<FourVector, 2> pcom_;
73  /// velocity four vector of the center of mass in the lab frame
75  /// velocity three vector of the center of mass in the lab frame
77  /**
78  * Orthonormal basis vectors in the center of mass frame,
79  * where the 0th one is parallel to momentum of incoming particle A
80  */
81  std::array<ThreeVector, 3> evecBasisAB_;
82  /// the minimum lightcone momentum scale carried by a gluon [GeV]
84  /**
85  * parameter \f$\beta\f$ for the gluon distribution function
86  * \f$ P(x) = x^{-1} (1 - x)^{1 + \beta} \f$
87  */
89  /**
90  * parameter \f$\alpha\f$ for the quark distribution function
91  * \f$ P(x) = x^{\alpha - 1} (1 - x)^{\beta - 1} \f$
92  */
94  /**
95  * parameter \f$\beta\f$ for the quark distribution function
96  * \f$ P(x) = x^{\alpha - 1} (1 - x)^{\beta - 1} \f$
97  */
99  /**
100  * Transverse momentum spread of the excited strings. [GeV]
101  * Transverse momenta of strings are sampled according to gaussian
102  * distribution with width sigma_qperp_
103  */
104  double sigma_qperp_;
105  /**
106  * parameter (StringZ:aLund) for the fragmentation function
107  * of leading baryon in soft non-diffractive string processes
108  */
110  /**
111  * parameter (StringZ:bLund) for the fragmentation function
112  * of leading baryon in soft non-diffractive string processes
113  */
115  /**
116  * parameter (StringZ:aLund) for the fragmentation function
117  * of other (produced) hadrons in soft non-diffractive string processes
118  */
120  /**
121  * parameter (StringZ:bLund) for the fragmentation function
122  * of other (produced) hadrons in soft non-diffractive string processes
123  */
125  /// strange quark suppression factor
127  /// diquark suppression factor
129  /// popcorn rate
131  /// damp popcorn meson from diquark remnant endpoint rate
133  /// transverse momentum spread in string fragmentation
135  /// string tension [GeV/fm]
137  /// constant proper time in the case of constant formation time [fm]
139  /// factor to be multiplied to formation times in soft strings
140  double soft_t_form_;
141  /// time of collision in the computational frame [fm]
143  /**
144  * Whether the formation time should depend on the mass of the fragment
145  * according to \iref{Andersson:1983ia} eq. 2.45:
146  *
147  * \f$ \tau = \sqrt{2}\frac{m}{\kappa} \f$
148  *
149  * The formation time and position is not calculated directly using the yoyo
150  * model because the spacetime rapidity where a string fragment forms is not
151  * equal to the fragment's momentum space rapidity. This cannot be easily
152  * combined with possible interactions before the formation time.
153  */
155  /**
156  * Probability of splitting a nucleon into the quark flavour it has only
157  * once and a diquark it has twice.
158  */
160 
161  /// Whether to use a separate fragmentation function for leading baryons.
163 
164  /**
165  * Whether to use the monash tune \iref{Skands:2014pea} for all string
166  * processes.
167  */
169 
170  /**
171  * additional cross-section suppression factor
172  * to take coherence effect into account.
173  */
175 
176  /**
177  * Optional center-of-mass energy used to initialize MPI-capable Pythia
178  * objects. If unset, the initialization energy is determined from the
179  * incoming hadrons.
180  */
181  std::optional<double> mpi_initialization_sqrts_;
182 
183  /**
184  * Additional Pythia 8 settings passed to each internal Pythia instance.
185  *
186  * These settings are applied after the corresponding SMASH string
187  * parameters and therefore override them if both configure the same
188  * Pythia setting.
189  */
190  std::vector<std::string> pythia_settings_;
191 
192  /**
193  * Compute flags identifying beam valence partons (quarks or diquarks)
194  * that act as leading partons after the initial interaction.
195  *
196  * The returned vector is aligned with the current Pythia event record
197  * (pythia.event): each entry is true if the corresponding particle is
198  * a valence parton originating from one of the incoming beam particles,
199  * i.e. a quark or diquark that carries the beam quantum numbers and
200  * should be considered "leading".
201  *
202  * This typically includes valence quarks extracted during the initial
203  * scattering, as well as surviving diquark remnants of the beam.
204  *
205  * \note The size of the returned vector equals pythia.event.size().
206  *
207  * \param[in,out] pythia Pythia instance containing the event to inspect.
208  * \return Per-particle flags for beam valence (leading) partons.
209  */
210  std::vector<bool> compute_beam_valence_flags(Pythia8::Pythia &pythia);
211 
212  /**
213  * Determine the custom leading-hadron status code from a string endpoint.
214  * For a string endpoint particle, return the appropriate SMASH leading
215  * status: diquark endpoints map to FROM_Leading_Diquark, otherwise
216  * FROM_Leading_Quark.
217  *
218  * \param[in] end String endpoint particle (quark or diquark).
219  * \return Integer status code corresponding to the appropriate
220  * LeadingStatus.
221  */
222  inline int leading_hadron_status_from_endpoint(const Pythia8::Particle &end) {
223  return static_cast<int>(end.isDiquark() ? LeadingStatus::FromLeadingDiquark
225  }
226 
227  /**
228  * Check whether a particle is tagged as a leading parton.
229  *
230  * \param[in] p Pythia particle.
231  * \return True if p has statusAbs() equal to LeadingStatus::Leading_Quark or
232  * LeadingStatus::Leading_Diquark.
233  */
234  inline bool is_leading_parton(const Pythia8::Particle &p) {
235  return p.statusAbs() == static_cast<int>(LeadingStatus::LeadingQuark) ||
236  p.statusAbs() == static_cast<int>(LeadingStatus::LeadingDiquark);
237  }
238 
239  /**
240  * Check whether a particle is tagged as originating from a leading quark.
241  *
242  * \param[in] p Pythia particle.
243  * \return True if p has statusAbs() equal to
244  * LeadingStatus::FROM_Leading_Quark.
245  */
246  inline bool is_leading_from_quark(const Pythia8::Particle &p) {
247  return p.statusAbs() == static_cast<int>(LeadingStatus::FromLeadingQuark);
248  }
249 
250  /**
251  * Check whether a particle is tagged as originating from a leading diquark.
252  *
253  * \param[in] p Pythia particle.
254  * \return True if p has statusAbs() equal to
255  * LeadingStatus::FROM_Leading_Diquark.
256  */
257  inline bool is_leading_from_diquark(const Pythia8::Particle &p) {
258  return p.statusAbs() == static_cast<int>(LeadingStatus::FromLeadingDiquark);
259  }
260 
261  /**
262  * Check whether a particle is tagged as originating from a leading
263  * endpoint.
264  *
265  * This is the union of is_leading_from_quark() and
266  * is_leading_from_diquark().
267  *
268  * \param[in] p Pythia particle.
269  * \return True if p is tagged as leading-from-quark or
270  * leading-from-diquark.
271  */
272  inline bool is_leading(const Pythia8::Particle &p) {
274  }
275 
276  /**
277  * final state array
278  * which must be accessed after the collision
279  */
280  ParticleList final_state_;
281 
282  /**
283  * Map containing PYTHIA objects for hard string routines.
284  * Particle IDs are used as the keys to obtain the respective object.
285  * This was introduced to reduce the amount of Pythia init() calls.
286  */
287  typedef std::map<std::pair<int, int>, std::unique_ptr<Pythia8::Pythia>>
289 
290  /// Map object to contain the different pythia objects
292 
293  /// PYTHIA object used in fragmentation
294  std::unique_ptr<Pythia8::Pythia> pythia_hadron_;
295 
296  /// An object to compute cross-sections
297  Pythia8::SigmaTotal pythia_sigmatot_;
298 
299  /**
300  * An object for the flavor selection in string fragmentation
301  * in the case of separate fragmentation function for leading baryon
302  */
303  Pythia8::StringFlav pythia_stringflav_;
304 
305  /**
306  * event record for intermediate partonic state
307  * in the hard string routine
308  */
309  Pythia8::Event event_intermediate_;
310 
311  /**
312  * Append a single two-endpoint string as an independent PYTHIA event.
313  *
314  * A minimal partonic event is constructed containing a string with the
315  * specified endpoint flavors and total four-momentum. The endpoint momenta
316  * are determined from two-body kinematics in the string rest frame and are
317  * aligned with either the projectile or target beam direction before being
318  * boosted back to the collision frame.
319  *
320  * Strings whose invariant mass is below the estimated fragmentation threshold
321  * are rejected.
322  *
323  * \param[in] p_str Four-momentum of the string.
324  * \param[in] ends PDG ids of the two string endpoints.
325  * \param[in] color_tag Color tag used to connect the string endpoints.
326  * \param[in] use_projectile_axis Whether to align the string with the
327  * projectile beam direction. If false, the
328  * target beam direction is used.
329  * \param[in] random_flip_of_endpoints Whether to randomly reverse the order
330  * of the two string endpoints before
331  * assigning endpoint momenta.
332  * \return True if a valid string event was created and appended, false
333  * otherwise.
334  */
335  bool append_string(const Pythia8::Vec4 &p_str, const std::array<int, 2> &ends,
336  int color_tag, bool use_projectile_axis,
337  bool random_flip_of_endpoints = false);
338 
339  /// PYTHIA event records containing string partons to be hadronized.
340  std::vector<Pythia8::Event> string_parton_events_;
341 
342  /**
343  * Single-diffractive process
344  * is based on single pomeron exchange described in \iref{Ingelman:1984ns}.
345  * \param[in] is_AB_to_AX specifies which hadron to excite into a string.
346  * true : A + B -> A + X,
347  * false : A + B -> X + B
348  * \return whether the process is successfully implemented.
349  */
350  bool next_SDiff(bool is_AB_to_AX);
351  /**
352  * Double-diffractive process ( A + B -> X + X )
353  * is similar to the single-diffractive process,
354  * but lightcone momenta of gluons are sampled
355  * in the same was as the UrQMD model \iref{Bass:1998ca},
356  * \iref{Bleicher:1999xi}.
357  * String masses are computed after pomeron exchange
358  * aquiring transverse momentum transfer.
359  * \return whether the process is successfully implemented.
360  */
361  bool next_DDiff();
362  /**
363  * Soft Non-diffractive process
364  * is modelled in accordance with dual-topological approach
365  * \iref{Capella:1978ig}.
366  * This involves a parton exchange in conjunction with momentum transfer.
367  * Probability distribution function of the lightcone momentum fraction
368  * carried by quark is based on the UrQMD model
369  * \iref{Bass:1998ca}, \iref{Bleicher:1999xi}.
370  * \return whether the process is successfully implemented.
371  *
372  * \throw std::runtime_error
373  * if incoming particles are neither mesonic nor baryonic
374  */
375  bool next_NDiffSoft();
376  /**
377  * Hard Non-diffractive process
378  * is based on PYTHIA 8 with partonic showers and interactions.
379  * \return whether the process is successfully implemented.
380  */
381  bool next_Hard(ProcessType type);
382  /**
383  * Baryon-antibaryon annihilation process
384  * Based on what UrQMD \iref{Bass:1998ca}, \iref{Bleicher:1999xi} does,
385  * it create two mesonic strings after annihilating one quark-antiquark pair.
386  * Each string has mass equal to half of sqrts.
387  * \return whether the process is successfully implemented.
388  *
389  * \throw std::invalid_argument
390  * if incoming particles are not baryon-antibaryon pair
391  */
392  bool next_BBbarAnn();
393 
394  public:
395  /**
396  * Constructor, initializes PYTHIA. Should only be called once.
397  *
398  * All parameters are taken from \p config via Configuration::take.
399  *
400  * \param[in,out] config SMASH configuration object (keys are consumed)
401  */
402  explicit StringProcess(Configuration &config);
403 
404  /**
405  * Common setup of PYTHIA objects for soft and hard string routines
406  * \param[out] pythia_in pointer to the PYTHIA object
407  * \param[in] strange_supp strangeness suppression factor
408  * (StringFlav:probStoUD) in fragmentation
409  * \param[in] diquark_supp diquark suppression factor
410  * (StringFlav:probQQtoQ) in fragmentation
411  * \param[in] popcorn_rate parameter (StringFlav:popcornRate)
412  * to determine the production rate of popcorn mesons from
413  * the diquark end of a string.
414  * \param[in] stringz_a parameter (StringZ:aLund)
415  * for the fragmentation function
416  * \param[in] stringz_b parameter (StringZ:bLund)
417  * for the fragmentation function
418  * \param[in] string_sigma_T transverse momentum spread (StringPT:sigma)
419  * in fragmentation [GeV]
420  *
421  * \see pythia8302/share/Pythia8/xmldoc/FlavourSelection.xml
422  * \see pythia8302/share/Pythia8/xmldoc/Fragmentation.xml
423  */
424  void common_setup_pythia(Pythia8::Pythia *pythia_in, double strange_supp,
425  double diquark_supp, double popcorn_rate,
426  double stringz_a, double stringz_b,
427  double string_sigma_T);
428 
429  /**
430  * Set PYTHIA random seeds to be desired values.
431  * The value is recalculated such that it is allowed by PYTHIA.
432  *
433  * \see smash::maximum_rndm_seed_in_pythia
434  */
436  const int seed_new = random::uniform_int(1, maximum_rndm_seed_in_pythia);
437 
438  pythia_hadron_->rndm.init(seed_new);
439  logg[LPythia].debug("pythia_hadron_ : rndm is initialized with seed ",
440  seed_new);
441  }
442  /**
443  * PYTHIA status codes used to track leading/valence ancestry.
444  *
445  * PYTHIA uses integer status codes to classify particles in the event
446  * record. SMASH uses a combination of standard PYTHIA codes and custom
447  * internal codes to tag leading partons and hadrons originating from
448  * leading quark/diquark endpoints.
449  *
450  * Custom values are chosen to avoid collisions with commonly used PYTHIA
451  * internal codes. Standard PYTHIA values are used deliberately where they
452  * activate specific hadronization machinery.
453  */
454  enum class LeadingStatus : int {
455  /// Custom status assigned to leading (valence) quarks.
456  LeadingQuark = 202,
457 
458  /// Standard PYTHIA beam-remnant status used for leading diquarks.
459  ///
460  /// Leading diquarks are assigned status 63 so that PYTHIA treats them
461  /// as beam remnants during hadronization. This allows PYTHIA's beam
462  /// remnant machinery to be used for leading baryon production, including
463  /// popcorn suppression and the optional hard-remnant-baryon treatment.
464  ///
465  /// In particular, when BeamRemnants:hardRemnantBaryon is enabled,
466  /// PYTHIA replaces the standard Lund symmetric fragmentation function
467  /// for the leading baryon by a dedicated remnant-baryon fragmentation
468  /// function controlled by BeamRemnants:aRemnantBaryon and
469  /// BeamRemnants:bRemnantBaryon. This produces harder leading baryons
470  /// than ordinary string fragmentation.
471  ///
472  /// Therefore status 63 is intentionally used here rather than a custom
473  /// status code.
474  LeadingDiquark = 63,
475 
476  /// Standard PYTHIA status for non-leading partons that should be
477  /// hadronized.
478  ///
479  /// The PYTHIA manual recommends status 23 for particles provided as
480  /// input to standalone hadronization. The precise value is not
481  /// physically important here, but using the recommended status keeps
482  /// the event record conventional.
483  ///
484  /// See:
485  /// https://pythia.org/latest-manual/HadronLevelStandalone.html
486  NonLeadingParton = 23,
487 
488  /// Custom status assigned to hadrons containing a leading quark.
489  FromLeadingQuark = 203,
490 
491  /// Custom status assigned to hadrons containing a leading diquark.
492  FromLeadingDiquark = 204,
493  };
494 
495  /**
496  * Tag leading hadrons in a hadronized string.
497  *
498  * After string fragmentation, this function identifies the hadrons that
499  * originate from the leading string endpoints and assigns them a custom
500  * status code (see LeadingStatus).
501  *
502  * The procedure is:
503  * - identify the two string endpoint partons (quarks or diquarks),
504  * - boost the event into the string rest frame,
505  * - sort all final-state hadrons by longitudinal momentum,
506  * - associate each endpoint with the hadron closest to its end of the
507  * string,
508  * - assign a leading-hadron status based on the flavor content of the
509  * endpoint parton.
510  *
511  * Diquark endpoints are processed before quark endpoints to ensure that
512  * leading baryons are preferentially associated with beam-remnant diquarks.
513  * A hadron can only be tagged once.
514  *
515  * For diquark endpoints, only baryons with matching baryon-number sign are
516  * considered. Quark endpoints may tag either mesons or baryons, but baryons
517  * must again have a compatible baryon-number sign.
518  *
519  * The event is temporarily transformed into the string rest frame during the
520  * identification procedure and restored to its original frame before
521  * returning.
522  *
523  * \param[in,out] event
524  * Hadronized Pythia event. The event is modified in-place by assigning
525  * custom status codes to identified leading hadrons.
526  */
527  void tag_leading_hadrons(Pythia8::Event &event);
528 
529  /**
530  * Convert a PYTHIA four-vector into a SMASH four-vector.
531  *
532  * \param[in] p PYTHIA four-vector.
533  * \return Corresponding SMASH four-vector.
534  */
535  static FourVector make_smash_4vec(const Pythia8::Vec4 &p) {
536  return FourVector(p.e(), p.px(), p.py(), p.pz());
537  }
538 
539  /**
540  * Convert a SMASH four-vector into a PYTHIA four-vector.
541  *
542  * \param[in] p SMASH four-vector.
543  * \return Corresponding PYTHIA four-vector.
544  */
545  static Pythia8::Vec4 make_pythia_4vec(const FourVector &p) {
546  return Pythia8::Vec4(p.x1(), p.x2(), p.x3(), p.x0());
547  }
548 
549  /**
550  * Generate the next string process for a given process type.
551  *
552  * \param[in] type Type of string process to generate.
553  * \return Whether the process was successfully generated.
554  */
555  bool next(ProcessType type);
556 
557  /// Rotation/boost matrix to transform particles to the center-of-mass frame.
558  Pythia8::RotBstMatrix to_cm_;
559 
560  /**
561  * Check whether all strings in a PYTHIA event are above fragmentation
562  * threshold.
563  *
564  * \param[in] event PYTHIA event record containing the string partons.
565  * \return True if all strings are above threshold.
566  */
567  bool string_above_threshold(const Pythia8::Event &event);
568 
569  /**
570  * Estimate the minimum invariant mass required for a string to fragment.
571  *
572  * \param[in] p_left Index of the left string endpoint in the PYTHIA event.
573  * \param[in] p_right Index of the right string endpoint in the PYTHIA event.
574  * \return Estimated string threshold mass [GeV].
575  */
576  double estimate_string_threshold(int p_left, int p_right);
577 
578  /**
579  * Set the color or anticolor index of a particle according to its type.
580  *
581  * Quarks receive a color index, antiquarks receive an anticolor index, and
582  * diquarks are treated according to their PYTHIA color-flow convention.
583  *
584  * \param[out] p Particle whose color information is modified.
585  * \param[in] color Color tag to assign.
586  */
587  void set_color_by_type(Pythia8::Particle &p, int color);
588  /**
589  * Hadronize a single partonic string configuration using Pythia8 and convert
590  * the produced hadrons into SMASH particles.
591  *
592  * The input event is interpreted as a single color-singlet string system.
593  * Fragmentation is performed in the string rest frame. The produced hadrons
594  * are converted to SMASH ParticleData objects, assigned formation times and
595  * cross-section scaling factors, and finally boosted out of the string rest
596  * frame.
597  *
598  * Leading hadrons originating from valence quark or diquark endpoints may be
599  * identified and assigned reduced cross sections according to the
600  * leading-hadron prescription.
601  *
602  * \param[in] string_evt Partonic string event to hadronize.
603  *
604  * \return List of fragmented hadrons on success.
605  * \return std::nullopt if fragmentation or particle conversion fails.
606  */
607  std::optional<ParticleList> hadronize(const Pythia8::Event &string_evt);
608 
609  /**
610  * Interface to pythia_sigmatot_ to compute cross-sections of A+B->
611  * different final states \iref{Schuler:1993wr}.
612  * \param[in] pdg_a pdg code of incoming particle A
613  * \param[in] pdg_b pdg code of incoming particle B
614  * \param[in] sqrt_s collision energy in the center of mass frame [GeV]
615  * \return array with single diffractive cross-sections AB->AX, AB->XB and
616  * double diffractive AB->XX.
617  */
618  std::array<double, 3> cross_sections_diffractive(int pdg_a, int pdg_b,
619  double sqrt_s) {
620  // This threshold magic is following Pythia. Todo(ryu): take care of this.
621  double sqrts_threshold = 2. * (1. + 1.0e-6);
622  /* In the case of mesons, the corresponding vector meson masses
623  * are used to evaluate the energy threshold. */
624  const int pdg_a_mod =
625  (std::abs(pdg_a) > 1000) ? pdg_a : 10 * (std::abs(pdg_a) / 10) + 3;
626  const int pdg_b_mod =
627  (std::abs(pdg_b) > 1000) ? pdg_b : 10 * (std::abs(pdg_b) / 10) + 3;
628  sqrts_threshold += pythia_hadron_->particleData.m0(pdg_a_mod) +
629  pythia_hadron_->particleData.m0(pdg_b_mod);
630  /* Constant cross-section for sub-processes below threshold equal to
631  * cross-section at the threshold. */
632  if (sqrt_s < sqrts_threshold) {
633  sqrt_s = sqrts_threshold;
634  }
635  pythia_sigmatot_.calc(pdg_a, pdg_b, sqrt_s);
636  return {pythia_sigmatot_.sigmaAX(), pythia_sigmatot_.sigmaXB(),
637  pythia_sigmatot_.sigmaXX()};
638  }
639 
640  /**
641  * \todo The following set_ functions are replaced with
642  * constructor with arguments.
643  * Must be cleaned up if necessary.
644  */
645 
646  /**
647  * set the minimum lightcone momentum scale carried by gluon.
648  * This is relevant for the double-diffractive process.
649  * The minimum lightcone momentum fraction is set to be
650  * pmin_gluon_lightcone_/sqrtsAB.
651  * \param p_light_cone_min a value that we want to use for
652  * pmin_gluon_lightcone_.
653  */
654  void set_pmin_gluon_lightcone(double p_light_cone_min) {
655  pmin_gluon_lightcone_ = p_light_cone_min;
656  }
657  /**
658  * lightcone momentum fraction of gluon is sampled
659  * according to probability distribution P(x) = 1/x * (1 - x)^{1 +
660  * pow_fgluon_beta_}
661  * in double-diffractive processes.
662  * \param betapow is a value that we want to use for pow_fgluon_beta_.
663  */
664  void set_pow_fgluon(double betapow) { pow_fgluon_beta_ = betapow; }
665  /**
666  * lightcone momentum fraction of quark is sampled
667  * according to probability distribution
668  * \f$ P(x) = x^{pow_fquark_alpha_ - 1} * (1 - x)^{pow_fquark_beta_ - 1} \f$
669  * in non-diffractive processes.
670  * \param alphapow is a value that we want to use for pow_fquark_alpha_.
671  * \param betapow is a value that we want to use for pow_fquark_beta_.
672  */
673  void set_pow_fquark(double alphapow, double betapow) {
674  pow_fquark_alpha_ = alphapow;
675  pow_fquark_beta_ = betapow;
676  }
677  /**
678  * set the average amount of transverse momentum transfer sigma_qperp_.
679  * \param sigma_qperp is a value that we want to use for sigma_qperp_.
680  */
681  void set_sigma_qperp_(double sigma_qperp) { sigma_qperp_ = sigma_qperp; }
682  /**
683  * set the string tension, which is used in form_intermediate_particles.
684  * \param kappa_string is a value that we want to use for string tension.
685  */
686  void set_tension_string(double kappa_string) {
687  kappa_tension_string_ = kappa_string;
688  }
689 
690  /**
691  * Set the center-of-mass energy used to initialize MPI-capable Pythia
692  * objects.
693  *
694  * If no value is set, the initialization energy is determined from the
695  * incoming hadrons.
696  *
697  * \param sqrts Center-of-mass energy [GeV] used for MPI initialization.
698  */
699  void set_mpi_initialization_sqrts(double sqrts) {
701  }
702 
703  /**
704  * initialization
705  * feed intial particles, time of collision and gamma factor of the center
706  * of mass. \param[in] incoming is the list of initial state particles.
707  * \param[in] tcoll is time of collision.
708  */
709  void init(const ParticleList &incoming, double tcoll);
710  /**
711  * compute three orthonormal basis vectors from unit vector
712  * in the longitudinal direction
713  * \param[in] evec_polar unit three-vector in the longitudinal direction
714  * \param[out] evec_basis orthonormal basis vectors of which
715  * evec_basis[0] is in the longitudinal direction while
716  * evec_basis[1] and evec_basis[2] span the transverse plane.
717  */
718  static void make_orthonormal_basis(ThreeVector &evec_polar,
719  std::array<ThreeVector, 3> &evec_basis);
720  /**
721  * compute the lightcone momenta of incoming particles
722  * where the longitudinal direction is set to be same
723  * as that of the three-momentum of particle A.
724  */
726 
727  /**
728  * Compare the valence quark contents of the actual and mapped hadrons and
729  * evaluate how many more constituents the actual hadron has compared to the
730  * mapped one.
731  * excess_quark[i - 1] is how many more quarks with flavor i (PDG id i)
732  * pdg_actual has compared to pdg_mapped.
733  * excess_antiq[i - 1] is how many more antiquarks with flavor i (PDG id -i)
734  * pdg_actual has compared to pdg_mapped.
735  *
736  * \param[in] pdg_actual PDG code of actual incoming particle.
737  * \param[in] pdg_mapped PDG code of mapped particles used in PYTHIA
738  * event generation.
739  * \param[out] excess_quark excess of quarks.
740  * \param[out] excess_antiq excess of anti-quarks.
741  */
742  static void find_excess_constituent(PdgCode &pdg_actual, PdgCode &pdg_mapped,
743  std::array<int, 5> &excess_quark,
744  std::array<int, 5> &excess_antiq);
745  /**
746  * Convert a partonic PYTHIA particle into the desired species
747  * and update the excess of constituents.
748  * If the quark flavor i is converted into another flavor j,
749  * excess_constituent[i - 1] increases by 1 and
750  * excess_constituent[j - 1] decreases by 1.
751  * Note that this happens only if
752  * excess_constituent[i - 1] < 0 and excess_constituent[j - 1] > 0
753  * (i.e., the incoming hadron has more constituents with flavor j
754  * and less constituents with flavor i, compared to the mapped hadron),
755  * so they get closer to 0 after the function call.
756  *
757  * \param[out] particle PYTHIA particle object to be converted.
758  * \param[out] excess_constituent excess in the number of quark constituents.
759  * If the particle has positive (negative) quark number,
760  * excess of quarks (anti-quarks) should be used.
761  *
762  * \see StringProcess::restore_constituent(Pythia8::Event &,
763  * std::array<std::array<int, 5>, 2> &,
764  * std::array<std::array<int, 5>, 2> &)
765  */
766  void replace_constituent(Pythia8::Particle &particle,
767  std::array<int, 5> &excess_constituent);
768 
769  /**
770  * Compute how many quarks and antiquarks we have in the system,
771  * and update the correspoing arrays with size 5.
772  * Note that elements of the array (0, 1, 2, 3, 4) correspond
773  * to d, u, s, c, b flavors.
774  *
775  * \param[in] event_intermediate PYTHIA partonic event record
776  * which contains output from PYTHIA (hard) event generation.
777  * \param[out] nquark_total total number of quarks in the system.
778  * This is computed based on event_intermediate.
779  * \param[out] nantiq_total total number of antiquarks in the system.
780  * This is computed based on event_intermediate.
781  */
782  void find_total_number_constituent(Pythia8::Event &event_intermediate,
783  std::array<int, 5> &nquark_total,
784  std::array<int, 5> &nantiq_total);
785 
786  /**
787  * Take total number of quarks and check if the system has
788  * enough constituents that need to be converted into other flavors.
789  * If that is not the case, a gluon is splitted into a quark-antiquark pair
790  * with desired flavor, so that their flavor can be changed afterwards.
791  * For example, if there is no antiquark in the system and we have
792  * excess_antiq = (1, -1, 0, 0, 0)
793  * (i.e., one ubar has to be converted into dbar),
794  * a gluon will be splitted into u-ubar pair.
795  *
796  * \param[out] event_intermediate PYTHIA partonic event record to be updated
797  * when a gluon happens to split into a qqbar pair.
798  * \param[out] nquark_total total number of quarks in the system.
799  * This is computed based on event_intermediate.
800  * \param[out] nantiq_total total number of antiquarks in the system.
801  * This is computed based on event_intermediate.
802  * \param[in] sign_constituent true (false)
803  * if want to check quarks (antiquarks) and their excesses.
804  * \param[in] excess_constituent excess in the number of quark constituents.
805  * If sign_constituent is true (false),
806  * excess of quarks (anti-quarks) should be used.
807  * \return false if there are not enough constituents and there is no gluon
808  * to split into desired quark-antiquark pair.
809  * Otherwise, it gives true.
810  */
812  Pythia8::Event &event_intermediate, std::array<int, 5> &nquark_total,
813  std::array<int, 5> &nantiq_total, bool sign_constituent,
814  std::array<std::array<int, 5>, 2> &excess_constituent);
815 
816  /**
817  * Take total number of quarks and check if the system has
818  * enough constituents that need to be converted into other flavors.
819  * If that is not the case, excesses of quarks and antiquarks are
820  * modified such that the net quark number of each flavor is
821  * conserved.
822  * For example, if there is no antiquark in the system and we have
823  * excess_antiq = (1, -1, 0, 0, 0)
824  * (i.e., one ubar has to be converted into dbar),
825  * excess_antiq will be changed into (0, 0, 0, 0, 0) and
826  * (-1, 1, 0, 0, 0) will be added to excess_quark
827  * (i.e., one d quark has to be converted into u quark instead).
828  *
829  * Number of quarks is checked if the first argument is
830  * the total number of quarks, and the second and third arguments are
831  * respectively excesses of quarks and antiquarks.
832  * Number of antiquarks is checked if the first argument is
833  * the total number of antiquarks, and the second and third arguments are
834  * respectively excesses of antiquarks and quarks.
835  *
836  * \param[in] nquark_total total number of quarks (antiquarks)
837  * in the system.
838  * \param[out] excess_quark excess of quarks (antiquarks)
839  * in incoming particles, compared to the mapped ones.
840  * \param[out] excess_antiq excess of anti-quarks (quarks)
841  * in incoming particles, compared to the mapped ones.
842  */
843  void rearrange_excess(std::array<int, 5> &nquark_total,
844  std::array<std::array<int, 5>, 2> &excess_quark,
845  std::array<std::array<int, 5>, 2> &excess_antiq);
846 
847  /**
848  * Take the intermediate partonic state from PYTHIA event with mapped hadrons
849  * and convert constituents into the desired ones according to the excess of
850  * quarks and anti-quarks.
851  * Quark (antiquark) flavor is changed and excess of quark (antiquark)
852  * is also updated by calling StringProcess::replace_constituent.
853  * Beginning with the most forward (or backward) constituent,
854  * conversion is done until the total net quark number of each flavor
855  * is same with that of incoming hadrons.
856  * (i.e., excess_quark minus excess_antiq of incoming hadrons becomes zero.)
857  *
858  * However, note that there are some circumstances where
859  * this procedure is not directly carried out.
860  * For example, a proton-kaon(+) collision mapped onto a proton-pion(+)
861  * might be an issue if it involves d + dbar -> g g partonic interaction,
862  * given that we anticipate to change dbar to sbar.
863  * If such case occurs, we first try to split gluon into
864  * quark-antiquark pair with desired flavor.
865  * If there are not enough gluons to split, we try to modify the excesses
866  * of constituents such that the net quark number is conserved.
867  *
868  * \param[out] event_intermediate PYTHIA partonic event record to be updated
869  * according to the valence quark contents of incoming hadrons.
870  * \param[out] excess_quark excess of quarks
871  * in incoming particles, compared to the mapped ones.
872  * \param[out] excess_antiq excess of anti-quarks
873  * in incoming particles, compared to the mapped ones.
874  *
875  * \see StringProcess::replace_constituent(Pythia8::Particle &,
876  * std::array<int, 5> &)
877  * \see StringProcess::splitting_gluon_qqbar(Pythia8::Event &,
878  * std::array<int, 5> &, std::array<int, 5> &,
879  * bool, std::array<std::array<int, 5>, 2> &)
880  * \see StringProcess::rearrange_excess(std::array<int, 5> &,
881  * std::array<std::array<int, 5>, 2> &,
882  * std::array<std::array<int, 5>, 2> &)
883  */
884  bool restore_constituent(Pythia8::Event &event_intermediate,
885  std::array<std::array<int, 5>, 2> &excess_quark,
886  std::array<std::array<int, 5>, 2> &excess_antiq);
887 
888  /**
889  * Identify a set of partons, which are connected
890  * to form a color-neutral string, from a given PYTHIA event record.
891  * All partons found are moved into a new event record for the further
892  * hadronization process.
893  * Note that col and acol of Pythia8::Particle contain information
894  * on the color flow.
895  * This function begins with the most forward (or backward) parton.
896  *
897  * For example,
898  * quark (col = 1, acol = 0), gluon (col = 2, acol = 1)
899  * and antiquark (col = 0, acol = 2) correspond to
900  * a \f$ \bar{q} \, g \, q \f$ mesonic string.
901  * quark (col = 1, acol = 0) and diquark (col = 0, acol = 1) correspond to
902  * a \f$ qq \, q\f$ baryonic string.
903  *
904  * \param[in] find_forward_string If it is set to be true (false),
905  * it begins with forward (backward) parton.
906  * \param[out] event_intermediate PYTHIA event record
907  * from which a string is identified.
908  * All partons found here are removed.
909  * \param[out] event_hadronize PYTHIA event record
910  * to which partons in a string are added.
911  */
912  void compose_string_parton(bool find_forward_string,
913  Pythia8::Event &event_intermediate,
914  Pythia8::Event &event_hadronize);
915  /**
916  * Identify a set of partons and junction(s), which are connected
917  * to form a color-neutral string, from a given PYTHIA event record.
918  * All partons found are moved into a new event record for the further
919  * hadronization process.
920  * Junction topology in PYTHIA combines three quarks (antiquarks)
921  * to make a color-neutral baryonic (anti-baryonic) configuration.
922  * A junction (anti-junction) carries three color (anti-color) indices
923  * which are connected with quarks (antiquarks).
924  * This function begins with the first junction.
925  *
926  * For example,
927  * if there is a kind-1 junction with legs (col = 1, 2 and 3),
928  * it will first look for three partons with color indices col = 1, 2 and 3
929  * and trace color indices until each leg is ``closed'' with quark.
930  * If there is no quark in the end, there should be an anti-junction
931  * and its legs are connected to partons with corresponding anti-colors.
932  *
933  * \param[out] find_forward_string If it is set to be true (false),
934  * it is a string in the forward (backward)
935  * direction.
936  * \param[out] event_intermediate PYTHIA event record
937  * from which a string is identified.
938  * All partons and junction(s) found here
939  * are removed.
940  * \param[out] event_hadronize PYTHIA event record
941  * to which partons in a string are added.
942  *
943  * \see StringProcess::find_junction_leg(bool, std::vector<int> &,
944  * Pythia8::Event &, Pythia8::Event &)
945  */
946  void compose_string_junction(bool &find_forward_string,
947  Pythia8::Event &event_intermediate,
948  Pythia8::Event &event_hadronize);
949 
950  /**
951  * Identify partons, which are associated with junction legs,
952  * from a given PYTHIA event record.
953  * All partons found are moved into a new event record for the further
954  * hadronization process.
955  * \param[in] sign_color true (false) if the junction is associated with
956  * color (anti-color) indices, corresponding
957  * baryonic (anti-baryonic) string
958  * \param[out] col set of color indices that need to be found.
959  * The value is set to be zero
960  * once the corresponding partons are found.
961  * \param[out] event_intermediate PYTHIA event record
962  * from which a string is identified.
963  * All partons and junction(s) found here
964  * are removed.
965  * \param[out] event_hadronize PYTHIA event record
966  * to which partons in a string are added.
967  *
968  * \see StringProcess::compose_string_junction(bool &,
969  * Pythia8::Event &, Pythia8::Event &)
970  */
971  void find_junction_leg(bool sign_color, std::vector<int> &col,
972  Pythia8::Event &event_intermediate,
973  Pythia8::Event &event_hadronize);
974 
975  /**
976  * Obtain index of the most forward or backward particle
977  * in a given PYTHIA event record.
978  * \param[in] find_forward if it looks for the most forward
979  * or backward particle.
980  * \param[in] np_end number of the last particle entries to be excluded
981  * in lookup. In other words, it finds the most forward
982  * (or backward) particle among
983  * event[1, ... , event.size() - 1 - np_end].
984  * \param[in] event PYTHIA event record which contains particle entries.
985  * Note that event[0] is reserved for information
986  * on the entire system.
987  * \return index of the selected particle,
988  * which is used to access the specific particle entry
989  * in the event record.
990  */
991  int get_index_forward(bool find_forward, int np_end, Pythia8::Event &event) {
992  int iforward = 1;
993  for (int ip = 2; ip < event.size() - np_end; ip++) {
994  const double y_quark_current = event[ip].y();
995  const double y_quark_forward = event[iforward].y();
996  if ((find_forward && y_quark_current > y_quark_forward) ||
997  (!find_forward && y_quark_current < y_quark_forward)) {
998  iforward = ip;
999  }
1000  }
1001  return iforward;
1002  }
1003 
1004  /**
1005  * Set formation times and cross-section scaling factors for fragmented
1006  * hadrons as described in \iref{Andersson:1983ia}.
1007  *
1008  * The input particles are expected to be in the string rest frame. This
1009  * function modifies them in place: particle momenta and production vertices
1010  * are boosted out of the string rest frame, formation times are assigned, and
1011  * optionally leading-hadron cross-section scaling factors are recomputed.
1012  *
1013  * \param[in,out] intermediate_particles Fragmented hadrons to process.
1014  * \param[in] pString Four-momentum of the string.
1015  * \param[in] evecLong Unit 3-vector along which the string is stretched.
1016  * \param[in] additional_xsec_supp Additional multiplicative factor applied to
1017  * cross-section scaling, e.g. coherence or medium effects.
1018  * \param[in] find_and_scale_leading If true, identify leading hadrons from
1019  * valence quark or diquark endpoints and assign their cross-section scaling
1020  * factors according to the leading-hadron prescription.
1021  *
1022  * \pre intermediate_particles is not empty.
1023  * \pre intermediate_particles contains only hadrons.
1024  */
1025  void form_intermediate_particles(ParticleList &intermediate_particles,
1026  const FourVector &pString,
1027  const ThreeVector &evecLong,
1028  double additional_xsec_supp = 1.0,
1029  bool find_and_scale_leading = true);
1030 
1031  /**
1032  * append new particle from PYTHIA to a specific particle list
1033  * \param[in] pdgid PDG id of particle
1034  * \param[in] momentum four-momentum of particle
1035  * \param[out] intermediate_particles particle list to which
1036  * the new particle is added.
1037  * \return whether PDG id exists in ParticleType table.
1038  */
1039  static bool append_intermediate_list(int pdgid, FourVector momentum,
1040  ParticleList &intermediate_particles) {
1041  const std::string s = std::to_string(pdgid);
1042  PdgCode pythia_code(s);
1043  ParticleTypePtr new_type = ParticleType::try_find(pythia_code);
1044  if (new_type) {
1045  ParticleData new_particle(ParticleType::find(pythia_code));
1046  new_particle.set_4momentum(momentum);
1047  intermediate_particles.push_back(new_particle);
1048  return true;
1049  } else {
1050  // if the particle does not exist in SMASH the pythia event is rerun
1051  return false;
1052  }
1053  }
1054 
1055  /**
1056  * convert Kaon-L or Kaon-S into K0 or Anti-K0
1057  * \param[out] pythia_id is PDG id to be converted.
1058  */
1059  static void convert_KaonLS(int &pythia_id) {
1060  if (pythia_id == 310 || pythia_id == 130) {
1061  pythia_id = (random::uniform_int(0, 1) == 0) ? 311 : -311;
1062  }
1063  }
1064 
1065  /**
1066  * find two quarks from a diquark. Order does not matter.
1067  * \param[in] diquark PDG id of diquark
1068  * \param[out] q1 PDG id of quark 1
1069  * \param[out] q2 PDG id of quark 2
1070  * \param[out] deg_spin spin degeneracy
1071  */
1072  static void quarks_from_diquark(int diquark, int &q1, int &q2, int &deg_spin);
1073 
1074  /**
1075  * Construct diquark from two quarks. Order does not matter.
1076  * \param[in] q1 PDG code of quark 1
1077  * \param[in] q2 PDG code of quark 2
1078  * \return PDG code of diquark composed of q1 and q2
1079  */
1080  static int diquark_from_quarks(int q1, int q2);
1081 
1082  /**
1083  * make a random selection to determine partonic contents at the string ends.
1084  * \param[in] pdgcode_in is PdgCode of hadron which transforms into a string.
1085  * \param[out] idq1 is PDG id of quark or anti-diquark.
1086  * \param[out] idq2 is PDG id of anti-quark or diquark.
1087  * \param[in] xi probability to split a nucleon into the quark it has only
1088  * once and a diquark of another flavour.
1089  */
1090  static void make_string_ends(const PdgCode &pdgcode_in, int &idq1, int &idq2,
1091  double xi);
1092 
1093  /**
1094  * Assign a cross section scaling factor to all outgoing particles.
1095  *
1096  * The factor is only non-zero, when the outgoing particle carries
1097  * a valence quark from the excited hadron. The assigned cross section
1098  * scaling factor is equal to the number of the valence quarks from the
1099  * fragmented hadron contained in the fragment divided by the total number
1100  * of valence quarks of that fragment multiplied by a coherence factor
1101  * \param[in] baryon_string baryon number of the string
1102  * \param[out] outgoing_particles list of string fragments to which scaling
1103  * factors are assigned
1104  * \param[in] evecLong direction in which the string is stretched
1105  * \param[in] suppression_factor additional coherence factor to be
1106  * multiplied with scaling factor
1107  */
1108  static void assign_all_scaling_factors(int baryon_string,
1109  ParticleList &outgoing_particles,
1110  const ThreeVector &evecLong,
1111  double suppression_factor);
1112 
1113  /**
1114  * Find the leading string fragments
1115  *
1116  * Find the first particle, which can carry nq1, and the last particle,
1117  * which can carry nq2 valence quarks and return their indices in
1118  * the given list.
1119  *
1120  * \param[in] nq1 number of valence quarks from excited hadron at forward
1121  * end of the string
1122  * \param[in] nq2 number of valence quarks from excited hadron at backward
1123  * end of the string
1124  * \param[in] list list of string fragments
1125  * \return indices of the leading hadrons in \p list
1126  */
1127  static std::pair<int, int> find_leading(int nq1, int nq2, ParticleList &list);
1128 
1129  /**
1130  * Assign a cross section scaling factor to the given particle.
1131  *
1132  * The scaling factor is the number of quarks from the excited hadron,
1133  * that the fragment carries devided by the total number of quarks in
1134  * this fragment multiplied by coherence factor.
1135  *
1136  * \param[in] nquark number of valence quarks from the excited hadron
1137  * contained in the given string fragment \p data
1138  * \param[out] data particle to assign a scaling factor to
1139  * \param[in] suppression_factor coherence factor to decrease scaling factor
1140  */
1141  static void assign_scaling_factor(int nquark, ParticleData &data,
1142  double suppression_factor);
1143 
1144  /**
1145  * Take pdg code and map onto particle specie
1146  * which can be handled by PYTHIA.
1147  * Positively charged baryons are mapped onto proton and other baryons are
1148  * mapped onto neutrons. Same rule applies for anti-baryons.
1149  * Positively (negatively) charged mesons are mapped onto pi+ (pi-).
1150  * Negatively and positively charged leptons are mapped respectivly onto
1151  * electron and positron.
1152  * Currently, we do not have cross sections for leptons and photons
1153  * with high energy, so such collisions should not happen.
1154  *
1155  * \param[in] pdg PdgCode that will be mapped
1156  * \return mapped PDG id to be used in PYTHIA
1157  *
1158  * \throw std::runtime_error
1159  * if the incoming particle is neither hadron nor lepton.
1160  */
1161  static int pdg_map_for_pythia(PdgCode &pdg);
1162 
1163  /**
1164  * \return forward lightcone momentum incoming particle A in CM-frame [GeV]
1165  * \see PPosA_
1166  */
1167  double getPPosA() { return PPosA_; }
1168 
1169  /**
1170  * \return backward lightcone momentum incoming particle Af in CM-frame [GeV]
1171  * \see PNegA_
1172  */
1173  double getPNegA() { return PNegA_; }
1174 
1175  /**
1176  * \return forward lightcone momentum incoming particle B in CM-frame [GeV]
1177  * \see PPosB_
1178  */
1179  double getPPosB() { return PPosB_; }
1180 
1181  /**
1182  * \return backward lightcone momentum incoming particle B in CM-frame [GeV]
1183  * \see PNegB_
1184  */
1185  double getPnegB() { return PNegB_; }
1186 
1187  /**
1188  * \return mass of incoming particle A [GeV]
1189  * \see massA_
1190  */
1191  double get_massA() { return massA_; }
1192 
1193  /**
1194  * \return mass of incoming particle B [GeV]
1195  * \see massB_
1196  */
1197  double get_massB() { return massB_; }
1198 
1199  /**
1200  * \return sqrt of mandelstam s [GeV]
1201  * \see sqrtsAB_
1202  */
1203  double get_sqrts() { return sqrtsAB_; }
1204 
1205  /**
1206  * \return array with PDG Codes of incoming particles
1207  * \see PDGcodes_
1208  */
1209  std::array<PdgCode, 2> get_PDGs() { return PDGcodes_; }
1210 
1211  /**
1212  * \return momenta of incoming particles in lab frame [GeV]
1213  * \see plab_
1214  */
1215  std::array<FourVector, 2> get_plab() { return plab_; }
1216 
1217  /**
1218  * \return momenta of incoming particles in center of mass frame [GeV]
1219  * \see pcom_
1220  */
1221  std::array<FourVector, 2> get_pcom() { return pcom_; }
1222 
1223  /**
1224  * \return velocity four vector of the COM in the lab frame
1225  * \see ucomAB_
1226  */
1228 
1229  /**
1230  * \return velocity three vector of the COM in the lab frame
1231  * \see vcomAB_
1232  */
1234 
1235  /**
1236  * \return collision time
1237  * \see time_collision_
1238  */
1239  double get_tcoll() { return time_collision_; }
1240 
1241  /**
1242  * \return final state
1243  * \see final_state_
1244  */
1245  ParticleList get_final_state() { return final_state_; }
1246 };
1247 
1248 } // namespace smash
1249 
1250 #endif // SRC_INCLUDE_SMASH_STRINGPROCESS_H_
Interface to the SMASH configuration files.
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
Definition: fourvector.h:33
ParticleData contains the dynamic information of a certain particle.
Definition: particledata.h:59
void set_4momentum(const FourVector &momentum_vector)
Set the particle's 4-momentum directly.
Definition: particledata.h:177
A pointer-like interface to global references to ParticleType objects.
Definition: particletype.h:731
static const ParticleTypePtr try_find(PdgCode pdgcode)
Returns the ParticleTypePtr for the given pdgcode.
Definition: particletype.cc:89
static const ParticleType & find(PdgCode pdgcode)
Returns the ParticleType object for the given pdgcode.
Definition: particletype.cc:99
PdgCode stores a Particle Data Group Particle Numbering Scheme particle type number.
Definition: pdgcode.h:108
String excitation processes used in SMASH.
Definition: stringprocess.h:46
Pythia8::StringFlav pythia_stringflav_
An object for the flavor selection in string fragmentation in the case of separate fragmentation func...
bool next_SDiff(bool is_AB_to_AX)
Single-diffractive process is based on single pomeron exchange described in Ingelman:1984ns .
pythia_map hard_map_
Map object to contain the different pythia objects.
void set_pmin_gluon_lightcone(double p_light_cone_min)
set the minimum lightcone momentum scale carried by gluon.
Pythia8::SigmaTotal pythia_sigmatot_
An object to compute cross-sections.
double pow_fgluon_beta_
parameter for the gluon distribution function
Definition: stringprocess.h:88
LeadingStatus
PYTHIA status codes used to track leading/valence ancestry.
@ FromLeadingDiquark
Custom status assigned to hadrons containing a leading diquark.
@ LeadingQuark
Custom status assigned to leading (valence) quarks.
@ NonLeadingParton
Standard PYTHIA status for non-leading partons that should be hadronized.
@ LeadingDiquark
Standard PYTHIA beam-remnant status used for leading diquarks.
@ FromLeadingQuark
Custom status assigned to hadrons containing a leading quark.
std::map< std::pair< int, int >, std::unique_ptr< Pythia8::Pythia > > pythia_map
Map containing PYTHIA objects for hard string routines.
std::vector< Pythia8::Event > string_parton_events_
PYTHIA event records containing string partons to be hadronized.
Pythia8::Event event_intermediate_
event record for intermediate partonic state in the hard string routine
std::array< PdgCode, 2 > PDGcodes_
PdgCodes of incoming particles.
Definition: stringprocess.h:68
double time_formation_const_
constant proper time in the case of constant formation time [fm]
double PNegB_
backward lightcone momentum p^{-} of incoming particle B in CM-frame [GeV]
Definition: stringprocess.h:60
void set_tension_string(double kappa_string)
set the string tension, which is used in form_intermediate_particles.
static FourVector make_smash_4vec(const Pythia8::Vec4 &p)
Convert a PYTHIA four-vector into a SMASH four-vector.
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.
double pow_fquark_beta_
parameter for the quark distribution function
Definition: stringprocess.h:98
bool next_NDiffSoft()
Soft Non-diffractive process is modelled in accordance with dual-topological approach Capella:1978ig ...
bool next_DDiff()
Double-diffractive process ( A + B -> X + X ) is similar to the single-diffractive process,...
static int pdg_map_for_pythia(PdgCode &pdg)
Take pdg code and map onto particle specie which can be handled by PYTHIA.
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...
void set_pow_fquark(double alphapow, double betapow)
lightcone momentum fraction of quark is sampled according to probability distribution in non-diffrac...
Pythia8::RotBstMatrix to_cm_
Rotation/boost matrix to transform particles to the center-of-mass frame.
FourVector ucomAB_
velocity four vector of the center of mass in the lab frame
Definition: stringprocess.h:74
ThreeVector vcomAB_
velocity three vector of the center of mass in the lab frame
Definition: stringprocess.h:76
void compute_incoming_lightcone_momenta()
compute the lightcone momenta of incoming particles where the longitudinal direction is set to be sam...
double popcorn_rate_
popcorn rate
double pmin_gluon_lightcone_
the minimum lightcone momentum scale carried by a gluon [GeV]
Definition: stringprocess.h:83
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...
static std::pair< int, int > find_leading(int nq1, int nq2, ParticleList &list)
Find the leading string fragments.
double PPosA_
forward lightcone momentum p^{+} of incoming particle A in CM-frame [GeV]
Definition: stringprocess.h:51
std::optional< ParticleList > hadronize(const Pythia8::Event &string_evt)
Hadronize a single partonic string configuration using Pythia8 and convert the produced hadrons into ...
double sqrtsAB_
sqrt of Mandelstam variable s of collision [GeV]
Definition: stringprocess.h:66
ParticleList final_state_
final state array which must be accessed after the collision
bool is_leading_from_quark(const Pythia8::Particle &p)
Check whether a particle is tagged as originating from a leading quark.
double PNegA_
backward lightcone momentum p^{-} of incoming particle A in CM-frame [GeV]
Definition: stringprocess.h:57
bool append_string(const Pythia8::Vec4 &p_str, const std::array< int, 2 > &ends, int color_tag, bool use_projectile_axis, bool random_flip_of_endpoints=false)
Append a single two-endpoint string as an independent PYTHIA event.
bool use_monash_tune_
Whether to use the monash tune Skands:2014pea for all string processes.
double soft_t_form_
factor to be multiplied to formation times in soft strings
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::unique_ptr< Pythia8::Pythia > pythia_hadron_
PYTHIA object used in fragmentation.
double massA_
mass of incoming particle A [GeV]
Definition: stringprocess.h:62
bool next_Hard(ProcessType type)
Hard Non-diffractive process is based on PYTHIA 8 with partonic showers and interactions.
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.
double PPosB_
forward lightcone momentum p^{+} of incoming particle B in CM-frame [GeV]
Definition: stringprocess.h:54
std::array< ThreeVector, 3 > evecBasisAB_
Orthonormal basis vectors in the center of mass frame, where the 0th one is parallel to momentum of i...
Definition: stringprocess.h:81
std::vector< std::string > pythia_settings_
Additional Pythia 8 settings passed to each internal Pythia instance.
std::optional< double > mpi_initialization_sqrts_
Optional center-of-mass energy used to initialize MPI-capable Pythia objects.
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...
double string_sigma_T_
transverse momentum spread in string fragmentation
ParticleList get_final_state()
std::array< double, 3 > cross_sections_diffractive(int pdg_a, int pdg_b, double sqrt_s)
Interface to pythia_sigmatot_ to compute cross-sections of A+B-> different final states Schuler:1993w...
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
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.
bool is_leading_parton(const Pythia8::Particle &p)
Check whether a particle is tagged as a leading parton.
static void convert_KaonLS(int &pythia_id)
convert Kaon-L or Kaon-S into K0 or Anti-K0
ThreeVector get_vcom()
double additional_xsec_supp_
additional cross-section suppression factor to take coherence effect into account.
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 damp_popcorn_
damp popcorn meson from diquark remnant endpoint rate
double strange_supp_
strange quark suppression factor
bool string_above_threshold(const Pythia8::Event &event)
Check whether all strings in a PYTHIA event are above fragmentation threshold.
std::array< PdgCode, 2 > get_PDGs()
static int diquark_from_quarks(int q1, int q2)
Construct diquark from two quarks.
std::array< FourVector, 2 > get_plab()
std::vector< bool > compute_beam_valence_flags(Pythia8::Pythia &pythia)
Compute flags identifying beam valence partons (quarks or diquarks) that act as leading partons after...
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 kappa_tension_string_
string tension [GeV/fm]
double pow_fquark_alpha_
parameter for the quark distribution function
Definition: stringprocess.h:93
bool is_leading(const Pythia8::Particle &p)
Check whether a particle is tagged as originating from a leading endpoint.
double stringz_b_leading_
parameter (StringZ:bLund) for the fragmentation function of leading baryon in soft non-diffractive st...
static bool append_intermediate_list(int pdgid, FourVector momentum, ParticleList &intermediate_particles)
append new particle from PYTHIA to a specific particle list
int leading_hadron_status_from_endpoint(const Pythia8::Particle &end)
Determine the custom leading-hadron status code from a string endpoint.
void set_pow_fgluon(double betapow)
lightcone momentum fraction of gluon is sampled according to probability distribution P(x) = 1/x * (1...
void set_mpi_initialization_sqrts(double sqrts)
Set the center-of-mass energy used to initialize MPI-capable Pythia objects.
bool next(ProcessType type)
Generate the next string process for a given process type.
bool mass_dependent_formation_times_
Whether the formation time should depend on the mass of the fragment according to Andersson:1983ia e...
double stringz_b_produce_
parameter (StringZ:bLund) for the fragmentation function of other (produced) hadrons in soft non-diff...
std::array< FourVector, 2 > get_pcom()
bool next_BBbarAnn()
Baryon-antibaryon annihilation process Based on what UrQMD Bass:1998ca , Bleicher:1999xi does,...
void set_color_by_type(Pythia8::Particle &p, int color)
Set the color or anticolor index of a particle according to its type.
StringProcess(Configuration &config)
Constructor, initializes PYTHIA.
void set_sigma_qperp_(double sigma_qperp)
set the average amount of transverse momentum transfer sigma_qperp_.
void tag_leading_hadrons(Pythia8::Event &event)
Tag leading hadrons in a hadronized string.
double stringz_a_leading_
parameter (StringZ:aLund) for the fragmentation function of leading baryon in soft non-diffractive st...
void init(const ParticleList &incoming, double tcoll)
initialization feed intial particles, time of collision and gamma factor of the center of mass.
bool is_leading_from_diquark(const Pythia8::Particle &p)
Check whether a particle is tagged as originating from a leading diquark.
double sigma_qperp_
Transverse momentum spread of the excited strings.
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...
static Pythia8::Vec4 make_pythia_4vec(const FourVector &p)
Convert a SMASH four-vector into a PYTHIA four-vector.
bool separate_fragment_baryon_
Whether to use a separate fragmentation function for leading baryons.
std::array< FourVector, 2 > plab_
momenta of incoming particles in the lab frame [GeV]
Definition: stringprocess.h:70
std::array< FourVector, 2 > pcom_
momenta of incoming particles in the center of mass frame [GeV]
Definition: stringprocess.h:72
double time_collision_
time of collision in the computational frame [fm]
void form_intermediate_particles(ParticleList &intermediate_particles, const FourVector &pString, const ThreeVector &evecLong, double additional_xsec_supp=1.0, bool find_and_scale_leading=true)
Set formation times and cross-section scaling factors for fragmented hadrons as described in Andersso...
double diquark_supp_
diquark suppression factor
static void find_excess_constituent(PdgCode &pdg_actual, PdgCode &pdg_mapped, std::array< int, 5 > &excess_quark, std::array< int, 5 > &excess_antiq)
Compare the valence quark contents of the actual and mapped hadrons and evaluate how many more consti...
double estimate_string_threshold(int p_left, int p_right)
Estimate the minimum invariant mass required for a string to fragment.
double massB_
mass of incoming particle B [GeV]
Definition: stringprocess.h:64
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...
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 ...
double stringz_a_produce_
parameter (StringZ:aLund) for the fragmentation function of other (produced) hadrons in soft non-diff...
void init_pythia_hadron_rndm()
Set PYTHIA random seeds to be desired values.
static void assign_scaling_factor(int nquark, ParticleData &data, double suppression_factor)
Assign a cross section scaling factor to the given particle.
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,...
static void quarks_from_diquark(int diquark, int &q1, int &q2, int &deg_spin)
find two quarks from a diquark.
The ThreeVector class represents a physical three-vector with the components .
Definition: threevector.h:31
Collection of useful constants that are known at compile time.
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > & logg
An array that stores all pre-configured Logger objects.
Definition: logging.h:245
constexpr int p
Proton.
T uniform_int(T min, T max)
Definition: random.h:106
Definition: action.h:24
constexpr int maximum_rndm_seed_in_pythia
The maximum value of the random seed used in PYTHIA.
Definition: constants.h:114
ProcessType
ProcessTypes are used to identify the type of the process.
Definition: processbranch.h:39
std::string to_string(ThermodynamicQuantity quantity)
Convert a ThermodynamicQuantity enum value to its corresponding string.
Definition: stringify.cc:26
static constexpr int LPythia
Definition: stringprocess.h:27