QMCPACK
InputSection Class Reference

Input section provides basic parsing and a uniform method of access to the raw parsed input. More...

+ Inheritance diagram for InputSection:
+ Collaboration diagram for InputSection:

Public Types

using Real = QMCTraits::FullPrecRealType
 
using Position = typename QMCTypes< Real, OHMMS_DIM >::PosType
 

Public Member Functions

 InputSection ()=default
 
 InputSection (const InputSection &other)=default
 
InputSectionoperator= (const InputSection &other)=default
 
bool has (const std::string &name) const
 
template<typename T >
get (const std::string &name) const
 
template<typename T >
bool setIfInInput (T &var, const std::string &tag)
 set var if input section has read the tag More...
 
void readXML (xmlNodePtr cur)
 Read variable values (initialize) from XML input, call checkValid. More...
 
void init (const std::unordered_map< std::string, std::any > &init_values)
 

Static Public Member Functions

template<typename ENUM_T >
static std::string reverseLookupInputEnumMap (ENUM_T enum_val, const std::unordered_map< std::string, std::any > &enum_map)
 Get string represtation of enum class type value from enum_val. More...
 

Protected Types

using DelegateHandler = std::function< std::any(xmlNodePtr cur, std::string &value_name)>
 Function that returns Input class as std::any. More...
 

Protected Member Functions

void readAttributes (xmlNodePtr cur, const std::string &element_name, const std::vector< std::string > &do_not_consume)
 reads attributes for both the root node and parameter/child nodes that aren't delegated. More...
 
void registerDelegate (const std::string &tag, DelegateHandler delegate_handler)
 register factory function for delegate input More...
 
virtual void checkParticularValidity ()
 Do validation for a particular subtype of InputSection Called by check_valid. More...
 
virtual std::any assignAnyEnum (const std::string &tag) const
 Derived class overrides this to get proper assignment of scoped enum values. More...
 
virtual void setFromStreamCustom (const std::string &ename, const std::string &name, std::istringstream &svalue)
 Derived class can overrides this to do custom parsing of the element values for Custom elements These can have a name attribute only. More...
 
void report () const
 
void report (std::ostream &out) const
 

Static Protected Member Functions

static std::any lookupAnyEnum (const std::string &enum_name, const std::string &enum_value, const std::unordered_map< std::string, std::any > &enum_map)
 Assign any enum helper for InputSection derived class assumes enum lookup table of this form: inline static const std::unordered_map<std::string, std::any> lookup_input_enum_value{{"integrator-uniform_grid", Integrator::UNIFORM_GRID}, {"integrator-uniform", Integrator::UNIFORM}, {"integrator-density", Integrator::DENSITY}, {"evaluator-loop", Evaluator::LOOP}, {"evaluator-matrix", Evaluator::MATRIX}};. More...
 

Protected Attributes

std::string section_name
 "Name" of the input section, you must define this in the subtype and the ename, name, type, or method must match. More...
 
std::vector< std::string > section_name_alternates
 For historical reasons some sections must recognize several different names. Assign them to this variable in your subtype. More...
 
std::unordered_set< std::string > attributes
 
std::unordered_set< std::string > parameters
 
std::unordered_set< std::string > delegates
 
std::unordered_set< std::string > required
 
std::unordered_set< std::string > multiple
 
std::unordered_set< std::string > strings
 
std::unordered_set< std::string > multi_strings
 
std::unordered_set< std::string > multi_reals
 
std::unordered_set< std::string > bools
 
std::unordered_set< std::string > integers
 
std::unordered_set< std::string > reals
 
std::unordered_set< std::string > positions
 
std::unordered_set< std::string > custom
 
std::unordered_set< std::string > enums
 list of enum inputs which allow a finite set of strings to map to enum values The enum class types and values need only be known to IS subtypes More...
 
std::unordered_map< std::string, std::any > default_values
 
std::unordered_map< std::string, std::function< std::any(xmlNodePtr cur, std::string &value_key)> > delegate_factories_
 
std::unordered_map< std::string, std::any > values_
 

Private Member Functions

bool isAttribute (const std::string &name) const
 
bool isDelegate (const std::string &name) const
 
bool isParameter (const std::string &name) const
 
bool isRequired (const std::string &name) const
 
bool isMultiple (const std::string &name) const
 
bool isEnumString (const std::string &name) const
 
bool isString (const std::string &name) const
 
bool isMultiString (const std::string &name) const
 
bool isMultiReal (const std::string &name) const
 
bool isBool (const std::string &name) const
 
bool isInteger (const std::string &name) const
 
bool isReal (const std::string &name) const
 
bool isPosition (const std::string &name) const
 
bool isCustom (const std::string &name) const
 
bool has_default (const std::string &name) const
 
void setDefaults ()
 
void setFromStream (const std::string &name, std::istringstream &svalue)
 
void setFromValue (const std::string &name, const std::any &svalue)
 Coerce input collected via init into types matching the definition of the input types defined in the InputSection subtype constructor. More...
 
template<typename T >
void assignValue (const std::string &name, const T &value)
 assign value into unordered map respecting values multiplicity It is a fatal exception to assign to a singular existing value. More...
 
void handleDelegate (const std::string &ename, const xmlNodePtr element)
 factor out delegate handling code for sanity. More...
 
void checkValid ()
 Check validity of inputs. More...
 

Detailed Description

Input section provides basic parsing and a uniform method of access to the raw parsed input.

It is still expected to be a composed part of the actual input class for a simulation class. It does not operate at reduced precision, i.e. numerical input is always parsed and retrieved at full precision. Gettting values from input section is strongly typed so you will get errors if you try to get numeric types at reduced precision.

