Version: SMASH-3.4
smash::anonymous_namespace{configuration.cc} Namespace Reference

Classes

struct  IsStdMap
 A utility type to be specialized to check if a type is a std::map . More...
 
struct  IsStdMap< std::map< MapKey, MapValue > >
 A specialization of IsStdMap<T> for cases where the boolean value should be set to true. More...
 

Functions

void descend_one_existing_level (std::optional< YAML::Node > &node, std::string_view key)
 Reset the passed in node to that one at the provided key, which is expected to exist in the node. More...
 
YAML::Node remove_empty_maps (YAML::Node root)
 Remove all empty maps of a YAML::Node. More...
 
YAML::Node operator|= (YAML::Node a, const YAML::Node &b)
 Merge two YAML::Nodes. More...
 
std::string join_quoted (KeyLabels keys)
 Build a string with a list of keys as specified in the code. More...
 
void fill_list_of_labels_per_key_in_yaml_tree (const YAML::Node &root_node, std::vector< KeyLabels > &list, KeyLabels &new_list_entry)
 Implementation of the algorithm to translate a YAML tree into lists of labels, each identifying a key from the YAML root node. More...
 
auto get_list_of_labels_per_key_in_yaml_tree (const YAML::Node &root_node)
 Create a list of lists of key labels present in the passed YAML node considered to be the root one of a YAML tree. More...
 
auto collect_input_keys_taken_as_maps ()
 Extract from the InputKeys database the labels of keys that have a std::map as type. More...
 
void adjust_list_of_labels_dealing_with_keys_taken_as_maps (std::vector< KeyLabels > &list_of_input_key_labels)
 Remove last labels of keys that are taken as maps in SMASH and remove duplicates from the resulting list. More...
 
Configuration::Is validate_key (const KeyLabels &labels)
 Given some YAML labels (assumed to be in order from the top section), it is checked whether any valid SMASH key with the same key exists. More...
 
void accumulate_validation (Configuration::Is &result_so_far, Configuration::Is new_value)
 Utility function to accumulate validation results of keys. More...
 

Function Documentation

◆ descend_one_existing_level()

void smash::anonymous_namespace{configuration.cc}::descend_one_existing_level ( std::optional< YAML::Node > &  node,
std::string_view  key 
)

Reset the passed in node to that one at the provided key, which is expected to exist in the node.

If this is not the case, the node is set to std::nullopt.

Parameters
[in,out]nodeAn optional node to be reset.
[in]keyThe key expected to exist in the given node.

Definition at line 40 of file configuration.cc.

41  {
42  if (node) {
43  for (const auto &section : node.value()) {
44  /* Two remarks:
45  1) The Node::operator[] creates an undefined node in the YAML tree if
46  the node corresponding to the passed key does not exist and hence
47  in this function, which descend one level which is expected to
48  exist, we need to use it only if we are sure the node exists.
49  2) Node::reset does what you might expect Node::operator= to do. But
50  operator= assigns a value to the node and so
51  node = node[key]
52  would lead to a further modification of the data structure and
53  this function would not be simply traversal. Note that node and
54  root_node_ point to the same memory and modification to the first
55  would affect the second, too. */
56  if (section.first.Scalar() == key) {
57  node.value().reset(node.value()[key]);
58  return;
59  }
60  }
61  node = std::nullopt;
62  }
63 }
Here is the caller graph for this function:

◆ remove_empty_maps()

YAML::Node smash::anonymous_namespace{configuration.cc}::remove_empty_maps ( YAML::Node  root)

Remove all empty maps of a YAML::Node.

Parameters
[in]rootYAML::Node that contains empty maps.
Returns
YAML::Node from above without empty maps.

Definition at line 71 of file configuration.cc.

71  {
72  if (root.IsMap()) {
73  std::vector<std::string> to_remove(root.size());
74  for (auto n : root) {
75  remove_empty_maps(n.second);
76  // If the node is an empty sequence, we do NOT remove it!
77  if (n.second.IsMap() && n.second.size() == 0) {
78  to_remove.emplace_back(n.first.Scalar());
79  }
80  }
81  for (const auto &key : to_remove) {
82  root.remove(key);
83  }
84  }
85  return root;
86 }
YAML::Node remove_empty_maps(YAML::Node root)
Remove all empty maps of a YAML::Node.
constexpr int n
Neutron.
Here is the caller graph for this function:

◆ operator|=()

YAML::Node smash::anonymous_namespace{configuration.cc}::operator|= ( YAML::Node  a,
const YAML::Node &  b 
)

Merge two YAML::Nodes.

