CMS 3D CMS Logo

ProductSelectorRules.cc
Go to the documentation of this file.
1 #include <algorithm>
2 #include <iterator>
3 #include <ostream>
4 #include <cctype>
5 
6 #include "boost/algorithm/string.hpp"
7 
13 
14 namespace edm {
15  // The following typedef is used only in this implementation file, in
16  // order to shorten several lines of code.
17  typedef std::vector<edm::BranchDescription const*> VCBDP;
18 
19  namespace {
20 
21  //--------------------------------------------------
22  // function partial_match is a helper for Rule. It encodes the
23  // matching of std::strings, and knows about wildcarding rules.
24  inline bool partial_match(const std::regex& regularExpression, const std::string& branchstring) {
25  return std::regex_match(branchstring, regularExpression);
26  }
27  } // namespace
28 
29  //--------------------------------------------------
30  // Class Rule is used to determine whether or not a given branch
31  // (really a ProductResolver, as described by the BranchDescription object
32  // that specifies that ProductResolver) matches a 'rule' specified by the
33  // configuration. Each Rule is configured with a single std::string from
34  // the configuration file.
35  //
36  // The configuration std::string is of the form:
37  //
38  // 'keep <spec>' ** or **
39  // 'drop <spec>'
40  //
41  // where '<spec>' is of the form:
42  //
43  // <product type>_<module label>_<instance name>_<process name>
44  //
45  // The 3 underscores must always be present. The four fields can
46  // be empty or composed of alphanumeric characters. "*" is an
47  // allowed wildcard that will match 0 or more of any characters.
48  // "?" is the other allowed wilcard that will match exactly one
49  // character. There is one exception to this, the entire '<spec>'
50  // can be one single "*" without any underscores and this is
51  // interpreted as "*_*_*_*". Anything else will lead to an exception
52  // being thrown.
53  //
54  // This class has much room for optimization. This should be
55  // revisited as soon as profiling data are available.
56 
57  ProductSelectorRules::Rule::Rule(std::string const& s, std::string const& parameterName, std::string const& owner)
58  : selectflag_(), productType_(), moduleLabel_(), instanceName_(), processName_() {
59  if (s.size() < 6)
61  << "Invalid statement in configuration file\n"
62  << "In " << owner << " parameter named '" << parameterName << "'\n"
63  << "Rule must have at least 6 characters because it must\n"
64  << "specify 'keep ' or 'drop ' and also supply a pattern.\n"
65  << "This is the invalid output configuration rule:\n"
66  << " " << s << "\n"
67  << "Exception thrown from ProductSelectorRules::Rule\n";
68 
69  if (s.substr(0, 4) == "keep")
70  selectflag_ = true;
71  else if (s.substr(0, 4) == "drop")
72  selectflag_ = false;
73  else
75  << "Invalid statement in configuration file\n"
76  << "In " << owner << " parameter named '" << parameterName << "'\n"
77  << "Rule must specify 'keep ' or 'drop ' and also supply a pattern.\n"
78  << "This is the invalid output configuration rule:\n"
79  << " " << s << "\n"
80  << "Exception thrown from ProductSelectorRules::Rule\n";
81 
82  if (!std::isspace(s[4])) {
84  << "Invalid statement in configuration file\n"
85  << "In " << owner << " parameter named '" << parameterName << "'\n"
86  << "In each rule, 'keep' or 'drop' must be followed by a space\n"
87  << "This is the invalid output configuration rule:\n"
88  << " " << s << "\n"
89  << "Exception thrown from ProductSelectorRules::Rule\n";
90  }
91 
92  // Now pull apart the std::string to get at the bits and pieces of the
93  // specification...
94 
95  // Grab from after 'keep/drop ' (note the space!) to the end of
96  // the std::string...
97  std::string spec(s.begin() + 5, s.end());
98 
99  // Trim any leading and trailing whitespace from spec
100  boost::trim(spec);
101 
102  if (spec == "*") // special case for wildcard
103  {
104  productType_ = ".*";
105  moduleLabel_ = ".*";
106  instanceName_ = ".*";
107  processName_ = ".*";
108  return;
109  } else {
110  std::vector<std::string> parts;
111  boost::split(parts, spec, boost::is_any_of("_"));
112 
113  // The std::vector must contain at least 4 parts
114  // and none may be empty.
115  bool good = (parts.size() == 4);
116 
117  // Require all the std::strings to contain only alphanumberic
118  // characters or "*" or "?"
119  if (good) {
120  for (int i = 0; i < 4; ++i) {
121  std::string& field = parts[i];
122  int size = field.size();
123  for (int j = 0; j < size; ++j) {
124  if (!(isalnum(field[j]) || field[j] == '*' || field[j] == '?')) {
125  good = false;
126  }
127  }
128 
129  // We are using the boost regex library to deal with the wildcards.
130  // The configuration file uses a syntax that accepts "*" and "?"
131  // as wildcards so we need to convert these to the syntax used in
132  // regular expressions.
133  boost::replace_all(parts[i], "*", ".*");
134  boost::replace_all(parts[i], "?", ".");
135  }
136  }
137 
138  if (!good) {
140  << "Invalid statement in configuration file\n"
141  << "In " << owner << " parameter named '" << parameterName << "'\n"
142  << "In each rule, after 'keep ' or 'drop ' there must\n"
143  << "be a branch specification of the form 'type_label_instance_process'\n"
144  << "There must be 4 fields separated by underscores\n"
145  << "The fields can only contain alphanumeric characters and the wildcards * or ?\n"
146  << "Alternately, a single * is also allowed for the branch specification\n"
147  << "This is the invalid output configuration rule:\n"
148  << " " << s << "\n"
149  << "Exception thrown from ProductSelectorRules::Rule\n";
150  }
151 
152  productType_ = parts[0];
153  moduleLabel_ = parts[1];
154  instanceName_ = parts[2];
155  processName_ = parts[3];
156  }
157  }
158 
159  void ProductSelectorRules::Rule::applyToAll(std::vector<BranchSelectState>& branchstates) const {
160  std::vector<BranchSelectState>::iterator it = branchstates.begin();
161  std::vector<BranchSelectState>::iterator end = branchstates.end();
162  for (; it != end; ++it)
163  applyToOne(it->desc, it->selectMe);
164  }
165 
166  void ProductSelectorRules::applyToAll(std::vector<BranchSelectState>& branchstates) const {
167  std::vector<Rule>::const_iterator it = rules_.begin();
168  std::vector<Rule>::const_iterator end = rules_.end();
169  for (; it != end; ++it)
170  it->applyToAll(branchstates);
171  }
172 
173  // bool
174  // Rule::applyToOne(edm::BranchDescription const* branch) const
175  // {
176  // bool match =
177  // partial_match(productType_, branch->friendlyClassName()) &&
178  // partial_match(moduleLabel_, branch->moduleLabel()) &&
179  // partial_match(instanceName_, branch->productInstanceName()) &&
180  // partial_match(processName_, branch->processName());
181 
182  // return match ? selectflag_ : !selectflag_;
183  // }
184 
186  if (this->appliesTo(branch))
187  result = selectflag_;
188  }
189 
191  return partial_match(productType_, branch->friendlyClassName()) &&
192  partial_match(moduleLabel_, branch->moduleLabel()) &&
193  partial_match(instanceName_, branch->productInstanceName()) &&
194  partial_match(processName_, branch->processName());
195  }
196 
197  const std::vector<std::string>& ProductSelectorRules::defaultSelectionStrings() {
198  static const std::vector<std::string> s_defaultStrings(1U, std::string("keep *"));
199  return s_defaultStrings;
200  }
201 
203  char const* parameterName,
204  std::vector<std::string> const& defaultStrings) {
205  ;
206  desc.addUntracked<std::vector<std::string> >(parameterName, defaultStrings)
207  ->setComment("Specifies which branches are kept or dropped.");
208  }
209 
211  std::string const& parameterName,
212  std::string const& parameterOwnerName)
213  : rules_(), parameterName_(parameterName), parameterOwnerName_(parameterOwnerName) {
214  // Fill the rules.
215  // If there is no parameter whose name is parameterName_ in the
216  // ParameterSet we are given, we use the following default.
217  std::vector<std::string> defaultCommands(1U, std::string("keep *"));
218 
219  std::vector<std::string> commands =
220  pset.getUntrackedParameter<std::vector<std::string> >(parameterName, defaultCommands);
221  if (commands.empty()) {
222  commands.push_back(defaultCommands[0]);
223  }
224  rules_.reserve(commands.size());
225  for (std::vector<std::string>::const_iterator it = commands.begin(), end = commands.end(); it != end; ++it) {
226  rules_.push_back(Rule(*it, parameterName, parameterOwnerName));
227  }
228  keepAll_ = commands.size() == 1 && commands[0] == defaultCommands[0];
229  }
230 
231 } // namespace edm
size
Write out results.
T getUntrackedParameter(std::string const &, T const &) const
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
static const std::vector< std::string > & defaultSelectionStrings()
void applyToOne(BranchDescription const *branch, bool &result) const
static void trim(std::string &s)
std::string const & processName() const
static void fillDescription(ParameterSetDescription &desc, char const *parameterName, std::vector< std::string > const &defaultStrings=defaultSelectionStrings())
void applyToAll(std::vector< BranchSelectState > &branchstates) const
Rule(std::string const &s, std::string const &parameterName, std::string const &owner)
std::string const & moduleLabel() const
std::string const & productInstanceName() const
ProductSelectorRules(ParameterSet const &pset, std::string const &parameterName, std::string const &parameterOwnerName)
commands
min number of hits for refit layers to remove
bool appliesTo(BranchDescription const *branch) const
std::string const & friendlyClassName() const
#define end
Definition: vmac.h:39
std::vector< edm::BranchDescription const * > VCBDP
HLT enums.
void applyToAll(std::vector< BranchSelectState > &branchstates) const
double split
Definition: MVATrainer.cc:139