Definition at line 37 of file InputSection.h.

Member Typedef Documentation

◆ DelegateHandler

using DelegateHandler = std::function<std::any(xmlNodePtr cur, std::string& value_name)>
protected

Function that returns Input class as std::any.

Parameters
[in]curxml_node being delegated by the Input Class
[out]value_namestring key value to store the delegate with

Definition at line 183 of file InputSection.h.

◆ Position

using Position = typename QMCTypes<Real, OHMMS_DIM>::PosType

Definition at line 41 of file InputSection.h.

◆ Real

Definition at line 40 of file InputSection.h.

Constructor & Destructor Documentation

◆ InputSection() [1/2]

InputSection ( )
default

◆ InputSection() [2/2]

InputSection ( const InputSection other)
default

Member Function Documentation

◆ assignAnyEnum()

std::any assignAnyEnum ( const std::string &  tag) const
protectedvirtual

Derived class overrides this to get proper assignment of scoped enum values.

In most cases all you'll need it to define the map and write: std::any DerivedInputSection::assignAnyEnum(const std::string& name) const { return lookupAnyEnum(name, get<std::string>(name), derived_input_lookup_enum); }

See test_InputSection.cpp and OneBodyDensityMatricesInput You really should do this if your input class has a finite set of string values for an input example: OneBodyDensityMatricesInput

can't be bothered then just define your enum option as a string.

Reimplemented in SpaceGridInput::SpaceGridInputSection, MagnetizationDensityInput::MagnetizationDensityInputSection, OneBodyDensityMatricesInput::OneBodyDensityMatricesInputSection, TestInputSection, and ReferencePointsInput::ReferencePointsInputSection.

Definition at line 20 of file InputSection.cpp.

Referenced by InputSection::get().

21 {
22  throw UniformCommunicateError("derived class must provide assignAnyEnum method if enum parameters are used");
23 }

◆ assignValue()

void assignValue ( const std::string &  name,
const T &  value 
)
private

assign value into unordered map respecting values multiplicity It is a fatal exception to assign to a singular existing value.

If the value isMultiple i.e. the value can legally appear multiple times in the input a vector of those values is built up at the key in the value map. If the value is never assigned to there is not an empty vector and that value is undefined in the map.

Definition at line 259 of file InputSection.cpp.

References InputSection::has(), InputSection::isMultiple(), InputSection::section_name, and InputSection::values_.

Referenced by InputSection::handleDelegate(), InputSection::setFromStream(), and InputSection::setFromValue().

260 {
261  if (has(name) && !isMultiple(name))
262  throw UniformCommunicateError("Input is invalid " + section_name + " contains " + name +
263  " node with duplicate name!");
264 
265  if (!isMultiple(name))
266  values_[name] = value;
267  else
268  {
269  if (has(name))
270  std::any_cast<std::vector<T>&>(values_[name]).push_back(value);
271  else
272  values_[name] = std::vector<T>{value};
273  }
274 }
bool isMultiple(const std::string &name) const
Definition: InputSection.h:250
std::unordered_map< std::string, std::any > values_
Definition: InputSection.h:83
bool has(const std::string &name) const
Definition: InputSection.h:87
std::string section_name
"Name" of the input section, you must define this in the subtype and the ename, name, type, or method must match.
Definition: InputSection.h:57

◆ checkParticularValidity()

virtual void checkParticularValidity ( )
inlineprotectedvirtual

Do validation for a particular subtype of InputSection Called by check_valid.

Default implementation is noop The InputSection subtype should make all correctness checks reasonable at parse time.

Reimplemented in SpaceGridInput::SpaceGridInputSection, MagnetizationDensityInput::MagnetizationDensityInputSection, and OneBodyDensityMatricesInput::OneBodyDensityMatricesInputSection.

Definition at line 195 of file InputSection.h.

Referenced by InputSection::checkValid().

195 {}

◆ checkValid()

void checkValid ( )
private

Check validity of inputs.

This class just checks if required values_ are present and calls checkParticularValidity which the InputSection subtype should override.

Definition at line 307 of file InputSection.cpp.

References InputSection::checkParticularValidity(), error(), InputSection::has(), InputSection::required, and InputSection::section_name.

Referenced by InputSection::init(), and InputSection::readXML().

308 {
309  // check that all required inputs are present
310  for (auto& name : required)
311  if (!has(name))
312  {
313  std::stringstream error;
314  error << "InputSection::check_valid required variable " << name << " in " << section_name
315  << " has not been assigned\n";
316  throw UniformCommunicateError(error.str());
317  }
319 };
void error(char const *m)
Definition: Standard.h:204
virtual void checkParticularValidity()
Do validation for a particular subtype of InputSection Called by check_valid.
Definition: InputSection.h:195
std::unordered_set< std::string > required
Definition: InputSection.h:65
bool has(const std::string &name) const
Definition: InputSection.h:87
std::string section_name
"Name" of the input section, you must define this in the subtype and the ename, name, type, or method must match.
Definition: InputSection.h:57

◆ get()

T get ( const std::string &  name) const
inline

Definition at line 92 of file InputSection.h.

References InputSection::assignAnyEnum(), and InputSection::values_.

Referenced by SpaceGridInput::checkAxes(), SpaceGridInput::SpaceGridInput(), qmcplusplus::TEST_CASE(), and WalkerLogManager::WalkerLogManager().