Parameters
[in]aYAML::Node into which b is merged.
[in]bYAML::Node that is merged into a.
Returns
YAML::Node which is the merge of a and b.

Definition at line 95 of file configuration.cc.

95  {
96  if (b.IsMap()) {
97  for (auto n0 : b) {
98  a[n0.first.Scalar()] |= n0.second;
99  }
100  } else {
101  a = b;
102  }
103  return a;
104 }

◆ join_quoted()

std::string smash::anonymous_namespace{configuration.cc}::join_quoted ( KeyLabels  keys)

Build a string with a list of keys as specified in the code.

Parameters
keysThe list of keys.
Returns
A std::string with the desired result.

Definition at line 112 of file configuration.cc.

112  {
113  return std::accumulate(keys.begin(), keys.end(), std::string{"{"},
114  [](const std::string &ss, const std::string_view &s) {
115  return ss + ((ss.size() == 1) ? "\"" : ", \"") +
116  std::string{s} + // NOLINT(whitespace/braces)
117  "\"";
118  }) +
119  "}";
120 }
Here is the caller graph for this function:

◆ fill_list_of_labels_per_key_in_yaml_tree()

void smash::anonymous_namespace{configuration.cc}::fill_list_of_labels_per_key_in_yaml_tree ( const YAML::Node &  root_node,
std::vector< KeyLabels > &  list,
KeyLabels new_list_entry 
)

Implementation of the algorithm to translate a YAML tree into lists of labels, each identifying a key from the YAML root node.

Since the level of nesting sections in a YAML input file is arbitrary, this is a typical task to be solved using recursion. The main idea here is to take advantage of YAML functionality and in particular of the possibility to iterate over trees and test for nature of a node (is it a Map or not?). Roughly speaking, from the tree top-level all upmost nodes are extracted and for each of them, recursively, the same procedure is done over and over again if they are maps. If a non-map node is found, i.e. a key value is found, then recursion ends and a new entry is added to list .

Parameters
[in]root_nodeThe root YAML node to extract from.
[in,out]listThe list of lists of labels to be filled.
[in,out]new_list_entryNew list of labels in process to be filled during recursion.

Definition at line 409 of file configuration.cc.

411  {
412  // Here sub_node is an iterator value, i.e. a key/value pair of nodes,
413  // not a single YAML node (that's how YAML library works)
414  for (const auto &sub_node : root_node) {
415  new_list_entry.push_back(sub_node.first.as<std::string_view>());
416  if (sub_node.second.IsMap())
417  fill_list_of_labels_per_key_in_yaml_tree(sub_node.second, list,
418  new_list_entry);
419  else
420  list.push_back(new_list_entry);
421  new_list_entry.pop_back();
422  }
423 }
void fill_list_of_labels_per_key_in_yaml_tree(const YAML::Node &root_node, std::vector< KeyLabels > &list, KeyLabels &new_list_entry)
Implementation of the algorithm to translate a YAML tree into lists of labels, each identifying a key...
Here is the caller graph for this function:

◆ get_list_of_labels_per_key_in_yaml_tree()

auto smash::anonymous_namespace{configuration.cc}::get_list_of_labels_per_key_in_yaml_tree ( const YAML::Node &  root_node)

Create a list of lists of key labels present in the passed YAML node considered to be the root one of a YAML tree.

Given a YAML::Node, for each key having a value, all labels to reach the given key from the passed node are collected and a std::vector containing them is built and inserted into the given list. This function is calling the actual implementation preparing auxiliary needed variables.

Parameters
[in]root_nodeThe root node of the YAML tree to be considered.
Returns
A std::vector<KeyLabels> containing the desired information.

Definition at line 438 of file configuration.cc.

438  {
439  std::vector<KeyLabels> list{};
440  KeyLabels aux{};
441  fill_list_of_labels_per_key_in_yaml_tree(root_node, list, aux);
442  return list;
443 }
std::vector< std::string_view > KeyLabels
Descriptive alias for storing key labels, i.e.
Definition: key.h:46
Here is the call graph for this function:
Here is the caller graph for this function:

◆ collect_input_keys_taken_as_maps()

auto smash::anonymous_namespace{configuration.cc}::collect_input_keys_taken_as_maps ( )

Extract from the InputKeys database the labels of keys that have a std::map as type.

Returns
A list of key labels.

Definition at line 482 of file configuration.cc.

