CMS 3D CMS Logo

ParameterDescriptionNode.h
Go to the documentation of this file.
1 #ifndef FWCore_ParameterSet_ParameterDescriptionNode_h
2 #define FWCore_ParameterSet_ParameterDescriptionNode_h
3 
4 // This is a base class for the class that describes
5 // the parameters that are allowed or required to be
6 // in a ParameterSet. It is also a base class for
7 // other more complex logical structures which describe
8 // which combinations of parameters are allowed to be
9 // in a ParameterSet.
10 
12 
13 #include <string>
14 #include <set>
15 #include <iosfwd>
16 #include <memory>
17 
18 namespace edm {
19 
20  class ParameterSet;
21  template <typename T> class ParameterDescriptionCases;
22  class DocFormatHelper;
23 
24  // Originally these were defined such that the values were the
25  // same as in the ParameterSet Entry class and the validation
26  // depended on that. But at the moment I'm typing this comment,
27  // the code no longer depends on the values being the same (which
28  // is probably good because nothing enforces the correspondence,
29  // a task for the future when someone has free time would be
30  // to define the values in a common header, but that would involve
31  // significant changes to ParameterSet ...)
33  k_int32 = 'I',
34  k_vint32 = 'i',
35  k_uint32 = 'U',
36  k_vuint32 = 'u',
37  k_int64 = 'L',
38  k_vint64 = 'l',
39  k_uint64 = 'X',
40  k_vuint64 = 'x',
41  k_double = 'D',
42  k_vdouble = 'd',
43  k_bool = 'B',
44  k_string = 'S',
45  k_vstring = 's',
46  k_EventID = 'E',
47  k_VEventID = 'e',
50  k_InputTag = 't',
51  k_VInputTag = 'v',
52  k_FileInPath = 'F',
55  k_EventRange = 'R',
57  k_PSet = 'Q',
58  k_VPSet = 'q'
59  };
60 
62 
64  template <class T>
65  static ParameterTypes toEnum();
66  };
67 
68  class Comment {
69  public:
70  Comment();
71  explicit Comment(std::string const& iComment);
72  explicit Comment(char const* iComment);
73  std::string const& comment() const { return comment_; }
74  private:
76  };
77 
79 
80  public:
81 
83 
84  explicit ParameterDescriptionNode(Comment const& iComment) :
85  comment_(iComment.comment()) {
86  }
87 
88  virtual ~ParameterDescriptionNode();
89 
90  virtual ParameterDescriptionNode* clone() const = 0;
91 
92  std::string const& comment() const { return comment_; }
93  void setComment(std::string const& value);
94  void setComment(char const* value);
95 
96  // The validate function should do one of three things, find that the
97  // node "exists", make the node "exist" by inserting missing parameters
98  // or throw. The only exception to this rule occurs when the argument
99  // named "optional" is true, which should only be possible for the
100  // top level nodes of a ParameterSetDescription. When a parameter is
101  // found or inserted its label is added into the list of validatedLabels.
103  std::set<std::string>& validatedLabels,
104  bool optional) const {
105  validate_(pset, validatedLabels, optional);
106  }
107 
108  // As long as it has default values, this will attempt to write
109  // parameters associated with a node into a cfi file that is
110  // being automatically generated. It is quite possible for
111  // to produce a cfi that will fail validation. In some cases,
112  // this will imply the user is required to supply certain missing
113  // parameters that do not appear in the cfi and do not have defaults
114  // in the description. It is also possible to create a pathological
115  // ParameterSetDescription where the algorithm fails to write
116  // a valid cfi, in some cases the description can be so pathological
117  // that it is impossible to write a cfi that will pass validation.
118  void writeCfi(std::ostream& os,
119  bool& startWithComma,
120  int indentation,
121  bool& wroteSomething) const {
122  writeCfi_(os, startWithComma, indentation, wroteSomething);
123  }
124 
125  // Print out the description in human readable format
126  void print(std::ostream& os,
127  bool optional,
128  bool writeToCfi,
129  DocFormatHelper& dfh) const;
130 
131  bool hasNestedContent() const {
132  return hasNestedContent_();
133  }
134 
135  void printNestedContent(std::ostream& os,
136  bool optional,
137  DocFormatHelper& dfh) const;
138 
139  // The next three functions are only called by the logical nodes
140  // on their subnodes. When executing these functions, the
141  // insertion of missing parameters does not occur.
142 
143  // Usually checks to see if a parameter exists in the configuration, but
144  // if the node is a logical node, then it returns the value of the logical
145  // expression.
146  bool exists(ParameterSet const& pset) const {
147  return exists_(pset);
148  }
149 
150  // For most nodes, this simply returns the same value as the exists
151  // function. But for AND nodes this returns true if either its subnodes
152  // exists. Used by operator&& during validation, if either of an AND node's
153  // subnodes exists, then both subnodes get validated.
154  bool partiallyExists(ParameterSet const& pset) const {
155  return partiallyExists_(pset);
156  }
157 
158  // For most nodes, this simply returns the same value as the exists
159  // function. It is different for an XOR node. It counts
160  // XOR subnodes whose exists function returns true. And it
161  // does this recursively into XOR nodes that are contained in
162  // other XOR nodes.
163  // Used by operator^ during validation:
164  // -- if it returns more than 1, then validation will throw,
165  // -- if it returns exactly one, then only the nonzero subnode gets validated
166  // -- if it returns zero, then validation tries to validate the first node and
167  // then rechecks to see what the missing parameter insertion did (there could
168  // be side effects on the nodes that were not validated)
170  return howManyXORSubNodesExist_(pset);
171  }
172 
173  /* Validation puts requirements on which parameters can and cannot exist
174  within a ParameterSet. The evaluation of whether a ParameterSet passes
175  or fails the rules in the ParameterSetDescription is complicated by
176  the fact that we allow missing parameters to be injected into the
177  ParameterSet during validation. One must worry whether injecting a
178  missing parameter invalidates some other part of the ParameterSet that
179  was already checked and determined to be OK. The following restrictions
180  avoid that problem.
181 
182  - The same parameter labels cannot occur in different nodes of the
183  same ParameterSetDescription. There are two exceptions to this.
184  Nodes that are contained in the cases of a ParameterSwitch or the
185  subnodes of an "exclusive or" are allowed to use the same labels.
186 
187  - If insertion is necessary to make an "exclusive or" node pass
188  validation, then the insertion could make more than one of the
189  possibilities evaluate true. This must be checked for after the
190  insertions occur. The behavior is to throw a Configuration exception
191  if this problem is encountered. (Example: (A && B) ^ (A && C) where
192  C already exists in the ParameterSet but A and B do not. A and B
193  get inserted by the algorithm, because it tries to make the first
194  possibility true when all fail without insertion. Then both
195  parts of the "exclusive or" pass, which is a validation failure).
196 
197  - Another potential problem is that a parameter insertion related
198  to one ParameterDescription could match unrelated wildcards causing
199  other validation requirements to change from being passing to failing
200  or vice versa. This makes it almost impossible to determine if a
201  ParameterSet passes validation. Each time you try to loop through
202  and check, the result of validation could change. To avoid this problem,
203  a list is maintained of the type for all wildcards. Another list is
204  maintained for the type of all parameters. As new items are added
205  we check for collisions. The function that builds the ParameterSetDescription,
206  will throw if this rule is violated. At the moment, the criteria
207  for a collision is matching types between a parameter and a wildcard.
208  (This criteria is overrestrictive. With some additional CPU and
209  code development the restriction could be loosened to parameters that
210  might be injected cannot match the type, trackiness, and wildcard label
211  pattern of any wildcard that requires a match. And further this
212  could not apply to wildcards on different branches of a ParameterSwitch
213  or "exclusive or".)
214 
215  These restrictions have the additional benefit that the things they prohibit
216  would tend to confuse a user trying to configure a module or a module developer
217  writing the code to extract the parameters from a ParameterSet. These rules
218  tend to prohibit bad design.
219 
220  One strategy to avoid problems with wildcard parameters is to add a nested
221  ParameterSet and put the wildcard parameters in the nested ParameterSet.
222  The names and types in a nested ParameterSet will not interfere with names
223  in the containing ParameterSet.
224  */
225  void checkAndGetLabelsAndTypes(std::set<std::string>& usedLabels,
226  std::set<ParameterTypes>& parameterTypes,
227  std::set<ParameterTypes>& wildcardTypes) const {
228  checkAndGetLabelsAndTypes_(usedLabels, parameterTypes, wildcardTypes);
229  }
230 
231  static void printSpaces(std::ostream& os, int n);
232 
233  protected:
234 
235  virtual void checkAndGetLabelsAndTypes_(std::set<std::string>& usedLabels,
236  std::set<ParameterTypes>& parameterTypes,
237  std::set<ParameterTypes>& wildcardTypes) const = 0;
238 
239  virtual void validate_(ParameterSet& pset,
240  std::set<std::string>& validatedLabels,
241  bool optional) const = 0;
242 
243  virtual void writeCfi_(std::ostream& os,
244  bool& startWithComma,
245  int indentation,
246  bool& wroteSomething) const = 0;
247 
248  virtual void print_(std::ostream&,
249  bool /*optional*/,
250  bool /*writeToCfi*/,
251  DocFormatHelper&) const { }
252 
253  virtual bool hasNestedContent_() const {
254  return false;
255  }
256 
257  virtual void printNestedContent_(std::ostream&,
258  bool /*optional*/,
259  DocFormatHelper&) const { }
260 
261  virtual bool exists_(ParameterSet const& pset) const = 0;
262 
263  virtual bool partiallyExists_(ParameterSet const& pset) const = 0;
264 
265  virtual int howManyXORSubNodesExist_(ParameterSet const& pset) const = 0;
266 
268  };
269 
270  template <>
273  static void destroy(ParameterDescriptionNode* p) { delete p; }
274  };
275 
276  // operator>> ---------------------------------------------
277 
278  std::unique_ptr<ParameterDescriptionCases<bool> >
279  operator>>(bool caseValue,
280  ParameterDescriptionNode const& node);
281 
282  std::unique_ptr<ParameterDescriptionCases<int> >
283  operator>>(int caseValue,
284  ParameterDescriptionNode const& node);
285 
286  std::unique_ptr<ParameterDescriptionCases<std::string> >
287  operator>>(std::string const& caseValue,
288  ParameterDescriptionNode const& node);
289 
290  std::unique_ptr<ParameterDescriptionCases<std::string> >
291  operator>>(char const* caseValue,
292  ParameterDescriptionNode const& node);
293 
294  std::unique_ptr<ParameterDescriptionCases<bool> >
295  operator>>(bool caseValue,
296  std::unique_ptr<ParameterDescriptionNode> node);
297 
298  std::unique_ptr<ParameterDescriptionCases<int> >
299  operator>>(int caseValue,
300  std::unique_ptr<ParameterDescriptionNode> node);
301 
302  std::unique_ptr<ParameterDescriptionCases<std::string> >
303  operator>>(std::string const& caseValue,
304  std::unique_ptr<ParameterDescriptionNode> node);
305 
306  std::unique_ptr<ParameterDescriptionCases<std::string> >
307  operator>>(char const* caseValue,
308  std::unique_ptr<ParameterDescriptionNode> node);
309 
310  // operator&& ---------------------------------------------
311 
312  std::unique_ptr<ParameterDescriptionNode>
313  operator&&(ParameterDescriptionNode const& node_left,
314  ParameterDescriptionNode const& node_right);
315 
316  std::unique_ptr<ParameterDescriptionNode>
317  operator&&(std::unique_ptr<ParameterDescriptionNode> node_left,
318  ParameterDescriptionNode const& node_right);
319 
320  std::unique_ptr<ParameterDescriptionNode>
321  operator&&(ParameterDescriptionNode const& node_left,
322  std::unique_ptr<ParameterDescriptionNode> node_right);
323 
324  std::unique_ptr<ParameterDescriptionNode>
325  operator&&(std::unique_ptr<ParameterDescriptionNode> node_left,
326  std::unique_ptr<ParameterDescriptionNode> node_right);
327 
328  // operator|| ---------------------------------------------
329 
330  std::unique_ptr<ParameterDescriptionNode>
331  operator||(ParameterDescriptionNode const& node_left,
332  ParameterDescriptionNode const& node_right);
333 
334  std::unique_ptr<ParameterDescriptionNode>
335  operator||(std::unique_ptr<ParameterDescriptionNode> node_left,
336  ParameterDescriptionNode const& node_right);
337 
338  std::unique_ptr<ParameterDescriptionNode>
339  operator||(ParameterDescriptionNode const& node_left,
340  std::unique_ptr<ParameterDescriptionNode> node_right);
341 
342  std::unique_ptr<ParameterDescriptionNode>
343  operator||(std::unique_ptr<ParameterDescriptionNode> node_left,
344  std::unique_ptr<ParameterDescriptionNode> node_right);
345 
346  // operator^ ---------------------------------------------
347 
348  std::unique_ptr<ParameterDescriptionNode>
349  operator^(ParameterDescriptionNode const& node_left,
350  ParameterDescriptionNode const& node_right);
351 
352  std::unique_ptr<ParameterDescriptionNode>
353  operator^(std::unique_ptr<ParameterDescriptionNode> node_left,
354  ParameterDescriptionNode const& node_right);
355 
356  std::unique_ptr<ParameterDescriptionNode>
357  operator^(ParameterDescriptionNode const& node_left,
358  std::unique_ptr<ParameterDescriptionNode> node_right);
359 
360  std::unique_ptr<ParameterDescriptionNode>
361  operator^(std::unique_ptr<ParameterDescriptionNode> node_left,
362  std::unique_ptr<ParameterDescriptionNode> node_right);
363 }
364 #endif
void validate(ParameterSet &pset, std::set< std::string > &validatedLabels, bool optional) const
std::istream & operator>>(std::istream &is, FileInPath &fip)
Definition: FileInPath.h:153
int howManyXORSubNodesExist(ParameterSet const &pset) const
S & print(S &os, JobReport::InputFile const &f)
Definition: JobReport.cc:65
virtual void printNestedContent_(std::ostream &, bool, DocFormatHelper &) const
std::string parameterTypeEnumToString(ParameterTypes iType)
static ParameterDescriptionNode * clone(ParameterDescriptionNode const *p)
std::unique_ptr< ParameterDescriptionNode > operator&&(ParameterDescriptionNode const &node_left, ParameterDescriptionNode const &node_right)
std::string const & comment() const
std::string const & comment() const
Definition: value.py:1
bool exists(ParameterSet const &pset) const
bool partiallyExists(ParameterSet const &pset) const
std::unique_ptr< ParameterDescriptionCases< bool > > operator||(std::unique_ptr< ParameterDescriptionCases< bool > >, std::unique_ptr< ParameterDescriptionCases< bool > >)
TEveGeoShape * clone(const TEveElement *element, TEveElement *parent)
Definition: eve_macros.cc:135
virtual ParameterDescriptionNode * clone() const =0
static ParameterTypes toEnum()
HLT enums.
static void destroy(ParameterDescriptionNode *p)
std::unique_ptr< ParameterDescriptionNode > operator^(ParameterDescriptionNode const &node_left, ParameterDescriptionNode const &node_right)
void checkAndGetLabelsAndTypes(std::set< std::string > &usedLabels, std::set< ParameterTypes > &parameterTypes, std::set< ParameterTypes > &wildcardTypes) const
void writeCfi(std::ostream &os, bool &startWithComma, int indentation, bool &wroteSomething) const
ParameterDescriptionNode(Comment const &iComment)
virtual void print_(std::ostream &, bool, bool, DocFormatHelper &) const
#define comment(par)
Definition: vmac.h:163