93  {
94  if constexpr (std::is_enum<T>::value)
95  {
96  std::any any_enum = assignAnyEnum(name);
97  return std::any_cast<T>(any_enum);
98  }
99  else
100  {
101  try
102  {
103  return std::any_cast<T>(values_.at(name));
104  }
105  catch (...)
106  {
107  std::throw_with_nested(UniformCommunicateError("Could not access value with name " + name));
108  }
109  }
110  }
std::unordered_map< std::string, std::any > values_
Definition: InputSection.h:83
virtual std::any assignAnyEnum(const std::string &tag) const
Derived class overrides this to get proper assignment of scoped enum values.

◆ handleDelegate()

void handleDelegate ( const std::string &  ename,
const xmlNodePtr  element 
)
private

factor out delegate handling code for sanity.

Definition at line 69 of file InputSection.cpp.

References InputSection::assignValue(), and InputSection::delegate_factories_.

Referenced by InputSection::readXML().

70 {
71  assert(delegate_factories_.find(ename) != delegate_factories_.end());
72  std::string value_key;
73  std::any value = delegate_factories_[ename](element, value_key);
74 
75  assignValue(value_key, value);
76 }
std::unordered_map< std::string, std::function< std::any(xmlNodePtr cur, std::string &value_key)> > delegate_factories_
Definition: InputSection.h:80
void assignValue(const std::string &name, const T &value)
assign value into unordered map respecting values multiplicity It is a fatal exception to assign to a...

◆ has()

◆ has_default()

bool has_default ( const std::string &  name) const
inlineprivate

Definition at line 260 of file InputSection.h.

References InputSection::default_values.

260 { return default_values.find(name) != default_values.end(); }
std::unordered_map< std::string, std::any > default_values
Definition: InputSection.h:79

◆ init()

void init ( const std::unordered_map< std::string, std::any > &  init_values)

Definition at line 176 of file InputSection.cpp.

References InputSection::checkValid(), InputSection::setDefaults(), and InputSection::setFromValue().

Referenced by qmcplusplus::TEST_CASE().

177 {
178  // assign inputted values
179  for (auto& [name, value] : init_values)
180  setFromValue(name, value);
181 
182  // assign default values for optional variables
183  setDefaults();
184 
185  // check input validity
186  checkValid();
187  //report();
188 }
void setFromValue(const std::string &name, const std::any &svalue)
Coerce input collected via init into types matching the definition of the input types defined in the ...
void checkValid()
Check validity of inputs.

◆ isAttribute()

bool isAttribute ( const std::string &  name) const
inlineprivate

Definition at line 246 of file InputSection.h.

References InputSection::attributes.

Referenced by InputSection::readAttributes().

246 { return attributes.find(name) != attributes.end(); }
std::unordered_set< std::string > attributes
Definition: InputSection.h:62

◆ isBool()

bool isBool ( const std::string &  name) const
inlineprivate

Definition at line 255 of file InputSection.h.

References InputSection::bools.

Referenced by InputSection::report(), InputSection::setFromStream(), and InputSection::setFromValue().

255 { return bools.find(name) != bools.end(); }
std::unordered_set< std::string > bools
Definition: InputSection.h:70

◆ isCustom()

bool isCustom ( const std::string &  name) const
inlineprivate

Definition at line 259 of file InputSection.h.

References InputSection::custom.

Referenced by InputSection::readAttributes(), and InputSection::readXML().

259 { return custom.find(name) != custom.end(); }
std::unordered_set< std::string > custom
Definition: InputSection.h:74

◆ isDelegate()

bool isDelegate ( const std::string &  name) const
inlineprivate

Definition at line 247 of file InputSection.h.

References InputSection::delegates.

Referenced by InputSection::readXML().

247 { return delegates.find(name) != delegates.end(); }
std::unordered_set< std::string > delegates
Definition: InputSection.h:64

◆ isEnumString()

bool isEnumString ( const std::string &  name) const
inlineprivate

Definition at line 251 of file InputSection.h.

References InputSection::enums.

Referenced by InputSection::setFromStream(), and InputSection::setFromValue().

251 { return enums.find(name) != enums.end(); }
std::unordered_set< std::string > enums
list of enum inputs which allow a finite set of strings to map to enum values The enum class types an...
Definition: InputSection.h:78

◆ isInteger()

bool isInteger ( const std::string &  name) const
inlineprivate

Definition at line 256 of file InputSection.h.

References InputSection::integers.

Referenced by InputSection::report(), InputSection::setFromStream(), and InputSection::setFromValue().

256 { return integers.find(name) != integers.end(); }
std::unordered_set< std::string > integers
Definition: InputSection.h:71

◆ isMultiple()

bool isMultiple ( const std::string &  name) const
inlineprivate

Definition at line 250 of file InputSection.h.

References InputSection::multiple.

Referenced by InputSection::assignValue().

250 { return multiple.find(name) != multiple.end(); }
std::unordered_set< std::string > multiple
Definition: InputSection.h:66

◆ isMultiReal()

bool isMultiReal ( const std::string &  name) const
inlineprivate

Definition at line 254 of file InputSection.h.

References InputSection::multi_reals.

Referenced by InputSection::setFromStream(), and InputSection::setFromValue().

254 { return multi_reals.find(name) != multi_reals.end(); }
std::unordered_set< std::string > multi_reals
Definition: InputSection.h:69

◆ isMultiString()

bool isMultiString ( const std::string &  name) const
inlineprivate

Definition at line 253 of file InputSection.h.

References InputSection::multi_strings.

Referenced by InputSection::setFromStream(), and InputSection::setFromValue().

