28 if (sqrts <= mass + stable_mass) {
33 const double p_f =
pCM(sqrts, stable_mass, mass);
42 if (sqrts <= m1 + m2) {
47 const double p_f =
pCM(sqrts, m1, m2);
57 if (part_types.size() != 2) {
58 throw std::runtime_error(
59 "Wrong number of particles in TwoBodyDecay constructor: " +
60 std::to_string(part_types.size()));
78 if (!(part_types[0]->is_stable() && part_types[1]->is_stable())) {
79 throw std::runtime_error(
80 "Error: Unstable particle in TwoBodyDecayStable constructor: " +
81 part_types[0]->pdgcode().
string() +
" " +
82 part_types[1]->pdgcode().
string());
102 return width(m0, G0, m);
114 if (part_types[1]->is_stable()) {
115 std::swap(part_types[0], part_types[1]);
119 if (!part_types[0]->is_stable() || part_types[1]->is_stable()) {
120 throw std::runtime_error(
"Error in TwoBodyDecaySemistable constructor: " +
121 part_types[0]->pdgcode().
string() +
" " +
122 part_types[1]->pdgcode().
string());
130 Lambda_(get_Lambda()),
131 tabulation_(nullptr) {}
154 const double tabulation_interval = std::max(2., 10. * res->
width_at_pole());
160 const double mres_max = sqrts - m_stable;
161 return integrate(mres_min, mres_max, [&](
double m) {
170 assert(
rho(m0) != 0);
175 double m1,
double m2)
const {
176 assert(
rho(m0) != 0);
177 const double p_f =
pCM(m, m1, m2);
188 if (part_types[0]->is_stable() || part_types[1]->is_stable()) {
189 throw std::runtime_error(
190 "Error: Stable particle in TwoBodyDecayUnstable constructor: " +
191 part_types[0]->pdgcode().
string() +
" " +
192 part_types[1]->pdgcode().
string());
212 const double tab_interval = std::max(2., 10. * sum_gamma);
215 m1_min + m2_min, tab_interval,
num_tab_pts, [&](
double sqrts) {
216 const double m1_max = sqrts - m2_min;
217 const double m2_max = sqrts - m1_min;
219 const double result =
integrate2d(m1_min, m1_max, m2_min, m2_max,
220 [&](
double m1,
double m2) {
222 sqrts, m1, m2, r1, r2,
L_);
237 const double p_f =
pCM(m, m1, m2);
250 throw std::runtime_error(
251 "Error: No dilepton in TwoBodyDecayDilepton constructor: " +
252 part_types[0]->pdgcode().
string() +
" " +
253 part_types[1]->pdgcode().
string());
263 const double ml_to_m_sqr = (ml / m) * (ml / m);
264 const double m0_to_m_cubed = (m0 / m) * (m0 / m) * (m0 / m);
265 return G0 * m0_to_m_cubed * std::sqrt(1. - 4. * ml_to_m_sqr) *
266 (1. + 2. * ml_to_m_sqr);
274 std::sort(part_types.begin(), part_types.end());
280 if (part_types.size() != 3) {
281 throw std::runtime_error(
282 "Wrong number of particles in ThreeBodyDecay constructor: " +
283 std::to_string(part_types.size()));
294 std::sort(list.begin(), list.end());
295 return particle_types_[0] == list[0] && particle_types_[1] == list[1] &&
296 particle_types_[2] == list[2];
311 ParticleTypePtrList part_types,
313 :
ThreeBodyDecay(part_types, l), tabulation_(nullptr), mother_(mother) {
317 throw std::runtime_error(
318 "Error: No dilepton in ThreeBodyDecayDilepton constructor: " +
319 part_types[0]->pdgcode().
string() +
" " +
320 part_types[1]->pdgcode().
string() +
" " +
321 part_types[2]->pdgcode().
string());
324 int non_lepton_position = -1;
325 for (
int i = 0; i < 3; ++i) {
327 non_lepton_position = i;
333 throw std::runtime_error(
"Error: Unsupported dilepton Dalitz decay!");
342 double m_dil,
double m_other,
346 if (m_par < m_dil + m_other) {
351 const double m_dil_sqr = m_dil * m_dil;
352 const double m_par_sqr = m_par * m_par;
353 const double m_par_cubed = m_par * m_par * m_par;
354 const double m_other_sqr = m_other * m_other;
355 const double ph_sp_factor = std::sqrt(1. - 4. * m_l * m_l / m_dil_sqr) *
356 (1. + 2. * m_l * m_l / m_dil_sqr);
361 switch (pdg.
spin()) {
368 pow_int(1. - m_dil / m_par * m_dil / m_par, 3) * ff * ff *
377 const double n1 = m_par_sqr - m_other_sqr;
378 const double rad =
pow_int(1. + m_dil_sqr / n1, 2) -
379 4. * m_par_sqr * m_dil_sqr / (n1 * n1);
385 std::pow(rad, 3. / 2.) * ff_sqr * ph_sp_factor;
389 throw std::runtime_error(
"Bad meson in ThreeBodyDecayDilepton: " +
393 switch (pdg.
code()) {
399 const double rad1 = (m_par + m_other) * (m_par + m_other) - m_dil_sqr;
400 const double rad2 = (m_par - m_other) * (m_par - m_other) - m_dil_sqr;
402 assert(rad1 > -1E-5);
404 }
else if (rad2 < 0.) {
405 assert(rad2 > -1E-5);
409 (m_par + m_other) / (m_par_cubed * m_other_sqr) *
411 const double t2 =
pow_int(std::sqrt(rad2), 3);
413 const double gamma_vi = t1 * t2 * ff * ff;
419 throw std::runtime_error(
"Bad baryon in ThreeBodyDecayDilepton: " +
423 throw std::runtime_error(
"Non-hadron in ThreeBodyDecayDilepton: " +
434 int non_lepton_position = -1;
435 for (
int i = 0; i < 3; ++i) {
437 non_lepton_position = i;
442 const double m_l =
particle_types_[(non_lepton_position + 1) % 3]->mass();
450 m_other + 2 * m_l, M0 + 10 * G0tot,
num_tab_pts, [&](
double m_parent) {
451 const double bottom = 2 * m_l;
452 const double top = m_parent - m_other;
459 m_parent, m_l, m_dil, m_other,
TwoBodyDecayUnstable(ParticleTypePtrList part_types, int l)
Construct a TwoBodyDecayUnstable.
double width(double m0, double G0, double m) const override
static Integrator2dCuhre integrate2d(1E7)
double Lambda_
Cut-off parameter Λ for unstable decays.
ThreeBodyDecayDilepton(ParticleTypePtr mother, ParticleTypePtrList part_types, int l)
Construct a ThreeBodyDecayDilepton.
static double integrand_rho_Manley_2res(double sqrts, double m1, double m2, ParticleTypePtr t1, ParticleTypePtr t2, int L)
TwoBodyDecay(ParticleTypePtrList part_types, int l)
Construct a TwoBodyDecay.
std::unique_ptr< Tabulation > tabulation_
Tabulation of the resonance integrals.
TwoBodyDecaySemistable(ParticleTypePtrList part_types, int l)
Construct a TwoBodyDecaySemistable.
double width(double m0, double G0, double m) const override
ParticleTypePtrList particle_types_
final-state particles of the decay
bool is_dilepton(const PdgCode pdg1, const PdgCode pdg2)
Collection of useful constants that are known at compile time.
constexpr int photon
Photon.
bool has_lepton_pair(const PdgCode pdg1, const PdgCode pdg2, const PdgCode pdg3)
double width(double m0, double G0, double m) const override
unsigned int particle_number() const override
unsigned int spin() const
constexpr T pow_int(const T base, unsigned const exponent)
Efficient template for calculating integer powers using squaring.
int L_
angular momentum of the decay
unsigned int particle_number() const override
double spectral_function(double m) const
Full spectral function of the resonance (relativistic Breit-Wigner distribution with mass-dependent ...
constexpr int invalid
Invalid particle.
bool has_particles(ParticleTypePtrList list) const override
double width(double m0, double G0, double m) const override
double in_width(double m0, double G0, double m, double m1, double m2) const override
constexpr double fine_structure
Fine-struture constant, approximately 1/137.
std::unique_ptr< Tabulation > tabulation_
Tabulation of the resonance integrals.
double blatt_weisskopf_sqr(const double p_ab, const int L)
DecayType is the abstract base class for all decay types.
ThreeBodyDecay represents a decay type with three final-state particles.
A C++ interface for numerical integration in two dimensions with the Cuba Cuhre integration function...
static const ParticleType & find(PdgCode pdgcode)
Returns the ParticleType object for the given pdgcode.
double rho(double m) const override
This is a virtual helper method which is used to write the width as Gamma(m) = Gamma_0 * rho(m) / rho...
TwoBodyDecayDilepton(ParticleTypePtrList part_types, int l)
Construct a TwoBodyDecayDilepton.
double min_mass_kinematic() const
The minimum mass of the resonance that is kinematically allowed.
double em_form_factor_sqr_vec(PdgCode pdg, double mass)
double rho(double m) const override
This is a virtual helper method which is used to write the width as Gamma(m) = Gamma_0 * rho(m) / rho...
static ParticleTypePtrList sort_particles(ParticleTypePtrList part_types)
sort the particle list
double in_width(double m0, double G0, double m, double m1, double m2) const override
bool has_particles(ParticleTypePtrList list) const override
Particle type contains the static properties of a particle species.
constexpr int num_tab_pts
double width(double m0, double G0, double m) const override
std::unique_ptr< Tabulation > tabulation_
Tabulation of the resonance integrals.
double Lambda_
Cut-off parameter Λ for semi-stable decays.
PdgCode stores a Particle Data Group Particle Numbering Scheme particle type number.
bool has_mother(ParticleTypePtr mother) const override
ThreeBodyDecay(ParticleTypePtrList part_types, int l)
Construct a ThreeBodyDecay.
double in_width(double m0, double G0, double m, double m1, double m2) const override
static double diff_width(double m_par, double m_l, double m_dil, double m_other, ParticleTypePtr other, ParticleTypePtr t)
Get the mass-differential width for a dilepton Dalitz decay, where is the invariant mass of the lep...
double form_factor_delta(double m)
static double integrand_rho_Manley_1res(double sqrts, double mass, double stable_mass, ParticleTypePtr type, int L)
TwoBodyDecay represents a decay type with two final-state particles.
TwoBodyDecayStable represents a decay type with two stable final-state particles. ...
std::int32_t code() const
double width_at_pole() const
A C++ interface for numerical integration in one dimension with the GSL CQUAD integration functions...
TwoBodyDecayStable(ParticleTypePtrList part_types, int l)
Construct a TwoBodyDecayStable.
ParticleTypePtr mother_
Type of the mother particle.
A pointer-like interface to global references to ParticleType objects.
double width(double m0, double G0, double m) const override
double em_form_factor_ps(PdgCode pdg, double mass)
double rho(double m) const override
This is a virtual helper method which is used to write the width as Gamma(m) = Gamma_0 * rho(m) / rho...
double in_width(double m0, double G0, double m, double m1, double m2) const override
double get_partial_width(const double m, const ParticleType &t_a, const ParticleType &t_b) const
Get the mass-dependent partial width of a resonance with mass m, decaying into two given daughter par...
double post_ff_sqr(double m, double M0, double srts0, double L)
An additional form factor for unstable final states as used in GiBUU, according to M...
T pCM(const T sqrts, const T mass_a, const T mass_b) noexcept
static ParticleTypePtrList & arrange_particles(ParticleTypePtrList &part_types)
Rearrange the particle list such that the first particle is the stable one.
std::string string() const
static Integrator integrate