Version: SMASH-1.8
configuration.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2014-2020
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
10 #ifndef SRC_INCLUDE_CONFIGURATION_H_
11 #define SRC_INCLUDE_CONFIGURATION_H_
12 
13 #include <array>
14 #include <set>
15 #include <stdexcept>
16 #include <string>
17 #include <utility>
18 #include <vector>
19 
20 #include <yaml-cpp/yaml.h> // NOLINT(build/include_order)
21 
22 #include "density.h"
23 #include "forwarddeclarations.h"
24 
25 namespace YAML {
26 
33 template <typename T>
34 struct convert {
42  static Node encode(const T &x) { return Node{static_cast<std::string>(x)}; }
43 
52  static bool decode(const Node &node, T &x) {
53  if (!node.IsScalar()) {
54  return false;
55  } else {
56  x = static_cast<T>(node.Scalar());
57  return true;
58  }
59  }
60 };
61 } // namespace YAML
62 
63 namespace smash {
465  public:
470  struct IncorrectTypeInAssignment : public std::runtime_error {
471  using std::runtime_error::runtime_error;
472  };
477  struct ParseError : public std::runtime_error {
478  using std::runtime_error::runtime_error;
479  };
480 
485  struct FileDoesNotExist : public std::runtime_error {
486  using std::runtime_error::runtime_error;
487  };
488 
496  class Value {
497  friend class Configuration;
498 
500  const YAML::Node node_;
502  const char *const key_;
503 
510  Value(const YAML::Node &n, const char *key) : node_(n), key_(key) {
511  if (!(n.IsScalar() || n.IsSequence() || n.IsMap())) {
512  std::stringstream err;
513  err << "Configuration value for \"" << key
514  << "\" is missing or invalid";
515  throw std::runtime_error(err.str());
516  }
517  }
518 
519  public:
521  Value(const Value &) = delete;
523  Value &operator=(const Value &) = delete;
524 
551  template <typename T>
552  T convert_for(const T &) const {
553  return *this;
554  }
555 
564  template <typename T>
565  operator T() const {
566  try {
567  return node_.as<T>();
568  } catch (YAML::TypedBadConversion<T> &e) {
570  "The value for key \"" + std::string(key_) +
571  "\" cannot be converted to the requested type.");
572  }
573  }
574 
580  template <typename T>
581  operator std::vector<T>() const {
582  try {
583  return node_.as<std::vector<T>>();
584  } catch (YAML::TypedBadConversion<T> &e) {
586  "One of the values in the sequence for key \"" + std::string(key_) +
587  "\" failed to convert to the requested type. E.g. [1 2] is a "
588  "sequence of one string \"1 2\" and [1, 2] is a sequence of two "
589  "integers. Often there is just a comma missing in the config "
590  "file.");
591  } catch (YAML::TypedBadConversion<std::vector<T>> &e) {
593  "The value for key \"" + std::string(key_) +
594  "\" cannot be converted to the requested type. A sequence was "
595  "expected but apparently not found.");
596  }
597  }
598 
606  template <typename T, size_t N>
607  operator std::array<T, N>() const {
608  const std::vector<T> vec = operator std::vector<T>();
609  const size_t n_read = vec.size();
610  // Alert if size does not match
611  if (n_read != N) {
612  throw IncorrectTypeInAssignment("Wrong number of values in array \"" +
613  std::string(key_) + "\". Expected " +
614  std::to_string(N) +
615  " values,"
616  " found " +
617  std::to_string(n_read) + ".");
618  }
619  std::array<T, N> arr;
620  std::copy_n(vec.begin(), N, arr.begin());
621  return arr;
622  }
623 
631  operator ReactionsBitSet() const {
632  const std::vector<std::string> v = operator std::vector<std::string>();
633  ReactionsBitSet s;
634  for (const auto &x : v) {
635  if (x == "All") {
636  s.set();
637  break;
638  } else if (x == "Elastic") {
640  } else if (x == "NN_to_NR") {
642  } else if (x == "NN_to_DR") {
644  } else if (x == "KN_to_KN") {
646  } else if (x == "KN_to_KDelta") {
648  } else if (x == "Strangeness_exchange") {
650  } else if (x == "NNbar") {
652  } else if (x == "PiDeuteron_to_NN") {
654  } else if (x == "PiDeuteron_to_pidprime") {
656  } else if (x == "NDeuteron_to_Ndprime") {
658  } else {
660  "The value for key \"" + std::string(key_) +
661  "\" should be \"All\", \"Elastic\", \"NN_to_NR\", \"NN_to_DR\","
662  "\"KN_to_KN\", \"KN_to_KDelta\", \"PiDeuteron_to_NN\", "
663  "\"PiDeuteron_to_pidprime\", \"NDeuteron_to_Ndprime\", "
664  "\"Strangeness_exchange\" or "
665  "\"NNbar\", or any combination of these.");
666  }
667  }
668  return s;
669  }
670 
678  operator std::set<ThermodynamicQuantity>() const {
679  const std::vector<std::string> v = operator std::vector<std::string>();
680  std::set<ThermodynamicQuantity> s;
681  for (const auto &x : v) {
682  if (x == "rho_eckart") {
684  } else if (x == "tmn") {
685  s.insert(ThermodynamicQuantity::Tmn);
686  } else if (x == "tmn_landau") {
688  } else if (x == "landau_velocity") {
690  } else if (x == "j_QBS") {
692  } else {
694  "The value for key \"" + std::string(key_) +
695  "\" should be \"rho_eckart\", \"tmn\""
696  ", \"tmn_landau\", \"landau_velocity\" or \"j_QBS\".");
697  }
698  }
699  return s;
700  }
701 
709  operator CalculationFrame() const {
710  const std::string s = operator std::string();
711  if (s == "center of velocity") {
713  }
714  if (s == "center of mass") {
716  }
717  if (s == "fixed target") {
719  }
721  "The value for key \"" + std::string(key_) +
722  "\" should be \"center of velocity\" or \"center of mass\" "
723  "or \"fixed target\".");
724  }
725 
733  operator FermiMotion() const {
734  const std::string s = operator std::string();
735  if (s == "off") {
736  return FermiMotion::Off;
737  }
738  if (s == "on") {
739  return FermiMotion::On;
740  }
741  if (s == "frozen") {
742  return FermiMotion::Frozen;
743  }
745  "The value for key \"" + std::string(key_) +
746  "\" should be \"off\" or \"on\" or \"frozen\".");
747  }
748 
756  operator DensityType() const {
757  const std::string s = operator std::string();
758  if (s == "hadron") {
759  return DensityType::Hadron;
760  }
761  if (s == "baryon") {
762  return DensityType::Baryon;
763  }
764  if (s == "baryonic isospin") {
766  }
767  if (s == "pion") {
768  return DensityType::Pion;
769  }
770  if (s == "total isospin") {
772  }
773  if (s == "none") {
774  return DensityType::None;
775  }
776  throw IncorrectTypeInAssignment("The value for key \"" +
777  std::string(key_) +
778  "\" should be \"hadron\" or \"baryon\" "
779  "or \"baryonic isospin\" or \"pion\" "
780  "or \"none\".");
781  }
782 
790  operator ExpansionMode() const {
791  const std::string s = operator std::string();
792  if (s == "NoExpansion") {
794  }
795  if (s == "MasslessFRW") {
797  }
798  if (s == "MassiveFRW") {
800  }
801  if (s == "Exponential") {
803  }
805  "The value for key \"" + std::string(key_) +
806  "\" should be \"NoExpansion\", \"MasslessFRW\"," +
807  "\"MassiveFRW\" or \"Exponential\".");
808  }
809 
817  operator TimeStepMode() const {
818  const std::string s = operator std::string();
819  if (s == "None") {
820  return TimeStepMode::None;
821  }
822  if (s == "Fixed") {
823  return TimeStepMode::Fixed;
824  }
825  throw IncorrectTypeInAssignment("The value for key \"" +
826  std::string(key_) +
827  "\" should be \"None\" or \"Fixed\".");
828  }
829 
837  operator BoxInitialCondition() const {
838  const std::string s = operator std::string();
839  if (s == "thermal momenta") {
841  }
842  if (s == "peaked momenta") {
844  }
846  "The value for key \"" + std::string(key_) +
847  "\" should be \"thermal momenta\" or \"peaked momenta\".");
848  }
849 
857  operator SphereInitialCondition() const {
858  const std::string s = operator std::string();
859  if (s == "thermal momenta") {
861  }
862  if (s == "IC_ES") {
864  }
865  if (s == "IC_1M") {
867  }
868  if (s == "IC_2M") {
870  }
871  if (s == "IC_Massive") {
873  }
875  "The value for key \"" + std::string(key_) +
876  "\" should be \"thermal momenta\", \"IC_ES\", " +
877  "\"IC_1M\", \"IC_2M\" or" + "\"IC_Massive\".");
878  }
879 
887  operator NNbarTreatment() const {
888  const std::string s = operator std::string();
889  if (s == "no annihilation") {
891  }
892  if (s == "resonances") {
894  }
895  if (s == "strings") {
897  }
899  "The value for key \"" + std::string(key_) + "\" should be " +
900  "\"no annihilation\", \"detailed balance\", or \"strings\".");
901  }
902 
910  operator Sampling() const {
911  const std::string s = operator std::string();
912  if (s == "quadratic") {
913  return Sampling::Quadratic;
914  }
915  if (s == "custom") {
916  return Sampling::Custom;
917  }
918  if (s == "uniform") {
919  return Sampling::Uniform;
920  }
922  "The value for key \"" + std::string(key_) +
923  "\" should be \"quadratic\", \"uniform\" or \"custom\".");
924  }
925 
933  operator ThermalizationAlgorithm() const {
934  const std::string s = operator std::string();
935  if (s == "mode sampling") {
937  }
938  if (s == "biased BF") {
940  }
941  if (s == "unbiased BF") {
943  }
945  "The value for key \"" + std::string(key_) +
946  "\" should be \"mode sampling\", \"biased BF\" or \"unbiased BF\".");
947  }
948 
956  operator CollisionCriterion() const {
957  const std::string s = operator std::string();
958  if (s == "Geometric") {
960  }
961  if (s == "Stochastic") {
963  }
964  throw IncorrectTypeInAssignment("The value for key \"" +
965  std::string(key_) + "\" should be " +
966  "\"Geometric\" or \"Stochastic\".");
967  }
968 
976  operator OutputOnlyFinal() const {
977  const std::string s = operator std::string();
978  if (s == "Yes") {
979  return OutputOnlyFinal::Yes;
980  }
981  if (s == "No") {
982  return OutputOnlyFinal::No;
983  }
984  if (s == "IfNotEmpty") {
986  }
987  throw IncorrectTypeInAssignment("The value for key \"" +
988  std::string(key_) + "\" should be " +
989  "\"Yes\", \"No\" or \"IfNotEmpty\".");
990  }
991  };
992 
998  explicit Configuration(const bf::path &path);
999 
1007  explicit Configuration(const bf::path &path, const bf::path &filename);
1008 
1009 #ifdef BUILD_TESTS
1010 
1018  explicit Configuration(const char *yaml) : root_node_(YAML::Load(yaml)) {}
1019 #endif
1020 
1022  Configuration(const Configuration &) = default;
1024  Configuration &operator=(const Configuration &) = default;
1025 
1027  Configuration(Configuration &&) = default;
1029  Configuration &operator=(Configuration &&) = default;
1030 
1041  void merge_yaml(const std::string &yaml);
1042 
1044  std::vector<std::string> list_upmost_nodes();
1045 
1067  Value take(std::initializer_list<const char *> keys);
1068 
1070  template <typename T>
1071  T take(std::initializer_list<const char *> keys, T default_value) {
1072  if (has_value(keys)) {
1073  return take(keys);
1074  }
1075  return default_value;
1076  }
1077 
1092  Value read(std::initializer_list<const char *> keys) const;
1093 
1095  template <typename T>
1096  T read(std::initializer_list<const char *> keys, T default_value) {
1097  if (has_value(keys)) {
1098  return read(keys);
1099  }
1100  return default_value;
1101  }
1102 
1108  void remove_all_but(const std::string &key);
1109 
1124  template <typename T>
1126  return root_node_[std::forward<T>(key)];
1127  }
1128 
1136  template <typename T>
1137  Configuration &operator=(T &&value) {
1138  root_node_ = std::forward<T>(value);
1139  return *this;
1140  }
1141 
1147  std::initializer_list<const char *> keys) const;
1152  bool has_value(std::initializer_list<const char *> keys) const;
1153 
1157  std::string unused_values_report() const;
1158 
1164  std::string to_string() const;
1165 
1166  private:
1173  Configuration(const YAML::Node &node) // NOLINT(runtime/explicit) : see above
1174  : root_node_(node) {}
1175 
1177  YAML::Node root_node_;
1178 };
1179 
1180 } // namespace smash
1181 
1182 #endif // SRC_INCLUDE_CONFIGURATION_H_
SphereInitialCondition::IC_Massive
smash
Definition: action.h:24
NN_to_DR
Definition: forwarddeclarations.h:215
ThermodynamicQuantity::TmnLandau
YAML::convert::encode
static Node encode(const T &x)
Serialization: Converts x (of any type) to a YAML::Node.
Definition: configuration.h:42
Sampling::Quadratic
Sample from areal / quadratic distribution.
CalculationFrame::CenterOfVelocity
ThermodynamicQuantity::LandauVelocity
smash::Configuration::list_upmost_nodes
std::vector< std::string > list_upmost_nodes()
Lists all YAML::Nodes from the configuration setup.
Definition: configuration.cc:132
TimeStepMode
TimeStepMode
The time step mode.
Definition: forwarddeclarations.h:113
smash::Configuration::Value::node_
const YAML::Node node_
a YAML leaf node
Definition: configuration.h:500
SphereInitialCondition::IC_2M
OutputOnlyFinal
OutputOnlyFinal
Whether and when only final state particles should be printed.
Definition: forwarddeclarations.h:200
YAML::convert
Convert from YAML::Node to SMASH-readable (C++) format and vice versa.
Definition: configuration.h:34
smash::Configuration::root_node_
YAML::Node root_node_
the general_config.yaml contents - fully parsed
Definition: configuration.h:1177
smash::Configuration::read
Value read(std::initializer_list< const char * > keys) const
Additional interface for SMASH to read configuration values without removing them.
Definition: configuration.cc:158
NNbar
Definition: forwarddeclarations.h:219
smash::DensityType::BaryonicIsospin
ExpansionMode::NoExpansion
PiDeuteron_to_NN
Definition: forwarddeclarations.h:220
ExpansionMode::Exponential
NNbarTreatment::Strings
Use string fragmentation.
smash::Configuration::to_string
std::string to_string() const
Returns a YAML string of the current tree.
Definition: configuration.cc:192
smash::Configuration::Value::Value
Value(const YAML::Node &n, const char *key)
Constructs the Value wrapper from a YAML::Node.
Definition: configuration.h:510
FermiMotion::Off
Don't use fermi motion.
smash::Configuration::unused_values_report
std::string unused_values_report() const
Returns a string listing the key/value pairs that have not been taken yet.
Definition: configuration.cc:186
smash::Configuration::has_value
bool has_value(std::initializer_list< const char * > keys) const
Returns whether there is a non-empty value behind the requested keys.
Definition: configuration.cc:181
BoxInitialCondition
BoxInitialCondition
Initial condition for a particle in a box.
Definition: forwarddeclarations.h:131
Strangeness_exchange
Definition: forwarddeclarations.h:218
smash::Configuration::read
T read(std::initializer_list< const char * > keys, T default_value)
Definition: configuration.h:1096
YAML
Definition: configuration.h:25
FermiMotion::Frozen
Use fermi motion without potentials.
ReactionsBitSet
std::bitset< 10 > ReactionsBitSet
Container for the 2 to 2 reactions in the code.
Definition: forwarddeclarations.h:226
smash::Configuration::ParseError
Definition: configuration.h:477
smash::Configuration::Configuration
Configuration(const YAML::Node &node)
Creates a subobject that has its root node at the given node.
Definition: configuration.h:1173
Sampling::Custom
Sample from custom, user-defined distribution.
smash::Configuration
Interface to the SMASH configuration files.
Definition: configuration.h:464
ThermalizationAlgorithm::UnbiasedBF
forwarddeclarations.h
ThermalizationAlgorithm
ThermalizationAlgorithm
Defines the algorithm used for the forced thermalization.
Definition: forwarddeclarations.h:237
OutputOnlyFinal::IfNotEmpty
Print only final-state particles, and those only if the event is not empty.
CollisionCriterion::Stochastic
Stochastic Criteiron.
smash::Configuration::Configuration
Configuration(const bf::path &path)
Reads config.yaml from the specified path.
Definition: configuration.cc:89
Sampling
Sampling
Possible methods of impact parameter sampling.
Definition: forwarddeclarations.h:103
ThermodynamicQuantity::Tmn
SphereInitialCondition::IC_1M
smash::Configuration::Configuration
Configuration(const char *yaml)
Definition: configuration.h:1018
ExpansionMode::MassiveFRW
SphereInitialCondition::ThermalMomenta
CollisionCriterion
CollisionCriterion
Criteria used to check collisions.
Definition: forwarddeclarations.h:192
smash::Configuration::Value
Return type of Configuration::take that automatically determines the target type.
Definition: configuration.h:496
density.h
ExpansionMode::MasslessFRW
smash::DensityType::Pion
NDeuteron_to_Ndprime
Definition: forwarddeclarations.h:222
OutputOnlyFinal::Yes
Print only final-state particles.
CalculationFrame::FixedTarget
ThermodynamicQuantity::EckartDensity
ThermalizationAlgorithm::ModeSampling
SphereInitialCondition::IC_ES
SphereInitialCondition
SphereInitialCondition
Initial condition for a particle in a sphere.
Definition: forwarddeclarations.h:149
KN_to_KN
Definition: forwarddeclarations.h:216
KN_to_KDelta
Definition: forwarddeclarations.h:217
ThermalizationAlgorithm::BiasedBF
NNbarTreatment::Resonances
Use intermediate Resonances.
CalculationFrame
CalculationFrame
The calculation frame.
Definition: forwarddeclarations.h:86
smash::DensityType
DensityType
Allows to choose which kind of density to calculate.
Definition: density.h:35
BoxInitialCondition::ThermalMomenta
Sampling::Uniform
Sample from uniform distribution.
smash::Configuration::Value::key_
const char *const key_
The key to be interpreted.
Definition: configuration.h:502
smash::Configuration::merge_yaml
void merge_yaml(const std::string &yaml)
Merge the configuration in yaml into the existing tree.
Definition: configuration.cc:118
FermiMotion::On
Use fermi motion in combination with potentials.
smash::Configuration::Value::convert_for
T convert_for(const T &) const
Convert the value to the type of the supplied argument.
Definition: configuration.h:552
smash::ProcessType::Elastic
elastic scattering: particles remain the same, only momenta change
smash::Configuration::IncorrectTypeInAssignment
Definition: configuration.h:470
BoxInitialCondition::PeakedMomenta
smash::Configuration::take
Value take(std::initializer_list< const char * > keys)
The default interface for SMASH to read configuration values.
Definition: configuration.cc:140
smash::DensityType::None
smash::Configuration::FileDoesNotExist
Definition: configuration.h:485
NN_to_NR
Definition: forwarddeclarations.h:214
smash::DensityType::Isospin3_tot
ThermodynamicQuantity::j_QBS
smash::Configuration::has_value_including_empty
bool has_value_including_empty(std::initializer_list< const char * > keys) const
Returns if there is a (maybe empty) value behind the requested keys.
Definition: configuration.cc:175
smash::Configuration::operator=
Configuration & operator=(T &&value)
Assignment overwrites the value of the current YAML node.
Definition: configuration.h:1137
NNbarTreatment
NNbarTreatment
Treatment of N Nbar Annihilation.
Definition: forwarddeclarations.h:173
smash::Configuration::Value::operator=
Value & operator=(const Value &)=delete
If you want to copy this you're doing it wrong.
smash::pdg::n
constexpr int n
Neutron.
Definition: pdgcode_constants.h:30
smash::Configuration::operator=
Configuration & operator=(const Configuration &)=default
If you want to copy this you're doing it wrong.
NNbarTreatment::NoAnnihilation
No Annihilation.
CalculationFrame::CenterOfMass
PiDeuteron_to_pidprime
Definition: forwarddeclarations.h:221
smash::DensityType::Hadron
CollisionCriterion::Geometric
(Default) geometric criterion.
ExpansionMode
ExpansionMode
Defines properties of expansion for the metric (e.g.
Definition: forwarddeclarations.h:165
smash::DensityType::Baryon
smash::Configuration::remove_all_but
void remove_all_but(const std::string &key)
Removes all entries in the map except for key.
Definition: configuration.cc:163
smash::Configuration::operator[]
Configuration operator[](T &&key)
Access to the YAML::Node behind the requested keys.
Definition: configuration.h:1125
smash::NeedsToWrap::No
TimeStepMode::Fixed
Use fixed time step.
YAML::convert::decode
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:52
FermiMotion
FermiMotion
Option to use Fermi Motion.
Definition: forwarddeclarations.h:93
smash::Configuration::take
T take(std::initializer_list< const char * > keys, T default_value)
Definition: configuration.h:1071