253 { return multi_strings.find(name) != multi_strings.end(); }
std::unordered_set< std::string > multi_strings
Definition: InputSection.h:68

◆ isParameter()

bool isParameter ( const std::string &  name) const
inlineprivate

Definition at line 248 of file InputSection.h.

References InputSection::parameters.

Referenced by InputSection::readXML().

248 { return parameters.find(name) != parameters.end(); }
std::unordered_set< std::string > parameters
Definition: InputSection.h:63

◆ isPosition()

bool isPosition ( const std::string &  name) const
inlineprivate

Definition at line 258 of file InputSection.h.

References InputSection::positions.

Referenced by InputSection::setFromStream(), and InputSection::setFromValue().

258 { return positions.find(name) != positions.end(); }
std::unordered_set< std::string > positions
Definition: InputSection.h:73

◆ isReal()

bool isReal ( const std::string &  name) const
inlineprivate

Definition at line 257 of file InputSection.h.

References InputSection::reals.

Referenced by InputSection::report(), InputSection::setFromStream(), and InputSection::setFromValue().

257 { return reals.find(name) != reals.end(); }
std::unordered_set< std::string > reals
Definition: InputSection.h:72

◆ isRequired()

bool isRequired ( const std::string &  name) const
inlineprivate

Definition at line 249 of file InputSection.h.

References InputSection::required.

249 { return required.find(name) != required.end(); }
std::unordered_set< std::string > required
Definition: InputSection.h:65

◆ isString()

bool isString ( const std::string &  name) const
inlineprivate

Definition at line 252 of file InputSection.h.

References InputSection::strings.

Referenced by InputSection::report(), InputSection::setFromStream(), and InputSection::setFromValue().

252 { return strings.find(name) != strings.end(); }
std::unordered_set< std::string > strings
Definition: InputSection.h:67

◆ lookupAnyEnum()

std::any lookupAnyEnum ( const std::string &  enum_name,
const std::string &  enum_value,
const std::unordered_map< std::string, std::any > &  enum_map 
)
staticprotected

Assign any enum helper for InputSection derived class assumes enum lookup table of this form: inline static const std::unordered_map<std::string, std::any> lookup_input_enum_value{{"integrator-uniform_grid", Integrator::UNIFORM_GRID}, {"integrator-uniform", Integrator::UNIFORM}, {"integrator-density", Integrator::DENSITY}, {"evaluator-loop", Evaluator::LOOP}, {"evaluator-matrix", Evaluator::MATRIX}};.

Definition at line 341 of file InputSection.cpp.

References qmcplusplus::lowerCase().

Referenced by ReferencePointsInput::ReferencePointsInputSection::assignAnyEnum(), TestInputSection::assignAnyEnum(), OneBodyDensityMatricesInput::OneBodyDensityMatricesInputSection::assignAnyEnum(), and MagnetizationDensityInput::MagnetizationDensityInputSection::assignAnyEnum().

344 {
345  std::string enum_value_str(lowerCase(enum_name + "-" + enum_value));
346  try
347  {
348  return enum_map.at(enum_value_str);
349  }
350  catch (std::out_of_range& oor_exc)
351  {
352  std::throw_with_nested(UniformCommunicateError("bad_enum_tag_value: " + enum_value_str));
353  }
354 }
std::string lowerCase(const std::string_view s)
++17

◆ operator=()

InputSection& operator= ( const InputSection other)
default

◆ readAttributes()

void readAttributes ( xmlNodePtr  cur,
const std::string &  element_name,
const std::vector< std::string > &  do_not_consume 
)
protected

reads attributes for both the root node and parameter/child nodes that aren't delegated.

Side effect only method updates values_.

Parameters
[in]curcurrent xml node
[in]element_namequalifying identifier with respect to the InputSection root node for the atttributes.
[in]do_not_consumedrop attributes used for element identification instead of the element name (this has complicated semantics in QMCPACK input) when a parameter has an ename="parameter" and the name attribute is used to identify the parameter we do not consume i.e. parse that name into the values_. If a top level section's indentifier is a name or type attribute we also need to avoid consuming it. Ideally any child node of significant complexity would be delegated to another input section.

Definition at line 33 of file InputSection.cpp.

References castXMLCharToChar(), error(), InputSection::isAttribute(), InputSection::isCustom(), qmcplusplus::lowerCase(), InputSection::section_name, InputSection::setFromStream(), and InputSection::setFromStreamCustom().

Referenced by InputSection::readXML().

36 {
37  xmlAttrPtr att = cur->properties;
38  while (att != NULL)
39  {
40  // unsafe att->name is an xmlChar, xmlChar is a UTF-8 byte
41  std::string name{lowerCase(castXMLCharToChar(att->name))};
42  // issue here is that we don't want to consume the name of the parameter as that has a special status in a parameter tag.
43  // This is due to the <parameter name="parameter_name> == <parameter_name> tag equivalence :(
44  std::string qualified_name{((element_name.size() > 0 && element_name != "parameter") ? (element_name + "::") : "") +
45  name};
46 
47  // Since parameters don't get a qualified name this will still prevent consumption of any of the do_not_consume attributes from them
48  if (std::any_of(do_not_consume.begin(), do_not_consume.end(), [&name](auto& dnc) { return name == dnc; }))
49  {
50  att = att->next;
51  continue;
52  }
53 
54  if (!isAttribute(qualified_name))
55  {
56  std::stringstream error;
57  error << "InputSection::readXML name " << name << " is not an attribute of " << section_name << "\n";
58  throw UniformCommunicateError(error.str());
59  }
60  std::istringstream stream(castXMLCharToChar(att->children->content));
61  if (isCustom(name))
62  setFromStreamCustom(element_name, qualified_name, stream);
63  else
64  setFromStream(qualified_name, stream);
65  att = att->next;
66  }
67 }
bool isCustom(const std::string &name) const
Definition: InputSection.h:259
void error(char const *m)
Definition: Standard.h:204
std::string lowerCase(const std::string_view s)
++17
char * castXMLCharToChar(xmlChar *c)
assign a value from a node. Use specialization for classes.
Definition: libxmldefs.h:62
bool isAttribute(const std::string &name) const
Definition: InputSection.h:246
void setFromStream(const std::string &name, std::istringstream &svalue)
std::string section_name
"Name" of the input section, you must define this in the subtype and the ename, name, type, or method must match.
Definition: InputSection.h:57
virtual void setFromStreamCustom(const std::string &ename, const std::string &name, std::istringstream &svalue)
Derived class can overrides this to do custom parsing of the element values for Custom elements These...

