10 #ifndef SRC_INCLUDE_SMASH_CONFIGURATION_H_
11 #define SRC_INCLUDE_SMASH_CONFIGURATION_H_
26 #include "yaml-cpp/yaml.h"
51 if constexpr (std::is_convertible_v<T, std::string>) {
52 return Node{
static_cast<std::string
>(x)};
54 static_assert(smash::has_to_string_v<T>,
55 "Encoding type T to YAML::Node requires an overload of "
56 "smash::to_string(T) to convert T to an std::string.");
69 static bool decode(
const Node &node, T &x) {
70 if (!node.IsScalar()) {
73 x =
static_cast<T
>(node.Scalar());
301 using std::runtime_error::runtime_error;
308 using std::runtime_error::runtime_error;
315 using std::runtime_error::runtime_error;
322 using std::logic_error::logic_error;
357 const std::filesystem::path &filename);
371 throw std::runtime_error(
372 "Unknown control flag in Configuration constructor"
373 " with a YAML formatted string. Please, use"
374 " Configuration::InitializeFromYAMLString.");
509 template <typename T>
513 return take({key.labels().begin(), key.labels().end()});
517 return take({key.labels().begin(), key.labels().end()});
519 throw std::logic_error(
520 "Key " + std::string{key} +
521 " was taken, but its value is not a map, although there is a "
522 "section in the configuration with its labels.");
530 return key.default_value();
531 }
catch (std::bad_optional_access &) {
532 throw std::invalid_argument(
533 "Key " + std::string{key} +
534 " without default value taken, but missing in configuration.");
552 template <
typename T>
555 throw std::logic_error(
556 "An input Key without dependent default cannot be taken specifying a "
557 "default value! Either define the key as having a dependent default "
558 "or take it without a default value (which is a Key property).");
563 return default_value;
588 template <
typename T>
598 throw std::logic_error(
599 "Key " + std::string{key} +
600 " was read, but its value is not a map, although there is a "
601 "section in the configuration with its labels.");
606 }
catch (std::bad_optional_access &) {
607 throw std::invalid_argument(
608 "Key " + std::string{key} +
609 " without default value read, but missing in configuration.");
627 template <
typename T>
630 throw std::logic_error(
631 "An input Key without dependent default cannot be read specifying a "
632 "default value! Either define the key as having a dependent default "
633 "or read it without a default value (which is a Key property).");
638 return default_value;
663 template <
typename T,
typename U = remove_cvref_t<T>,
664 typename std::enable_if_t<std::is_convertible_v<T, U>,
bool> = true>
668 node = std::forward<T>(value);
733 template <
typename T>
735 const auto found_node =
737 return found_node.has_value() && !(found_node.value().IsMap());
747 template <
typename T>
749 const auto found_node =
751 return found_node.has_value() && !(found_node.value().IsNull()) &&
752 !(found_node.value().IsMap());
762 return found_node.has_value() && found_node.value().IsMap();
801 Is validate(
bool full_validation =
true)
const;
828 if (!(
n.IsScalar() ||
n.IsSequence() ||
n.IsMap())) {
829 std::stringstream err;
830 err <<
"Configuration value for \"" << key
831 <<
"\" is missing or invalid";
832 throw std::runtime_error(err.str());
850 template <
typename T>
853 return node_.as<T>();
854 }
catch (YAML::TypedBadConversion<T> &e) {
856 "The value for key \"" + std::string(
key_) +
857 "\" cannot be converted to the requested type.");
866 template <
typename T>
867 operator std::vector<T>()
const {
869 return node_.as<std::vector<T>>();
870 }
catch (YAML::TypedBadConversion<T> &e) {
872 "One of the values in the sequence for key \"" + std::string(
key_) +
873 "\" failed to convert to the requested type. E.g. [1 2] is a "
874 "sequence of one string \"1 2\" and [1, 2] is a sequence of two "
875 "integers. Often there is just a comma missing in the config "
877 }
catch (YAML::TypedBadConversion<std::vector<T>> &e) {
879 "The value for key \"" + std::string(
key_) +
880 "\" cannot be converted to the requested type. A sequence was "
881 "expected but apparently not found.");
892 template <
typename T,
size_t N>
893 operator std::array<T, N>()
const {
894 const std::vector<T> vec =
operator std::vector<T>();
895 const size_t n_read = vec.size();
899 std::string(
key_) +
"\". Expected " +
905 std::array<T, N> arr;
906 std::copy_n(vec.begin(), N, arr.begin());
918 const std::vector<std::string> v =
operator std::vector<std::string>();
920 for (
const auto &x : v) {
924 }
else if (x ==
"Elastic") {
926 }
else if (x ==
"NN_to_NR") {
928 }
else if (x ==
"NN_to_DR") {
930 }
else if (x ==
"KN_to_KN") {
932 }
else if (x ==
"KN_to_KDelta") {
934 }
else if (x ==
"Strangeness_exchange") {
936 }
else if (x ==
"NNbar") {
938 }
else if (x ==
"PiDeuteron_to_NN") {
940 }
else if (x ==
"PiDeuteron_to_pidprime") {
942 }
else if (x ==
"NDeuteron_to_Ndprime") {
946 "The value for key \"" + std::string(
key_) +
947 "\" should be \"All\", \"Elastic\", \"NN_to_NR\", \"NN_to_DR\","
948 "\"KN_to_KN\", \"KN_to_KDelta\", \"PiDeuteron_to_NN\", "
949 "\"PiDeuteron_to_pidprime\", \"NDeuteron_to_Ndprime\", "
950 "\"Strangeness_exchange\" or "
951 "\"NNbar\", or any combination of these.");
965 const std::vector<std::string> v =
operator std::vector<std::string>();
967 for (
const auto &x : v) {
971 }
else if (x ==
"Meson_3to1") {
973 }
else if (x ==
"Deuteron_3to2") {
975 }
else if (x ==
"NNbar_5to2") {
977 }
else if (x ==
"A3_Nuclei_4to2") {
981 "The value for key \"" + std::string(
key_) +
982 "\" should be \"All\", \"Meson_3to1\", "
983 "\"Deuteron_3to2\" or \"NNbar_5to2\", "
984 "\"A3_Nuclei_4to2\", or any combination of "
998 operator std::set<ThermodynamicQuantity>()
const {
999 const std::vector<std::string> v =
operator std::vector<std::string>();
1000 std::set<ThermodynamicQuantity> s;
1001 for (
const auto &x : v) {
1002 if (x ==
"rho_eckart") {
1004 }
else if (x ==
"tmn") {
1006 }
else if (x ==
"tmn_landau") {
1008 }
else if (x ==
"landau_velocity") {
1010 }
else if (x ==
"j_QBS") {
1014 "The value for key \"" + std::string(
key_) +
1015 "\" should be \"rho_eckart\", \"tmn\""
1016 ", \"tmn_landau\", \"landau_velocity\" or \"j_QBS\".");
1030 const std::string s =
operator std::string();
1031 if (s ==
"center of velocity") {
1034 if (s ==
"center of mass") {
1037 if (s ==
"fixed target") {
1041 "The value for key \"" + std::string(
key_) +
1042 "\" should be \"center of velocity\" or \"center of mass\" "
1043 "or \"fixed target\".");
1054 const std::string s =
operator std::string();
1061 if (s ==
"frozen") {
1065 "The value for key \"" + std::string(
key_) +
1066 "\" should be \"off\" or \"on\" or \"frozen\".");
1077 const std::string s =
operator std::string();
1078 if (s ==
"hadron") {
1081 if (s ==
"baryon") {
1084 if (s ==
"baryonic isospin") {
1090 if (s ==
"total isospin") {
1098 "\" should be \"hadron\" or \"baryon\" "
1099 "or \"baryonic isospin\" or \"pion\" "
1111 const std::string s =
operator std::string();
1112 if (s ==
"NoExpansion") {
1115 if (s ==
"MasslessFRW") {
1118 if (s ==
"MassiveFRW") {
1121 if (s ==
"Exponential") {
1125 "The value for key \"" + std::string(
key_) +
1126 "\" should be \"NoExpansion\", \"MasslessFRW\"," +
1127 "\"MassiveFRW\" or \"Exponential\".");
1134 const std::string s =
operator std::string();
1135 if (s ==
"Covariant Gaussian") {
1138 if (s ==
"Finite difference") {
1145 "The value for key \"" + std::string(
key_) +
1146 "\" should be \"Covariant Gaussian\", \"Finite difference\"," +
1154 const std::string s =
operator std::string();
1155 if (s ==
"Chain Rule") {
1158 if (s ==
"Direct") {
1162 "The value for key \"" + std::string(
key_) +
1163 "\" should be \"Chain Rule\" or \"Direct\".");
1170 const std::string s =
operator std::string();
1171 if (s ==
"Covariant Gaussian") {
1174 if (s ==
"Discrete") {
1177 if (s ==
"Triangular") {
1181 "The value for key \"" + std::string(
key_) +
1182 "\" should be \"Covariant Gaussian\", \"Discrete\"," +
1183 " or \"Triangular\".");
1194 const std::string s =
operator std::string();
1203 "\" should be \"None\" or \"Fixed\".");
1214 const std::string s =
operator std::string();
1215 if (s ==
"thermal momenta") {
1218 if (s ==
"thermal momenta quantum") {
1221 if (s ==
"peaked momenta") {
1225 "The value for key \"" + std::string(
key_) +
1226 "\" should be \"thermal momenta\", \"thermal momenta quantum\", " +
1227 "or \"peaked momenta\".");
1238 const std::string s =
operator std::string();
1239 if (s ==
"thermal momenta") {
1242 if (s ==
"thermal momenta quantum") {
1254 if (s ==
"IC_Massive") {
1258 "The value for key \"" + std::string(
key_) +
1259 "\" should be \"thermal momenta\", \"thermal momenta quantum\", " +
1260 "\"IC_ES\", \"IC_1M\", \"IC_2M\" or" +
"\"IC_Massive\".");
1271 const std::string s =
operator std::string();
1272 if (s ==
"no annihilation") {
1275 if (s ==
"resonances") {
1278 if (s ==
"two to five") {
1281 if (s ==
"strings") {
1285 "The value for key \"" + std::string(
key_) +
"\" should be " +
1286 "\"no annihilation\", \"resonances\", \"two to five\" or " +
1298 const std::string s =
operator std::string();
1299 if (s ==
"quadratic") {
1302 if (s ==
"custom") {
1305 if (s ==
"uniform") {
1309 "The value for key \"" + std::string(
key_) +
1310 "\" should be \"quadratic\", \"uniform\" or \"custom\".");
1321 const std::string s =
operator std::string();
1322 if (s ==
"mode sampling") {
1325 if (s ==
"biased BF") {
1328 if (s ==
"unbiased BF") {
1332 "The value for key \"" + std::string(
key_) +
1333 "\" should be \"mode sampling\", \"biased BF\" or \"unbiased BF\".");
1344 const std::string s =
operator std::string();
1345 if (s ==
"Geometric") {
1348 if (s ==
"Stochastic") {
1351 if (s ==
"Covariant") {
1355 "The value for key \"" + std::string(
key_) +
"\" should be " +
1356 "\"Geometric\", \"Stochastic\" " +
"or \"Covariant\".");
1367 const std::string s =
operator std::string();
1368 if (s ==
"BottomUp") {
1371 if (s ==
"TopDown") {
1374 if (s ==
"TopDownMeasured") {
1378 "The value for key \"" + std::string(
key_) +
"\" should be " +
1379 "\"BottomUp\", \"TopDown\" " +
"or \"TopDownMeasured\".");
1390 const std::string s =
operator std::string();
1394 if (s ==
"Largest") {
1397 if (s ==
"Closest") {
1400 if (s ==
"LargestFromUnstable") {
1403 if (s ==
"ClosestFromUnstable") {
1407 "The value for key \"" + std::string(
key_) +
"\" should be " +
1408 "\"None\", \"Largest\", \"Closest\", \"LargestFromUnstable\", or "
1409 "\"ClosestFromUnstable\".");
1421 const std::string s =
operator std::string();
1422 if (s ==
"Constant_Tau") {
1424 }
else if (s ==
"Dynamic") {
1428 std::string(
key_) +
"\" should be " +
1429 "\"Constant_Tau\" or \"Dynamic\".");
1440 const std::string s =
operator std::string();
1447 if (s ==
"IfNotEmpty") {
1451 std::string(
key_) +
"\" should be " +
1452 "\"Yes\", \"No\" or \"IfNotEmpty\".");
1463 const std::vector<std::string> v =
operator std::vector<std::string>();
1465 for (
const auto &x : v) {
1469 }
else if (x ==
"Elastic") {
1471 }
else if (x ==
"Decay") {
1473 }
else if (x ==
"Inelastic") {
1475 }
else if (x ==
"SoftString") {
1477 }
else if (x ==
"HardString") {
1481 "The value for key \"" + std::string(
key_) +
1482 "\" should be \"All\", \"Elastic\", \"Decay\", "
1483 "\"Inelastic\", \"SoftString\", \"HardString\", "
1484 "or any combination of these.");
1513 std::vector<std::string_view> keys)
const;
1538 std::vector<std::string_view> keys)
const;
1548 template <
class Key,
class Value>
1549 struct isMap<std::map<Key, Value>> : std::true_type {};
1562 Value take(std::vector<std::string_view> labels);
1575 Value read(std::vector<std::string_view> labels)
const;
Proxy object to be used when taking or reading keys in the configuration.
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.
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...
T take(const Key< T > &key, T default_value)
Alternative method to take a key value, specifying the default value.
void set_value(Key< U > key, T &&value)
Overwrite the value of the YAML node corresponding to the specified key.
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.
Configuration extract_sub_configuration(KeyLabels section, Configuration::GetEmpty empty_if_not_existing=Configuration::GetEmpty::No)
Create a new configuration from a then-removed section of the present object.
T read(const Key< T > &key) const
Additional interface for SMASH to read configuration values without removing them.
Configuration(const std::filesystem::path &path)
Read config.yaml from the specified path.
void enclose_into_section(KeyLabels section)
Enclose the configuration into the given section.
YAML::Node root_node_
The general_config.yaml contents - fully parsed.
YAML::Node find_node_creating_it_if_not_existing(std::vector< std::string_view > keys) const
Descend in and if needed modify the YAML tree from the given node using the provided keys.
Configuration(const YAML::Node &node)
Create a sub-object that has its root node at the given node.
int uncaught_exceptions_
Counter to be able to optionally throw in destructor.
bool did_key_exist_and_was_it_already_taken(const KeyLabels &labels) const
Find out whether a key has been already taken.
Configuration(const char *yaml)
bool has_value(const Key< T > &key) const
Return whether there is a non-empty value behind the requested key (which is supposed not to refer to...
void clear()
Erase the Configuration content.
Configuration(const char *yaml, const char sflag)
Initialize configuration with a YAML formatted string.
T read(const Key< T > &key, T default_value)
Alternative method to read a key value, specifying the default value.
bool has_key(const Key< T > &key) const
Return whether the configuration has a (possibly empty) non-map key.
bool has_section(const KeyLabels &labels) const
Return whether there is a (possibly empty) section with the given labels.
Is validate(bool full_validation=true) const
Validate content of configuration in terms of YAML keys.
std::optional< YAML::Node > find_existing_node(std::vector< std::string_view > keys) const
Descend in the YAML tree from the given node using the provided 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.
static const char InitializeFromYAMLString
Flag to mark initialization with a YAML formatted string.
Configuration extract_complete_sub_configuration(KeyLabels section, Configuration::GetEmpty empty_if_not_existing=Configuration::GetEmpty::No)
Alternative method to extract a sub-configuration, which retains the labels from the top-level in the...
T take(const Key< T > &key)
The default interface for SMASH to read configuration values.
void remove_all_entries_in_section_but_one(const std::string &key, KeyLabels section={})
Remove all entries in the given section except for key.
std::vector< std::string > list_upmost_nodes()
Lists all YAML::Nodes from the configuration setup.
std::vector< KeyLabels > existing_keys_already_taken_
List of taken keys to throw on taking same key twice.
Configuration & operator=(const Configuration &)=delete
Prevent Configuration objects from being copy-assigned.
Object to store a YAML input file key together with metadata associated to it.
bool has_dependent_default() const noexcept
Ask whether the default value depends on other other keys.
default_type default_value() const
Get the default value of the key.
const KeyLabels & labels() const
Method to access the Key labels.
default_type type
Let the clients of this class have access to the key type.
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.
FluidizationType
Possible methods to convert SMASH particle into fluid cells.
@ ConstantTau
Hypersurface crossed at a fixed proper time.
@ Dynamic
Dynamic fluidization based on local densities.
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.
std::bitset< 5 > FluidizableProcessesBitSet
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.
DensityType
Allows to choose which kind of density to calculate.
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.
std::vector< std::string > KeyLabels
Descriptive alias for storing key labels, i.e.
std::string to_string(ThermodynamicQuantity quantity)
Convert a ThermodynamicQuantity enum value to its corresponding string.
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.
Thrown if a Key is taken twice.
Utility type trait (general case) for the take and read public methods.