Version: SMASH-3.2.2
configuration.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2014-2025
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
10 #ifndef SRC_INCLUDE_SMASH_CONFIGURATION_H_
11 #define SRC_INCLUDE_SMASH_CONFIGURATION_H_
12 
13 #include <algorithm>
14 #include <array>
15 #include <exception>
16 #include <filesystem>
17 #include <iostream>
18 #include <map>
19 #include <optional>
20 #include <set>
21 #include <stdexcept>
22 #include <string>
23 #include <utility>
24 #include <vector>
25 
26 #include "yaml-cpp/yaml.h"
27 
28 #include "cxx17compat.h"
29 #include "forwarddeclarations.h"
30 #include "key.h"
31 #include "stringify.h"
32 
33 namespace YAML {
34 
41 template <typename T>
42 struct convert {
50  static Node encode(const T &x) {
51  if constexpr (std::is_convertible_v<T, std::string>) {
52  return Node{static_cast<std::string>(x)};
53  } else {
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.");
57  return Node{smash::to_string(x)};
58  }
59  }
60 
69  static bool decode(const Node &node, T &x) {
70  if (!node.IsScalar()) {
71  return false;
72  } else {
73  x = static_cast<T>(node.Scalar());
74  return true;
75  }
76  }
77 };
78 } // namespace YAML
79 
80 namespace smash {
81 
295  public:
300  struct IncorrectTypeInAssignment : public std::runtime_error {
301  using std::runtime_error::runtime_error;
302  };
307  struct ParseError : public std::runtime_error {
308  using std::runtime_error::runtime_error;
309  };
314  struct FileDoesNotExist : public std::runtime_error {
315  using std::runtime_error::runtime_error;
316  };
321  struct TakeSameKeyTwice : public std::logic_error {
322  using std::logic_error::logic_error;
323  };
324 
328  static const char InitializeFromYAMLString = 'S';
329 
334  enum class GetEmpty { Yes, No };
335 
340  enum class Is { Invalid, Deprecated, Valid };
341 
347  explicit Configuration(const std::filesystem::path &path);
348 
356  explicit Configuration(const std::filesystem::path &path,
357  const std::filesystem::path &filename);
358 
367  explicit Configuration(const char *yaml, const char sflag) {
368  if (sflag == InitializeFromYAMLString) {
369  merge_yaml(yaml);
370  } else {
371  throw std::runtime_error(
372  "Unknown control flag in Configuration constructor"
373  " with a YAML formatted string. Please, use"
374  " Configuration::InitializeFromYAMLString.");
375  }
376  }
377 
378 #ifdef BUILD_TESTS
387  explicit Configuration(const char *yaml) : root_node_(YAML::Load(yaml)) {
388  if (root_node_.IsNull())
389  root_node_ = YAML::Node{YAML::NodeType::Map};
390  }
391 #endif
392 
401  Configuration(const Configuration &) = delete;
409 
424 
431 
441  ~Configuration() noexcept(false);
442 
453  void merge_yaml(const std::string &yaml);
454 
456  std::vector<std::string> list_upmost_nodes();
457 
509  template <typename T>
510  T take(const Key<T> &key) {
511  if (has_value(key)) {
512  // The following return statement converts a Value into T
513  return take({key.labels().begin(), key.labels().end()});
514  } else if (has_section(key.labels())) {
515  // In this case, if the Key type is a map, we take it, otherwise fails
516  if constexpr (isMap<typename Key<T>::type>::value) {
517  return take({key.labels().begin(), key.labels().end()});
518  } else {
519  throw std::logic_error(
520  "Key " + std::string{key} + // NOLINT(whitespace/braces)
521  " was taken, but its value is not a map, although there is a "
522  "section in the configuration with its labels.");
523  }
524  } else if (did_key_exist_and_was_it_already_taken(key.labels())) {
525  throw TakeSameKeyTwice("Attempt to take key " +
526  std::string{key} + // NOLINT(whitespace/braces)
527  " twice.");
528  } else {
529  try {
530  return key.default_value();
531  } catch (std::bad_optional_access &) {
532  throw std::invalid_argument(
533  "Key " + std::string{key} + // NOLINT(whitespace/braces)
534  " without default value taken, but missing in configuration.");
535  }
536  }
537  }
538 
552  template <typename T>
553  T take(const Key<T> &key, T default_value) {
554  if (!key.has_dependent_default()) {
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).");
559  }
560  if (has_value(key)) {
561  return take(key);
562  }
563  return default_value;
564  }
565 
588  template <typename T>
589  T read(const Key<T> &key) const {
590  if (has_value(key)) {
591  // The following return statement converts a Value into T
592  return read({key.labels().begin(), key.labels().end()});
593  } else if (has_section(key.labels())) {
594  // In this case, if the Key type is a map, we take it, otherwise fails
595  if constexpr (isMap<typename Key<T>::type>::value) {
596  return read({key.labels().begin(), key.labels().end()});
597  } else {
598  throw std::logic_error(
599  "Key " + std::string{key} + // NOLINT(whitespace/braces)
600  " was read, but its value is not a map, although there is a "
601  "section in the configuration with its labels.");
602  }
603  } else {
604  try {
605  return key.default_value();
606  } catch (std::bad_optional_access &) {
607  throw std::invalid_argument(
608  "Key " + std::string{key} + // NOLINT(whitespace/braces)
609  " without default value read, but missing in configuration.");
610  }
611  }
612  }
613 
627  template <typename T>
628  T read(const Key<T> &key, T default_value) {
629  if (!key.has_dependent_default()) {
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).");
634  }
635  if (has_value(key)) {
636  return read(key);
637  }
638  return default_value;
639  }
640 
663  template <typename T, typename U = remove_cvref_t<T>,
664  typename std::enable_if_t<std::is_convertible_v<T, U>, bool> = true>
665  void set_value(Key<U> key, T &&value) {
667  {key.labels().begin(), key.labels().end()});
668  node = std::forward<T>(value);
669  }
670 
682  void remove_all_entries_in_section_but_one(const std::string &key,
683  KeyLabels section = {});
684 
705  KeyLabels section, Configuration::GetEmpty empty_if_not_existing =
707 
715  KeyLabels section, Configuration::GetEmpty empty_if_not_existing =
717 
723  void enclose_into_section(KeyLabels section);
724 
733  template <typename T>
734  bool has_key(const Key<T> &key) const {
735  const auto found_node =
736  find_existing_node({key.labels().begin(), key.labels().end()});
737  return found_node.has_value() && !(found_node.value().IsMap());
738  }
739 
747  template <typename T>
748  bool has_value(const Key<T> &key) const {
749  const auto found_node =
750  find_existing_node({key.labels().begin(), key.labels().end()});
751  return found_node.has_value() && !(found_node.value().IsNull()) &&
752  !(found_node.value().IsMap());
753  }
754 
760  bool has_section(const KeyLabels &labels) const {
761  const auto found_node = find_existing_node({labels.begin(), labels.end()});
762  return found_node.has_value() && found_node.value().IsMap();
763  }
764 
769  bool is_empty() const { return root_node_.size() == 0; }
770 
774  std::string to_string() const;
775 
782  void clear() { root_node_.reset(); }
783 
801  Is validate(bool full_validation = true) const;
802 
803  private:
813  class Value {
814  friend class Configuration;
815 
817  const YAML::Node node_;
819  const char *const key_;
820 
827  Value(const YAML::Node &n, const char *key) : node_(n), key_(key) {
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());
833  }
834  }
835 
836  public:
838  Value(const Value &) = delete;
840  Value &operator=(const Value &) = delete;
841 
850  template <typename T>
851  operator T() const {
852  try {
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.");
858  }
859  }
860 
866  template <typename T>
867  operator std::vector<T>() const {
868  try {
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 "
876  "file.");
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.");
882  }
883  }
884 
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();
896  // Alert if size does not match
897  if (n_read != N) {
898  throw IncorrectTypeInAssignment("Wrong number of values in array \"" +
899  std::string(key_) + "\". Expected " +
900  std::to_string(N) +
901  " values,"
902  " found " +
903  std::to_string(n_read) + ".");
904  }
905  std::array<T, N> arr;
906  std::copy_n(vec.begin(), N, arr.begin());
907  return arr;
908  }
909 
917  operator ReactionsBitSet() const {
918  const std::vector<std::string> v = operator std::vector<std::string>();
919  ReactionsBitSet s;
920  for (const auto &x : v) {
921  if (x == "All") {
922  s.set();
923  break;
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") {
944  } else {
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.");
952  }
953  }
954  return s;
955  }
956 
964  operator MultiParticleReactionsBitSet() const {
965  const std::vector<std::string> v = operator std::vector<std::string>();
967  for (const auto &x : v) {
968  if (x == "All") {
969  s.set();
970  break;
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") {
979  } else {
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 "
985  "these.");
986  }
987  }
988  return s;
989  }
990 
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") {
1005  s.insert(ThermodynamicQuantity::Tmn);
1006  } else if (x == "tmn_landau") {
1008  } else if (x == "landau_velocity") {
1010  } else if (x == "j_QBS") {
1011  s.insert(ThermodynamicQuantity::j_QBS);
1012  } else {
1014  "The value for key \"" + std::string(key_) +
1015  "\" should be \"rho_eckart\", \"tmn\""
1016  ", \"tmn_landau\", \"landau_velocity\" or \"j_QBS\".");
1017  }
1018  }
1019  return s;
1020  }
1021 
1029  operator CalculationFrame() const {
1030  const std::string s = operator std::string();
1031  if (s == "center of velocity") {
1033  }
1034  if (s == "center of mass") {
1036  }
1037  if (s == "fixed target") {
1039  }
1041  "The value for key \"" + std::string(key_) +
1042  "\" should be \"center of velocity\" or \"center of mass\" "
1043  "or \"fixed target\".");
1044  }
1045 
1053  operator FermiMotion() const {
1054  const std::string s = operator std::string();
1055  if (s == "off") {
1056  return FermiMotion::Off;
1057  }
1058  if (s == "on") {
1059  return FermiMotion::On;
1060  }
1061  if (s == "frozen") {
1062  return FermiMotion::Frozen;
1063  }
1065  "The value for key \"" + std::string(key_) +
1066  "\" should be \"off\" or \"on\" or \"frozen\".");
1067  }
1068 
1076  operator DensityType() const {
1077  const std::string s = operator std::string();
1078  if (s == "hadron") {
1079  return DensityType::Hadron;
1080  }
1081  if (s == "baryon") {
1082  return DensityType::Baryon;
1083  }
1084  if (s == "baryonic isospin") {
1086  }
1087  if (s == "pion") {
1088  return DensityType::Pion;
1089  }
1090  if (s == "total isospin") {
1092  }
1093  if (s == "none") {
1094  return DensityType::None;
1095  }
1096  throw IncorrectTypeInAssignment("The value for key \"" +
1097  std::string(key_) +
1098  "\" should be \"hadron\" or \"baryon\" "
1099  "or \"baryonic isospin\" or \"pion\" "
1100  "or \"none\".");
1101  }
1102 
1110  operator ExpansionMode() const {
1111  const std::string s = operator std::string();
1112  if (s == "NoExpansion") {
1114  }
1115  if (s == "MasslessFRW") {
1117  }
1118  if (s == "MassiveFRW") {
1120  }
1121  if (s == "Exponential") {
1123  }
1125  "The value for key \"" + std::string(key_) +
1126  "\" should be \"NoExpansion\", \"MasslessFRW\"," +
1127  "\"MassiveFRW\" or \"Exponential\".");
1128  }
1129 
1133  operator DerivativesMode() const {
1134  const std::string s = operator std::string();
1135  if (s == "Covariant Gaussian") {
1137  }
1138  if (s == "Finite difference") {
1140  }
1141  if (s == "Off") {
1142  return DerivativesMode::Off;
1143  }
1145  "The value for key \"" + std::string(key_) +
1146  "\" should be \"Covariant Gaussian\", \"Finite difference\"," +
1147  " or \"Off\".");
1148  }
1149 
1153  operator FieldDerivativesMode() const {
1154  const std::string s = operator std::string();
1155  if (s == "Chain Rule") {
1157  }
1158  if (s == "Direct") {
1160  }
1162  "The value for key \"" + std::string(key_) +
1163  "\" should be \"Chain Rule\" or \"Direct\".");
1164  }
1165 
1169  operator SmearingMode() const {
1170  const std::string s = operator std::string();
1171  if (s == "Covariant Gaussian") {
1173  }
1174  if (s == "Discrete") {
1175  return SmearingMode::Discrete;
1176  }
1177  if (s == "Triangular") {
1178  return SmearingMode::Triangular;
1179  }
1181  "The value for key \"" + std::string(key_) +
1182  "\" should be \"Covariant Gaussian\", \"Discrete\"," +
1183  " or \"Triangular\".");
1184  }
1185 
1193  operator TimeStepMode() const {
1194  const std::string s = operator std::string();
1195  if (s == "None") {
1196  return TimeStepMode::None;
1197  }
1198  if (s == "Fixed") {
1199  return TimeStepMode::Fixed;
1200  }
1201  throw IncorrectTypeInAssignment("The value for key \"" +
1202  std::string(key_) +
1203  "\" should be \"None\" or \"Fixed\".");
1204  }
1205 
1213  operator BoxInitialCondition() const {
1214  const std::string s = operator std::string();
1215  if (s == "thermal momenta") {
1217  }
1218  if (s == "thermal momenta quantum") {
1220  }
1221  if (s == "peaked momenta") {
1223  }
1225  "The value for key \"" + std::string(key_) +
1226  "\" should be \"thermal momenta\", \"thermal momenta quantum\", " +
1227  "or \"peaked momenta\".");
1228  }
1229 
1237  operator SphereInitialCondition() const {
1238  const std::string s = operator std::string();
1239  if (s == "thermal momenta") {
1241  }
1242  if (s == "thermal momenta quantum") {
1244  }
1245  if (s == "IC_ES") {
1247  }
1248  if (s == "IC_1M") {
1250  }
1251  if (s == "IC_2M") {
1253  }
1254  if (s == "IC_Massive") {
1256  }
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\".");
1261  }
1262 
1270  operator NNbarTreatment() const {
1271  const std::string s = operator std::string();
1272  if (s == "no annihilation") {
1274  }
1275  if (s == "resonances") {
1277  }
1278  if (s == "two to five") {
1280  }
1281  if (s == "strings") {
1282  return NNbarTreatment::Strings;
1283  }
1285  "The value for key \"" + std::string(key_) + "\" should be " +
1286  "\"no annihilation\", \"resonances\", \"two to five\" or " +
1287  " \"strings\".");
1288  }
1289 
1297  operator Sampling() const {
1298  const std::string s = operator std::string();
1299  if (s == "quadratic") {
1300  return Sampling::Quadratic;
1301  }
1302  if (s == "custom") {
1303  return Sampling::Custom;
1304  }
1305  if (s == "uniform") {
1306  return Sampling::Uniform;
1307  }
1309  "The value for key \"" + std::string(key_) +
1310  "\" should be \"quadratic\", \"uniform\" or \"custom\".");
1311  }
1312 
1320  operator ThermalizationAlgorithm() const {
1321  const std::string s = operator std::string();
1322  if (s == "mode sampling") {
1324  }
1325  if (s == "biased BF") {
1327  }
1328  if (s == "unbiased BF") {
1330  }
1332  "The value for key \"" + std::string(key_) +
1333  "\" should be \"mode sampling\", \"biased BF\" or \"unbiased BF\".");
1334  }
1335 
1343  operator CollisionCriterion() const {
1344  const std::string s = operator std::string();
1345  if (s == "Geometric") {
1347  }
1348  if (s == "Stochastic") {
1350  }
1351  if (s == "Covariant") {
1353  }
1355  "The value for key \"" + std::string(key_) + "\" should be " +
1356  "\"Geometric\", \"Stochastic\" " + "or \"Covariant\".");
1357  }
1358 
1366  operator TotalCrossSectionStrategy() const {
1367  const std::string s = operator std::string();
1368  if (s == "BottomUp") {
1370  }
1371  if (s == "TopDown") {
1373  }
1374  if (s == "TopDownMeasured") {
1376  }
1378  "The value for key \"" + std::string(key_) + "\" should be " +
1379  "\"BottomUp\", \"TopDown\" " + "or \"TopDownMeasured\".");
1380  }
1381 
1389  operator PseudoResonance() const {
1390  const std::string s = operator std::string();
1391  if (s == "None") {
1392  return PseudoResonance::None;
1393  }
1394  if (s == "Largest") {
1395  return PseudoResonance::Largest;
1396  }
1397  if (s == "Closest") {
1398  return PseudoResonance::Closest;
1399  }
1400  if (s == "LargestFromUnstable") {
1402  }
1403  if (s == "ClosestFromUnstable") {
1405  }
1407  "The value for key \"" + std::string(key_) + "\" should be " +
1408  "\"None\", \"Largest\", \"Closest\", \"LargestFromUnstable\", or "
1409  "\"ClosestFromUnstable\".");
1410  }
1411 
1420  operator FluidizationType() const {
1421  const std::string s = operator std::string();
1422  if (s == "Constant_Tau") {
1424  } else if (s == "Dynamic") {
1426  }
1427  throw IncorrectTypeInAssignment("The value for key \"" +
1428  std::string(key_) + "\" should be " +
1429  "\"Constant_Tau\" or \"Dynamic\".");
1430  }
1431 
1439  operator OutputOnlyFinal() const {
1440  const std::string s = operator std::string();
1441  if (s == "Yes") {
1442  return OutputOnlyFinal::Yes;
1443  }
1444  if (s == "No") {
1445  return OutputOnlyFinal::No;
1446  }
1447  if (s == "IfNotEmpty") {
1449  }
1450  throw IncorrectTypeInAssignment("The value for key \"" +
1451  std::string(key_) + "\" should be " +
1452  "\"Yes\", \"No\" or \"IfNotEmpty\".");
1453  }
1454 
1462  operator FluidizableProcessesBitSet() const {
1463  const std::vector<std::string> v = operator std::vector<std::string>();
1465  for (const auto &x : v) {
1466  if (x == "All") {
1467  s.set();
1468  break;
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") {
1479  } else {
1481  "The value for key \"" + std::string(key_) +
1482  "\" should be \"All\", \"Elastic\", \"Decay\", "
1483  "\"Inelastic\", \"SoftString\", \"HardString\", "
1484  "or any combination of these.");
1485  }
1486  }
1487  return s;
1488  }
1489  };
1490 
1498  Configuration(const YAML::Node &node) // NOLINT(runtime/explicit) : see above
1499  : root_node_(YAML::Clone(node)) {}
1500 
1513  std::vector<std::string_view> keys) const;
1514 
1537  std::optional<YAML::Node> find_existing_node(
1538  std::vector<std::string_view> keys) const;
1539 
1543  template <class T>
1544  struct isMap : std::false_type {};
1548  template <class Key, class Value>
1549  struct isMap<std::map<Key, Value>> : std::true_type {};
1550 
1562  Value take(std::vector<std::string_view> labels);
1563 
1575  Value read(std::vector<std::string_view> labels) const;
1576 
1585  return std::find(existing_keys_already_taken_.begin(),
1587  labels) != existing_keys_already_taken_.end();
1588  }
1589 
1591  YAML::Node root_node_{YAML::NodeType::Map};
1592 
1594  int uncaught_exceptions_{std::uncaught_exceptions()};
1595 
1597  std::vector<KeyLabels> existing_keys_already_taken_{};
1598 };
1599 
1600 } // namespace smash
1601 
1602 #endif // SRC_INCLUDE_SMASH_CONFIGURATION_H_
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.
bool is_empty() const
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.
Definition: key.h:104
bool has_dependent_default() const noexcept
Ask whether the default value depends on other other keys.
Definition: key.h:185
default_type default_value() const
Get the default value of the key.
Definition: key.h:177
const KeyLabels & labels() const
Method to access the Key labels.
Definition: key.h:297
default_type type
Let the clients of this class have access to the key type.
Definition: key.h:168
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.
@ From_HardString
@ From_Inelastic
@ From_Elastic
@ From_SoftString
@ From_Decay
std::bitset< 4 > MultiParticleReactionsBitSet
Container for the n to m reactions in the code.
CalculationFrame
The calculation frame.
@ NNbar_5to2
@ A3_Nuclei_4to2
@ Deuteron_3to2
@ Meson_3to1
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.
@ KN_to_KDelta
@ KN_to_KN
@ NN_to_NR
@ PiDeuteron_to_pidprime
@ NDeuteron_to_Ndprime
@ Strangeness_exchange
@ PiDeuteron_to_NN
@ NN_to_DR
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.
constexpr int n
Neutron.
Definition: action.h:24
std::vector< std::string > KeyLabels
Descriptive alias for storing key labels, i.e.
Definition: key.h:42
std::string to_string(ThermodynamicQuantity quantity)
Convert a ThermodynamicQuantity enum value to its corresponding string.
Definition: stringify.cc:25
Convert from YAML::Node to SMASH-readable (C++) format and vice versa.
Definition: configuration.h:42
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...
Definition: configuration.h:69
static Node encode(const T &x)
Serialization: Converts x (of any type) to a YAML::Node.
Definition: configuration.h:50
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.