◆ readXML()

void readXML ( xmlNodePtr  cur)

Read variable values (initialize) from XML input, call checkValid.

Ideally this will always be called from the constructor of an input class the InputSection is defined in the scope of.

Definition at line 78 of file InputSection.cpp.

References castXMLCharToChar(), InputSection::checkValid(), error(), getXMLAttributeValue(), InputSection::handleDelegate(), InputSection::isCustom(), InputSection::isDelegate(), InputSection::isParameter(), qmcplusplus::lowerCase(), InputSection::readAttributes(), InputSection::section_name, InputSection::section_name_alternates, InputSection::setDefaults(), InputSection::setFromStream(), and InputSection::setFromStreamCustom().

Referenced by CSLocalEnergyInput::CSLocalEnergyInput(), LocalEnergyInput::LocalEnergyInput(), MagnetizationDensityInput::MagnetizationDensityInput(), MomentumDistributionInput::MomentumDistributionInput(), OneBodyDensityMatricesInput::OneBodyDensityMatricesInput(), PerParticleHamiltonianLoggerInput::PerParticleHamiltonianLoggerInput(), QMCDriverNew::putWalkerLogs(), ReferencePointsInput::ReferencePointsInput(), RMCLocalEnergyInput::RMCLocalEnergyInput(), SelfHealingOverlapInput::SelfHealingOverlapInput(), SpaceGridInput::SpaceGridAxisInput::SpaceGridAxisInput(), SpaceGridInput::SpaceGridInput(), SpaceGridInput::SpaceGridOriginInput::SpaceGridOriginInput(), qmcplusplus::TEST_CASE(), and WalkerLogInput::WalkerLogInput().

79 {
80  assert(cur != nullptr);
81  // For historical reasons that actual "type" of the element/input section is expressed in a very inconsistent way.
82  // It could be coded via the element name i.e. the tag, or at minimum a method, type, or name attribute.
83  std::string section_ename{lowerCase(castXMLCharToChar(cur->name))};
84  std::string section_method(lowerCase(getXMLAttributeValue(cur, "method")));
85  std::string section_type(lowerCase(getXMLAttributeValue(cur, "type")));
86  std::string section_name_actual(lowerCase(getXMLAttributeValue(cur, "name")));
87  // at anyrate one of these must match the section_name.
88  std::string lcase_section_name{lowerCase(section_name)};
89 
90  auto checkSectionName = [&section_name = section_name,
91  &section_name_alternates = section_name_alternates](auto& possible_sname) {
92  std::string lcase_section_name{lowerCase(section_name)};
93  if (possible_sname == lcase_section_name)
94  return true;
95  if (section_name_alternates.size() > 0)
96  return std::any_of(section_name_alternates.begin(), section_name_alternates.end(),
97  [&possible_sname](auto& name_alternate) {
98  std::string lcase_alternate{lowerCase(name_alternate)};
99  return possible_sname == lcase_alternate;
100  });
101  return false;
102  };
103 
104  if (!(checkSectionName(section_ename) || checkSectionName(section_method) || checkSectionName(section_type) ||
105  checkSectionName(section_name_actual)))
106  {
107  std::stringstream error;
108  error << "Input is invalid \"" << lcase_section_name << "\" does not match a defined input node!";
109  throw UniformCommunicateError(error.str());
110  }
111 
112  // these attributes don't get an element name passed to them because by convention we save and define them unqualified.
113  readAttributes(cur, "", {"type"});
114  // read parameters
115  xmlNodePtr element = cur->xmlChildrenNode;
116  while (element != NULL)
117  {
118  // ename is the "name" of the XML element i.e. <ename [attributes]>
119  std::string ename{lowerCase(castXMLCharToChar(element->name))};
120  // value of the elements attribute = name
121  std::string name(lowerCase(getXMLAttributeValue(element, "name")));
122  // we need both ename and name to figure out how to handle an element because of the <parameter name="actual_parameter"> pattern.
123  // If the name attribute isn't there it should equal the element name.
124  if (name.size() < 1)
125  name = ename;
126 
127  if (isDelegate(ename))
128  {
129  handleDelegate(ename, element);
130  }
131  else if (isCustom(ename))
132  {
133  std::istringstream stream(XMLNodeString{element});
134  setFromStreamCustom(ename, name, stream);
135  }
136  else if (ename == "parameter" || isParameter(ename))
137  {
138  if (ename == "parameter")
139  ename = name;
140  else
141  // We do this because the semantics of parameters are such that name can not have a unique value because
142  // if it did have one that the equivalence of <parameter_name> and <parameter name="parameter_name"> would
143  // be broken. Input code being ported could depend on this an an invariant.
144  name = ename;
145  if (!isParameter(ename))
146  {
147  std::stringstream error;
148  error << "InputSection::readXML name " << name << " is not a parameter of " << section_name << "\n";
149  throw UniformCommunicateError(error.str());
150  }
151 
152  std::istringstream stream(XMLNodeString{element});
153  setFromStream(name, stream);
154  readAttributes(element, name, {"name"});
155  }
156  else if (ename != "text")
157  {
158  std::stringstream error;
159  error << "InputSection::readXML node name " << ename << " is not handled by InputSection subtype " << section_name
160  << "\n";
161  throw UniformCommunicateError(error.str());
162  }
163  // else can't be an error case because this is how the whitespace text nodes
164  element = element->next;
165  }
166 
167  // assign default values for optional variables
168  setDefaults();
169 
170  // check input validity
171  checkValid();
172  //report();
173 }
void handleDelegate(const std::string &ename, const xmlNodePtr element)
factor out delegate handling code for sanity.
std::vector< std::string > section_name_alternates
For historical reasons some sections must recognize several different names. Assign them to this vari...
Definition: InputSection.h:60
bool isCustom(const std::string &name) const
Definition: InputSection.h:259
void error(char const *m)
Definition: Standard.h:204
void readAttributes(xmlNodePtr cur, const std::string &element_name, const std::vector< std::string > &do_not_consume)
reads attributes for both the root node and parameter/child nodes that aren&#39;t delegated.
bool isDelegate(const std::string &name) const
Definition: InputSection.h:247
std::string lowerCase(const std::string_view s)
++17
void checkValid()
Check validity of inputs.
char * castXMLCharToChar(xmlChar *c)
assign a value from a node. Use specialization for classes.
Definition: libxmldefs.h:62
std::string getXMLAttributeValue(const xmlNodePtr cur, const std::string_view name)
get the value string for attribute name if name is unfound in cur you get an empty string back this i...
void setFromStream(const std::string &name, std::istringstream &svalue)
convert xmlNode contents into a std::string
bool isParameter(const std::string &name) const
Definition: InputSection.h:248
std::string section_name
"Name" of the input section, you must define this in the subtype and the ename, name, type, or method must match.
Definition: InputSection.h:57
virtual void setFromStreamCustom(const std::string &ename, const std::string &name, std::istringstream &svalue)
Derived class can overrides this to do custom parsing of the element values for Custom elements These...