482  {
483  std::vector<KeyLabels> labels_of_keys_taken_as_map{};
484  for (const auto &keys_variant : smash::InputKeys::all_keys()) {
485  std::visit(
486  [&labels_of_keys_taken_as_map](auto &&var) {
487  /*
488  * The following if checks if the SMASH input key has a map as value
489  * and it deserves some explanation about the type extraction:
490  *
491  * - arg -> object of type: std::cref(const Key<T>)
492  * - arg.get() -> object of type: const Key<T>&
493  * - decltype(arg.get()) -> type: const Key<T>&
494  * - std::decay_t<decltype(arg.get())>::type -> type: Key<T>
495  * - std::decay_t<decltype(arg.get())>::type::value -> type: T
496  */
497  if constexpr (IsStdMap<typename std::decay_t<
498  decltype(var.get())>::type>::value)
499  labels_of_keys_taken_as_map.push_back(var.get().labels());
500  },
501  keys_variant);
502  }
503  return labels_of_keys_taken_as_map;
504 }
static const std::vector< key_references_variant > & all_keys()
Get list of references to all existing SMASH keys.
Definition: input_keys.cc:32
Here is the call graph for this function:
Here is the caller graph for this function:

◆ adjust_list_of_labels_dealing_with_keys_taken_as_maps()

void smash::anonymous_namespace{configuration.cc}::adjust_list_of_labels_dealing_with_keys_taken_as_maps ( std::vector< KeyLabels > &  list_of_input_key_labels)

Remove last labels of keys that are taken as maps in SMASH and remove duplicates from the resulting list.

The keys that are taken as maps in SMASH are here collected using the database InputKeys and the list of keys contained in the configuration must be adjusted by hand. This is a corner case, since YAML nodes that are maps are by definition sections and cannot be distinguished from keys "with a map value" in the recursive process to create the list of key labels.

Parameters
[in,out]list_of_input_key_labelsThe list of key labels to adjust.

Definition at line 518 of file configuration.cc.

519  {
520  const std::vector<KeyLabels> labels_of_keys_taken_as_map =
522  for (const auto &labels : labels_of_keys_taken_as_map) {
523  std::for_each(list_of_input_key_labels.begin(),
524  list_of_input_key_labels.end(),
525  [&labels](KeyLabels &labels_of_input_key) {
526  if (std::equal(labels.begin(), labels.end(),
527  labels_of_input_key.begin(),
528  labels_of_input_key.begin() + labels.size()))
529  labels_of_input_key = labels;
530  });
531  }
532  // The identical keys in list are now next to each other and we do
533  // not need/want to sort the list before calling std::unique.
534  list_of_input_key_labels.erase(std::unique(list_of_input_key_labels.begin(),
535  list_of_input_key_labels.end()),
536  list_of_input_key_labels.end());
537 }
auto collect_input_keys_taken_as_maps()
Extract from the InputKeys database the labels of keys that have a std::map as type.
UnaryFunction for_each(Container &&c, UnaryFunction &&f)
Convenience wrapper for std::for_each that operates on a complete container.
Definition: algorithms.h:96
Here is the call graph for this function:
Here is the caller graph for this function:

◆ validate_key()

Configuration::Is smash::anonymous_namespace{configuration.cc}::validate_key ( const KeyLabels labels)

Given some YAML labels (assumed to be in order from the top section), it is checked whether any valid SMASH key with the same key exists.

All possible checks are done in a way such that the user is informed about

  • if the key has never been valid;
  • if the key was valid in the past but it has been removed;
  • if the key is valid but deprecated.
Parameters
[in]labelsThe series of labels identifying the key.
Returns
Configuration::Is::Valid if the key is valid;
Configuration::Is::Deprecated if the key is Deprecated and
Configuration::Is::Invalid if the key is invalid.

Definition at line 554 of file configuration.cc.

