ParameterGroup_impl.hpp
Go to the documentation of this file.
1 //===========================================================================
2 //
3 // File: ParameterGroup_impl.hpp
4 //
5 // Created: Tue Jun 2 19:06:46 2009
6 //
7 // Author(s): Bård Skaflestad <bard.skaflestad@sintef.no>
8 // Atgeirr F Rasmussen <atgeirr@sintef.no>
9 //
10 // $Date$
11 //
12 // $Revision$
13 //
14 //===========================================================================
15 
16 /*
17  Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
18  Copyright 2009, 2010 Statoil ASA.
19 
20  This file is part of the Open Porous Media project (OPM).
21 
22  OPM is free software: you can redistribute it and/or modify
23  it under the terms of the GNU General Public License as published by
24  the Free Software Foundation, either version 3 of the License, or
25  (at your option) any later version.
26 
27  OPM is distributed in the hope that it will be useful,
28  but WITHOUT ANY WARRANTY; without even the implied warranty of
29  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30  GNU General Public License for more details.
31 
32  You should have received a copy of the GNU General Public License
33  along with OPM. If not, see <http://www.gnu.org/licenses/>.
34 */
35 
36 #ifndef OPM_PARAMETERGROUP_IMPL_HEADER
37 #define OPM_PARAMETERGROUP_IMPL_HEADER
38 
39 #include <iostream>
40 #include <string>
41 #include <stdexcept>
42 
47 #include <opm/common/ErrorMacros.hpp>
48 
49 namespace Opm {
50  namespace parameter {
51 
52  template<>
54  static ParameterGroup
56  std::string& conversion_error,
57  bool enable_output)
58  {
59  std::string tag = item.getTag();
60  if (tag != ID_xmltag__param_grp) {
61  conversion_error = "The XML tag was '" + tag +
62  "' but should be '" +
63  ID_xmltag__param_grp + "'.\n";
64  return ParameterGroup("", 0, enable_output);
65  }
66  conversion_error = "";
67  const ParameterGroup& pg = dynamic_cast<const ParameterGroup&>(item);
68  return pg;
69  }
70  static std::string type() {return "ParameterGroup";}
71  };
72 
73  template <typename T>
74  inline std::string
75  ParameterGroup::to_string(const T& val)
76  {
77  std::ostringstream os;
78  os << val;
79  return os.str();
80  }
81 
82  template <>
83  inline std::string
84  ParameterGroup::to_string(const bool& b) {
85  if (b) {
86  return ID_true;
87  } else {
88  return ID_false;
89  }
90  }
91 
92  template <>
93  inline std::string
94  ParameterGroup::to_string(const ParameterGroup&)
95  {
96  return std::string("<parameter group>");
97  }
98 
99  inline std::pair<std::string, std::string>
100  ParameterGroup::filename_split(const std::string& filename)
101  {
102  int fpos = filename.rfind('.');
103  std::string name = filename.substr(0, fpos);
104  std::string type = filename.substr(fpos+1);
105  return std::make_pair(name, type);
106  }
107 
108  template <typename StringArray>
109  ParameterGroup::ParameterGroup(int argc, StringArray argv, bool verify_syntax,
110  const bool enable_output)
111  : path_(ID_path_root), parent_(0), output_is_enabled_(enable_output)
112  {
113  if (verify_syntax && (argc < 2)) {
114  std::cerr << "Usage: " << argv[0] << " "
115  << "[paramfilename1.{xml,param}] "
116  << "[paramfilename2.{xml,param}] "
117  << "[overridden_arg1=value1] "
118  << "[overridden_arg2=value2] "
119  << "[...]" << std::endl;
120  exit(EXIT_FAILURE);
121  }
122  this->parseCommandLineArguments(argc, argv, verify_syntax);
123  }
124 
125  template <typename StringArray>
126  void ParameterGroup::parseCommandLineArguments(int argc, StringArray argv, bool verify_syntax)
127  {
128  std::vector<std::string> files;
129  std::vector<std::pair<std::string, std::string> > assignments;
130  for (int i = 1; i < argc; ++i) {
131  std::string arg(argv[i]);
132  int fpos = arg.find(ID_delimiter_assignment);
133  if (fpos == int(std::string::npos)) {
134  std::string filename = arg.substr(0, fpos);
135  files.push_back(filename);
136  continue;
137  }
138  int pos = fpos + ID_delimiter_assignment.size();
139  int spos = arg.find(ID_delimiter_assignment, pos);
140  if (spos == int(std::string::npos)) {
141  std::string name = arg.substr(0, fpos);
142  std::string value = arg.substr(pos, spos);
143  assignments.push_back(std::make_pair(name, value));
144  continue;
145  }
146  std::cout << "WARNING: Too many assignements (' "
148  << "') detected in argument " << i << ".\n";
149  }
150  for (int i = 0; i < int(files.size()); ++i) {
151  std::pair<std::string, std::string> file_type = filename_split(files[i]);
152  if (file_type.second == "xml") {
153  this->readXML(files[i]);
154  } else if (file_type.second == "param") {
155  this->readParam(files[i]);
156  } else {
157  if (verify_syntax) {
158  std::cerr << "ERROR: Input '" << files[i] << "' is not a valid name for a parameter file.\n";
159  std::cerr << " Valid filename extensions are 'xml' and 'param'.\n";
160  OPM_THROW(std::runtime_error, "ParameterGroup cannot handle argument: " << files[i]);
161  } else {
162  unhandled_arguments_.push_back(files[i]);
163  }
164  }
165  }
166  for (int i = 0; i < int(assignments.size()); ++i) {
167  this->insertParameter(assignments[i].first, assignments[i].second);
168  }
169  }
170 
171 
172  template<typename T>
173  inline T ParameterGroup::get(const std::string& name) const
174  {
175  return this->get<T>(name, ParameterRequirementNone());
176  }
177 
178  template<typename T, class Requirement>
179  inline T ParameterGroup::get(const std::string& name,
180  const Requirement& r) const
181  {
182  setUsed();
183  std::pair<std::string, std::string> name_path = split(name);
184  map_type::const_iterator it = map_.find(name_path.first);
185  if (it == map_.end()) {
186  if (parent_ != 0) {
187  // If we have a parent, ask it instead.
188  if (output_is_enabled_) {
189  //TermColors::Red();
190  std::cout << name;
191  //TermColors::Normal();
192  std::cout << " not found at "
193  << (path() + ID_delimiter_path)
194  << ", asking parent." << std::endl;
195  }
196  return parent_->get<T>(name, r);
197  } else {
198  // We are at the top, name has not been found.
199  std::cerr << "ERROR: The group '"
200  << this->path()
201  << "' does not contain an element named '"
202  << name
203  << "'.\n";
204  throw NotFoundException();
205  }
206  }
207  if (name_path.second == "") {
208  T val = this->translate<T>(*it, r);
209  it->second->setUsed();
210  if (output_is_enabled_) {
211  //TermColors::Green();
212  std::cout << name;
213  //TermColors::Normal();
214  std::cout << " found at " << (path() + ID_delimiter_path)
215  << ", value is " << to_string(val) << std::endl;
216  }
217  return val;
218  } else {
219  ParameterGroup& pg = dynamic_cast<ParameterGroup&>(*(*it).second);
220  pg.setUsed();
221  return pg.get<T>(name_path.second, r);
222  }
223  }
224 
225  template<typename T>
226  inline T ParameterGroup::getDefault(const std::string& name,
227  const T& default_value) const
228  {
229  return this->getDefault<T>(name, default_value, ParameterRequirementNone());
230  }
231 
232  template<typename T, class Requirement>
233  inline T ParameterGroup::getDefault(const std::string& name,
234  const T& default_value,
235  const Requirement& r) const
236  {
237  setUsed();
238  std::pair<std::string, std::string> name_path = split(name);
239  map_type::const_iterator it = map_.find(name_path.first);
240  if (it == map_.end()) {
241  if (parent_ != 0) {
242  // If we have a parent, ask it instead.
243  if (output_is_enabled_) {
244  //TermColors::Red();
245  std::cout << name;
246  //TermColors::Normal();
247  std::cout << " not found at " << (path() + ID_delimiter_path)
248  << ", asking parent." << std::endl;
249  }
250  return parent_->getDefault<T>(name, default_value, r);
251  } else {
252  // We check the requirement for the default value
253  std::string requirement_result = r(default_value);
254  if (requirement_result != "") {
255  std::cerr << "ERROR: The default value for the "
256  << " element named '"
257  << name
258  << "' in the group '"
259  << this->path()
260  << "' failed to meet a requirenemt.\n";
261  std::cerr << "The requirement enforcer returned the following message:\n"
262  << requirement_result
263  << "\n";
265  }
266  }
267  if (output_is_enabled_) {
268  //TermColors::Blue();
269  std::cout << name;
270  //TermColors::Normal();
271  std::cout << " not found. Using default value '"
272  << to_string(default_value) << "'." << std::endl;
273  }
274  return default_value;
275  }
276  if (name_path.second == "") {
277  T val = this->translate<T>(*it, r);
278  it->second->setUsed();
279  if (output_is_enabled_) {
280  //TermColors::Green();
281  std::cout << name;
282  //TermColors::Normal();
283  std::cout << " found at " << (path() + ID_delimiter_path)
284  << ", value is '" << to_string(val) << "'." << std::endl;
285  }
286  return val;
287  } else {
288  ParameterGroup& pg = dynamic_cast<ParameterGroup&>(*(*it).second);
289  pg.setUsed();
290  return pg.getDefault<T>(name_path.second, default_value, r);
291  }
292  }
293 
294  template<typename T, class Requirement>
295  inline T ParameterGroup::translate(const pair_type& named_data,
296  const Requirement& chk) const
297  {
298  const std::string& name = named_data.first;
299  const data_type data = named_data.second;
300  std::string conversion_error;
301  T value = ParameterMapItemTrait<T>::convert(*data, conversion_error,
302  output_is_enabled_);
303  if (conversion_error != "") {
304  std::cerr << "ERROR: Failed to convert the element named '"
305  << name
306  << "' in the group '"
307  << this->path()
308  << "' to the type '"
310  << "'.\n";
311  std::cerr << "The conversion routine returned the following message:\n"
312  << conversion_error
313  << "\n";
314  throw WrongTypeException();
315  }
316  std::string requirement_result = chk(value);
317  if (requirement_result != "") {
318  std::cerr << "ERROR: The element named '"
319  << name
320  << "' in the group '"
321  << this->path()
322  << "' of type '"
324  << "' failed to meet a requirenemt.\n";
325  std::cerr << "The requirement enforcer returned the following message:\n"
326  << requirement_result
327  << "\n";
328  throw RequirementFailedException<Requirement>();
329  }
330  return value;
331  }
332  } // namespace parameter
333 } // namespace Opm
334 
335 #endif // OPM_PARAMETERGROUP_IMPL_HEADER
Definition: ParameterRequirement.hpp:52
std::pair< std::string, std::string > split(const std::string &name)
static ParameterGroup convert(const ParameterMapItem &item, std::string &conversion_error, bool enable_output)
Definition: ParameterGroup_impl.hpp:55
Definition: AnisotropicEikonal.hpp:43
Definition: ParameterGroup.hpp:109
void readXML(const std::string &xml_filename)
Reads the contents of the xml file specified by xml_filename into this ParameterGroup.
T getDefault(const std::string &name, const T &default_value) const
This method is used to read a parameter from the parameter group.
Definition: ParameterGroup_impl.hpp:226
const std::string ID_false
Definition: ParameterStrings.hpp:44
void setUsed() const
Definition: ParameterMapItem.hpp:58
T get(const std::string &name) const
This method is used to read a parameter from the parameter group.
Definition: ParameterGroup_impl.hpp:173
Definition: ParameterGroup.hpp:111
virtual std::string getTag() const =0
This function returns a string describing the ParameterMapItem.
Definition: ParameterMapItem.hpp:48
const std::string ID_delimiter_assignment
Definition: ParameterStrings.hpp:67
const double second
Definition: Units.hpp:93
void readParam(const std::string &param_filename)
Reads the contents of the param file specified by param_filename into this ParameterGroup.
std::string path() const
Returns the path of the parameter group.
Definition: ParameterMapItem.hpp:65
const std::string ID_true
Definition: ParameterStrings.hpp:43
const std::string ID_path_root
Definition: ParameterStrings.hpp:64
const std::string ID_delimiter_path
Definition: ParameterStrings.hpp:65
void insertParameter(const std::string &name, const std::string &value)
Insert a new parameter item into the group.
static std::string type()
Definition: ParameterGroup_impl.hpp:70
const std::string ID_xmltag__param_grp
Definition: ParameterStrings.hpp:46
static T convert(const ParameterMapItem &, std::string &conversion_error)