◆ registerDelegate()

void registerDelegate ( const std::string &  tag,
DelegateHandler  delegate_handler 
)
protected

register factory function for delegate input

Parameters
[in]tagparmater name or node ename delgation is controlled by
[in]delegate_handlerfactory function for delegated input function.

Definition at line 190 of file InputSection.cpp.

References InputSection::delegate_factories_.

Referenced by SpaceGridInput::SpaceGridInputSection::SpaceGridInputSection().

192 {
193  delegate_factories_[tag] = factory;
194 }
std::unordered_map< std::string, std::function< std::any(xmlNodePtr cur, std::string &value_key)> > delegate_factories_
Definition: InputSection.h:80

◆ report() [1/2]

void report ( ) const
protected

Definition at line 339 of file InputSection.cpp.

References qmcplusplus::app_log().

339 { report(app_log()); }
std::ostream & app_log()
Definition: OutputManager.h:65

◆ report() [2/2]

void report ( std::ostream &  out) const
protected

Definition at line 321 of file InputSection.cpp.

References InputSection::isBool(), InputSection::isInteger(), InputSection::isReal(), InputSection::isString(), InputSection::section_name, and InputSection::values_.

322 {
323  out << "\n" << section_name;
324  for (auto& [name, value] : values_)
325  {
326  out << "\n " << name << " = ";
327  if (isString(name))
328  out << std::any_cast<std::string>(value);
329  else if (isBool(name))
330  out << std::any_cast<bool>(value);
331  else if (isInteger(name))
332  out << std::any_cast<int>(value);
333  else if (isReal(name))
334  out << std::any_cast<Real>(value);
335  }
336  out << "\n\n";
337 }
bool isBool(const std::string &name) const
Definition: InputSection.h:255
bool isInteger(const std::string &name) const
Definition: InputSection.h:256
std::unordered_map< std::string, std::any > values_
Definition: InputSection.h:83
bool isString(const std::string &name) const
Definition: InputSection.h:252
bool isReal(const std::string &name) const
Definition: InputSection.h:257
std::string section_name
"Name" of the input section, you must define this in the subtype and the ename, name, type, or method must match.
Definition: InputSection.h:57

◆ reverseLookupInputEnumMap()

static std::string reverseLookupInputEnumMap ( ENUM_T  enum_val,
const std::unordered_map< std::string, std::any > &  enum_map 
)
inlinestatic

Get string represtation of enum class type value from enum_val.

work around the lack of a bidirectional std c++ map type.

Definition at line 148 of file InputSection.h.

Referenced by qmcplusplus::TEST_CASE().

150  {
151  std::string lookup_str = "not found";
152  for (const auto& enum_node : enum_map)
153  {
154  if (enum_node.second.type() == typeid(decltype(enum_val)) &&
155  enum_val == std::any_cast<decltype(enum_val)>(enum_node.second))
156  {
157  lookup_str = enum_node.first;
158  break;
159  }
160  }
161  return lookup_str;
162  }

◆ setDefaults()

