ParameterSet.h
1 /*
2  * MoMEMta: a modular implementation of the Matrix Element Method
3  * Copyright (C) 2016 Universite catholique de Louvain (UCL), Belgium
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 
20 #pragma once
21 
22 #include <map>
23 #include <memory>
24 #include <string>
25 
26 #include <momemta/any.h>
27 #include <momemta/InputTag.h>
28 #include <momemta/impl/traits.h>
29 #include <momemta/Logging.h>
30 #include <momemta/Utils.h>
31 
32 struct InputTag;
34 class Configuration;
35 class ParameterSet;
36 
37 namespace momemta {
38 struct ArgDef;
39 void setInputTagsForInput(const ArgDef&, ParameterSet&, const std::vector<InputTag>&);
40 class ComputationGraph;
41 }
42 
82 class ParameterSet {
83  public:
84  ParameterSet() = default;
85 
86  template<typename T> const T& get(const std::string& name) const {
87  auto value = m_set.find(name);
88  if (value == m_set.end())
89  throw not_found_error("Parameter '" + name + "' not found.");
90 
91  try {
92  return momemta::any_cast<const T&>(value->second.value);
93  } catch (const momemta::bad_any_cast& e) {
94  LOG(fatal) << "Exception while trying to get parameter '" << name << "'. Requested a '"
95  << demangle(typeid(T).name())
96  << "' while parameter is a '"
97  << demangle(value->second.value.type().name())
98  << "'";
99  throw e;
100  }
101  }
102 
103  template<typename T> T& get(const std::string& name) {
104  auto value = m_set.find(name);
105  if (value == m_set.end())
106  throw not_found_error("Parameter '" + name + "' not found.");
107 
108  try {
109  return momemta::any_cast<T&>(value->second.value);
110  } catch (const momemta::bad_any_cast& e) {
111  LOG(fatal) << "Exception while trying to get parameter '" << name << "'. Requested a '"
112  << demangle(typeid(T).name())
113  << "' while parameter is a '"
114  << demangle(value->second.value.type().name())
115  << "'";
116  throw e;
117  }
118  }
119 
120  template<typename T> const T& get(const std::string& name, const T& defaultValue) const {
121  auto value = m_set.find(name);
122  if (value == m_set.end())
123  return defaultValue;
124 
125  try {
126  return momemta::any_cast<const T&>(value->second.value);
127  } catch (const momemta::bad_any_cast &e) {
128  LOG(fatal) << "Exception while trying to get parameter '" << name << "'. Requested a '"
129  << demangle(typeid(T).name())
130  << "' while parameter is a '"
131  << demangle(value->second.value.type().name())
132  << "'";
133  throw e;
134  }
135  }
136 
144  const momemta::any& rawGet(const std::string& name) const;
145 
146  bool exists(const std::string& name) const;
147  template<typename T> bool existsAs(const std::string& name) const {
148  auto value = m_set.find(name);
149  return (value != m_set.end() && value->second.value.type() == typeid(T));
150  }
151 
158  template<typename T>
159  typename std::enable_if<std::is_same<T, bool>::value ||
160  std::is_same<T, InputTag>::value>::type set(const std::string& name, const T& value) {
161  set_helper(name, value);
162  }
163 
172  template<typename T>
173  void set(const std::string& name, const std::vector<T>& value) {
174  static_assert(
175  std::is_same<T, int64_t>::value ||
176  std::is_same<T, double>::value ||
177  std::is_same<T, bool>::value ||
178  std::is_same<T, std::string>::value ||
179  std::is_same<T, InputTag>::value,
180  "Type not supported"
181  );
182  set_helper(name, value);
183  }
184 
193  template<typename T>
194  typename std::enable_if<is_string<T>::value>::type set(const std::string& name, const T& value) {
195  set_helper(name, std::string(value));
196  }
197 
206  template<typename T>
207  typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value>::type set(const std::string& name, const T& value) {
208  set_helper(name, static_cast<int64_t>(value));
209  }
210 
219  template<typename T>
220  typename std::enable_if<std::is_floating_point<T>::value>::type set(const std::string& name, const T& value) {
221  set_helper(name, static_cast<double>(value));
222  }
223 
224  std::string getModuleName() const {
225  return get<std::string>("@name", "");
226  }
227 
228  std::string getModuleType() const {
229  return get<std::string>("@type", "");
230  }
231 
232  const ParameterSet& globalParameters() const {
233  auto it = m_set.find("@global_parameters");
234  if (it == m_set.end())
235  return *this;
236 
237  return momemta::any_cast<const ParameterSet&>(it->second.value);
238  }
239 
247  virtual ParameterSet* clone() const;
248 
249  std::vector<std::string> getNames() const;
250 
251  protected:
252  friend class ConfigurationReader;
253  friend class Configuration;
254  friend class ParameterSetParser;
255  friend class momemta::ComputationGraph;
256  friend void momemta::setInputTagsForInput(const momemta::ArgDef&, ParameterSet&, const std::vector<InputTag>&);
257 
259  struct Element {
260  momemta::any value;
261  bool lazy = false;
262 
263  template <typename T>
264  Element(const T& v) {
265  value = v;
266  }
267 
268  template <typename T>
269  Element(const T& v, bool l) {
270  value = v;
271  lazy = l;
272  }
273  };
274 
275  ParameterSet(const std::string& module_type, const std::string& module_name);
276 
282  virtual bool lazy() const;
283 
290  virtual void create(const std::string& name, const momemta::any& value);
291  virtual void setInternal(const std::string& name, Element& element, const momemta::any& value);
292 
293  virtual void freeze();
294 
295  std::map<std::string, Element> m_set;
296 
297  private:
298 
299  class not_found_error: public std::runtime_error {
300  using std::runtime_error::runtime_error;
301  };
302 
303  class frozen_error: public std::runtime_error {
304  using std::runtime_error::runtime_error;
305  };
306 
307  void setGlobalParameters(const ParameterSet&);
308 
317  template<typename T>
318  void set_helper(const std::string& name, const T& value) {
319  static_assert(
320  std::is_same<T, int64_t>::value ||
321  std::is_same<T, double>::value ||
322  std::is_same<T, bool>::value ||
323  std::is_same<T, std::string>::value ||
324  std::is_same<T, InputTag>::value ||
325  std::is_same<T, std::vector<int64_t>>::value ||
326  std::is_same<T, std::vector<double>>::value ||
327  std::is_same<T, std::vector<bool>>::value ||
328  std::is_same<T, std::vector<std::string>>::value ||
329  std::is_same<T, std::vector<InputTag>>::value,
330  "Type not supported"
331  );
332 
333  if (frozen) {
334  LOG(fatal) << "You are not allowed to edit a set once frozen.";
335  throw frozen_error("This ParameterSet is frozen");
336  }
337 
338  raw_set(name, value);
339  }
340 
341  template <typename T>
342  void raw_set(const std::string& name, const T& value) {
343 
344  auto it = m_set.find(name);
345  // If the element does not exist in the set, we create it
346  // Otherwise, we simply update the value
347  if (it == m_set.end()) {
348  create(name, value);
349  } else {
350  setInternal(name, it->second, value);
351  }
352  }
353 
354  void remove(const std::string& name);
355 
356  bool frozen = false;
357 };
A lua configuration file parser.
A small wrapper around a momemta::any value.
Definition: ParameterSet.h:259
Definition: Graph.h:21
An identifier of a module&#39;s output.
Definition: InputTag_fwd.h:37
Defines an input / output.
Definition: ModuleDef.h:40
A class encapsulating a lua table.
Definition: ParameterSet.h:82
A frozen snapshot of the configuration file.
Definition: Configuration.h:36
Element(const T &v)
If true, it means we hold a lazy value which should be evaluated.
Definition: ParameterSet.h:264