554  {
555  const auto &list = InputKeys::all_keys();
556  auto key_ref_var_it =
557  std::find_if(list.begin(), list.end(), [&labels](auto key) {
558  return std::visit(
559  [&labels](auto &&arg) { return arg.get().has_same_labels(labels); },
560  key);
561  });
562  if (key_ref_var_it == list.end()) {
563  logg[LConfiguration].error("Key ", smash::quote(smash::join(labels, ": ")),
564  " is not a valid SMASH input key.");
565  return Configuration::Is::Invalid;
566  }
567 
568  smash::InputKeys::key_references_variant found_variant = *key_ref_var_it;
569  const auto key_labels =
570  std::visit([](auto &&var) { return static_cast<std::string>(var.get()); },
571  found_variant);
572 
573  if (std::visit([](auto &&var) { return !var.get().is_allowed(); },
574  found_variant)) {
575  const auto v_removal = std::visit(
576  [](auto &&var) { return var.get().removed_in(); }, found_variant);
577  logg[LConfiguration].error("Key ", key_labels,
578  " has been removed in version ", v_removal,
579  " and it is not valid anymore.");
580  return Configuration::Is::Invalid;
581  }
582  if (std::visit([](auto &&var) { return var.get().is_deprecated(); },
583  found_variant)) {
584  const auto v_deprecation = std::visit(
585  [](auto &&var) { return var.get().deprecated_in(); }, found_variant);
586  logg[LConfiguration].warn(
587  "Key ", key_labels, " has been deprecated in version ", v_deprecation);
588  return Configuration::Is::Deprecated;
589  } else {
590  logg[LConfiguration].debug("Key ", key_labels, " is valid!");
591  return Configuration::Is::Valid;
592  }
593 }
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > & logg
An array that stores all pre-configured Logger objects.
Definition: logging.h:245
std::string quote(const std::string &s)
Add quotes around string.
static constexpr int LConfiguration
std::string join(const std::vector< std::string > &v, std::string_view delim)
Join strings using delimiter.
std::variant< std::reference_wrapper< const Key< bool > >, std::reference_wrapper< const Key< int > >, std::reference_wrapper< const Key< int64_t > >, std::reference_wrapper< const Key< double > >, std::reference_wrapper< const Key< std::string > >, std::reference_wrapper< const Key< std::array< int, 3 > >>, std::reference_wrapper< const Key< std::array< double, 2 > >>, std::reference_wrapper< const Key< std::array< double, 3 > >>, std::reference_wrapper< const Key< std::pair< double, double > >>, std::reference_wrapper< const Key< std::vector< double > >>, std::reference_wrapper< const Key< std::vector< std::string > >>, std::reference_wrapper< const Key< std::set< ThermodynamicQuantity > >>, std::reference_wrapper< const Key< std::map< PdgCode, int > >>, std::reference_wrapper< const Key< std::map< std::string, std::string > >>, std::reference_wrapper< const Key< einhard::LogLevel > >, std::reference_wrapper< const Key< BoxInitialCondition > >, std::reference_wrapper< const Key< CalculationFrame > >, std::reference_wrapper< const Key< CharmRescattering > >, std::reference_wrapper< const Key< CollisionCriterion > >, std::reference_wrapper< const Key< DensityType > >, std::reference_wrapper< const Key< DerivativesMode > >, std::reference_wrapper< const Key< ExpansionMode > >, std::reference_wrapper< const Key< FermiMotion > >, std::reference_wrapper< const Key< DileptonBremsPionFormFactor > >, std::reference_wrapper< const Key< FieldDerivativesMode > >, std::reference_wrapper< const Key< FluidizableProcessesBitSet > >, std::reference_wrapper< const Key< FluidizationType > >, std::reference_wrapper< const Key< MultiParticleReactionsBitSet > >, std::reference_wrapper< const Key< SpinInteractionType > >, std::reference_wrapper< const Key< NNbarTreatment > >, std::reference_wrapper< const Key< OutputOnlyFinal > >, std::reference_wrapper< const Key< PdgCode > >, std::reference_wrapper< const Key< PseudoResonance > >, std::reference_wrapper< const Key< ReactionsBitSet > >, std::reference_wrapper< const Key< RestFrameDensityDerivativesMode > >, std::reference_wrapper< const Key< Sampling > >, std::reference_wrapper< const Key< SmearingMode > >, std::reference_wrapper< const Key< SphereInitialCondition > >, std::reference_wrapper< const Key< ThermalizationAlgorithm > >, std::reference_wrapper< const Key< TimeStepMode > >, std::reference_wrapper< const Key< HardStringTransitionMode > >, std::reference_wrapper< const Key< TotalCrossSectionStrategy > >> key_references_variant
Alias for the type to be used in the list of keys.
Definition: input_keys.h:7754
Here is the call graph for this function:
Here is the caller graph for this function:

◆ accumulate_validation()

void smash::anonymous_namespace{configuration.cc}::accumulate_validation ( Configuration::Is result_so_far,
Configuration::Is  new_value 
)

Utility function to accumulate validation results of keys.

This is basically the logic needed to make a full validation of a configuration, considered that we have three possible states. It extend the logical AND between two boolean values.

Parameters
[in,out]result_so_farStatus of the configuration so far to be combined with the new key state.
[in]new_valueNew key state to be considered.

Definition at line 606 of file configuration.cc.

607  {
608  switch (result_so_far) {
609  case Configuration::Is::Invalid:
610  break;
611  case Configuration::Is::Deprecated:
612  if (new_value != Configuration::Is::Valid) {
613  result_so_far = new_value;
614  }
615  break;
616  case Configuration::Is::Valid:
617  result_so_far = new_value;
618  break;
619  }
620 }
Here is the caller graph for this function: