59 const auto offset =
this - std::addressof(
list_all()[0]);
64 assert(offset >= 0 && offset < 0xffff);
90 const auto found = std::lower_bound(
129 min_mass_kinematic_(-1.),
130 min_mass_spectral_(-1.),
131 charge_(pdgcode_.charge()),
133 I3_(pdgcode_.isospin3()) {}
144 std::string basename, charge;
146 if (name.find(
"⁺⁺") != std::string::npos) {
147 basename = name.substr(0, name.length() -
sizeof(
"⁺⁺") + 1);
149 }
else if (name.find(
"⁺") != std::string::npos) {
150 basename = name.substr(0, name.length() -
sizeof(
"⁺") + 1);
152 }
else if (name.find(
"⁻⁻") != std::string::npos) {
153 basename = name.substr(0, name.length() -
sizeof(
"⁻⁻") + 1);
155 }
else if (name.find(
"⁻") != std::string::npos) {
156 basename = name.substr(0, name.length() -
sizeof(
"⁻") + 1);
158 }
else if (name.find(
"⁰") != std::string::npos) {
159 basename = name.substr(0, name.length() -
sizeof(
"⁰") + 1);
168 constexpr
char bar[] =
"\u0305";
172 return basename + charge;
195 throw std::runtime_error(
"Invalid charge " + std::to_string(charge));
200 static ParticleTypeList type_list;
204 std::istringstream lineinput(line.text);
207 std::string parity_string;
208 std::vector<std::string> pdgcode_strings;
210 pdgcode_strings.reserve(4);
211 lineinput >>
name >>
mass >> width >> parity_string;
214 if (parity_string ==
"+") {
216 }
else if (parity_string ==
"-") {
221 if (lineinput.fail() || fail) {
223 "While loading the ParticleType data:\nFailed to convert the input "
224 "string to the expected data types.",
228 while (!lineinput.eof()) {
229 pdgcode_strings.push_back(
"");
230 lineinput >> pdgcode_strings.back();
231 if (lineinput.fail()) {
233 "While loading the ParticleType data:\nFailed to convert the input "
234 "string to the expected data types.",
238 if (pdgcode_strings.size() < 1) {
240 "While loading the ParticleType data:\nFailed to convert the input "
241 "string due to missing PDG code.",
245 pdgcode.resize(pdgcode_strings.size());
246 std::transform(pdgcode_strings.begin(), pdgcode_strings.end(),
248 [](
const std::string &s) { return PdgCode(s); });
253 throw std::runtime_error(
"Nucleon mass in input file different from " +
257 throw std::runtime_error(
"Pion mass in input file different from " +
261 throw std::runtime_error(
"Kaon mass in input file different from " +
265 throw std::runtime_error(
"Omega mass in input file different from " +
269 throw std::runtime_error(
"Delta mass in input file different from " +
273 throw std::runtime_error(
"Deuteron mass in input file different from " +
278 for (
size_t i = 0; i <
pdgcode.size(); i++) {
279 std::string full_name =
name;
286 <<
"Setting particle type: " << type_list.back();
293 type_list.emplace_back(full_name,
mass, width, anti_parity, anti);
295 <<
"Setting antiparticle type: " << type_list.back();
299 type_list.shrink_to_fit();
302 std::sort(type_list.begin(), type_list.end());
306 for (
const auto &t : type_list) {
307 if (t.pdgcode() == prev_pdg) {
309 t.pdgcode().string());
311 prev_pdg = t.pdgcode();
315 throw std::runtime_error(
"Error: Type list was already built!");
322 for (
const auto &t : type_list) {
326 for (
auto &t : type_list) {
349 if (type_resonance.is_stable() ||
350 type_resonance.pdgcode().baryon_number() != 1) {
358 if (type.is_nucleus()) {
370 for (
const auto &mode :
decay_modes().decay_mode_list()) {
389 const double m_step = 0.01;
390 double right_bound_bis;
391 for (
unsigned int i = 0;; i++) {
398 const double precision = 1E-6;
399 double left_bound_bis = right_bound_bis - m_step;
400 while (right_bound_bis - left_bound_bis > precision) {
401 const double mid = (left_bound_bis + right_bound_bis) / 2.0;
403 right_bound_bis = mid;
405 left_bound_bis = mid;
425 if (m < mode->threshold()) {
433 const auto offset =
this - std::addressof(
list_all()[0]);
434 const auto &modes = (*DecayModes::all_decay_modes)[offset];
435 assert(
is_stable() || !modes.is_empty());
446 for (
unsigned int i = 0; i < modes.size(); i++) {
457 if (!ptype.is_stable() && ptype.decay_modes().is_empty()) {
458 throw std::runtime_error(
459 "Unstable particle " + ptype.name() +
460 " has no decay chanels! Either add one to it in decaymodes file or "
461 "set it's width to 0 in particles file.");
464 throw std::runtime_error(
465 "d' cannot be used without deuteron. Modify input particles file "
484 throw std::runtime_error(
485 "Problem in selecting decaymodes in wanted_decaymode()");
505 DecayBranchList partial;
506 partial.reserve(decay_mode_list.size());
507 for (
unsigned int i = 0; i < decay_mode_list.size(); i++) {
509 const auto FinalTypes = decay_mode_list[i]->type().particle_types();
510 double scale_B = 0.0;
511 double scale_I3 = 0.0;
515 for (
const auto &finaltype : FinalTypes) {
518 finaltype->isospin3_rel();
521 double sqrt_s = (
p + UB * scale_B + UI3 * scale_I3).abs();
523 const double w =
partial_width(sqrt_s, decay_mode_list[i].get());
527 std::make_unique<DecayBranch>(decay_mode_list[i]->type(), w));
535 const ParticleTypePtrList dlist)
const {
541 for (
const auto &mode : decaymodes) {
542 double partial_width_at_pole =
width_at_pole() * mode->weight();
543 if (mode->type().has_particles(dlist)) {
544 w += mode->type().width(
mass(), partial_width_at_pole, m);
558 for (
const auto &mode : decaymodes) {
559 double partial_width_at_pole =
width_at_pole() * mode->weight();
560 const ParticleTypePtrList l = {&p_a.
type(), &p_b.
type()};
561 if (mode->type().has_particles(l)) {
562 w += mode->type().in_width(
mass(), partial_width_at_pole, m,
575 const double m_pole =
mass();
580 const double tanx = std::tan(x);
581 const double m_x = m_pole + width * tanx;
582 const double jacobian = width * (1.0 + tanx * tanx);
615 const double cms_energy,
619 const double max_mass = std::nextafter(cms_energy - mass_stable, 0.);
625 const double pcm_max =
pCM(cms_energy, mass_stable, min_mass);
632 const double sf_ratio_max =
636 double mass_res, val;
640 const double max = blw_max * q_max;
647 const double pcm =
pCM(cms_energy, mass_stable, mass_res);
658 "maximum is being increased in sample_resonance_mass: ",
659 this->max_factor1_,
" ", val / max,
" ", this->
pdgcode(),
" ",
660 mass_stable,
" ", cms_energy,
" ", mass_res);
661 this->max_factor1_ *= val / max;
672 const ParticleType &t2,
const double cms_energy,
int L)
const {
676 const double max_mass_1 =
678 const double max_mass_2 =
681 const double pcm_max =
685 double mass_1, mass_2, val;
698 const double pcm =
pCM(cms_energy, mass_1, mass_2);
710 "maximum is being increased in sample_resonance_masses: ",
712 " ", cms_energy,
" ", mass_1,
" ", mass_2);
719 return {mass_1, mass_2};
724 std::stringstream err;
725 err <<
"Particle " << *
this <<
" is stable, so it makes no"
726 <<
" sense to print its spectral function, etc.";
727 throw std::runtime_error(err.str());
730 double rightmost_pole = 0.0;
732 for (
const auto &mode : decaymodes) {
733 double pole_mass_sum = 0.0;
735 pole_mass_sum +=
p->mass();
737 if (pole_mass_sum > rightmost_pole) {
738 rightmost_pole = pole_mass_sum;
742 std::cout <<
"# mass m[GeV], width w(m) [GeV],"
743 <<
" spectral function(m^2)*m [GeV^-1] of " << *
this << std::endl;
744 constexpr
double m_step = 0.02;
748 constexpr
double spectral_function_threshold = 8.e-3;
749 std::cout << std::fixed << std::setprecision(5);
750 for (
unsigned int i = 0;; i++) {
751 const double m = m_min + m_step * i;
753 if (m > rightmost_pole * 2 && sf < spectral_function_threshold) {
756 std::cout << m <<
" " << w <<
" " << sf << std::endl;
762 return out << type.
name() << std::setfill(
' ') << std::right
763 <<
"[ mass:" << field<6> << type.
mass()
765 <<
", PDG:" << field<6> << pdg
766 <<
", charge:" << field<3> << pdg.
charge()
767 <<
", spin:" << field<2> << pdg.
spin() <<
"/2 ]";
777 static std::map<std::set<ParticleTypePtr>, ParticleTypePtrList>
778 map_possible_resonances_of;
779 std::set<ParticleTypePtr> incoming{type_a, type_b};
780 const ParticleTypePtrList incoming_types = {type_a, type_b};
782 if (map_possible_resonances_of.count(incoming) == 0) {
784 <<
"Filling map of compatible resonances for ptypes " << type_a->
name()
785 <<
" " << type_b->
name();
786 ParticleTypePtrList resonance_list{};
791 if (resonance.is_stable()) {
795 if ((resonance.pdgcode() == type_a->
pdgcode()) ||
796 (resonance.pdgcode() == type_b->
pdgcode())) {
800 if (resonance.charge() != type_a->
charge() + type_b->
charge()) {
804 if (resonance.baryon_number() !=
809 if (resonance.strangeness() !=
813 const auto &decaymodes = resonance.decay_modes().decay_mode_list();
814 for (
const auto &mode : decaymodes) {
815 if (mode->type().has_particles(incoming_types)) {
816 resonance_list.push_back(&resonance);
823 map_possible_resonances_of[incoming] = resonance_list;
826 return map_possible_resonances_of[incoming];
DecayBranch is a derivative of ProcessBranch, which is used to represent decay channels.
const DecayType & type() const
The DecayModes class is used to store and update information about decay branches (i....
const DecayBranchList & decay_mode_list() const
DecayType is the abstract base class for all decay types.
virtual bool is_dilepton_decay() const
virtual double width(double m0, double G0, double m) const =0
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
A C++ interface for numerical integration in one dimension with the GSL CQUAD integration functions.
static bool exists(const std::string &name)
Returns whether the ParticleType with the given pdgcode exists.
static const IsoParticleType & find(const std::string &name)
Returns the IsoParticleType object for the given name.
int isospin() const
Returns twice the total isospin of the multiplet.
static void create_multiplet(const ParticleType &type)
Add a new multiplet to the global list of IsoParticleTypes, which contains type.
ParticleData contains the dynamic information of a certain particle.
const ParticleType & type() const
Get the type of the particle.
double effective_mass() const
Get the particle's effective mass.
A pointer-like interface to global references to ParticleType objects.
Particle type contains the static properties of a particle species.
double min_mass_spectral_
minimum mass, where the spectral function is non-zero Mutable, because it is initialized at first cal...
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.
const DecayModes & decay_modes() const
double spectral_function(double m) const
Full spectral function of the resonance (relativistic Breit-Wigner distribution with mass-dependent ...
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...
static const ParticleTypePtr try_find(PdgCode pdgcode)
Returns the ParticleTypePtr for the given pdgcode.
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...
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.
static bool exists(PdgCode pdgcode)
static void check_consistency()
double max_factor2_
Maximum factor for double-res mass sampling, cf. sample_resonance_masses.
const std::string & name() const
double min_mass_kinematic_
minimum kinematically allowed mass of the particle Mutable, because it is initialized at first call o...
int32_t charge() const
The charge of the particle.
double spectral_function_no_norm(double m) const
Full spectral function without normalization factor.
static ParticleTypePtrList & list_nucleons()
static ParticleTypePtrList & list_anti_nucleons()
static const ParticleTypeList & list_all()
int isospin_
Isospin of the particle; filled automatically from pdgcode_.
double isospin3_rel() const
double spectral_function_simple(double m) const
This one is the most simple form of the spectral function, using a Cauchy distribution (non-relativis...
double width_at_pole() const
static ParticleTypePtrList & list_anti_Deltas()
PdgCode pdgcode_
PDG Code of the particle.
bool has_antiparticle() const
ParticleType(std::string n, double m, double w, Parity p, PdgCode id)
Creates a fully initialized ParticleType object.
static ParticleTypePtrList & list_baryon_resonances()
static constexpr double width_cutoff
Decay width cutoff for considering a particle as stable.
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.
static ParticleTypePtrList & list_Deltas()
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 ...
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 .
double norm_factor_
This normalization factor ensures that the spectral function is normalized to unity,...
int baryon_number() const
ParticleTypePtr operator&() const
Returns an object that acts like a pointer, except that it requires only 2 bytes and inhibits pointer...
double max_factor1_
Maximum factor for single-res mass sampling, cf. sample_resonance_mass.
double spectral_function_const_width(double m) const
std::pair< double, double > sample_resonance_masses(const ParticleType &t2, const double cms_energy, int L=0) const
Resonance mass sampling for 2-particle final state with two resonances.
static ParticleTypePtrList & list_light_nuclei()
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.
double mass_
pole mass of the particle
PdgCode stores a Particle Data Group Particle Numbering Scheme particle type number.
int baryon_number() const
unsigned int spin() const
std::string string() const
PdgCode get_antiparticle() const
Construct the antiparticle to a given PDG code.
int charge() const
The charge of the particle.
static std::pair< double, int > force_scale(const ParticleType &data)
Evaluates the scaling factor of the forces acting on the particles.
The ThreeVector class represents a physical three-vector with the components .
Collection of useful constants that are known at compile time.
std::ostream & operator<<(std::ostream &out, const ActionPtr &action)
Convenience: dereferences the ActionPtr to Action.
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
#define unlikely(x)
Tell the branch predictor that this expression is likely false.
ParticleTypePtrList deltas_list
Global pointer to the Particle Type list of deltas.
ParticleTypePtrList baryon_resonances_list
Global pointer to the Particle Type list of baryon resonances.
const ParticleTypeList * all_particle_types
Global pointer to the Particle Type list.
ParticleTypePtrList anti_deltas_list
Global pointer to the Particle Type list of anti-deltas.
ParticleTypePtrList light_nuclei_list
Global pointer to the Particle Type list of light nuclei.
ParticleTypePtrList anti_nucs_list
Global pointer to the Particle Type list of anti-nucleons.
ParticleTypePtrList nucleons_list
Global pointer to the Particle Type list of nucleons.
constexpr int64_t deuteron
Deuteron.
T cauchy(T pole, T width, T min, T max)
Draws a random number from a Cauchy distribution (sometimes also called Lorentz or non-relativistic B...
std::iterator_traits< octet_iterator >::difference_type sequence_length(octet_iterator lead_it)
Given an iterator to the beginning of a UTF-8 sequence, return the length of the next UTF-8 code poin...
constexpr double delta_mass
Delta mass in GeV.
T pCM(const T sqrts, const T mass_a, const T mass_b) noexcept
ParticleTypePtrList list_possible_resonances(const ParticleTypePtr type_a, const ParticleTypePtr type_b)
Lists the possible resonances that decay into two particles.
void ensure_all_read(std::istream &input, const Line &line)
Makes sure that nothing is left to read from this line.
static Integrator integrate
double breit_wigner(double m, double pole, double width)
Returns a relativistic Breit-Wigner distribution.
static std::string antiname(const std::string &name, PdgCode code)
Construct an antiparticle name-string from the given name-string for the particle and its PDG code.
build_vector_< Line > line_parser(const std::string &input)
Helper function for parsing particles.txt and decaymodes.txt.
Parity
Represent the parity of a particle type.
constexpr double deuteron_mass
Deuteron mass in GeV.
constexpr double nucleon_mass
Nucleon mass in GeV.
double blatt_weisskopf_sqr(const double p_ab, const int L)
static constexpr int LResonances
Potentials * pot_pointer
Pointer to a Potential class.
constexpr double pion_mass
Pion mass in GeV.
constexpr double really_small
Numerical error tolerance.
std::string build_error_string(std::string message, const Line &line)
Builds a meaningful error message.
constexpr double kaon_mass
Kaon mass in GeV.
RectangularLattice< FourVector > * UB_lat_pointer
Pointer to the skyrme potential on the lattice.
double breit_wigner_nonrel(double m, double pole, double width)
Returns a non-relativistic Breit-Wigner distribution, which is essentially a Cauchy distribution with...
static std::string chargestr(int charge)
Construct a charge string, given the charge as integer.
bool almost_equal(const N x, const N y)
Checks two numbers for relative approximate equality.
constexpr double omega_mass
omega mass in GeV.
RectangularLattice< FourVector > * UI3_lat_pointer
Pointer to the symmmetry potential on the lattice.
WhichDecaymodes
Decide which decay mode widths are returned in get partical widths.
@ Hadronic
Ignore dilepton decay modes widths.
@ Dileptons
Only return dilepton decays widths.
@ All
All decay mode widths.
static constexpr int LParticleType
Line consists of a line number and the contents of that line.