10 #ifndef SRC_INCLUDE_SMASH_CONFIGURATION_H_
11 #define SRC_INCLUDE_SMASH_CONFIGURATION_H_
23 #include "yaml-cpp/yaml.h"
45 static Node
encode(
const T &x) {
return Node{
static_cast<std::string
>(x)}; }
55 static bool decode(
const Node &node, T &x) {
56 if (!node.IsScalar()) {
59 x =
static_cast<T
>(node.Scalar());
283 using std::runtime_error::runtime_error;
290 using std::runtime_error::runtime_error;
298 using std::runtime_error::runtime_error;
323 if (!(
n.IsScalar() ||
n.IsSequence() ||
n.IsMap())) {
324 std::stringstream err;
325 err <<
"Configuration value for \"" << key
326 <<
"\" is missing or invalid";
327 throw std::runtime_error(err.str());
363 template <
typename T>
376 template <
typename T>
379 return node_.as<T>();
380 }
catch (YAML::TypedBadConversion<T> &e) {
382 "The value for key \"" + std::string(
key_) +
383 "\" cannot be converted to the requested type.");
392 template <
typename T>
393 operator std::vector<T>()
const {
395 return node_.as<std::vector<T>>();
396 }
catch (YAML::TypedBadConversion<T> &e) {
398 "One of the values in the sequence for key \"" + std::string(
key_) +
399 "\" failed to convert to the requested type. E.g. [1 2] is a "
400 "sequence of one string \"1 2\" and [1, 2] is a sequence of two "
401 "integers. Often there is just a comma missing in the config "
403 }
catch (YAML::TypedBadConversion<std::vector<T>> &e) {
405 "The value for key \"" + std::string(
key_) +
406 "\" cannot be converted to the requested type. A sequence was "
407 "expected but apparently not found.");
418 template <
typename T,
size_t N>
419 operator std::array<T, N>()
const {
420 const std::vector<T> vec =
operator std::vector<T>();
421 const size_t n_read = vec.size();
425 std::string(
key_) +
"\". Expected " +
429 std::to_string(n_read) +
".");
431 std::array<T, N> arr;
432 std::copy_n(vec.begin(), N, arr.begin());
444 const std::vector<std::string> v =
operator std::vector<std::string>();
446 for (
const auto &x : v) {
450 }
else if (x ==
"Elastic") {
452 }
else if (x ==
"NN_to_NR") {
454 }
else if (x ==
"NN_to_DR") {
456 }
else if (x ==
"KN_to_KN") {
458 }
else if (x ==
"KN_to_KDelta") {
460 }
else if (x ==
"Strangeness_exchange") {
462 }
else if (x ==
"NNbar") {
464 }
else if (x ==
"PiDeuteron_to_NN") {
466 }
else if (x ==
"PiDeuteron_to_pidprime") {
468 }
else if (x ==
"NDeuteron_to_Ndprime") {
472 "The value for key \"" + std::string(
key_) +
473 "\" should be \"All\", \"Elastic\", \"NN_to_NR\", \"NN_to_DR\","
474 "\"KN_to_KN\", \"KN_to_KDelta\", \"PiDeuteron_to_NN\", "
475 "\"PiDeuteron_to_pidprime\", \"NDeuteron_to_Ndprime\", "
476 "\"Strangeness_exchange\" or "
477 "\"NNbar\", or any combination of these.");
491 const std::vector<std::string> v =
operator std::vector<std::string>();
493 for (
const auto &x : v) {
497 }
else if (x ==
"Meson_3to1") {
499 }
else if (x ==
"Deuteron_3to2") {
501 }
else if (x ==
"NNbar_5to2") {
503 }
else if (x ==
"A3_Nuclei_4to2") {
507 "The value for key \"" + std::string(
key_) +
508 "\" should be \"All\", \"Meson_3to1\", "
509 "\"Deuteron_3to2\" or \"NNbar_5to2\", "
510 "\"A3_Nuclei_4to2\", or any combination of "
524 operator std::set<ThermodynamicQuantity>()
const {
525 const std::vector<std::string> v =
operator std::vector<std::string>();
526 std::set<ThermodynamicQuantity> s;
527 for (
const auto &x : v) {
528 if (x ==
"rho_eckart") {
530 }
else if (x ==
"tmn") {
532 }
else if (x ==
"tmn_landau") {
534 }
else if (x ==
"landau_velocity") {
536 }
else if (x ==
"j_QBS") {
540 "The value for key \"" + std::string(
key_) +
541 "\" should be \"rho_eckart\", \"tmn\""
542 ", \"tmn_landau\", \"landau_velocity\" or \"j_QBS\".");
556 const std::string s =
operator std::string();
557 if (s ==
"center of velocity") {
560 if (s ==
"center of mass") {
563 if (s ==
"fixed target") {
567 "The value for key \"" + std::string(
key_) +
568 "\" should be \"center of velocity\" or \"center of mass\" "
569 "or \"fixed target\".");
580 const std::string s =
operator std::string();
591 "The value for key \"" + std::string(
key_) +
592 "\" should be \"off\" or \"on\" or \"frozen\".");
603 const std::string s =
operator std::string();
610 if (s ==
"baryonic isospin") {
616 if (s ==
"total isospin") {
624 "\" should be \"hadron\" or \"baryon\" "
625 "or \"baryonic isospin\" or \"pion\" "
637 const std::string s =
operator std::string();
638 if (s ==
"NoExpansion") {
641 if (s ==
"MasslessFRW") {
644 if (s ==
"MassiveFRW") {
647 if (s ==
"Exponential") {
651 "The value for key \"" + std::string(
key_) +
652 "\" should be \"NoExpansion\", \"MasslessFRW\"," +
653 "\"MassiveFRW\" or \"Exponential\".");
660 const std::string s =
operator std::string();
661 if (s ==
"Covariant Gaussian") {
664 if (s ==
"Finite difference") {
671 "The value for key \"" + std::string(
key_) +
672 "\" should be \"Covariant Gaussian\", \"Finite difference\"," +
680 const std::string s =
operator std::string();
681 if (s ==
"Chain Rule") {
688 "The value for key \"" + std::string(
key_) +
689 "\" should be \"Chain Rule\" or \"Direct\".");
696 const std::string s =
operator std::string();
697 if (s ==
"Covariant Gaussian") {
700 if (s ==
"Discrete") {
703 if (s ==
"Triangular") {
707 "The value for key \"" + std::string(
key_) +
708 "\" should be \"Covariant Gaussian\", \"Discrete\"," +
709 " or \"Triangular\".");
720 const std::string s =
operator std::string();
729 "\" should be \"None\" or \"Fixed\".");
740 const std::string s =
operator std::string();
741 if (s ==
"thermal momenta") {
744 if (s ==
"thermal momenta quantum") {
747 if (s ==
"peaked momenta") {
751 "The value for key \"" + std::string(
key_) +
752 "\" should be \"thermal momenta\", \"thermal momenta quantum\", " +
753 "or \"peaked momenta\".");
764 const std::string s =
operator std::string();
765 if (s ==
"thermal momenta") {
768 if (s ==
"thermal momenta quantum") {
780 if (s ==
"IC_Massive") {
784 "The value for key \"" + std::string(
key_) +
785 "\" should be \"thermal momenta\", \"thermal momenta quantum\", " +
786 "\"IC_ES\", \"IC_1M\", \"IC_2M\" or" +
"\"IC_Massive\".");
797 const std::string s =
operator std::string();
798 if (s ==
"no annihilation") {
801 if (s ==
"resonances") {
804 if (s ==
"two to five") {
807 if (s ==
"strings") {
811 "The value for key \"" + std::string(
key_) +
"\" should be " +
812 "\"no annihilation\", \"resonances\", \"two to five\" or " +
824 const std::string s =
operator std::string();
825 if (s ==
"quadratic") {
831 if (s ==
"uniform") {
835 "The value for key \"" + std::string(
key_) +
836 "\" should be \"quadratic\", \"uniform\" or \"custom\".");
847 const std::string s =
operator std::string();
848 if (s ==
"mode sampling") {
851 if (s ==
"biased BF") {
854 if (s ==
"unbiased BF") {
858 "The value for key \"" + std::string(
key_) +
859 "\" should be \"mode sampling\", \"biased BF\" or \"unbiased BF\".");
870 const std::string s =
operator std::string();
871 if (s ==
"Geometric") {
874 if (s ==
"Stochastic") {
877 if (s ==
"Covariant") {
881 "The value for key \"" + std::string(
key_) +
"\" should be " +
882 "\"Geometric\", \"Stochastic\" " +
"or \"Covariant\".");
893 const std::string s =
operator std::string();
894 if (s ==
"BottomUp") {
897 if (s ==
"TopDown") {
900 if (s ==
"TopDownMeasured") {
904 "The value for key \"" + std::string(
key_) +
"\" should be " +
905 "\"BottomUp\", \"TopDown\" " +
"or \"TopDownMeasured\".");
916 const std::string s =
operator std::string();
920 if (s ==
"Largest") {
923 if (s ==
"Closest") {
926 if (s ==
"LargestFromUnstable") {
929 if (s ==
"ClosestFromUnstable") {
933 "The value for key \"" + std::string(
key_) +
"\" should be " +
934 "\"None\", \"Largest\", \"Closest\", \"LargestFromUnstable\", or "
935 "\"ClosestFromUnstable\".");
946 const std::string s =
operator std::string();
953 if (s ==
"IfNotEmpty") {
957 std::string(
key_) +
"\" should be " +
958 "\"Yes\", \"No\" or \"IfNotEmpty\".");
994 const std::filesystem::path &filename);
1008 throw std::runtime_error(
1009 "Unknown control flag in Configuration constructor"
1010 " with a YAML formatted string. Please, use"
1011 " Configuration::InitializeFromYAMLString.");
1026 root_node_ = YAML::Node{YAML::NodeType::Map};
1125 Value take(std::initializer_list<const
char *> keys);
1128 template <typename T>
1129 T
take(std::initializer_list<const
char *> keys, T default_value) {
1133 return default_value;
1150 Value
read(std::initializer_list<const char *> keys)
const;
1153 template <
typename T>
1154 T
read(std::initializer_list<const char *> keys, T default_value) {
1158 return default_value;
1170 template <
typename T>
1171 void set_value(std::initializer_list<const char *> keys, T &&value) {
1173 node = std::forward<T>(value);
1188 const std::string &key, std::initializer_list<const char *> section = {});
1210 std::initializer_list<const char *> keys,
1219 std::initializer_list<const char *> keys)
const;
1224 bool has_value(std::initializer_list<const char *> keys)
const;
1262 Is validate(
bool full_validation =
true)
const;
1287 std::vector<const char *> keys)
const;
1312 std::vector<const char *> keys)
const;
Return type of Configuration::take that automatically determines the target type.
Value(const YAML::Node &n, const char *key)
Construct the Value wrapper from a YAML::Node.
Value(const Value &)=delete
If you want to copy this you're doing it wrong.
T convert_for(const T &) const
Convert the value to the type of the supplied argument.
const char *const key_
The key to be interpreted.
const YAML::Node node_
a YAML leaf node
Value & operator=(const Value &)=delete
If you want to copy this you're doing it wrong.
Interface to the SMASH configuration files.
Is
Return type of Configuration::validate which conveys more information that simply a two-state boolean...
bool has_value(std::initializer_list< const char * > keys) const
Return whether there is a non-empty value behind the requested keys.
Configuration(const Configuration &)=delete
Prevent Configuration objects from being copied.
void merge_yaml(const std::string &yaml)
Merge the configuration in yaml into the existing tree.
std::string to_string() const
Return a string of the current YAML tree.
bool has_value_including_empty(std::initializer_list< const char * > keys) const
Return whether there is a (maybe empty) value behind the requested keys.
Configuration(const std::filesystem::path &path)
Read config.yaml from the specified path.
void remove_all_entries_in_section_but_one(const std::string &key, std::initializer_list< const char * > section={})
Remove all entries in the given section except for key.
YAML::Node find_node_creating_it_if_not_existing(std::vector< const char * > keys) const
Descend in and if needed modify the YAML tree from the given node using the provided keys.
YAML::Node root_node_
The general_config.yaml contents - fully parsed.
void set_value(std::initializer_list< const char * > keys, T &&value)
Overwrite the value of the specified YAML node.
Configuration extract_sub_configuration(std::initializer_list< const char * > keys, Configuration::GetEmpty empty_if_not_existing=Configuration::GetEmpty::No)
Create a new configuration from a then-removed section of the present object.
Configuration(const YAML::Node &node)
Create a subobject that has its root node at the given node.
int uncaught_exceptions_
Counter to be able to optionally throw in destructor.
Configuration(const char *yaml)
void clear()
Erase the Configuration content.
Value take(std::initializer_list< const char * > keys)
The default interface for SMASH to read configuration values.
Configuration(const char *yaml, const char sflag)
Initialize configuration with a YAML formatted string.
Value read(std::initializer_list< const char * > keys) const
Additional interface for SMASH to read configuration values without removing them.
Is validate(bool full_validation=true) const
Validate content of configuration in terms of YAML keys.
~Configuration() noexcept(false)
Destroy the object, optionally throwing if not all keys were taken.
GetEmpty
Flag to tune method(s) behavior such that it is descriptive from the caller side.
std::optional< YAML::Node > find_existing_node(std::vector< const char * > keys) const
Descend in the YAML tree from the given node using the provided keys.
static const char InitializeFromYAMLString
Flag to mark initialization with a YAML formatted string.
T read(std::initializer_list< const char * > keys, T default_value)
std::vector< std::string > list_upmost_nodes()
Lists all YAML::Nodes from the configuration setup.
Configuration & operator=(const Configuration &)=delete
Prevent Configuration objects from being copy-assigned.
SmearingMode
Modes of smearing.
FermiMotion
Option to use Fermi Motion.
@ On
Use fermi motion in combination with potentials.
@ Frozen
Use fermi motion without potentials.
@ Off
Don't use fermi motion.
std::bitset< 10 > ReactionsBitSet
Container for the 2 to 2 reactions in the code.
ThermalizationAlgorithm
Defines the algorithm used for the forced thermalization.
NNbarTreatment
Treatment of N Nbar Annihilation.
@ NoAnnihilation
No Annihilation.
@ TwoToFive
Directly create 5 pions, use with multi-particle reactions.
@ Resonances
Use intermediate Resonances.
@ Strings
Use string fragmentation.
TimeStepMode
The time step mode.
@ Fixed
Use fixed time step.
@ None
Don't use time steps; propagate from action to action.
@ EckartDensity
Density in the Eckart frame.
@ Tmn
Energy-momentum tensor in lab frame.
@ LandauVelocity
Velocity of the Landau rest frame.
@ j_QBS
Electric (Q), baryonic (B) and strange (S) currents.
@ TmnLandau
Energy-momentum tensor in Landau rest frame.
TotalCrossSectionStrategy
Determine how total cross sections for collision finding should be computed.
@ 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.
Sampling
Possible methods of impact parameter sampling.
@ Quadratic
Sample from areal / quadratic distribution.
@ Custom
Sample from custom, user-defined distribution.
@ Uniform
Sample from uniform distribution.
std::bitset< 4 > MultiParticleReactionsBitSet
Container for the n to m reactions in the code.
CalculationFrame
The calculation frame.
DerivativesMode
Modes of calculating the gradients.
CollisionCriterion
Criteria used to check collisions.
@ Stochastic
Stochastic Criteiron.
@ Geometric
Geometric criterion.
@ Covariant
Covariant Criterion.
FieldDerivativesMode
Modes of calculating the field gradients: chain rule or direct.
SphereInitialCondition
Initial condition for a particle in a sphere.
@ ThermalMomentaBoltzmann
A thermalized ensemble is generated, with momenta sampled from a Maxwell-Boltzmann distribution.
@ IC_ES
Off-equilibrium distribution used in massless comparisons of SMASH to the extended universe metric.
@ ThermalMomentaQuantum
A thermalized ensemble is generated, with momenta of baryons(mesons) sampled from a Fermi(Bose) distr...
@ IC_Massive
A generalization of IC_ES for the non-zero mass case; note that there is currently no analytical comp...
@ IC_2M
Off-equilibrium distribution used in massless comparisons of SMASH to the extended universe metric.
@ IC_1M
Off-equilibrium distribution used in massless comparisons of SMASH to the extended universe metric.
PseudoResonance
Which pseudo-resonance fills the inelastic gap in the transition to string region of cross sections.
@ Closest
Resonance with the pole mass closest from the invariant mass of incoming particles for all processes.
@ ClosestFromUnstable
Closest resonance for a given mass from processes with at least one resonance in the incoming particl...
@ None
No pseudo-resonance is created.
@ LargestFromUnstable
Heaviest possible resonance from processes with at least one resonance in the incoming particles.
@ Largest
Resonance of largest mass for all processes.
OutputOnlyFinal
Whether and when only final state particles should be printed.
@ IfNotEmpty
Print only final-state particles, and those only if the event is not empty.
@ Yes
Print only final-state particles.
@ No
Print initial, intermediate and final-state particles.
BoxInitialCondition
Initial condition for a particle in a box.
@ ThermalMomentaBoltzmann
A thermalized ensemble is generated, with momenta sampled from a Maxwell-Boltzmann distribution.
@ ThermalMomentaQuantum
A thermalized ensemble is generated, with momenta of baryons(mesons) sampled from a Fermi(Bose) distr...
@ PeakedMomenta
All particles have the same momentum with T being the temperature.
ExpansionMode
Defines properties of expansion for the metric (e.g.
DensityType
Allows to choose which kind of density to calculate.
Convert from YAML::Node to SMASH-readable (C++) format and vice versa.
static bool decode(const Node &node, T &x)
Deserialization: Converts a YAML::Node to any SMASH-readable data type and returns whether or not thi...
static Node encode(const T &x)
Serialization: Converts x (of any type) to a YAML::Node.
Thrown if the file does not exist.
Thrown when the types in the config file and C++ don't match.
Thrown for YAML parse errors.