void setDefaults ( )
private

Definition at line 196 of file InputSection.cpp.

References InputSection::default_values, InputSection::has(), and InputSection::setFromValue().

Referenced by InputSection::init(), and InputSection::readXML().

197 {
198  for (auto& [name, default_value] : default_values)
199  if (!has(name))
200  setFromValue(name, default_value);
201 }
void setFromValue(const std::string &name, const std::any &svalue)
Coerce input collected via init into types matching the definition of the input types defined in the ...
std::unordered_map< std::string, std::any > default_values
Definition: InputSection.h:79
bool has(const std::string &name) const
Definition: InputSection.h:87

◆ setFromStream()

void setFromStream ( const std::string &  name,
std::istringstream &  svalue 
)
private

Definition at line 203 of file InputSection.cpp.

References InputSection::assignValue(), error(), InputSection::isBool(), InputSection::isEnumString(), InputSection::isInteger(), InputSection::isMultiReal(), InputSection::isMultiString(), InputSection::isPosition(), InputSection::isReal(), InputSection::isString(), and InputSection::section_name.

Referenced by InputSection::readAttributes(), and InputSection::readXML().

204 {
205  if (isString(name) || isEnumString(name))
206  {
207  std::string value;
208  svalue >> value;
209  assignValue(name, value);
210  }
211  else if (isMultiString(name))
212  {
213  std::vector<std::string> string_values;
214  for (std::string value; svalue >> value;)
215  string_values.push_back(value);
216  assignValue(name, string_values);
217  }
218  else if (isMultiReal(name))
219  {
220  std::vector<Real> real_values;
221  for (Real value; svalue >> value;)
222  real_values.push_back(static_cast<Real>(value));
223  assignValue(name, real_values);
224  }
225  else if (isBool(name))
226  {
227  std::string sval;
228  svalue >> sval;
229  bool value = sval == "yes" || sval == "true" || sval == "1";
230  assignValue(name, value);
231  }
232  else if (isInteger(name))
233  {
234  int value;
235  svalue >> value;
236  assignValue(name, value);
237  }
238  else if (isReal(name))
239  {
240  Real value;
241  svalue >> value;
242  assignValue(name, Real(value));
243  }
244  else if (isPosition(name))
245  {
246  Position value;
247  svalue >> value;
248  assignValue(name, value);
249  }
250  else
251  {
252  std::stringstream error;
253  error << "InputSection::set_from_stream name " << name << " in " << section_name << " does not have a type\n";
254  throw UniformCommunicateError(error.str());
255  }
256 }
bool isBool(const std::string &name) const
Definition: InputSection.h:255
QMCTraits::FullPrecRealType Real
Definition: InputSection.h:40
void error(char const *m)
Definition: Standard.h:204
bool isEnumString(const std::string &name) const
Definition: InputSection.h:251
bool isMultiReal(const std::string &name) const
Definition: InputSection.h:254
typename QMCTypes< Real, OHMMS_DIM >::PosType Position
Definition: InputSection.h:41
bool isInteger(const std::string &name) const
Definition: InputSection.h:256
void assignValue(const std::string &name, const T &value)
assign value into unordered map respecting values multiplicity It is a fatal exception to assign to a...
bool isString(const std::string &name) const
Definition: InputSection.h:252
bool isPosition(const std::string &name) const
Definition: InputSection.h:258
bool isMultiString(const std::string &name) const
Definition: InputSection.h:253
bool isReal(const std::string &name) const
Definition: InputSection.h:257
std::string section_name
"Name" of the input section, you must define this in the subtype and the ename, name, type, or method must match.
Definition: InputSection.h:57

◆ setFromStreamCustom()

void setFromStreamCustom ( const std::string &  ename,
const std::string &  name,
std::istringstream &  svalue 
)
protectedvirtual

Derived class can overrides this to do custom parsing of the element values for Custom elements These can have a name attribute only.

Parameters
[in]enamename of the element svalue comes from, top level attributes do not have ename.
[in]namename of the attribute
[in]svalueinput stream consisting of the contents of one element. It is expected that your custom stream handler will consume this entirely.

Reimplemented in CustomTestInput, and SpaceGridInput::SpaceGridAxisInput::SpaceGridAxisInputSection.

Definition at line 25 of file InputSection.cpp.

Referenced by InputSection::readAttributes(), and InputSection::readXML().

28 {
29  throw UniformCommunicateError("derived class must provide handleCustom method if custom parameters are used");
30 }

◆ setFromValue()

void setFromValue ( const std::string &  name,
const std::any &  svalue 
)
private

Coerce input collected via init into types matching the definition of the input types defined in the InputSection subtype constructor.

Definition at line 276 of file InputSection.cpp.

References InputSection::assignValue(), error(), InputSection::isBool(), InputSection::isEnumString(), InputSection::isInteger(), InputSection::isMultiReal(), InputSection::isMultiString(), InputSection::isPosition(), InputSection::isReal(), InputSection::isString(), and InputSection::section_name.

Referenced by InputSection::init(), and InputSection::setDefaults().

