36 : finder_parameters_(config, parameters),
37 isotropic_(config.take(
InputKeys::collTerm_isotropic)),
38 box_length_(parameters.box_length),
39 string_formation_time_(
40 config.take(
InputKeys::collTerm_stringParam_formationTime)) {
43 "Constant elastic isotropic cross-section mode:",
" using ",
48 throw std::invalid_argument(
49 "Multi-body reactions (like e.g. 3->1 or 3->2) are only possible with "
52 "criterion. Change your config accordingly.");
62 throw std::invalid_argument(
63 "To prevent double counting it is not possible to enable deuteron 3->2 "
64 "reactions\nand reactions involving the d' at the same time\ni.e. to "
65 "include \"Deuteron_3to2\" in `Multi_Particle_Reactions` and\n "
66 "\"PiDeuteron_to_pidprime\" "
67 "or \"NDeuteron_to_Ndprime\" in `Included_2to2` at the same time.\n"
68 "Change your config accordingly.");
75 throw std::invalid_argument(
76 "Do not use the d' resonance and enable \"Deuteron_3to2\" "
77 "`Multi_Particle_Reactions` at the same time. Either use the direct "
78 "3-to-2 reactions or the d' together with \"PiDeuteron_to_pidprime\" "
79 "and \"NDeuteron_to_Ndprime\" in `Included_2to2`. Otherwise the "
80 "deuteron 3-to-2 reactions would be double counted.");
91 throw std::invalid_argument(
92 "In order to conserve detailed balance, when \"NNbar_5to2\" is "
93 "included in\n`Multi_Particle_Reactions`, the `NNbarTreatment` has to "
94 "be set to \"two to five\" and vice versa.");
99 throw std::invalid_argument(
100 "'NNbar' has to be in the list of allowed 2 to 2 processes "
101 "to enable annihilation to go through resonances");
137 if (sqrts_range_Npi.second < sqrts_range_Npi.first)
138 sqrts_range_Npi.second = sqrts_range_Npi.first;
140 "Lower bound of Sqrts_Range_Npi too small, setting it to mass "
141 "threshold. New range is [",
142 sqrts_range_Npi.first,
',', sqrts_range_Npi.second,
"] GeV");
146 if (sqrts_range_NN.second < sqrts_range_NN.first)
147 sqrts_range_NN.second = sqrts_range_NN.first;
149 "Lower bound of Sqrts_Range_NN too small, setting it to mass "
150 "threshold. New range is [",
151 sqrts_range_NN.first,
',', sqrts_range_NN.second,
"] GeV.");
154 return {sqrts_range_Npi,
164 : elastic_parameter(config.take(
InputKeys::collTerm_elasticCrossSection)),
165 low_snn_cut(parameters.low_snn_cut),
166 scale_xs(parameters.scale_xs),
168 config.take(
InputKeys::collTerm_additionalElasticCrossSection)),
169 maximum_cross_section(parameters.maximum_cross_section),
170 coll_crit(parameters.coll_crit),
171 nnbar_treatment(parameters.nnbar_treatment),
172 included_2to2(parameters.included_2to2),
173 included_multi(parameters.included_multi),
174 testparticles(parameters.testparticles),
175 two_to_one(parameters.two_to_one),
176 allow_collisions_within_nucleus(
177 config.take(
InputKeys::modi_collider_collisionWithinNucleus)),
178 spin_interaction_type(parameters.spin_interaction_type),
179 strings_switch(parameters.strings_switch),
180 use_AQM(config.take(
InputKeys::collTerm_useAQM)),
181 strings_with_probability(
182 config.take(
InputKeys::collTerm_stringsWithProbability)),
183 only_warn_for_high_prob(
184 config.take(
InputKeys::collTerm_onlyWarnForHighProbability)),
186 total_xs_strategy(config.take(
InputKeys::collTerm_totXsStrategy)),
187 pseudoresonance_method(config.take(
InputKeys::collTerm_pseudoresonance)),
188 AQM_charm_suppression(
189 config.take(
InputKeys::collTerm_HF_AQMcSuppression)),
190 AQM_bottom_suppression(
191 config.take(
InputKeys::collTerm_HF_AQMbSuppression)) {
194 "Evaluating total cross sections from partial processes.");
197 throw std::invalid_argument(
198 "The BottomUp strategy for total cross section evaluation is needed to "
199 "have only elastic interactions, please change the configuration "
203 "Evaluating total cross sections from parametrizations.");
206 "Evaluating total cross sections from parametrizations only for "
207 "measured processes.");
212 throw std::invalid_argument(
213 "Suppression factors for AQM should be between 0 and 1.");
219 const std::vector<FourVector>& beam_momentum,
220 const double gcell_vol)
const {
226 assert(data_a.
id() >= 0);
227 assert(data_b.
id() >= 0);
232 bool never_interacted_before =
235 if (in_same_nucleus && never_interacted_before) {
247 const double time_until_collision =
251 if (time_until_collision < 0. || time_until_collision >= dt) {
266 ScatterActionPtr act = std::make_unique<ScatterAction>(
272 act->set_stochastic_pos_idx();
280 const double distance_squared =
282 ? act->transverse_distance_sqr()
284 ? act->cov_transverse_distance_sqr()
295 if (incoming_parametrized) {
302 double xs = act->cross_section() *
fm2_mb /
310 const double v_rel = act->relative_velocity();
313 const double prob = xs * v_rel * dt / gcell_vol;
316 "Stochastic collison criterion parameters (2-particles):\nprob = ",
317 prob,
", xs = ", xs,
", v_rel = ", v_rel,
", dt = ", dt,
318 ", gcell_vol = ", gcell_vol,
322 std::stringstream err;
323 err <<
"Probability larger than 1 for stochastic rates. ( P_22 = " << prob
327 <<
" at sqrts[GeV] = " << act->sqrt_s()
328 <<
" with xs[fm^2]/Ntest = " << xs
329 <<
"\nConsider using smaller timesteps.";
333 throw std::runtime_error(err.str());
339 if (random_no > prob) {
356 const double cross_section_criterion = xs * M_1_PI;
359 if (distance_squared >= cross_section_criterion) {
364 "\n ", data_a,
"\n<-> ", data_b);
368 if (incoming_parametrized) {
376 const ParticleList& plist,
double dt,
const double gcell_vol)
const {
384 bool all_projectile =
386 return data.belongs_to() == BelongsTo::Projectile;
390 return data.belongs_to() == BelongsTo::Target;
394 return data.get_history().collisions_per_particle == 0;
396 if ((all_projectile || all_target) && none_collided) {
412 ScatterActionMultiPtr act =
413 std::make_unique<ScatterActionMulti>(plist, time_until_collision);
415 act->set_stochastic_pos_idx();
424 act->get_total_weight() /
429 std::stringstream err;
430 err <<
"Probability " << prob <<
" larger than 1 for stochastic rates for ";
432 err << data.type().name();
434 err <<
" at sqrts[GeV] = " << act->sqrt_s()
435 <<
"\nConsider using smaller timesteps.";
439 throw std::runtime_error(err.str());
445 if (random_no > prob) {
453 const ParticleList& search_list,
double dt,
const double gcell_vol,
454 const std::vector<FourVector>& beam_momentum)
const {
455 std::vector<ActionPtr> actions;
459 if (p1.id() < p2.id()) {
463 actions.push_back(std::move(act));
473 if (p1.id() < p2.id() && p2.id() < p3.id()) {
477 actions.push_back(std::move(act));
484 if (p1.id() < p2.id() && p2.id() < p3.id() && p3.id() < p4.id()) {
488 actions.push_back(std::move(act));
494 search_list.size() >= 5) {
496 if ((p1.id() < p2.id() && p2.id() < p3.id() &&
497 p3.id() < p4.id() && p4.id() < p5.id()) &&
498 (p1.is_pion() && p2.is_pion() && p3.is_pion() &&
499 p4.is_pion() && p5.is_pion())) {
502 {p1, p2, p3, p4, p5}, dt, gcell_vol);
504 actions.push_back(std::move(act));
518 const ParticleList& search_list,
const ParticleList& neighbors_list,
519 double dt,
const std::vector<FourVector>& beam_momentum)
const {
520 std::vector<ActionPtr> actions;
527 assert(p1.id() != p2.id());
531 actions.push_back(std::move(act));
539 const ParticleList& search_list,
const Particles& surrounding_list,
540 double dt,
const std::vector<FourVector>& beam_momentum)
const {
541 std::vector<ActionPtr> actions;
549 auto result = std::find_if(
550 search_list.begin(), search_list.end(),
552 if (result != search_list.end()) {
559 actions.push_back(std::move(act));
567 constexpr
double time = 0.0;
570 const size_t N_pairs = N_isotypes * (N_isotypes - 1) / 2;
572 std::cout << N_isotypes <<
" iso-particle types." << std::endl;
573 std::cout <<
"They can make " << N_pairs <<
" pairs." << std::endl;
574 std::vector<double> momentum_scan_list = {0.1, 0.3, 0.5, 1.0,
575 2.0, 3.0, 5.0, 10.0};
578 if (&A_isotype > &B_isotype) {
581 bool any_nonzero_cs =
false;
582 std::vector<std::string> r_list;
585 if (A_type > B_type) {
589 for (
auto mom : momentum_scan_list) {
590 A.set_4momentum(A.pole_mass(), mom, 0.0, 0.0);
592 ScatterActionPtr act = std::make_unique<ScatterAction>(
599 const double total_cs = act->cross_section();
600 if (total_cs <= 0.0) {
603 any_nonzero_cs =
true;
604 for (
const auto& channel : act->collision_channels()) {
605 const auto type = channel->get_type();
609 r = A_type->name() + B_type->name() + std::string(
" → strings");
614 ? std::string(
" (inel)")
615 : std::string(
" (?)");
616 r = A_type->name() + B_type->name() + std::string(
" → ") +
617 channel->particle_types()[0]->name() +
618 channel->particle_types()[1]->name() + r_type;
626 std::sort(r_list.begin(), r_list.end());
627 r_list.erase(std::unique(r_list.begin(), r_list.end()), r_list.end());
628 if (any_nonzero_cs) {
629 for (
auto r : r_list) {
631 if (r_list.back() != r) {
635 std::cout << std::endl;
665 namespace decaytree {
713 Node(
const std::string& name,
double weight,
714 ParticleTypePtrList&& initial_particles,
715 ParticleTypePtrList&& final_particles, ParticleTypePtrList&& state,
716 std::vector<Node>&& children)
736 ParticleTypePtrList&& initial_particles,
737 ParticleTypePtrList&& final_particles) {
739 ParticleTypePtrList state(
state_);
740 for (
const auto&
p : initial_particles) {
741 state.erase(std::find(state.begin(), state.end(),
p));
743 for (
const auto&
p : final_particles) {
747 std::sort(state.begin(), state.end(),
749 return a->name() < b->name();
752 Node new_node(name, weight, std::move(initial_particles),
753 std::move(final_particles), std::move(state), {});
754 children_.emplace_back(std::move(new_node));
765 std::vector<FinalStateCrossSection> result;
778 for (uint64_t i = 0; i < depth; i++) {
783 child.print_helper(depth + 1);
799 uint64_t depth, std::vector<FinalStateCrossSection>& result,
800 const std::string& name,
double weight,
801 bool show_intermediate_states =
false)
const {
809 std::string new_name;
812 if (show_intermediate_states) {
814 if (!new_name.empty()) {
822 for (
const auto& s :
state_) {
823 new_name += s->name();
826 if (show_intermediate_states) {
835 child.final_state_cross_sections_helper(depth + 1, result, new_name,
836 weight, show_intermediate_states);
850 const DecayBranchPtr& decay,
851 ParticleTypePtrList& final_state) {
852 std::stringstream name;
853 name <<
"[" << res_name <<
"->";
854 for (
const auto&
p : decay->particle_types()) {
856 final_state.push_back(
p);
880 uint32_t n_unstable = 0;
881 double sqrts_minus_masses = sqrts;
886 sqrts_minus_masses -= ptype->
mass();
889 n_unstable != 0 ? 1. /
static_cast<double>(n_unstable) : 1.;
893 const double sqrts_decay = sqrts_minus_masses + ptype->
mass();
894 bool can_decay =
false;
899 double final_state_mass = 0.;
900 for (
const auto&
p : decay->particle_types()) {
901 final_state_mass +=
p->mass();
903 if (final_state_mass > sqrts_decay) {
908 ParticleTypePtrList parts;
910 auto& new_node = node.
add_action(name, norm * decay->weight(), {ptype},
931 static void deduplicate(std::vector<FinalStateCrossSection>& final_state_xs) {
932 std::sort(final_state_xs.begin(), final_state_xs.end(),
935 auto current = final_state_xs.begin();
936 while (current != final_state_xs.end()) {
937 auto adjacent = std::adjacent_find(
938 current, final_state_xs.end(),
940 return a.name_ == b.name_;
943 if (adjacent != final_state_xs.end()) {
944 adjacent->cross_section_ += (adjacent + 1)->cross_section_;
945 final_state_xs.erase(adjacent + 1);
952 bool final_state, std::vector<double>& plab)
const {
953 typedef std::vector<std::pair<double, double>> xs_saver;
954 std::map<std::string, xs_saver> xs_dump;
955 std::map<std::string, double> outgoing_total_mass;
958 int n_momentum_points = 200;
959 constexpr
double momentum_step = 0.02;
960 if (plab.size() > 0) {
961 n_momentum_points = plab.size();
963 std::sort(plab.begin(), plab.end());
964 plab.erase(std::unique(plab.begin(), plab.end()), plab.end());
966 for (
int i = 0; i < n_momentum_points; i++) {
968 if (plab.size() > 0) {
971 momentum = momentum_step * (i + 1);
973 a_data.set_4momentum(m_a, momentum, 0.0, 0.0);
975 const double sqrts = (a_data.momentum() + b_data.
momentum()).abs();
976 const ParticleList incoming = {a_data, b_data};
977 ScatterActionPtr act = std::make_unique<ScatterAction>(
985 {&a, &b}, {&a, &b}, {});
986 const CollisionBranchList& processes = act->collision_channels();
987 for (
const auto& process : processes) {
988 const double xs = process->weight();
993 std::stringstream process_description_stream;
994 process_description_stream << *process;
995 const std::string& description = process_description_stream.str();
997 for (
const auto& ptype : process->particle_types()) {
998 m_tot += ptype->mass();
1000 outgoing_total_mass[description] = m_tot;
1001 if (!xs_dump[description].empty() &&
1002 std::abs(xs_dump[description].back().first - sqrts) <
1004 xs_dump[description].back().second += xs;
1006 xs_dump[description].push_back(std::make_pair(sqrts, xs));
1009 std::stringstream process_description_stream;
1010 process_description_stream << *process;
1011 const std::string& description = process_description_stream.str();
1012 ParticleTypePtrList initial_particles = {&a, &b};
1013 ParticleTypePtrList final_particles = process->particle_types();
1014 auto& process_node =
1015 tree.
add_action(description, xs, std::move(initial_particles),
1016 std::move(final_particles));
1020 xs_dump[
"total"].push_back(std::make_pair(sqrts, act->cross_section()));
1022 outgoing_total_mass[
"total"] = -1.0;
1027 for (
const auto&
p : final_state_xs) {
1032 if (
p.name_ ==
"") {
1035 outgoing_total_mass[
p.name_] =
p.mass_;
1036 xs_dump[
p.name_].push_back(std::make_pair(sqrts,
p.cross_section_));
1043 for (
auto it = begin(xs_dump); it != end(xs_dump);) {
1045 const xs_saver& xs = (*it).second;
1047 for (
const auto&
p : xs) {
1051 it = xs_dump.erase(it);
1058 std::vector<std::string> all_channels;
1059 for (
const auto& channel : xs_dump) {
1060 all_channels.push_back(channel.first);
1062 std::sort(all_channels.begin(), all_channels.end(),
1063 [&](
const std::string& str_a,
const std::string& str_b) {
1064 return outgoing_total_mass[str_a] < outgoing_total_mass[str_b];
1068 std::cout <<
"# Dumping partial " << a.
name() << b.
name()
1069 <<
" cross-sections in mb, energies in GeV" << std::endl;
1070 std::cout <<
" sqrt_s";
1074 for (
const auto& channel : all_channels) {
1077 std::cout << std::endl;
1080 for (
int i = 0; i < n_momentum_points; i++) {
1082 if (plab.size() > 0) {
1085 momentum = momentum_step * (i + 1);
1087 a_data.set_4momentum(m_a, momentum, 0.0, 0.0);
1089 const double sqrts = (a_data.momentum() + b_data.
momentum()).abs();
1090 std::printf(
"%9.6f", sqrts);
1091 for (
const auto& channel : all_channels) {
1092 const xs_saver energy_and_xs = xs_dump[channel];
1094 for (; j < energy_and_xs.size() && energy_and_xs[j].first < sqrts; j++) {
1097 if (j < energy_and_xs.size() &&
1098 std::abs(energy_and_xs[j].first - sqrts) <
really_small) {
1099 xs = energy_and_xs[j].second;
1101 std::printf(
"%16.6f", xs);
Interface to the SMASH configuration files.
T take(const Key< T > &key)
The default interface for SMASH to read configuration values.
const DecayBranchList & decay_mode_list() const
double abs() const
calculate the lorentz invariant absolute value
IsoParticleType is a class to represent isospin multiplets.
static const IsoParticleTypeList & list_all()
Returns a list of all IsoParticleTypes.
ParticleData contains the dynamic information of a certain particle.
void set_4momentum(const FourVector &momentum_vector)
Set the particle's 4-momentum directly.
const ParticleType & type() const
Get the type of the particle.
double xsec_scaling_factor(double delta_time=0.) const
Return the cross section scaling factor at a given time.
uint32_t id_process() const
Get the id of the last action.
const FourVector & momentum() const
Get the particle's 4-momentum.
BelongsTo belongs_to() const
Getter for belongs_to label.
int32_t id() const
Get the id of the particle.
HistoryData get_history() const
Get history information.
double pole_mass() const
Get the particle's pole mass ("on-shell").
const FourVector & position() const
Get the particle's position in Minkowski space.
A pointer-like interface to global references to ParticleType objects.
Particle type contains the static properties of a particle species.
const DecayModes & decay_modes() const
static const ParticleTypePtr try_find(PdgCode pdgcode)
Returns the ParticleTypePtr for the given pdgcode.
const std::string & name() const
The Particles class abstracts the storage and manipulation of particles.
PdgCode stores a Particle Data Group Particle Numbering Scheme particle type number.
const bool only_warn_for_high_prob
Switch to turn off throwing an exception for collision probabilities larger than 1.
const int testparticles
Number of test particles.
ScatterActionsFinderParameters(Configuration &config, const ExperimentParameters ¶meters)
Class constructor.
const ReactionsBitSet included_2to2
List of included 2<->2 reactions.
const double elastic_parameter
Elastic cross section parameter (in mb).
const bool strings_switch
Indicates whether string fragmentation is switched on.
const TotalCrossSectionStrategy total_xs_strategy
Method used to evaluate total cross sections for collision finding.
const double AQM_charm_suppression
Factor to reduce cross sections for charmed hadrons.
const MultiParticleReactionsBitSet included_multi
List of included multi-particle reactions.
const bool allow_collisions_within_nucleus
If particles within the same nucleus are allowed to collide for their first time.
const NNbarTreatment nnbar_treatment
Switch for NNbar reactions.
const double AQM_bottom_suppression
Factor to reduce cross sections for bottomed hadrons.
const CollisionCriterion coll_crit
Specifies which collision criterion is used.
const SpinInteractionType spin_interaction_type
Switch to control whether to include spin interactions.
ScatterActionsFinder(Configuration &config, const ExperimentParameters ¶meters)
Constructor of the finder with the given parameters.
ScatterActionsFinderParameters finder_parameters_
Struct collecting several parameters.
ActionList find_actions_in_cell(const ParticleList &search_list, double dt, const double gcell_vol, const std::vector< FourVector > &beam_momentum) const override
Search for all the possible collisions within one cell.
void dump_cross_sections(const ParticleType &a, const ParticleType &b, double m_a, double m_b, bool final_state, std::vector< double > &plab) const
Print out partial cross-sections of all processes that can occur in the collision of a(mass = m_a) an...
const bool isotropic_
Do all collisions isotropically.
double max_transverse_distance_sqr(int testparticles) const
The maximal distance over which particles can interact in case of the geometric criterion,...
ActionPtr check_collision_two_part(const ParticleData &data_a, const ParticleData &data_b, double dt, const std::vector< FourVector > &beam_momentum={}, const double gcell_vol=0.0) const
Check for a single pair of particles (id_a, id_b) if a collision will happen in the next timestep and...
const double string_formation_time_
Parameter for formation time.
std::unique_ptr< StringProcess > string_process_interface_
Class that deals with strings, interfacing Pythia.
void dump_reactions() const
Prints out all the 2-> n (n > 1) reactions with non-zero cross-sections between all possible pairs of...
bool is_constant_elastic_isotropic() const
If there is only one particle sort, no decays (only elastic scatterings are possible),...
ActionPtr check_collision_multi_part(const ParticleList &plist, double dt, const double gcell_vol) const
Check for multiple i.e.
const double box_length_
Box length: needed to determine coordinates of collision correctly in case of collision through the w...
ActionList find_actions_with_surrounding_particles(const ParticleList &search_list, const Particles &surrounding_list, double dt, const std::vector< FourVector > &beam_momentum) const override
Search for all the possible secondary collisions between the outgoing particles and the rest.
ActionList find_actions_with_neighbors(const ParticleList &search_list, const ParticleList &neighbors_list, double dt, const std::vector< FourVector > &beam_momentum) const override
Search for all the possible collisions among the neighboring cells.
double collision_time(const ParticleData &p1, const ParticleData &p2, double dt, const std::vector< FourVector > &beam_momentum) const
Determine the collision time of the two particles.
Collection of useful constants that are known at compile time.
@ TwoToFive
Directly create 5 pions, use with multi-particle reactions.
@ Resonances
Use intermediate Resonances.
@ TopDownMeasured
Mix the two above, using the parametrizations only for measured processes, and summing up partials fo...
@ TopDown
Use parametrizations based on existing data, rescaling with AQM for unmeasured processes.
@ BottomUp
Sum the existing partial contributions.
@ Stochastic
Stochastic Criteiron.
@ Geometric
Geometric criterion.
@ Covariant
Covariant Criterion.
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
static std::string make_decay_name(const std::string &res_name, const DecayBranchPtr &decay, ParticleTypePtrList &final_state)
Generate name for decay and update final state.
static void add_decays(Node &node, double sqrts)
Add nodes for all decays possible from the given node and all of its children.
constexpr int64_t dprime
Deuteron-prime resonance.
std::string fill_left(const std::string &s, size_t width, char fill=' ')
Fill string with characters to the left until the given width is reached.
bool parametrization_exists(const PdgCode &pdg_a, const PdgCode &pdg_b)
Checks if supplied codes have existing parametrizations of total cross sections.
static void deduplicate(std::vector< FinalStateCrossSection > &final_state_xs)
Deduplicate the final-state cross sections by summing.
@ TwoToTwo
See here for a short description.
@ Elastic
See here for a short description.
@ StringHard
See here for a short description.
bool all_of(Container &&c, UnaryPredicate &&p)
Convenience wrapper for std::all_of that operates on a complete container.
static StringTransitionParameters create_string_transition_parameters(Configuration &config)
constexpr double nucleon_mass
Nucleon mass in GeV.
constexpr double pion_mass
Pion mass in GeV.
T pCM_from_s(const T s, const T mass_a, const T mass_b) noexcept
constexpr double really_small
Numerical error tolerance.
void isoclean(std::string &s)
Remove ⁺, ⁻, ⁰ from string.
static constexpr int LFindScatter
bool is_string_soft_process(ProcessType p)
Check if a given process type is a soft string excitation.
double s_from_plab(double plab, double m_P, double m_T)
Convert p_lab to Mandelstam-s for a fixed-target setup, with a projectile of mass m_P and momentum pl...
constexpr double fm2_mb
mb <-> fm^2 conversion factor.
Helper structure for Experiment.
std::optional< bool > use_monash_tune_default
Bool for the default usage of the monash tune in the collider modus.
const ReactionsBitSet included_2to2
This indicates which two to two reactions are switched off.
Represent a final-state cross section.
FinalStateCrossSection(const std::string &name, double cross_section, double mass)
Construct a final-state cross section.
std::string name_
Name of the final state.
double cross_section_
Corresponding cross section in mb.
double mass_
Total mass of final state particles.
int32_t collisions_per_particle
Collision counter per particle, zero only for initially present particles.
Constants related to transition between low and high collision energies.
Node of a decay tree, representing a possible action (2-to-2 or 1-to-2).
std::vector< Node > children_
Possible actions after this action.
void final_state_cross_sections_helper(uint64_t depth, std::vector< FinalStateCrossSection > &result, const std::string &name, double weight, bool show_intermediate_states=false) const
Internal helper function for final_state_cross_sections, to be called recursively to calculate all fi...
ParticleTypePtrList final_particles_
Final-state particle types in this action.
std::vector< FinalStateCrossSection > final_state_cross_sections() const
Node & add_action(const std::string &name, double weight, ParticleTypePtrList &&initial_particles, ParticleTypePtrList &&final_particles)
Add an action to the children of this node.
ParticleTypePtrList initial_particles_
Initial-state particle types in this action.
void print() const
Print the decay tree starting with this node.
void print_helper(uint64_t depth) const
Internal helper function for print, to be called recursively to print all nodes.
double weight_
Weight (cross section or branching ratio).
Node(const Node &)=delete
Cannot be copied.
Node(const std::string &name, double weight, ParticleTypePtrList &&initial_particles, ParticleTypePtrList &&final_particles, ParticleTypePtrList &&state, std::vector< Node > &&children)
Node(Node &&)=default
Move constructor.
ParticleTypePtrList state_
Particle types corresponding to the global state after this action.
std::string name_
Name for printing.