CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ParameterSetDescription.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: ParameterSet
4 // Class : ParameterSetDescription
5 //
6 // Implementation:
7 // <Notes on implementation>
8 //
9 // Original Author: Chris Jones
10 // Created: Tue Jul 31 15:30:35 EDT 2007
11 //
12 
14 
20 
21 #include "boost/bind.hpp"
22 
23 #include <sstream>
24 #include <ostream>
25 #include <iomanip>
26 #include <algorithm>
27 
28 namespace edm {
29 
31  anythingAllowed_(false),
32  unknown_(false) {
33  }
34 
36  }
37 
38  void
40  { comment_ = value; }
41 
42  void
44  { comment_ = value; }
45 
46  void
48  {
49  anythingAllowed_ = true;
50  }
51 
52  void
54  {
55  unknown_ = true;
56  }
57 
61  std::auto_ptr<ParameterDescriptionNode> clonedNode(node.clone());
62  return addNode(clonedNode, false, true);
63  }
64 
67  addNode(std::auto_ptr<ParameterDescriptionNode> node) {
68  return addNode(node, false, true);
69  }
70 
74  std::auto_ptr<ParameterDescriptionNode> clonedNode(node.clone());
75  return addNode(clonedNode, true, writeToCfi);
76  }
77 
80  addOptionalNode(std::auto_ptr<ParameterDescriptionNode> node, bool writeToCfi) {
81  return addNode(node, true, writeToCfi);
82  }
83 
86  addNode(std::auto_ptr<ParameterDescriptionNode> node,
87  bool optional,
88  bool writeToCfi) {
89 
90  std::set<std::string> nodeLabels;
91  std::set<ParameterTypes> nodeParameterTypes;
92  std::set<ParameterTypes> nodeWildcardTypes;
93  node->checkAndGetLabelsAndTypes(nodeLabels, nodeParameterTypes, nodeWildcardTypes);
94  throwIfLabelsAlreadyUsed(nodeLabels);
95  throwIfWildcardCollision(nodeParameterTypes, nodeWildcardTypes);
96 
98  entry.setOptional(optional);
99  entry.setWriteToCfi(writeToCfi);
100  entries_.push_back(entry);
101  ParameterDescriptionNode* returnValue = node.get();
102  entries_.back().setNode(node);
103  return returnValue;
104  }
105 
106  void
108  {
109  if (unknown_ || anythingAllowed()) return;
110 
111  std::set<std::string> validatedLabels;
113  boost::bind(&ParameterSetDescription::validateNode, _1, boost::ref(pset), boost::ref(validatedLabels)));
114 
115  std::vector<std::string> parameterNames = pset.getParameterNames();
116  if (validatedLabels.size() != parameterNames.size()) {
117 
118  // Three labels will be magically inserted into the top level
119  // of a module ParameterSet even though they are not in the
120  // python configuration files. If these are present, then
121  // assume they are OK and count them as validated.
122 
123  std::string module_label("@module_label");
124  if (pset.exists(module_label)) {
125  validatedLabels.insert(module_label);
126  }
127 
128  std::string module_type("@module_type");
129  if (pset.exists(module_type)) {
130  validatedLabels.insert(module_type);
131  }
132 
133  std::string module_edm_type("@module_edm_type");
134  if (pset.exists(module_edm_type)) {
135  validatedLabels.insert(module_edm_type);
136  }
137 
138  std::string service_type("@service_type");
139  if (pset.exists(service_type)) {
140  validatedLabels.insert(service_type);
141  }
142 
143  // Try again
144  if (validatedLabels.size() != parameterNames.size()) {
145 
146  throwIllegalParameters(parameterNames, validatedLabels);
147  }
148  }
149  }
150 
151  void
153  bool startWithComma,
154  int indentation) const {
155  bool wroteSomething = false;
156 
158  _1,
159  boost::ref(os),
160  boost::ref(startWithComma),
161  indentation,
162  boost::ref(wroteSomething)));
163 
164  if (wroteSomething) {
165  char oldFill = os.fill();
166  os << "\n" << std::setfill(' ') << std::setw(indentation - 2) << "";
167  os.fill(oldFill);
168  }
169  }
170 
173  ParameterSet & pset,
174  std::set<std::string> & validatedLabels) {
175  entry.node()->validate(pset, validatedLabels, entry.optional());
176  }
177 
179  print(std::ostream & os, DocFormatHelper & dfh) const {
180 
181  if (isUnknown()) {
182  dfh.indent(os);
183  os << "Description is unknown. The configured PSet will not be validated\n";
184  dfh.indent(os);
185  os << "because the plugin has not defined this parameter set description.\n";
186  if (!dfh.brief()) os << "\n";
187  }
188 
189  if (anythingAllowed()) {
190  dfh.indent(os);
191  os << "Description allows anything and requires nothing.\n";
192  dfh.indent(os);
193  os << "The configured PSet will not be validated.\n";
194  if (!dfh.brief()) os << "\n";
195  }
196 
197  if (entries_.empty()) {
198  dfh.indent(os);
199  os << "Description is empty\n";
200  if (!dfh.brief()) os << "\n";
201  return;
202  }
203 
204  // Zeroth pass is only to calculate column widths in advance of any printing
205  dfh.setPass(0);
206  dfh.setCounter(0);
208  _1,
209  boost::ref(os),
210  boost::ref(dfh)));
211 
212  // First pass prints top level parameters and references to structure
213  dfh.setPass(1);
214  dfh.setCounter(0);
216  _1,
217  boost::ref(os),
218  boost::ref(dfh)));
219 
220  // Second pass prints substructure that goes into different sections of the
221  // output document
222  dfh.setPass(2);
223  dfh.setCounter(0);
225  _1,
226  boost::ref(os),
227  boost::ref(dfh)));
228  }
229 
230  void
232  std::vector<std::string> const& parameterNames,
233  std::set<std::string> const& validatedLabels) {
234 
235  std::set<std::string> parNames(parameterNames.begin(), parameterNames.end());
236 
237 
238  std::set<std::string> diffNames;
239  std::insert_iterator<std::set<std::string> > insertIter(diffNames, diffNames.begin());
240  std::set_difference(parNames.begin(), parNames.end(),
241  validatedLabels.begin(), validatedLabels.end(),
242  insertIter);
243 
244  std::stringstream ss;
245  for (std::set<std::string>::const_iterator iter = diffNames.begin(),
246  iEnd = diffNames.end();
247  iter != iEnd;
248  ++iter) {
249  ss << " \"" << *iter << "\"\n";
250  }
251  if (diffNames.size() == 1U) {
253  << "Illegal parameter found in configuration. The parameter is named:\n"
254  << ss.str()
255  << "You could be trying to use a parameter name that is not\n"
256  << "allowed for this plugin or it could be misspelled.\n";
257  }
258  else {
260  << "Illegal parameters found in configuration. The parameters are named:\n"
261  << ss.str()
262  << "You could be trying to use parameter names that are not\n"
263  << "allowed for this plugin or they could be misspelled.\n";
264  }
265  }
266 
267  void
269  std::ostream & os,
270  bool & startWithComma,
271  int indentation,
272  bool & wroteSomething) {
273  if (entry.writeToCfi()) {
274  entry.node()->writeCfi(os, startWithComma, indentation, wroteSomething);
275  }
276  }
277 
278  void
280  std::ostream & os,
281  DocFormatHelper & dfh) {
282  if (dfh.pass() < 2) {
283  entry.node()->print(os, entry.optional(), entry.writeToCfi(), dfh);
284  }
285  else {
286  entry.node()->printNestedContent(os, entry.optional(), dfh);
287  }
288  }
289 
290  void
292  throwIfLabelsAlreadyUsed(std::set<std::string> const& nodeLabels) {
293 
294  std::set<std::string> duplicateLabels;
295  std::insert_iterator<std::set<std::string> > insertIter(duplicateLabels, duplicateLabels.begin());
296  std::set_intersection(nodeLabels.begin(), nodeLabels.end(),
297  usedLabels_.begin(), usedLabels_.end(),
298  insertIter);
299  if (duplicateLabels.empty()) {
300  usedLabels_.insert(nodeLabels.begin(), nodeLabels.end());
301  }
302  else {
303 
304  std::stringstream ss;
305  for (std::set<std::string>::const_iterator iter = duplicateLabels.begin(),
306  iEnd = duplicateLabels.end();
307  iter != iEnd;
308  ++iter) {
309  ss << " \"" << *iter << "\"\n";
310  }
312  << "Labels used in different nodes of a ParameterSetDescription\n"
313  << "must be unique. The following duplicate labels were detected:\n"
314  << ss.str()
315  << "\n";
316  }
317  }
318 
319  void
321  throwIfWildcardCollision(std::set<ParameterTypes> const& nodeParameterTypes,
322  std::set<ParameterTypes> const& nodeWildcardTypes) {
323 
324  // 1. Check that the new wildcard types do not collide with the existing
325  // parameter types.
326  // 2. Check that the new parameter types do not collide with the existing
327  // wildcard types.
328  // 3. Then insert them.
329  // The order of those steps is important because a wildcard with a default
330  // value could insert a type in both sets and this is OK.
331 
332  // We assume the node already checked for collisions between the new parameter
333  // types and the new wildcard types before passing the sets to this function.
334 
335  if (!nodeWildcardTypes.empty()) {
336 
337  std::set<ParameterTypes> duplicateTypes1;
338  std::insert_iterator<std::set<ParameterTypes> > insertIter1(duplicateTypes1, duplicateTypes1.begin());
339  std::set_intersection(typesUsedForParameters_.begin(), typesUsedForParameters_.end(),
340  nodeWildcardTypes.begin(), nodeWildcardTypes.end(),
341  insertIter1);
342 
343  if (!duplicateTypes1.empty()) {
344 
345  std::stringstream ss;
346  for (std::set<ParameterTypes>::const_iterator iter = duplicateTypes1.begin(),
347  iEnd = duplicateTypes1.end();
348  iter != iEnd;
349  ++iter) {
350  ss << " \"" << parameterTypeEnumToString(*iter) << "\"\n";
351  }
353  << "Within a ParameterSetDescription, the type used for a wildcard must\n"
354  << "not be the same as the type used for other parameters. This rule\n"
355  << "is violated for the following types:\n"
356  << ss.str()
357  << "\n";
358  }
359  }
360 
361  if (!typesUsedForWildcards_.empty()) {
362 
363  std::set<ParameterTypes> duplicateTypes2;
364  std::insert_iterator<std::set<ParameterTypes> > insertIter2(duplicateTypes2, duplicateTypes2.begin());
365  std::set_intersection(typesUsedForWildcards_.begin(), typesUsedForWildcards_.end(),
366  nodeParameterTypes.begin(), nodeParameterTypes.end(),
367  insertIter2);
368 
369  if (!duplicateTypes2.empty()) {
370 
371  std::stringstream ss;
372  for (std::set<ParameterTypes>::const_iterator iter = duplicateTypes2.begin(),
373  iEnd = duplicateTypes2.end();
374  iter != iEnd;
375  ++iter) {
376  ss << " \"" << parameterTypeEnumToString(*iter) << "\"\n";
377  }
379  << "Within a ParameterSetDescription, the type used for a wildcard must\n"
380  << "not be the same as the type used for other parameters. This rule is\n"
381  << "violated for the following types :\n"
382  << ss.str()
383  << "\n";
384  }
385  }
386 
387  typesUsedForParameters_.insert(nodeParameterTypes.begin(), nodeParameterTypes.end());
388  typesUsedForWildcards_.insert(nodeWildcardTypes.begin(), nodeWildcardTypes.end());
389  }
390 
394  ParameterDescriptionNode const& node2,
395  bool optional, bool writeToCfi) {
396  std::auto_ptr<ParameterDescriptionNode> pdIfExists(new IfExistsDescription(node1, node2));
397  return addNode(pdIfExists, optional, writeToCfi);
398  }
399 }
virtual ParameterDescriptionNode * clone() const =0
static void throwIllegalParameters(std::vector< std::string > const &parameterNames, std::set< std::string > const &validatedNames)
edm::value_ptr< ParameterDescriptionNode > const & node() const
void throwIfWildcardCollision(std::set< ParameterTypes > const &nodeParameterTypes, std::set< ParameterTypes > const &nodeWildcardTypes)
void setAllowAnything()
allow any parameter label/value pairs
void validate(ParameterSet &pset) const
std::set< std::string > usedLabels_
bool exists(std::string const &parameterName) const
checks if a parameter exists
ParameterDescriptionNode * ifExists(ParameterDescriptionNode const &node1, ParameterDescriptionNode const &node2)
ParameterDescriptionNode * addNode(ParameterDescriptionNode const &node)
static void writeNode(SetDescriptionEntry const &entry, std::ostream &os, bool &startWithComma, int indentation, bool &wroteSomething)
void writeCfi(std::ostream &os, bool startWithComma, int indentation) const
std::string parameterTypeEnumToString(ParameterTypes iType)
tuple node
Definition: Node.py:50
void setCounter(int value)
std::set< ParameterTypes > typesUsedForParameters_
Func for_all(ForwardSequence &s, Func f)
wrapper for std::for_each
Definition: Algorithms.h:16
void setComment(std::string const &value)
void throwIfLabelsAlreadyUsed(std::set< std::string > const &nodeLabels)
std::pair< std::string, MonitorElement * > entry
Definition: ME_MAP.h:8
void print(std::ostream &os, DocFormatHelper &dfh) const
ParameterDescriptionNode * addOptionalNode(ParameterDescriptionNode const &node, bool writeToCfi)
tuple pset
Definition: CrabTask.py:85
std::vector< std::string > getParameterNames() const
void setPass(int value)
static void validateNode(SetDescriptionEntry const &entry, ParameterSet &pset, std::set< std::string > &validatedNames)
static void printNode(SetDescriptionEntry const &entry, std::ostream &os, DocFormatHelper &dfh)
static const uint16_t unknown_
Definition: Constants.h:20
std::set< ParameterTypes > typesUsedForWildcards_
void checkAndGetLabelsAndTypes(std::set< std::string > &usedLabels, std::set< ParameterTypes > &parameterTypes, std::set< ParameterTypes > &wildcardTypes) const
void indent(std::ostream &os) const