277 {
278  try
279  {
280  if (isString(name) || isEnumString(name))
281  assignValue(name, std::any_cast<std::string>(value));
282  else if (isMultiString(name))
283  assignValue(name, std::any_cast<std::vector<std::string>>(value));
284  else if (isMultiReal(name))
285  assignValue(name, std::any_cast<std::vector<std::string>>(value));
286  else if (isBool(name))
287  assignValue(name, std::any_cast<bool>(value));
288  else if (isInteger(name))
289  assignValue(name, std::any_cast<int>(value));
290  else if (isReal(name))
291  assignValue(name, std::any_cast<Real>(value));
292  else if (isPosition(name))
293  assignValue(name, std::any_cast<Position>(value));
294  else
295  {
296  std::stringstream error;
297  error << "InputSection::set_from_value name " << name << " in " << section_name << " does not have a type\n";
298  throw UniformCommunicateError(error.str());
299  }
300  }
301  catch (const std::bad_cast& exc)
302  {
303  std::throw_with_nested(UniformCommunicateError("std::any_cast failed in setFromValue for name:" + name));
304  }
305 }
bool isBool(const std::string &name) const
Definition: InputSection.h:255
void error(char const *m)
Definition: Standard.h:204
bool isEnumString(const std::string &name) const
Definition: InputSection.h:251
bool isMultiReal(const std::string &name) const
Definition: InputSection.h:254
bool isInteger(const std::string &name) const
Definition: InputSection.h:256
void assignValue(const std::string &name, const T &value)
assign value into unordered map respecting values multiplicity It is a fatal exception to assign to a...
bool isString(const std::string &name) const
Definition: InputSection.h:252
bool isPosition(const std::string &name) const
Definition: InputSection.h:258
bool isMultiString(const std::string &name) const
Definition: InputSection.h:253
bool isReal(const std::string &name) const
Definition: InputSection.h:257
std::string section_name
"Name" of the input section, you must define this in the subtype and the ename, name, type, or method must match.
Definition: InputSection.h:57

◆ setIfInInput()

template bool setIfInInput< ReferencePointsInput::Coord > ( T &  var,
const std::string &  tag 
)
inline

set var if input section has read the tag

Parameters
[out]varexternal variable to be set if tag was defined
[in]tagstring tag of value could be parameter or atttribute name
Returns
whether input section has tag

use this is you prefer have native c++ types for input class members as well as set default via native c++ declaration. See OneBodyDensityMatricesInput for example.

Definition at line 122 of file InputSection.h.

References InputSection::has().

Referenced by MomentumDistributionInput::MomentumDistributionInput().

123  {
124  if (has(tag))
125  {
126  var = get<T>(tag);
127  return true;
128  }
129  else
130  return false;
131  }
bool has(const std::string &name) const
Definition: InputSection.h:87

Member Data Documentation

◆ attributes

◆ bools

◆ custom

std::unordered_set<std::string> custom
protected

◆ default_values

◆ delegate_factories_

std::unordered_map<std::string, std::function<std::any(xmlNodePtr cur, std::string& value_key)> > delegate_factories_
protected

Definition at line 80 of file InputSection.h.

Referenced by InputSection::handleDelegate(), and InputSection::registerDelegate().

◆ delegates

std::unordered_set<std::string> delegates
protected

◆ enums

◆ integers

◆ multi_reals

std::unordered_set<std::string> multi_reals
protected

Definition at line 69 of file InputSection.h.

Referenced by InputSection::isMultiReal(), and TestInputSection::TestInputSection().

◆ multi_strings

◆ multiple

std::unordered_set<std::string> multiple
protected

◆ parameters

◆ positions

◆ reals

◆ required

◆ section_name

std::string section_name
protected

"Name" of the input section, you must define this in the subtype and the ename, name, type, or method must match.

Definition at line 57 of file InputSection.h.

Referenced by InputSection::assignValue(), InputSection::checkValid(), CSLocalEnergyInput::CSLocalEnergyInputSection::CSLocalEnergyInputSection(), LocalEnergyInput::LocalEnergyInputSection::LocalEnergyInputSection(), MagnetizationDensityInput::MagnetizationDensityInputSection::MagnetizationDensityInputSection(), MomentumDistributionInput::MomentumDistributionInputSection::MomentumDistributionInputSection(), OneBodyDensityMatricesInput::OneBodyDensityMatricesInputSection::OneBodyDensityMatricesInputSection(), PerParticleHamiltonianLoggerInput::PerParticleHamiltonianLoggerInputSection::PerParticleHamiltonianLoggerInputSection(), InputSection::readAttributes(), InputSection::readXML(), ReferencePointsInput::ReferencePointsInputSection::ReferencePointsInputSection(), InputSection::report(), RMCLocalEnergyInput::RMCLocalEnergyInputSection::RMCLocalEnergyInputSection(), SelfHealingOverlapInput::SelfHealingOverlapInputSection::SelfHealingOverlapInputSection(), InputSection::setFromStream(), InputSection::setFromValue(), SpaceGridInput::SpaceGridAxisInput::SpaceGridAxisInputSection::SpaceGridAxisInputSection(), SpaceGridInput::SpaceGridInputSection::SpaceGridInputSection(), SpaceGridInput::SpaceGridOriginInput::SpaceGridOriginInputSection::SpaceGridOriginInputSection(), TestAssignAnyEnum::TestAssignAnyEnum(), TestInputSection::TestInputSection(), and WalkerLogInput::WalkerLogInput().

◆ section_name_alternates

std::vector<std::string> section_name_alternates
protected

For historical reasons some sections must recognize several different names. Assign them to this variable in your subtype.

Definition at line 60 of file InputSection.h.

Referenced by LocalEnergyInput::LocalEnergyInputSection::LocalEnergyInputSection(), InputSection::readXML(), and RMCLocalEnergyInput::RMCLocalEnergyInputSection::RMCLocalEnergyInputSection().

◆ strings

◆ values_

std::unordered_map<std::string, std::any> values_
protected

The documentation for this class was generated from the following files: