24 if (sqrts <= mass + stable_mass) {
29 const double p_f =
pCM(sqrts, stable_mass, mass);
38 if (sqrts <= m1 + m2) {
43 const double p_f =
pCM(sqrts, m1, m2);
53 if (part_types.size() != 2) {
54 throw std::runtime_error(
55 "Wrong number of particles in TwoBodyDecay constructor: " +
56 std::to_string(part_types.size()));
74 if (!(part_types[0]->is_stable() && part_types[1]->is_stable())) {
75 throw std::runtime_error(
76 "Error: Unstable particle in TwoBodyDecayStable constructor: " +
77 part_types[0]->pdgcode().
string() +
" " +
78 part_types[1]->pdgcode().
string());
98 return width(m0, G0, m);
110 if (part_types[1]->is_stable()) {
111 std::swap(part_types[0], part_types[1]);
115 if (!part_types[0]->is_stable() || part_types[1]->is_stable()) {
116 throw std::runtime_error(
"Error in TwoBodyDecaySemistable constructor: " +
117 part_types[0]->pdgcode().
string() +
" " +
118 part_types[1]->pdgcode().
string());
126 Lambda_(get_Lambda()),
127 tabulation_(nullptr) {}
150 const double tabulation_interval = std::max(2., 10. * res->
width_at_pole());
156 const double mres_max = sqrts - m_stable;
157 return integrate(mres_min, mres_max, [&](
double m) {
166 assert(
rho(m0) != 0);
171 double m1,
double m2)
const {
172 assert(
rho(m0) != 0);
173 const double p_f =
pCM(m, m1, m2);
183 :
TwoBodyDecay(part_types, l), Lambda_(get_Lambda()), tabulation_(nullptr) {
184 if (part_types[0]->is_stable() || part_types[1]->is_stable()) {
185 throw std::runtime_error(
186 "Error: Stable particle in TwoBodyDecayUnstable constructor: " +
187 part_types[0]->pdgcode().
string() +
" " +
188 part_types[1]->pdgcode().
string());
208 const double tab_interval = std::max(2., 10. * sum_gamma);
211 m1_min + m2_min, tab_interval,
num_tab_pts, [&](
double sqrts) {
212 const double m1_max = sqrts - m2_min;
213 const double m2_max = sqrts - m1_min;
215 const double result =
integrate2d(m1_min, m1_max, m2_min, m2_max,
216 [&](
double m1,
double m2) {
218 sqrts, m1, m2, r1, r2,
L_);
233 const double p_f =
pCM(m, m1, m2);
246 throw std::runtime_error(
247 "Error: No dilepton in TwoBodyDecayDilepton constructor: " +
248 part_types[0]->pdgcode().
string() +
" " +
249 part_types[1]->pdgcode().
string());
259 const double ml_to_m_sqr = (ml / m) * (ml / m);
260 const double m0_to_m_cubed = (m0 / m) * (m0 / m) * (m0 / m);
261 return G0 * m0_to_m_cubed * std::sqrt(1. - 4. * ml_to_m_sqr) *
262 (1. + 2. * ml_to_m_sqr);
270 std::sort(part_types.begin(), part_types.end());
276 if (part_types.size() != 3) {
277 throw std::runtime_error(
278 "Wrong number of particles in ThreeBodyDecay constructor: " +
279 std::to_string(part_types.size()));
290 std::sort(list.begin(), list.end());
307 ParticleTypePtrList part_types,
309 :
ThreeBodyDecay(part_types, l), tabulation_(nullptr), mother_(mother) {
313 throw std::runtime_error(
314 "Error: No dilepton in ThreeBodyDecayDilepton constructor: " +
315 part_types[0]->pdgcode().
string() +
" " +
316 part_types[1]->pdgcode().
string() +
" " +
317 part_types[2]->pdgcode().
string());
320 int non_lepton_position = -1;
321 for (
int i = 0; i < 3; ++i) {
323 non_lepton_position = i;
329 throw std::runtime_error(
"Error: Unsupported dilepton Dalitz decay!");
338 double m_dil,
double m_other,
342 if (m_par < m_dil + m_other) {
347 const double m_dil_sqr = m_dil * m_dil;
348 const double m_par_sqr = m_par * m_par;
349 const double m_par_cubed = m_par * m_par * m_par;
350 const double m_other_sqr = m_other * m_other;
351 const double ph_sp_factor = std::sqrt(1. - 4. * m_l * m_l / m_dil_sqr) *
352 (1. + 2. * m_l * m_l / m_dil_sqr);
357 switch (pdg.
spin()) {
364 pow_int(1. - m_dil / m_par * m_dil / m_par, 3) * ff * ff *
373 const double n1 = m_par_sqr - m_other_sqr;
374 const double rad =
pow_int(1. + m_dil_sqr / n1, 2) -
375 4. * m_par_sqr * m_dil_sqr / (n1 * n1);
381 std::pow(rad, 3. / 2.) * ff_sqr * ph_sp_factor;
385 throw std::runtime_error(
"Bad meson in ThreeBodyDecayDilepton: " +
389 switch (pdg.
code()) {
395 const double rad1 = (m_par + m_other) * (m_par + m_other) - m_dil_sqr;
396 const double rad2 = (m_par - m_other) * (m_par - m_other) - m_dil_sqr;
398 assert(rad1 > -1E-5);
400 }
else if (rad2 < 0.) {
401 assert(rad2 > -1E-5);
405 (m_par + m_other) / (m_par_cubed * m_other_sqr) *
407 const double t2 =
pow_int(std::sqrt(rad2), 3);
409 const double gamma_vi = t1 * t2 * ff * ff;
419 const double rad1 = (m_par - m_other) * (m_par - m_other) - m_dil_sqr;
420 const double rad2 = (m_par + m_other) * (m_par + m_other) - m_dil_sqr;
422 assert(rad1 > -1E-5);
424 }
else if (rad2 < 0.) {
425 assert(rad2 > -1E-5);
429 (m_par - m_other) / (m_par_cubed * m_other_sqr) *
431 const double t2 =
pow_int(std::sqrt(rad2), 3);
432 const double ff = 1.08;
433 const double gamma_vi = t1 * t2 * ff;
439 throw std::runtime_error(
"Bad baryon in ThreeBodyDecayDilepton: " +
443 throw std::runtime_error(
"Non-hadron in ThreeBodyDecayDilepton: " +
454 int non_lepton_position = -1;
455 for (
int i = 0; i < 3; ++i) {
457 non_lepton_position = i;
462 const double m_l =
particle_types_[(non_lepton_position + 1) % 3]->mass();
470 m_other + 2 * m_l, M0 + 10 * G0tot,
num_tab_pts, [&](
double m_parent) {
471 const double bottom = 2 * m_l;
472 const double top = m_parent - m_other;
479 m_parent, m_l, m_dil, m_other,
DecayType is the abstract base class for all decay types.
int L_
angular momentum of the decay
ParticleTypePtrList particle_types_
final-state particles of the decay
A C++ interface for numerical integration in two dimensions with the Cuba Cuhre integration function.
A C++ interface for numerical integration in one dimension with the GSL CQUAD integration functions.
A pointer-like interface to global references to ParticleType objects.
Particle type contains the static properties of a particle species.
double spectral_function(double m) const
Full spectral function of the resonance (relativistic Breit-Wigner distribution with mass-dependent ...
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...
static const ParticleType & find(PdgCode pdgcode)
Returns the ParticleType object for the given pdgcode.
double min_mass_kinematic() const
The minimum mass of the resonance that is kinematically allowed.
double width_at_pole() const
PdgCode stores a Particle Data Group Particle Numbering Scheme particle type number.
std::int32_t code() const
unsigned int spin() const
std::string string() const
ParticleTypePtr mother_
Type of the mother particle.
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...
bool has_mother(ParticleTypePtr mother) const override
See DecayType::has_mother.
double width(double m0, double G0, double m) const override
ThreeBodyDecayDilepton(ParticleTypePtr mother, ParticleTypePtrList part_types, int l)
Construct a ThreeBodyDecayDilepton.
std::unique_ptr< Tabulation > tabulation_
Tabulation of the resonance integrals.
ThreeBodyDecay represents a decay type with three final-state particles.
double width(double m0, double G0, double m) const override
bool has_particles(ParticleTypePtrList list) const override
unsigned int particle_number() 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
double width(double m0, double G0, double m) const override
Get the mass-dependent width of a two-body decay into stable particles according to Manley:1992yb .
TwoBodyDecayDilepton(ParticleTypePtrList part_types, int l)
Construct a TwoBodyDecayDilepton.
std::unique_ptr< Tabulation > tabulation_
Tabulation of the resonance integrals.
double rho(double m) const override
See TwoBodyDecay::rho.
TwoBodyDecaySemistable(ParticleTypePtrList part_types, int l)
Construct a TwoBodyDecaySemistable.
double Lambda_
Cut-off parameter Λ for semi-stable decays.
double in_width(double m0, double G0, double m, double m1, double m2) const override
Get the mass-dependent in-width for a resonance formation process from one stable and one unstable pa...
double width(double m0, double G0, double m) const override
Get the mass-dependent width of a two-body decay into one stable and one unstable particle according ...
TwoBodyDecayStable represents a decay type with two stable final-state particles.
double width(double m0, double G0, double m) const override
Get the mass-dependent width of a two-body decay into stable particles according to Manley:1992yb .
double in_width(double m0, double G0, double m, double m1, double m2) const override
Get the mass-dependent in-width for a resonance formation process from two stable particles according...
double rho(double m) const override
See TwoBodyDecay::rho.
TwoBodyDecayStable(ParticleTypePtrList part_types, int l)
Construct a TwoBodyDecayStable.
double in_width(double m0, double G0, double m, double m1, double m2) const override
double width(double m0, double G0, double m) const override
double rho(double m) const override
See TwoBodyDecay::rho.
std::unique_ptr< Tabulation > tabulation_
Tabulation of the resonance integrals.
TwoBodyDecayUnstable(ParticleTypePtrList part_types, int l)
Construct a TwoBodyDecayUnstable.
double Lambda_
Cut-off parameter Λ for unstable decays.
TwoBodyDecay represents a decay type with two final-state particles.
unsigned int particle_number() const override
TwoBodyDecay(ParticleTypePtrList part_types, int l)
Construct a TwoBodyDecay.
bool has_particles(ParticleTypePtrList list) const override
Collection of useful constants that are known at compile time.
constexpr int N1520_z
N(1520)⁰.
constexpr int photon
Photon.
constexpr int N1520_p
N(1520)⁺.
constexpr int invalid
Invalid particle.
bool is_dilepton(const PdgCode pdg1, const PdgCode pdg2)
static ParticleTypePtrList sort_particles(ParticleTypePtrList part_types)
sort the particle list
T pCM(const T sqrts, const T mass_a, const T mass_b) noexcept
double em_form_factor_sqr_vec(PdgCode pdg, double mass)
static double integrand_rho_Manley_2res(double sqrts, double m1, double m2, ParticleTypePtr t1, ParticleTypePtr t2, int L)
static Integrator integrate
static ParticleTypePtrList & arrange_particles(ParticleTypePtrList &part_types)
Rearrange the particle list such that the first particle is the stable one.
static Integrator2d integrate2d(1E7)
double form_factor_delta([[maybe_unused]] double m)
bool has_lepton_pair(const PdgCode pdg1, const PdgCode pdg2, const PdgCode pdg3)
constexpr size_t num_tab_pts
Number of tabulation points.
constexpr T pow_int(const T base, unsigned const exponent)
Efficient template for calculating integer powers using squaring.
double blatt_weisskopf_sqr(const double p_ab, const int L)
static double integrand_rho_Manley_1res(double sqrts, double mass, double stable_mass, ParticleTypePtr type, int L)
constexpr double fine_structure
Fine-struture constant, approximately 1/137.
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.
double em_form_factor_ps(PdgCode pdg, double mass)