Version: SMASH-3.4
particletype.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2021,2023-2026
3  * SMASH Team
4  *
5  * GNU General Public License (GPLv3 or later)
6  */
7 #ifndef SRC_INCLUDE_SMASH_PARTICLETYPE_H_
8 #define SRC_INCLUDE_SMASH_PARTICLETYPE_H_
9 
10 #include <algorithm>
11 #include <cassert>
12 #include <cstdint>
13 #include <optional>
14 #include <string>
15 #include <utility>
16 #include <vector>
17 
18 #include "forwarddeclarations.h"
19 #include "macros.h"
20 #include "pdgcode.h"
21 
22 namespace smash {
23 
24 /**
25  * Represent the parity of a particle type.
26  */
27 enum class Parity {
28  /// Positive parity.
29  Pos,
30  /// Negative parity.
31  Neg
32 };
33 
34 /// Decide which decay mode widths are returned in get partical widths.
35 enum class WhichDecaymodes {
36  /// All decay mode widths
37  All,
38  /// Ignore dilepton decay modes widths
39  Hadronic,
40  /// Only return dilepton decays widths
41  Dileptons
42 };
43 
44 /**
45  * \param p Given parity.
46  * \return Inverted parity.
47  */
49  switch (p) {
50  case Parity::Pos:
51  return Parity::Neg;
52  case Parity::Neg:
53  return Parity::Pos;
54  }
55  // This is unreachable and should be optimized away.
56  // It is required to silence a compiler warning.
57  throw std::runtime_error("unreachable");
58 }
59 
60 /**
61  * \param x Left-hand parity
62  * \param y Right-hand parity
63  * \return Product of `x` and `y`.
64  */
65 inline Parity operator*(Parity x, Parity y) {
66  if (x == y) {
67  return Parity::Pos;
68  } else {
69  return Parity::Neg;
70  }
71 }
72 
73 /**
74  * \param x Left-hand parity
75  * \param y Right-hand parity
76  * \return Product of `x` and `y`.
77  */
78 inline void operator*=(Parity &x, Parity y) {
79  if (x == y) {
80  x = Parity::Pos;
81  } else {
82  x = Parity::Neg;
83  }
84 }
85 
86 /**
87  * \ingroup data
88  *
89  * Particle type contains the static properties of a particle species
90  *
91  * Before creation of Experiment, SMASH initializes the list of particles
92  * (\ref list_all). After construction these values are immutable.
93  *
94  * The list of particles is stored in such a way that look up of a ParticleType
95  * object (\ref find) for a given PDG code is as efficient as possible
96  * (\f$\mathcal O(\log N)\f$). This is still not efficient enough to use PdgCode
97  * as a substitute for storing information about a particle type, though. Use
98  * ParticleTypePtr instead.
99  */
101  public:
102  /**
103  * Decay width cutoff for considering a particle as stable.
104  *
105  * We currently regard a particle type as stable if its on-shell width is less
106  * than 10 keV. The cutoff is chosen such that the η and the η' are stable.
107  */
108  // If this is changed, make sure to update the userguide in
109  // `include/configuration.h`.
110  static constexpr double width_cutoff = 1e-5;
111 
112  /**
113  * Creates a fully initialized ParticleType object.
114  *
115  * \param[in] n The name of the particle.
116  * \param[in] m The mass of the particle.
117  * \param[in] w The width of the particle.
118  * \param[in] p The parity of the particle.
119  * \param[in] id The PDG code of the particle.
120  *
121  * \note The remaining properties ParticleType provides are derived from the
122  * PDG code and therefore cannot be set explicitly (this avoids the
123  * chance of introducing inconsistencies).
124  */
125  ParticleType(std::string n, double m, double w, Parity p, PdgCode id);
126 
127  /**
128  * Copies are not allowed as they break intended use. Instead use a const-ref
129  * or ParticleTypePtr (as returned from operator&).
130  */
131  ParticleType(const ParticleType &) = delete;
132  /// assignment is not allowed, see copy constructor above
133  ParticleType &operator=(const ParticleType &) = delete;
134 
135  /// move ctors are needed for std::sort
136  ParticleType(ParticleType &&) = default;
137  /// move ctors are needed for std::sort
139 
140  /// \return the DecayModes object for this particle type.
141  const DecayModes &decay_modes() const;
142 
143  /// \return the name of the particle.
144  const std::string &name() const { return name_; }
145 
146  /// \return the particle pole mass.
147  double mass() const { return mass_; }
148 
149  /// \return the squared particle mass.
150  double mass_sqr() const { return mass_ * mass_; }
151 
152  /// \return the particle width (at the mass pole).
153  double width_at_pole() const { return width_; }
154 
155  /// \return the parity of the particle.
156  Parity parity() const { return parity_; }
157 
158  /// \return the PDG code of the particle.
159  PdgCode pdgcode() const { return pdgcode_; }
160 
161  /// \copydoc PdgCode::has_antiparticle
162  bool has_antiparticle() const { return pdgcode_.has_antiparticle(); }
163 
164  /// \return a pointer to the corresponding antiparticle ParticleType object.
166 
167  /// \copydoc PdgCode::antiparticle_sign
168  int antiparticle_sign() const { return pdgcode_.antiparticle_sign(); }
169 
170  /**
171  * Returns twice the isospin vector length \f$I\f$.
172  *
173  * This returns e.g. 1 for nucleons, 2 for pions and 3 for Deltas.
174  * It is always positive.
175  */
176  int isospin() const;
177 
178  /// \copydoc PdgCode::isospin3
179  int isospin3() const { return I3_; }
180 
181  /// \return the isospin-3 component relative to the total isospin.
182  double isospin3_rel() const {
183  unsigned int I = isospin();
184  return (I == 0) ? 0 : static_cast<double>(isospin3()) / I;
185  }
186 
187  /// \return a pointer to the Isospin-multiplet of this PDG Code.
189 
190  /// \copydoc PdgCode::charge
191  int32_t charge() const { return charge_; }
192 
193  /// \copydoc PdgCode::spin
194  unsigned int spin() const { return pdgcode_.spin(); }
195 
196  /// \copydoc PdgCode::spin_degeneracy
197  unsigned int spin_degeneracy() const { return pdgcode_.spin_degeneracy(); }
198 
199  /// \copydoc PdgCode::is_hadron
200  bool is_hadron() const { return pdgcode_.is_hadron(); }
201 
202  /// \copydoc PdgCode::is_lepton
203  bool is_lepton() const { return pdgcode_.is_lepton(); }
204 
205  /// \copydoc PdgCode::is_baryon
206  bool is_baryon() const { return pdgcode_.is_baryon(); }
207 
208  /// \copydoc PdgCode::is_meson
209  bool is_meson() const { return pdgcode_.is_meson(); }
210 
211  /// \copydoc PdgCode::baryon_number
212  int baryon_number() const { return pdgcode_.baryon_number(); }
213 
214  /// \copydoc PdgCode::strangeness
215  int strangeness() const { return pdgcode_.strangeness(); }
216 
217  /// \copydoc PdgCode::is_nucleon
218  bool is_nucleon() const { return pdgcode_.is_nucleon(); }
219 
220  /// \copydoc PdgCode::is_pion
221  bool is_pion() const { return pdgcode_.is_pion(); }
222 
223  /// \copydoc PdgCode::is_kaon
224  bool is_kaon() const { return pdgcode_.is_kaon(); }
225 
226  /// \copydoc PdgCode::is_Delta
227  bool is_Delta() const { return pdgcode_.is_Delta(); }
228 
229  /// \copydoc PdgCode::is_rho
230  bool is_rho() const { return pdgcode_.is_rho(); }
231 
232  /// \return Is this a nucleon resonance (N*)?
233  inline bool is_Nstar() const {
234  return is_baryon() && isospin() == 1 && !pdgcode_.is_nucleon() &&
235  pdgcode_.strangeness() == 0 && pdgcode_.charmness() == 0;
236  }
237 
238  /// \copydoc PdgCode::is_Nstar1535
239  bool is_Nstar1535() const { return pdgcode_.is_Nstar1535(); }
240 
241  /// \return Is this a Sigma resonance (Sigma*)?
242  inline bool is_Sigmastar() const { return pdgcode_.is_Sigmastar(); }
243 
244  /// \return Is this a Delta resonance (Delta*)?
245  inline bool is_Deltastar() const {
246  return is_baryon() && isospin() == 3 && !pdgcode_.is_Delta() &&
247  pdgcode_.strangeness() == 0 && pdgcode_.charmness() == 0;
248  }
249 
250  /// \return whether the particle is stable
251  inline bool is_stable() const { return width_ < width_cutoff; }
252 
253  /// \return whether the particle is a nucleus
254  inline bool is_nucleus() const { return pdgcode_.is_nucleus(); }
255 
256  /// \return whether the particle is an (anti-)deuteron
257  inline bool is_deuteron() const { return pdgcode_.is_deuteron(); }
258 
259  /// \return whether the particle is an (anti-)triton
260  inline bool is_triton() const { return pdgcode_.is_triton(); }
261 
262  /// \return whether the particle is an artificial d' resonance
263  inline bool is_dprime() const {
264  return is_nucleus() && std::abs(pdgcode_.get_decimal()) == 1000010021;
265  }
266 
267  /// \return whether the particle is a cc̅ state
268  inline bool is_charmonia() const { return pdgcode_.is_charmonia(); }
269 
270  /**
271  * The minimum mass of the resonance that is kinematically allowed.
272  *
273  * Calculate the minimum rest energy the resonance must have
274  * for any decay channel to be kinematically available.
275  * (In other words, find the smallest sum of final-state particle masses.)
276  *
277  * \return The minimum mass that a particle of this type can assume, where at
278  * least one decay is possible.
279  */
280  double min_mass_kinematic() const;
281 
282  /**
283  * The minimum mass of the resonance, where the spectral function is non-zero.
284  *
285  * Calculate the the smallest mass where the spectral function still has a
286  * contribution. This value can be different from min_mass_kinematic,
287  * if the spectral function becomes zero at masses higher than
288  * min_mass_kinematic, since the width is put to zero due to the width_cutoff.
289  *
290  * The distinction between it and min_mass_kinematic() might be necessary in
291  * edge cases, where a reaction is very close to the kinematic threshold or
292  * for optimizations.
293  *
294  * \return The minimum mass that a particle of this type can assume, where the
295  * spectral function still has a non-zero value.
296  */
297  double min_mass_spectral() const;
298 
299  /**
300  * Get the mass-dependent partial decay width of a particle with mass m
301  * in a particular decay mode.
302  *
303  * \param[in] m Invariant mass of the decaying particle.
304  * \param[in] mode Decay mode to consider.
305  * \return the partial width of this specific mode for this mass
306  */
307  double partial_width(const double m, const DecayBranch *mode) const;
308 
309  /**
310  * Get the mass-dependent total width of a particle with mass m.
311  *
312  * \param[in] m Invariant mass of the decaying particle.
313  * \return the total width for all modes for this mass
314  */
315  double total_width(const double m) const;
316 
317  /**
318  * Helper Function that containes the if-statement logic that decides if a
319  * decay mode is either a hadronic and dilepton decay mode.
320  * \param[in] t type of decay.
321  * \param[in] wh enum that decides which decay modes are wanted.
322  * \return true if a decay branch is wanted and false if not.
323  */
324  bool wanted_decaymode(const DecayType &t, WhichDecaymodes wh) const;
325 
326  /**
327  * Get all the mass-dependent partial decay widths of a particle with mass m.
328  * This function needs to know the 4-momentum and the position of the decaying
329  * particle to calculate the square root of s of the final state particles and
330  * mass \param[in] p 4-momentum of the decaying particle. \param[in] x
331  * position of the decaying particle. \param[in] wh enum that decides which
332  * decaymodes are returned. \return a list of process branches, whose weights
333  * correspond to the actual partial widths.
334  */
335  DecayBranchList get_partial_widths(const FourVector p, const ThreeVector x,
336  WhichDecaymodes wh) const;
337 
338  /**
339  * Get the mass-dependent partial width of a resonance with mass m,
340  * decaying into two given daughter particles.
341  *
342  * \param[in] m Invariant mass of the decaying resonance.
343  * \param[in] dlist List of daughter particles.
344  * \return the partial width for this mass and this specific decay channel
345  */
346  double get_partial_width(const double m,
347  const ParticleTypePtrList dlist) const;
348 
349  /**
350  * Get the mass-dependent partial in-width of a resonance with mass m,
351  * decaying into two given daughter particles. For stable daughter
352  * particles, the in-width equals the 'normal' partial decay width
353  * (i.e. the 'out-width').
354  *
355  * \param[in] m Invariant mass of the decaying resonance.
356  * \param[in] p_a First daughter particle.
357  * \param[in] p_b Second daughter particle.
358  * \return the partial in-width for this mass and this specific decay channel
359  */
360  double get_partial_in_width(const double m, const ParticleData &p_a,
361  const ParticleData &p_b) const;
362 
363  /**
364  * Full spectral function
365  * \f$ A(m) = \frac{2}{\pi} N
366  * \frac{m^2\Gamma(m)}{(m^2-m_0^2)^2+(m\Gamma(m))^2} \f$
367  * of the resonance (relativistic Breit-Wigner distribution with
368  * mass-dependent width, where N is a normalization factor).
369  *
370  * \param[in] m Actual off-shell mass of the resonance, where the
371  * spectral function is to be evaluated.
372  * \return the value of the spectral function for this mass
373  *
374  * \note The normalization factor N ensures that the spectral function is
375  * normalized to unity.
376  */
377  double full_spectral_function(double m) const;
378 
379  /**
380  * Full spectral function without normalization factor.
381  * \see spectral_function
382  *
383  * \param[in] m Actual off-shell mass of the resonance, where the
384  * spectral function is to be evaluated.
385  * \return the value of the non-normalized spectral function for this mass
386  */
387  double no_norm_spectral_function(double m) const;
388 
389  /**
390  * This one is the most simple form of the spectral function, using a
391  * Cauchy distribution (non-relativistic Breit-Wigner with constant width).
392  * It can be integrated analytically, and is normalized to 1 when integrated
393  * from -inf to inf.
394  *
395  * \param[in] m Actual off-shell mass of the resonance, where the
396  * spectral function is to be evaluated.
397  * \return the Cauchy spectral function at mass m
398  */
399  double breit_wigner_spectral_function(double m) const;
400 
401  /**
402  * Sample mass from the simple spectral function (Breit-Wigner/Cauchy
403  * distribution).
404  *
405  * \param[in] energy Maximum energy from which the mass should be sampled.
406  * If not given, the mass is sampled from the relevant range
407  * of the Breit-Wigner distribution, truncating it at
408  * mass_limit_.
409  * \return sampled mass
410  *
411  * \note The energy can be larger than mass_limit_, which is set to a high
412  * enough value such that the spectral functions are negligible above it.
413  */
415  double energy = mass_limit_) const;
416 
417  /**
418  * Sample mass from the full spectral function.
419  *
420  * \param[in] energy Maximum energy from which the mass should be sampled.
421  * If not given, the mass is sampled from the relevant range
422  * of the spectral function, truncating it at mass_limit_.
423  * \return sampled mass
424  */
425  double sample_full_spectral_function(double energy = mass_limit_) const;
426 
427  /**
428  * Calculate the ratio between the full spectral function and simple one.
429  *
430  * \param[in] m Mass of the resonance where the ratio is to be evaluated.
431  * \return ratio between spectral functions
432  */
433  double ratio_spectral_full_to_breit_wigner(double m) const;
434 
435  /**
436  * Getter used in the resonance mass sampling functions.
437  * If the member is not yet initialized, it runs the algorithm to find the
438  * value.
439  *
440  * \return maximum ratio between full spectral function and simple
441  */
445  }
447  }
448 
449  /**
450  * Resonance mass sampling for 2-particle final state with one resonance
451  * (type given by 'this') and one stable particle.
452  *
453  * \param[in] mass_stable Mass of the stable particle.
454  * \param[in] cms_energy center-of-mass energy of the 2-particle final state.
455  * \param[in] L relative angular momentum of the final-state particles
456  *
457  * \return The mass of the resonance particle.
458  */
459  double sample_resonance_mass(const double mass_stable,
460  const double cms_energy, int L = 0) const;
461 
462  /**
463  * Prints out width and spectral function versus mass to the
464  * standard output. This is useful for debugging and analysis.
465  *
466  * \throw if the particle type is stable
467  */
469 
470  /**
471  * \return a list of all ParticleType objects.
472  *
473  * \note This list is currently sorted, but do not rely on it.
474  * \note It might make sense to inline this function to optimize runtime
475  * performance.
476  */
477  static const ParticleTypeList &list_all();
478 
479  /// \return a list of all nucleons (i.e. proton and neutron).
480  static ParticleTypePtrList &list_nucleons();
481  /// \return a list of all anti-nucleons (i.e. anti-proton and anti-neutron).
482  static ParticleTypePtrList &list_anti_nucleons();
483  /**
484  * \return a list of the Delta(1232) baryons
485  * (i.e. all four charge states).
486  */
487  static ParticleTypePtrList &list_Deltas();
488  /**
489  * \return a list of the anti-Delta(1232) baryons
490  * (i.e. all four charge states).
491  */
492  static ParticleTypePtrList &list_anti_Deltas();
493  /**
494  * \return a list of all baryon resonances,
495  * i.e. unstable baryons (not including antibaryons).
496  */
497  static ParticleTypePtrList &list_baryon_resonances();
498  /**
499  * \return a list of all light nuclei from SMASH particle list.
500  * Nucleons are not included into light nuclei by convention.
501  */
502  static ParticleTypePtrList &list_light_nuclei();
503 
504  /**
505  * Returns the ParticleTypePtr for the given \p pdgcode.
506  * If the particle type is not found, an invalid ParticleTypePtr is returned.
507  * You can convert a ParticleTypePtr to a bool to check whether it is valid.
508  *
509  * \note The complexity of the search is \f$\mathcal O(\log N)\f$. Therefore,
510  * do not use this function except for user input that selects a particle
511  * type. All other internal references for a particle type should use
512  * ParticleTypePtr instead.
513  *
514  * \param[in] pdgcode the unique pdg code to try to find
515  * \return the ParticleTypePtr that corresponds to this pdg code, or an
516  invalid pointer
517  */
518  static const ParticleTypePtr try_find(PdgCode pdgcode);
519 
520  /**
521  * Returns the ParticleType object for the given \p pdgcode.
522  * If the particle is not found, a PdgNotFoundFailure is thrown.
523  *
524  * \note The complexity of the search is \f$\mathcal O(\log N)\f$. Therefore,
525  * do not use this function except for user input that selects a particle
526  * type. All other internal references for a particle type should use
527  * ParticleTypePtr instead.
528  *
529  * \param[in] pdgcode the unique pdg code to try to find
530  * \return the ParticleTypePtr that corresponds to this pdg code
531  * \throw PdgNotFoundFailure pdgcode not found in available particle types
532  */
533  static const ParticleType &find(PdgCode pdgcode);
534 
535  /// \ingroup exception
536  struct PdgNotFoundFailure : public std::runtime_error {
537  using std::runtime_error::runtime_error;
538  };
539 
540  /**
541  * \param[in] pdgcode the PdgCode to look for
542  * \return whether the ParticleType with the given \p pdgcode exists.
543  *
544  * \note The complexity of the search is \f$\mathcal O(\log N)\f$.
545  */
546  static bool exists(PdgCode pdgcode);
547 
548  /**
549  * \param[in] name the name to look for
550  * \return whether the ParticleType with the given \p name exists.
551  *
552  * \note The complexity of the search is \f$\mathcal O(N)\f$.
553  */
554  static bool exists(const std::string &name);
555 
556  /**
557  * Initialize the global ParticleType list (list_all) from the given input
558  * data. This function must only be called once (will fail on second
559  * invocation).
560  *
561  * \param[in] particles A string that contains the definition of ParticleTypes
562  * to be created.
563  * \throw LoadFailure if a line in the particle file could not be read, or if
564  * there are duplicates in it
565  * \throw runtime_error if the mass of of nucleons, kaons and deltas are
566  * different from the hardcoded masses, or if this
567  * function is called more than once
568  */
569  static void create_type_list(const std::string &particles);
570 
571  /**
572  * \param[in] rhs another ParticleType to compare to
573  * \return whether the two ParticleType objects have the same PDG code.
574  */
575  bool operator==(const ParticleType &rhs) const {
576  return pdgcode() == rhs.pdgcode();
577  }
578  /**
579  * \param[in] rhs another ParticleType to compare to
580  * \return whether the two ParticleType objects have different PDG codes.
581  */
582  bool operator!=(const ParticleType &rhs) const {
583  return pdgcode() != rhs.pdgcode();
584  }
585  /**
586  * "Less than" operator for sorting the ParticleType list (by PDG code)
587  *
588  * \param[in] rhs another ParticleType to compare to
589  * \return whether the PDG code of rhs is larger than the one from *this
590  */
591  bool operator<(const ParticleType &rhs) const {
592  return pdgcode() < rhs.pdgcode();
593  }
594 
595  /**
596  * \throw runtime_error if unstable particles have no decay modes
597  * \throw runtime_error if fake dibaryon d' is present without d
598  *
599  * Note that the particles and decay modes have to be initialized, otherwise
600  * calling this is undefined behavior.
601  */
602  static void check_consistency();
603 
604  /**
605  * Returns an object that acts like a pointer, except that it requires only 2
606  * bytes and inhibits pointer arithmetics.
607  *
608  * This is an optimization for creating references to ParticleType objects.
609  * With a normal pointer you would require the original object to stay in its
610  * place in memory, as otherwise the pointer would dangle. The ParticleTypePtr
611  * does not have this problem as it only stores the index of the ParticleType
612  * in the global vector of ParticleType objects.
613  *
614  * In addition to returning a more efficient reference type, the overload of
615  * operator& effectively inhibits passing ParticleType objects by pointer.
616  * This is an intended restriction since ParticleType objects should only be
617  * passed by const-ref. (You can now pass by ParticleTypePtr instead, but
618  * please prefer not to. It might be useful when you want to store a reference
619  * inside the function anyway, but that can just as well be done with a
620  * const-ref parameter. A ParticleTypePtr can be invalid, a const-ref
621  * is always a valid reference semantically.)
622  *
623  * \par Pre-condition:
624  * The operator expects that the ParticleType object is stored in the vector
625  * returned by ParticleType::list_all. Therefore, never create new
626  * ParticleType
627  * objects (that includes copies and moves)!
628  *
629  * \par Note on distributed execution:
630  * At some point we might want to have several copies of the ParticleType
631  * vector - on different machines or NUMA nodes. In that case
632  * ParticleType::list_all will return the local vector. This operator will
633  * continue to work as expected as long as the ParticleType object is an entry
634  * of this local vector. The ParticleTypePtr can then be used to communicate a
635  * ParticleType over node / NUMA boundaries (an actual pointer would not work,
636  * though).
637  *
638  * \note It might make sense to inline this function to optimize runtime
639  * performance.
640  *
641  * \return A pointer-like object referencing this ParticleType object.
642  *
643  * \see ParticleTypePtr
644  */
645  ParticleTypePtr operator&() const;
646 
647  /// \ingroup exception
648  struct LoadFailure : public std::runtime_error {
649  using std::runtime_error::runtime_error;
650  };
651 
652  private:
653  /**
654  * Limit for sampling the resonance masses. Implicitly, this assumes that the
655  * spectral functions of all resonances are negligible at this value.
656  */
657  static constexpr double mass_limit_ = 10.0;
658  /// name of the particle
659  std::string name_;
660  /// pole mass of the particle
661  double mass_;
662  /// width of the particle
663  double width_;
664  /// Parity of the particle
666  /// PDG Code of the particle
668  /**
669  * minimum kinematically allowed mass of the particle
670  * Mutable, because it is initialized at first call of minimum mass function,
671  * so it's logically const, but not physically const, which is a classical
672  * case for using mutable.
673  */
674  mutable double min_mass_kinematic_;
675  /**
676  * minimum mass, where the spectral function is non-zero
677  * Mutable, because it is initialized at first call of minimum mass function,
678  * so it's logically const, but not physically const, which is a classical
679  * case for using mutable.
680  */
681  mutable double min_mass_spectral_;
682  /** This normalization factor ensures that the spectral function is normalized
683  * to unity, when integrated over its full domain. */
684  mutable double norm_factor_ = -1.;
685  /// Charge of the particle; filled automatically from pdgcode_.
686  int32_t charge_;
687  /// Isospin of the particle; filled automatically from pdgcode_.
688  mutable int isospin_;
689  /// Isospin projection of the particle; filled automatically from pdgcode_.
690  int I3_;
691 
692  /// Container for the isospin multiplet information
694 
695  /**
696  * Maximum ratio between full spectral function and the mass-independent
697  * Breit-Wigner. This is used for sampling the resonance mass.
698  */
699  mutable std::optional<double> max_ratio_spectral_full_to_breit_wigner_ =
700  std::nullopt;
701 
702  /**
703  * Calculates the maximum ratio between full spectral function and simple one.
704  * Usually it will be at the right edge of a mass range, but numerically this
705  * might be a problem since at very large masses both spectral functions go to
706  * zero, so we take a fixed maximal value.
707  * For some resonances the full spectral function has peaks beyond the pole
708  * mass, which will give the largest ratio, so this algorithm scans for this
709  * case from the right, until the regular pole mass peak.
710  * The actual value is the maximum between the ratio at the last found peak,
711  * the ratio at the mass limit, and 1 as a fallback.
712  */
714 
715  /**\ingroup logging
716  * Writes all information about the particle type to the output stream.
717  *
718  * \param[out] out The ostream into which to output
719  * \param[in] type The ParticleType object to write into out
720  */
721  friend std::ostream &operator<<(std::ostream &out, const ParticleType &type);
722 };
723 
724 /**
725  * \ingroup data
726  *
727  * A pointer-like interface to global references to ParticleType objects.
728  *
729  * \see ParticleType::operator&
730  */
732  public:
733  /// \return Dereferences the pointer and returns the ParticleType object.
734  const ParticleType &operator*() const { return lookup(); }
735 
736  /// \return Dereferences the pointer and returns the ParticleType object.
737  const ParticleType *operator->() const {
738  // this requires std::addressof because &lookup() would call
739  // ParticleType::operator& and return ParticleTypePtr again
740  return std::addressof(lookup());
741  }
742 
743  /// Default construction initializes with an invalid index.
744  ParticleTypePtr() = default;
745 
746  /**
747  * \param[in] rhs the ParticleTypePtr to compare to
748  * \return whether the two objects reference the same ParticleType object.
749  */
750  bool operator==(const ParticleTypePtr &rhs) const {
751  return index_ == rhs.index_;
752  }
753 
754  /**
755  * \param[in] rhs the ParticleTypePtr to compare to
756  * \return whether the two objects reference different ParticleType objects.
757  */
758  bool operator!=(const ParticleTypePtr &rhs) const {
759  return index_ != rhs.index_;
760  }
761  /**
762  * "Less than" operator
763  *
764  * \param[in] rhs the ParticleTypePtr to compare to
765  * \return whether the index is smaller than rhs' index.
766  */
767  bool operator<(const ParticleTypePtr &rhs) const {
768  return index_ < rhs.index_;
769  }
770 
771  /// \return whether the objects stores a valid ParticleType reference.
772  operator bool() const { return index_ != 0xffff; }
773 
774  private:
775  /**
776  * ParticleType::operator& is a friend in order to call the constructor
777  *
778  * \return the pointer to a ParticleType
779  */
781 
782  /** Constructs a pointer to the ParticleType object at offset \p i.
783  *
784  * \param[in] i the offset where to create.
785  */
786  explicit ParticleTypePtr(std::uint16_t i) : index_(i) {}
787 
788  /**
789  * Helper function that does the ParticleType lookup from the stored index.
790  *
791  * \par Implementation:
792  * In debug builds this function asserts that the index is valid.
793  * It then asks for the vector of all ParticleType objects
794  * (ParticleType::list_all) and uses vector::operator[] to return an lvalue
795  * reference to the ParticleType object at the offset \p index_.
796  *
797  * \return a reference to the ParticleType object at offset \p index_.
798  */
799  const ParticleType &lookup() const {
800  assert(index_ != 0xffff);
801  return ParticleType::list_all()[index_];
802  }
803 
804  /**
805  * Stores the index of the references ParticleType object in the global
806  * vector. The value 0xffff is used to denote an invalid index (similar to a
807  * null pointer).
808  */
809  std::uint16_t index_ = 0xffff;
810 };
811 
813  assert(has_antiparticle());
814  return &find(pdgcode_.get_antiparticle());
815 }
816 
817 /**
818  * Lists the possible resonances that decay into two particles.
819  *
820  * \param[in] type_a first incoming particle.
821  * \param[in] type_b second incoming particle.
822  * \return list of possible resonances.
823  *
824  * \note Internally, a `static std::map` is used as a caching mechanism and is
825  * filled the first time this function is called, such that calling it again
826  * just returns the same list.
827  */
828 ParticleTypePtrList list_possible_resonances(const ParticleTypePtr type_a,
829  const ParticleTypePtr type_b);
830 
831 /**
832  * Resonance mass sampling for 2-particle final state with two resonances.
833  *
834  * \param[in] t1 Type of the first resonance
835  * \param[in] t2 Type of the second resonance.
836  * \param[in] cms_energy center-of-mass energy of the 2-particle final state.
837  * \param[in] L relative angular momentum of the final-state particles
838  *
839  * \return The masses of the resonance particles.
840  */
841 std::pair<double, double> sample_two_resonance_masses(const ParticleType &t1,
842  const ParticleType &t2,
843  const double cms_energy,
844  int L = 0);
845 } // namespace smash
846 
847 #endif // SRC_INCLUDE_SMASH_PARTICLETYPE_H_
DecayBranch is a derivative of ProcessBranch, which is used to represent decay channels.
The DecayModes class is used to store and update information about decay branches (i....
Definition: decaymodes.h:29
DecayType is the abstract base class for all decay types.
Definition: decaytype.h:23
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
Definition: fourvector.h:33
IsoParticleType is a class to represent isospin multiplets.
ParticleData contains the dynamic information of a certain particle.
Definition: particledata.h:59
A pointer-like interface to global references to ParticleType objects.
Definition: particletype.h:731
bool operator==(const ParticleTypePtr &rhs) const
Definition: particletype.h:750
const ParticleType & operator*() const
Definition: particletype.h:734
bool operator<(const ParticleTypePtr &rhs) const
"Less than" operator
Definition: particletype.h:767
ParticleTypePtr()=default
Default construction initializes with an invalid index.
bool operator!=(const ParticleTypePtr &rhs) const
Definition: particletype.h:758
const ParticleType & lookup() const
Helper function that does the ParticleType lookup from the stored index.
Definition: particletype.h:799
std::uint16_t index_
Stores the index of the references ParticleType object in the global vector.
Definition: particletype.h:809
const ParticleType * operator->() const
Definition: particletype.h:737
ParticleTypePtr(std::uint16_t i)
Constructs a pointer to the ParticleType object at offset i.
Definition: particletype.h:786
Particle type contains the static properties of a particle species.
Definition: particletype.h:100
double min_mass_spectral_
minimum mass, where the spectral function is non-zero Mutable, because it is initialized at first cal...
Definition: particletype.h:681
double sample_full_spectral_function(double energy=mass_limit_) const
Sample mass from the full spectral function.
bool is_pion() const
Definition: particletype.h:221
double min_mass_spectral() const
The minimum mass of the resonance, where the spectral function is non-zero.
IsoParticleType * iso_multiplet_
Container for the isospin multiplet information.
Definition: particletype.h:693
int I3_
Isospin projection of the particle; filled automatically from pdgcode_.
Definition: particletype.h:690
bool is_triton() const
Definition: particletype.h:260
double breit_wigner_spectral_function(double m) const
This one is the most simple form of the spectral function, using a Cauchy distribution (non-relativis...
bool is_baryon() const
Definition: particletype.h:206
const DecayModes & decay_modes() const
Parity parity_
Parity of the particle.
Definition: particletype.h:665
int isospin3() const
Definition: particletype.h:179
std::string name_
name of the particle
Definition: particletype.h:659
ParticleTypePtr get_antiparticle() const
Definition: particletype.h:812
bool is_Nstar() const
Definition: particletype.h:233
double sample_resonance_mass(const double mass_stable, const double cms_energy, int L=0) const
Resonance mass sampling for 2-particle final state with one resonance (type given by 'this') and one ...
double get_partial_width(const double m, const ParticleTypePtrList dlist) const
Get the mass-dependent partial width of a resonance with mass m, decaying into two given daughter par...
int strangeness() const
Definition: particletype.h:215
static const ParticleTypePtr try_find(PdgCode pdgcode)
Returns the ParticleTypePtr for the given pdgcode.
Definition: particletype.cc:89
void dump_width_and_spectral_function() const
Prints out width and spectral function versus mass to the standard output.
double total_width(const double m) const
Get the mass-dependent total width of a particle with mass m.
bool wanted_decaymode(const DecayType &t, WhichDecaymodes wh) const
Helper Function that containes the if-statement logic that decides if a decay mode is either a hadron...
void calculate_max_ratio_spectral_full_to_breit_wigner() const
Calculates the maximum ratio between full spectral function and simple one.
static const ParticleType & find(PdgCode pdgcode)
Returns the ParticleType object for the given pdgcode.
Definition: particletype.cc:99
bool is_nucleus() const
Definition: particletype.h:254
double min_mass_kinematic() const
The minimum mass of the resonance that is kinematically allowed.
PdgCode pdgcode() const
Definition: particletype.h:159
static bool exists(PdgCode pdgcode)
double full_spectral_function(double m) const
Full spectral function of the resonance (relativistic Breit-Wigner distribution with mass-dependent ...
static void check_consistency()
const std::string & name() const
Definition: particletype.h:144
double min_mass_kinematic_
minimum kinematically allowed mass of the particle Mutable, because it is initialized at first call o...
Definition: particletype.h:674
ParticleType & operator=(const ParticleType &)=delete
assignment is not allowed, see copy constructor above
int32_t charge() const
The charge of the particle.
Definition: particletype.h:191
int antiparticle_sign() const
Definition: particletype.h:168
static ParticleTypePtrList & list_nucleons()
Definition: particletype.cc:69
bool is_rho() const
Definition: particletype.h:230
ParticleType & operator=(ParticleType &&)=default
move ctors are needed for std::sort
bool is_hadron() const
Definition: particletype.h:200
unsigned int spin_degeneracy() const
Definition: particletype.h:197
static ParticleTypePtrList & list_anti_nucleons()
Definition: particletype.cc:71
double max_ratio_spectral_full_to_breit_wigner() const
Getter used in the resonance mass sampling functions.
Definition: particletype.h:442
bool is_Nstar1535() const
Definition: particletype.h:239
static const ParticleTypeList & list_all()
Definition: particletype.cc:51
bool is_stable() const
Definition: particletype.h:251
int isospin_
Isospin of the particle; filled automatically from pdgcode_.
Definition: particletype.h:688
ParticleType(const ParticleType &)=delete
Copies are not allowed as they break intended use.
bool is_dprime() const
Definition: particletype.h:263
double isospin3_rel() const
Definition: particletype.h:182
double width_
width of the particle
Definition: particletype.h:663
bool operator<(const ParticleType &rhs) const
"Less than" operator for sorting the ParticleType list (by PDG code)
Definition: particletype.h:591
bool is_Delta() const
Definition: particletype.h:227
bool operator!=(const ParticleType &rhs) const
Definition: particletype.h:582
double width_at_pole() const
Definition: particletype.h:153
static ParticleTypePtrList & list_anti_Deltas()
Definition: particletype.cc:77
PdgCode pdgcode_
PDG Code of the particle.
Definition: particletype.h:667
bool has_antiparticle() const
Definition: particletype.h:162
ParticleType(std::string n, double m, double w, Parity p, PdgCode id)
Creates a fully initialized ParticleType object.
bool is_nucleon() const
Definition: particletype.h:218
double mass() const
Definition: particletype.h:147
static ParticleTypePtrList & list_baryon_resonances()
Definition: particletype.cc:81
static constexpr double width_cutoff
Decay width cutoff for considering a particle as stable.
Definition: particletype.h:110
DecayBranchList get_partial_widths(const FourVector p, const ThreeVector x, WhichDecaymodes wh) const
Get all the mass-dependent partial decay widths of a particle with mass m.
bool is_Sigmastar() const
Definition: particletype.h:242
static ParticleTypePtrList & list_Deltas()
Definition: particletype.cc:75
bool is_lepton() const
Definition: particletype.h:203
bool is_deuteron() const
Definition: particletype.h:257
bool is_meson() const
Definition: particletype.h:209
double ratio_spectral_full_to_breit_wigner(double m) const
Calculate the ratio between the full spectral function and simple one.
int32_t charge_
Charge of the particle; filled automatically from pdgcode_.
Definition: particletype.h:686
double get_partial_in_width(const double m, const ParticleData &p_a, const ParticleData &p_b) const
Get the mass-dependent partial in-width of a resonance with mass m, decaying into two given daughter ...
double sample_breit_wigner_spectral_function(double energy=mass_limit_) const
Sample mass from the simple spectral function (Breit-Wigner/Cauchy distribution).
bool is_kaon() const
Definition: particletype.h:224
static void create_type_list(const std::string &particles)
Initialize the global ParticleType list (list_all) from the given input data.
int isospin() const
Returns twice the isospin vector length .
unsigned int spin() const
Definition: particletype.h:194
double norm_factor_
This normalization factor ensures that the spectral function is normalized to unity,...
Definition: particletype.h:684
int baryon_number() const
Definition: particletype.h:212
ParticleTypePtr operator&() const
Returns an object that acts like a pointer, except that it requires only 2 bytes and inhibits pointer...
Definition: particletype.cc:57
bool operator==(const ParticleType &rhs) const
Definition: particletype.h:575
ParticleType(ParticleType &&)=default
move ctors are needed for std::sort
std::optional< double > max_ratio_spectral_full_to_breit_wigner_
Maximum ratio between full spectral function and the mass-independent Breit-Wigner.
Definition: particletype.h:699
bool is_Deltastar() const
Definition: particletype.h:245
static constexpr double mass_limit_
Limit for sampling the resonance masses.
Definition: particletype.h:657
double no_norm_spectral_function(double m) const
Full spectral function without normalization factor.
IsoParticleType * iso_multiplet() const
Definition: particletype.h:188
double mass_sqr() const
Definition: particletype.h:150
static ParticleTypePtrList & list_light_nuclei()
Definition: particletype.cc:85
bool is_charmonia() const
Definition: particletype.h:268
double partial_width(const double m, const DecayBranch *mode) const
Get the mass-dependent partial decay width of a particle with mass m in a particular decay mode.
Parity parity() const
Definition: particletype.h:156
double mass_
pole mass of the particle
Definition: particletype.h:661
PdgCode stores a Particle Data Group Particle Numbering Scheme particle type number.
Definition: pdgcode.h:108
bool is_Nstar1535() const
Definition: pdgcode.h:422
bool is_rho() const
Definition: pdgcode.h:483
int antiparticle_sign() const
Definition: pdgcode.h:734
int baryon_number() const
Definition: pdgcode.h:388
bool is_meson() const
Definition: pdgcode.h:401
bool is_charmonia() const
Definition: pdgcode.h:383
unsigned int spin() const
Definition: pdgcode.h:691
bool is_pion() const
Definition: pdgcode.h:471
bool is_kaon() const
Definition: pdgcode.h:465
bool is_Sigmastar() const
Definition: pdgcode.h:458
bool is_lepton() const
Definition: pdgcode.h:372
bool is_nucleus() const
Definition: pdgcode.h:361
bool is_deuteron() const
Definition: pdgcode.h:504
int charmness() const
Definition: pdgcode.h:633
int strangeness() const
Definition: pdgcode.h:626
int32_t get_decimal() const
Definition: pdgcode.h:852
bool is_baryon() const
Definition: pdgcode.h:398
bool is_nucleon() const
Definition: pdgcode.h:404
PdgCode get_antiparticle() const
Construct the antiparticle to a given PDG code.
Definition: pdgcode.h:329
bool is_hadron() const
Definition: pdgcode.h:367
bool is_triton() const
Definition: pdgcode.h:510
bool is_Delta() const
Definition: pdgcode.h:428
bool has_antiparticle() const
Definition: pdgcode.h:519
unsigned int spin_degeneracy() const
Definition: pdgcode.h:727
The ThreeVector class represents a physical three-vector with the components .
Definition: threevector.h:31
friend std::ostream & operator<<(std::ostream &out, const ParticleType &type)
Writes all information about the particle type to the output stream.
constexpr int p
Proton.
constexpr int n
Neutron.
Definition: action.h:24
ParticleTypePtrList list_possible_resonances(const ParticleTypePtr type_a, const ParticleTypePtr type_b)
Lists the possible resonances that decay into two particles.
void operator*=(Parity &x, Parity y)
Definition: particletype.h:78
EnergyMomentumTensor operator-(EnergyMomentumTensor a, const EnergyMomentumTensor &b)
Direct subtraction operator.
Parity
Represent the parity of a particle type.
Definition: particletype.h:27
@ Neg
Negative parity.
@ Pos
Positive parity.
EnergyMomentumTensor operator*(EnergyMomentumTensor a, const double b)
Direct multiplication operator.
std::pair< double, double > sample_two_resonance_masses(const ParticleType &t1, const ParticleType &t2, const double cms_energy, int L=0)
Resonance mass sampling for 2-particle final state with two resonances.
WhichDecaymodes
Decide which decay mode widths are returned in get partical widths.
Definition: particletype.h:35
@ Hadronic
Ignore dilepton decay modes widths.
@ Dileptons
Only return dilepton decays widths.
@ All
All decay mode widths.