ModuleUtils.cc
1 /*
2  * MoMEMta: a modular implementation of the Matrix Element Method
3  * Copyright (C) 2017 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 #include <ModuleUtils.h>
20 
21 #include <momemta/Logging.h>
22 
23 #include <ModuleDefUtils.h>
24 
25 namespace {
26 
27 template<typename T>
28 T* findPSet(const momemta::ArgDef& input_def, T& parameters) {
29  typedef typename std::remove_cv<T>::type type;
30 
31  T* pset = &parameters;
32  std::vector<momemta::AttrDef> nested_attributes = input_def.nested_attributes;
33  while (!nested_attributes.empty()) {
34  momemta::AttrDef nested_attribute = nested_attributes.front();
35  nested_attributes.erase(nested_attributes.begin());
36 
37  if (pset->template existsAs<type>(nested_attribute.name))
38  pset = &pset->template get<type>(nested_attribute.name);
39  else {
40  pset = nullptr;
41  break;
42  }
43  }
44 
45  return pset;
46 }
47 }
48 
49 bool momemta::validateModuleParameters(const ModuleList::value_type& module_def, const ParameterSet& parameters) {
50 
51  std::vector<std::string> errors;
52  std::vector<std::string> warnings;
53 
54  // Check that all attributes are defined
55  // TODO: We can imagine here validating also the type of the attribute
56  for (const auto& attr_def: module_def.attributes) {
57 
58  // Ignore global or optional attributes
59  if (attr_def.global || attr_def.optional)
60  continue;
61 
62  if (! parameters.exists(attr_def.name))
63  errors.emplace_back("Attribute not found: " + attr_def.name);
64  }
65 
66  // Check that all inputs are defined
67  for (const auto& input_def: module_def.inputs) {
68  // Ignore optional inputs
69  if (input_def.optional)
70  continue;
71 
72  const ParameterSet* pset = &parameters;
73  std::vector<AttrDef> nested_attributes = input_def.nested_attributes;
74  while (!nested_attributes.empty()) {
75  AttrDef nested_attribute = nested_attributes.front();
76  nested_attributes.erase(nested_attributes.begin());
77 
78  if (pset->existsAs<ParameterSet>(nested_attribute.name))
79  pset = &pset->get<ParameterSet>(nested_attribute.name);
80  else {
81  LOG(error) << "Attribute " << nested_attribute.name << " not found in PSet "
82  << pset->getModuleType() << "::" << pset->getModuleName();
83  pset = nullptr;
84  break;
85  }
86  }
87 
88  if (!pset || !pset->exists(input_def.name))
89  errors.emplace_back("Input not found: " + input_def.name);
90  }
91 
92  // Check for parameters not found in the module definition
93  const auto& parameter_names = parameters.getNames();
94  for (const auto& name: parameter_names) {
95 
96  // Ignore internal parameters
97  if (name.length() > 0 && name[0] == '@')
98  continue;
99 
100  if (! momemta::inputOrAttrExists(name, module_def))
101  warnings.emplace_back("Unexpected parameter: " + name);
102  }
103 
104  if (! warnings.empty()) {
105  // Warnings found during validation
106  LOG(warning) << "Warnings found during validation of parameters for module "
107  << parameters.getModuleType() << "::" << parameters.getModuleName();
108  for (const auto& warning: warnings)
109  LOG(warning) << " " << warning;
110  LOG(warning) << "These parameters will never be used by the module, check your configuration file.";
111  }
112 
113  if (!errors.empty()) {
114  // Validation failed. Print errors.
115  LOG(error) << "Validation of parameters for module " << parameters.getModuleType() << "::"
116  << parameters.getModuleName() << " failed: ";
117  for (const auto& error: errors)
118  LOG(error) << " " << error;
119 
120  LOG(error) << "Check your configuration file.";
121  }
122 
123  return errors.empty();
124 }
125 
126 momemta::gtl::optional<std::vector<InputTag>> momemta::getInputTagsForInput(const ArgDef& input,
127  const ParameterSet& parameters) {
128 
129  const ParameterSet* pset = findPSet(input, parameters);
130  assert(pset || input.optional);
131 
132  if (! pset)
133  return gtl::nullopt;
134 
135  if (input.optional && !pset->exists(input.name))
136  return gtl::nullopt;
137 
138  if (input.many) {
139  return pset->get<std::vector<InputTag>>(input.name);
140  } else {
141  return gtl::make_optional<std::vector<InputTag>>({pset->get<InputTag>(input.name)});
142  }
143 }
144 
145 void momemta::setInputTagsForInput(const ArgDef& input,
146  ParameterSet& parameters,
147  const std::vector<InputTag>& inputTags) {
148 
149  ParameterSet* pset = findPSet(input, parameters);
150  assert(pset);
151 
152  if (input.many) {
153  pset->raw_set(input.name, inputTags);
154  } else {
155  assert(inputTags.size() == 1);
156  pset->raw_set(input.name, inputTags.front());
157  }
158 }
Type type(lua_State *L, int index)
Extract the type of a lua value.
Definition: utils.cc:81
bool optional
Only meaningful for inputs.
Definition: ModuleDef.h:43
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
Defines an attribute.
Definition: ModuleDef.h:27
std::vector< AttrDef > nested_attributes
Definition: ModuleDef.h:55