opm-core/opm/core/utility/parameters/ParameterGroup.hpp
Markus Blatt 52b40c9477 Allow to prevent ParameterGroup from printing to std::cout.
This commit adds a verbose flag to the constructor of
ParameterGroup to allow for deactivating any
output to std:cout. This is handy for parallel runs where we only
want to print statistics on one process.
2015-05-08 11:13:30 +02:00

309 lines
13 KiB
C++

//===========================================================================
//
// File: ParameterGroup.hpp
//
// Created: Tue Jun 2 19:11:11 2009
//
// Author(s): Bård Skaflestad <bard.skaflestad@sintef.no>
// Atgeirr F Rasmussen <atgeirr@sintef.no>
//
// $Date$
//
// $Revision$
//
//===========================================================================
/*
Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
Copyright 2009, 2010 Statoil ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPM_PARAMETERGROUP_HEADER
#define OPM_PARAMETERGROUP_HEADER
#include <exception>
#include <map>
#include <string>
#include <vector>
#include <memory>
#include <opm/core/utility/parameters/ParameterMapItem.hpp>
#include <opm/core/utility/parameters/ParameterRequirement.hpp>
namespace Opm {
namespace parameter {
/// ParameterGroup is a class that is used to provide run-time parameters.
/// The standard use of the class is to call create it with the
/// (int argc, char** argv) constructor (where the arguments are those
/// given by main). This parses the command line, where each token
/// either
/// A) specifies a parameter (by a "param=value" token).
/// B) specifies a xml file to be read (by a "filename.xml" token).
/// C) specifies a param file to be read (by a "filename.param" token).
/// After the tokens are parsed they are stored in a tree structure
/// in the ParameterGroup object; it is worth mentioning that parameters
/// are inherited in this tree structure. Thus, if ``grid\_prefix'' is
/// given a value in the root node, this value will be visible in all
/// parts of the tree (unless the parameter is overwritten in a subtree).
/// Applications using this ParameterGroup objects will usually write out
/// a message for each node in the three that is used by the application;
/// this is one way to determine valid parameters.
///
/// Parameters specified as "param=value" on the command line
///
/// To specify a parameter on the command line, you must know where in the tree the
/// parameter resides. The syntax for specifying parameters on the command line given
/// an application called ``simulator'' is
/// simulator param1=value grp/param2=value
// for parameter ``param1'' lying at the root and ``param2'' in the group
/// ``grp''. If the same parameters are specified multiple times on the command
/// line, only the last will be used. Thus an application named ``simulator'' run with
/// the following command
/// simulator param=value1 param=value2
/// will use value2 as the value of ``param''.
///
/// XML parameters
///
/// In the introduction to this section it was mentioned that the parameters for
/// the simulator are organized in a tree structure. This is mirrored in the XML
/// file by the use of groups; a group is a collection of parameters and subgroups
/// enclosed by a \fixed{<ParameterGroup>}-\fixed{</ParameterGroup>} pair. The only
/// attribute of relevance in a \fixed{ParameterGroup} tag is that of \fixed{name},
/// which is used to navigate in the tree.
/// The actual parameters are specified by the \fixed{<Parameter />} tag. Each
/// parameter has three attributes: \fixed{name}, \fixed{type}, and \fixed{value}.
/// Both name and value should be evident. Type is one of \fixed{bool} (for things
/// that are either true or false), \fixed{int} (for integers), \fixed{double} (for
/// floating point numbers with double precision), \fixed{string} (for text
/// strings), or \fixed{file} (for files and directories relative to the location
/// of the XML file).
///
/// param files
///
/// A param file consists of multiple lienes, where each line consists of "param=value".
/// This syntax is identical to the one for paramters specified on the command line.
///
///
/// If one combines both XML files and parameters, one should note that that if a parameter
/// is specified on the command line is also found in a XML file, the parameter
/// specified on the command line is the one used. Thus, if ``parameters.xml''
/// specifies that ``stepsize'' is 2.71828 while, the command used to run the
/// application ``simulator'' is
/// simulator stepsize=3.14159 parameters.xml
/// the simulator will run with ``stepsize'' equal to 3.14159.
///
class ParameterGroup : public ParameterMapItem {
public:
struct NotFoundException : public std::exception {};
struct WrongTypeException : public std::exception {};
struct ConversionFailedException : public std::exception {};
template<typename T>
struct RequirementFailedException : public std::exception {};
ParameterGroup();
ParameterGroup(const std::string& path, const ParameterGroup* parent,
const bool enable_output);
// From ParameterMapItem
virtual ~ParameterGroup();
virtual std::string getTag() const;
/// \brief A constructor typically used to initialize a
/// ParameterGroup from command-line arguments.
///
/// It is required that argv[0] is the program name, while if
/// 0 < i < argc, then argv[i] is either
/// the name of an xml file, parameter file or parametername=value.
///
/// \param argc is the number of command-line arguments,
/// including the name of the executable.
/// \param argv is an array of char*, each of which is a
/// command line argument.
/// \param verify_syntax If true (default), then it is an error to
/// pass arguments that cannot be handled by the ParameterGroup,
/// or an empty argument list. If false, such arguments are stored
/// and can be retrieved later with unhandledArguments().
/// \param enable_output Whether to enable output or not.
template <typename StringArray>
ParameterGroup(int argc, StringArray argv, const bool verify_syntax = true,
const bool enabled_output=true);
/// \brief This method checks if there is something with name
/// \p name in the parameter gropup.
///
/// \param name is the name of the parameter.
/// \return true if \p name is the name of something in the parameter
/// group, false otherwise.
bool has(const std::string& name) const;
/// \brief This method is used to read a parameter from the
/// parameter group.
///
/// NOTE: If the reading of the parameter fails, then this method
/// throws an appropriate exception.
///
/// \param name is the name of the parameter in question.
/// \return The value associated with then name in this parameter
/// group.
template<typename T>
T get(const std::string& name) const;
template<typename T, class Requirement>
T get(const std::string& name, const Requirement&) const;
/// \brief This method is used to read a parameter from the
/// parameter group.
///
/// NOTE: If the reading of the parameter fails, then either
/// a) this method returns \p default_value if there
/// was no parameter with name \p name in
/// the parameter group
/// or
/// b) this method throws an appropriate exception.
///
/// \param name is the name of the parameter in question.
/// \param default_value the default value of the parameter in
/// question.
/// \return The value associated with this name in this parameter
/// group.
template<typename T>
T getDefault(const std::string& name,
const T& default_value) const;
template<typename T, class Requirement>
T getDefault(const std::string& name,
const T& default_value,
const Requirement& r) const;
/// \brief This method returns the parameter group given by name,
/// i.e. it is an alias of get<ParameterGroup>().
///
/// \param name is the name of the parameter group sought.
/// \return the parameter group sought.
ParameterGroup getGroup(const std::string& name) const;
/// \brief Disables the output from get, getDefault and getGroup.
/// By default, such output is enabled.
void disableOutput();
/// \brief Enables the output from get, getDefault and getGroup.
/// By default, such output is enabled.
void enableOutput();
/// \brief Returs true if and only if output from get, getDefault
/// and getGroup is enabled.
///
/// \return true if and only if output from get, getDefault and
/// getGroup is enabled.
bool isOutputEnabled() const;
/// \brief Reads the contents of the xml file specified by
/// xml_filename into this ParameterGroup.
///
/// \param xml_filename is the name of a xml file.
void readXML(const std::string& xml_filename);
/// \brief Reads the contents of the param file specified by
/// param_filename into this ParameterGroup.
///
/// NOTE: A param file contains lines on the form 'a/b/c=d'.
// The '/' separates ParameterGroups and Parameters
/// (e.g. c is a Parameter in the ParameterGroup b,
/// and b is a ParameterGroup in the ParameterGroup a)
/// while '=' separates the name from the value (e.g. the
/// value of the parameter c above will be d).
/// NOTE: A param file does not store any type information about
/// its values.
///
/// \param param_filename is the name of a param file.
void readParam(const std::string& param_filename);
/// \brief Writes this ParameterGroup into a param file
/// specified by param_filename.
///
/// \param param_filename is the name of a param file.
void writeParam(const std::string& param_filename) const;
/// \brief Writes this ParameterGroup to a stream.
///
/// \param stream is the stream to write to.
void writeParamToStream(std::ostream& stream) const;
/// vki param interface - deprecated
template<typename T>
void get(const char* name, T& value, const T& default_value) const {
value = this->getDefault<T>(name, default_value);
}
/// vki param interface - deprecated
template<typename T>
void get(const char* name, T& value) const {
value = this->get<T>(name);
}
/// \brief Return true if any parameters are unused.
bool anyUnused() const;
/// \brief Shows which parameters which are used or unused.
void displayUsage(bool used_params = false) const;
/// \brief Returns the path of the parameter group.
std::string path() const;
/// Insert a new item into the group.
void insert(const std::string& name,
const std::shared_ptr<ParameterMapItem>& data);
/// Insert a new parameter item into the group.
void insertParameter(const std::string& name, const std::string& value);
/// Unhandled arguments from command line parsing.
const std::vector<std::string>& unhandledArguments() const;
private:
typedef std::shared_ptr<ParameterMapItem> data_type;
typedef std::pair<std::string, data_type> pair_type;
typedef std::map<std::string, data_type> map_type;
std::string path_;
map_type map_;
const ParameterGroup* parent_;
bool output_is_enabled_;
std::vector<std::string> unhandled_arguments_;
template<typename T, class Requirement>
T translate(const pair_type& data, const Requirement& chk) const;
template <typename StringArray>
void parseCommandLineArguments(int argc, StringArray argv, bool verify_syntax);
void recursiveSetIsOutputEnabled(bool output_is_enabled);
// helper routines to do textual I/O
template <typename T>
static std::string to_string(const T& val);
static std::pair<std::string, std::string>
filename_split(const std::string& filename);
};
} // namespace parameter
} // namespace Opm
#include <opm/core/utility/parameters/ParameterGroup_impl.hpp>
#endif // OPM_PARAMETERGROUP_HEADER