CMS 3D CMS Logo

TriggerSelector.cc
Go to the documentation of this file.
1 #include "TriggerSelector.h"
2 
6 
7 #include <iostream>
8 #include <boost/regex.hpp>
9 #include <algorithm>
10 #include <cassert>
11 
12 namespace dqmservices {
13 
14  // compatibility constructor
15 
16  TriggerSelector::TriggerSelector(Strings const& pathspecs, Strings const& names) : useOld_(true) {
17  acceptAll_ = false;
18  eventSelector_.reset(new edm::EventSelector(pathspecs, names));
19  }
20 
21  TriggerSelector::TriggerSelector(edm::ParameterSet const& config, Strings const& triggernames, bool old_)
22  : useOld_(old_) {
23  acceptAll_ = false;
24  if (old_) {
25  // old mode forced
26  acceptAll_ = false;
27  eventSelector_.reset(new edm::EventSelector(config, triggernames));
28  return;
29  }
30  if (!config.empty()) {
31  // let's see if non empty TriggerSelector is present
32  try {
33  std::string myPath = trim(config.getParameter<std::string>("TriggerSelector"));
34  if (!myPath.empty()) {
35  init(myPath, triggernames);
36  return;
37  }
38  } catch (...) {
39  }
40 
41  // now try with the SelectEvents
42  try {
43  Strings paths;
44  paths = config.getParameter<Strings>("SelectEvents");
45  if (!paths.empty()) {
46  useOld_ = true;
47  eventSelector_.reset(new edm::EventSelector(config, triggernames));
48  return;
49  }
50  } catch (...) {
51  }
52  }
53  // if selection parameters aren't present, don't do selection
54  // log
55  acceptAll_ = true;
56  }
57 
58  TriggerSelector::TriggerSelector(std::string const& expression, Strings const& triggernames) : useOld_(false) {
59  init(trim(expression), triggernames);
60  }
61 
62  void TriggerSelector::init(std::string const& expression, Strings const& triggernames) {
63  // debug_ = true;
64  if (expression.empty()) {
65  acceptAll_ = true;
66  return;
67  }
68  if (expression.size() == 1 && expression.at(0) == '*')
69  acceptAll_ = true;
70  else
71  acceptAll_ = false;
72 
73  // replace all possible alternate operators (.AND. and .OR.)
74  {
75  using namespace boost;
77  temp = regex_replace(expression, regex(".AND."), "&&");
78  expression_ = regex_replace(temp, regex(".and."), "&&");
79  temp = regex_replace(expression_, regex(".OR."), "||");
80  expression_ = regex_replace(temp, regex(".or."), "||");
81  }
82 
83  // build decision tree
84  masterElement_.reset(new TreeElement(expression_, triggernames));
85  }
86 
87  /*
88  Obsolete
89 */
92  }
93 
95  if (useOld_) {
96  return eventSelector_->acceptEvent(tr);
97  }
98 
99  if (acceptAll_)
100  return true;
101 
102  return masterElement_->returnStatus(tr);
103  }
104 
105  bool TriggerSelector::acceptEvent(unsigned char const* array_of_trigger_results, int number_of_trigger_paths) const {
106  if (useOld_)
107  return eventSelector_->acceptEvent(array_of_trigger_results, number_of_trigger_paths);
108 
109  if (acceptAll_)
110  return true;
111 
112  // Form HLTGlobalStatus object to represent the array_of_trigger_results
113  edm::HLTGlobalStatus tr(number_of_trigger_paths);
114  int byteIndex = 0;
115  int subIndex = 0;
116  for (int pathIndex = 0; pathIndex < number_of_trigger_paths; ++pathIndex) {
117  int state = array_of_trigger_results[byteIndex] >> (subIndex * 2);
118  state &= 0x3;
119  edm::HLTPathStatus pathStatus(static_cast<edm::hlt::HLTState>(state));
120  tr[pathIndex] = pathStatus;
121  ++subIndex;
122  if (subIndex == 4) {
123  ++byteIndex;
124  subIndex = 0;
125  }
126  }
127  // Now make the decision, based on the HLTGlobalStatus tr,
128  // which we have created from the supplied array of results
129  masterElement_->returnStatus(tr);
130  return masterElement_->returnStatus(tr);
131  }
132 
134  Strings const& tr,
135  TreeElement* parentElement)
136  : op_(NonInit), trigBit_(-1) {
137  std::string str_ = trim(inputString);
138  children_.clear();
139  parent_ = parentElement;
140 
141  size_t offset_ = 0;
142  bool occurrences_ = false;
143 
144  if (str_.empty())
145  throw edm::Exception(edm::errors::Configuration) << "Syntax Error (empty element)" << std::endl;
146 
147  static const size_t bopsSize_ = 2;
148  static const std::string binaryOperators_[bopsSize_] = {"||", "&&"};
149 
150  for (size_t opr = 0; opr < bopsSize_; opr++) {
151  bool exitloop_ = false;
152  while (!exitloop_) {
153  size_t t_end_;
154 
155  std::string tmpStr = str_.substr(offset_);
156  t_end_ = tmpStr.find(binaryOperators_[opr]);
157  if (debug_)
158  std::cout << "offset: " << offset_ << " length: " << t_end_ << " string: " << tmpStr << std::endl;
159 
160  if (t_end_ == std::string::npos) {
161  // right side element
162  if (occurrences_)
163  children_.push_back(new TreeElement(tmpStr, tr, this));
164  break;
165  }
166  t_end_ += offset_;
167  if (t_end_ == 0 || t_end_ + 2 >= str_.size())
168  throw edm::Exception(edm::errors::Configuration) << "Syntax Error (operator is not unary)\n";
169  else {
170  // count bracket in preceeding part
171  size_t brackets_ = 0;
172  for (size_t k = offset_; k < t_end_; k++) {
173  if (str_.at(k) == '(') {
174  brackets_++;
175  } else if (str_.at(k) == ')') {
176  if (brackets_ == 0) {
177  throw edm::Exception(edm::errors::Configuration) << "Syntax Error (brackets)\n";
178  } else {
179  brackets_--;
180  }
181  }
182  }
183  if (brackets_ == 0) {
184  std::string next = str_.substr(offset_, t_end_ - offset_);
185  children_.push_back(new TreeElement(next, tr, this));
186  occurrences_ = true;
187  offset_ = t_end_ + 2;
188  } else {
189  // operator is inside brackets, find another
190  int bracketcnt_ = 0;
191  for (size_t k = offset_; true; k++) {
192  if (k >= str_.size()) {
193  if (bracketcnt_ != 0)
194  throw edm::Exception(edm::errors::Configuration) << "Syntax Error (brackets)\n";
195  exitloop_ = true;
196  if (occurrences_) {
197  children_.push_back(new TreeElement(str_.substr(offset_), tr, this));
198  }
199  break;
200  }
201  // look for another operator
202  if (k >= t_end_ + 2 && bracketcnt_ == 0) {
203  std::string temp = str_.substr(k);
204  size_t pos = temp.find(binaryOperators_[opr]);
205  if (pos == std::string::npos) {
206  exitloop_ = true;
207  if (occurrences_) {
208  children_.push_back(new TreeElement(str_.substr(offset_), tr, this));
209  }
210  break;
211  } else {
212  int brcount_ = 0;
213  for (size_t s = 0; s < pos; s++) {
214  // counting check of brackets from last position to operator
215  if (temp.at(pos) == '(') {
216  brcount_++;
217  } else if (temp.at(pos) == ')') {
218  if (brcount_ == 0) {
219  throw edm::Exception(edm::errors::Configuration) << "Syntax error (brackets)\n";
220  } else {
221  brcount_--;
222  }
223  }
224  }
225  if (brcount_ != 0)
226  throw edm::Exception(edm::errors::Configuration) << "Syntax error (brackets)\n";
227 
228  children_.push_back(new TreeElement(str_.substr(offset_, pos + k), tr, this));
229  offset_ = k + pos + 2;
230  occurrences_ = true;
231  if (offset_ >= str_.size())
232  throw edm::Exception(edm::errors::Configuration) << "Syntax Error (operator is not unary)\n";
233  break;
234  }
235  }
236 
237  if (str_.at(k) == '(')
238  bracketcnt_++;
239  if (str_.at(k) == ')')
240  bracketcnt_--;
241  }
242  }
243  }
244  }
245  if (occurrences_) {
246  if (opr == 0)
247  op_ = OR;
248  else
249  op_ = AND;
250  return;
251  }
252  }
253 
254  if (str_.empty()) {
255  op_ = AND;
256  if (debug_)
257  std::cout << "warning: empty element (will return true)" << std::endl;
258  return;
259  }
260 
261  if (str_.at(0) == '!') {
262  op_ = NOT;
263  std::string next = str_.substr(1);
264  children_.push_back(new TreeElement(next, tr, this));
265  return;
266  }
267  size_t beginBlock_ = str_.find('(');
268  size_t endBlock_ = str_.rfind(')');
269  bool found_lbracket = (beginBlock_ != std::string::npos);
270  bool found_rbracket = (endBlock_ != std::string::npos);
271 
272  if (found_lbracket != found_rbracket) {
273  throw edm::Exception(edm::errors::Configuration) << "Syntax Error (brackets)\n";
274  } else if (found_lbracket && found_rbracket) {
275  if (beginBlock_ >= endBlock_) {
276  throw edm::Exception(edm::errors::Configuration) << "Syntax Error (brackets)\n";
277  }
278  if (beginBlock_ != 0 || endBlock_ != str_.size() - 1)
279  throw edm::Exception(edm::errors::Configuration) << "Syntax Error (invalid character)\n";
280 
281  std::string next = str_.substr(beginBlock_ + 1, endBlock_ - beginBlock_ - 1);
282 
283  children_.push_back(new TreeElement(next, tr, this));
284  op_ = BR; // a bracket
285  return;
286  } else if (!found_lbracket && !found_rbracket) // assume single trigger or wildcard (parsing)
287  {
288  bool ignore_if_missing = true;
289  size_t chr_pos = str_.find('@');
290  if (chr_pos != std::string::npos) {
291  ignore_if_missing = false;
292  str_ = str_.substr(0, chr_pos);
293  }
294 
295  std::vector<Strings::const_iterator> matches = edm::regexMatch(tr, str_);
296  if (matches.empty()) {
297  if (!ignore_if_missing) // && !edm::is_glob(str_))
298  throw edm::Exception(edm::errors::Configuration) << "Trigger name (or match) not present" << std::endl;
299  else {
300  if (debug_)
301  std::cout << "TriggerSelector: Couldn't match any triggers from: " << str_ << std::endl
302  << " Node will not be added " << std::endl;
303  op_ = OR;
304  return;
305  }
306  }
307  if (matches.size() == 1) {
308  // Single Trigger match
309  trigBit_ = distance(tr.begin(), matches[0]);
310  if (debug_)
311  std::cout << "added trigger path: " << trigBit_ << std::endl;
312  return;
313  }
314  if (matches.size() > 1) {
315  op_ = OR;
316  for (size_t l = 0; l < matches.size(); l++)
317  children_.push_back(new TreeElement(*(matches[l]), tr, this));
318  }
319  }
320  }
321 
323  if (!input.empty()) {
324  std::string::size_type pos = input.find_first_not_of(' ');
325  if (pos != std::string::npos)
326  input.erase(0, pos);
327 
328  pos = input.find_last_not_of(' ');
329  if (pos != std::string::npos)
330  input.erase(pos + 1);
331  }
332  return input;
333  }
334 
337  if (!input.empty()) {
338  for (size_t pos = 0; pos < input.size(); pos++) {
339  char ch = input.at(pos);
340  if (ch == '&')
341  output.append("&amp;");
342  else
343  output.append(1, ch);
344  }
345  }
346  return output;
347  }
348 
350  if (children_.empty()) {
351  if (op_ == OR || op_ == NOT)
352  return false;
353  if (op_ == AND || op_ == BR)
354  return true;
355 
356  if (trigBit_ < 0 || (unsigned int)trigBit_ >= trStatus.size())
357  throw edm::Exception(edm::errors::Configuration) << "Internal Error: array out of bounds " << std::endl;
358 
359  if ((trStatus[trigBit_]).state() == edm::hlt::Pass)
360  return true;
361  // else if ((trStatus[trigBit]).state() == edm::hlt::Fail) return false;
362 
363  return false;
364  }
365  if (op_ == NOT) { // NEGATION
366  return !children_[0]->returnStatus(trStatus);
367  }
368  if (op_ == BR) { // BRACKET
369  return children_[0]->returnStatus(trStatus);
370  }
371  if (op_ == AND) { // AND
372  bool status = true;
373  for (size_t i = 0; i < children_.size(); i++)
374  status = status && children_[i]->returnStatus(trStatus);
375  return status;
376  } else if (op_ == OR) { // OR
377  bool status = false;
378  for (size_t i = 0; i < children_.size(); i++)
379  status = status || children_[i]->returnStatus(trStatus);
380  return status;
381  }
383  << "Internal error: reached end of returnStatus(...) op:state= " << op_ << std::endl;
384  return false;
385  }
386 
388  for (std::vector<TreeElement*>::iterator it = children_.begin(); it != children_.end(); it++)
389  delete *it;
390  children_.clear();
391  }
392 } // namespace dqmservices
Definition: CLHEP.h:16
static std::string trim(std::string input)
Definition: config.py:1
uint16_t size_type
const std::string names[nVars_]
static std::string const input
Definition: EdmProvDump.cc:50
static std::string makeXMLString(std::string const &input)
unsigned int size() const
Get number of paths stored.
bool returnStatus(edm::HLTGlobalStatus const &trStatus) const
accept
Definition: HLTenums.h:18
static std::vector< std::string > getEventSelectionVString(edm::ParameterSet const &pset)
TriggerSelector(Strings const &pathspecs, Strings const &names)
std::shared_ptr< TreeElement > masterElement_
TreeElement(std::string const &inputString, Strings const &tr, TreeElement *parentElement=nullptr)
void init(std::string const &path, Strings const &triggernames)
std::vector< std::vector< std::string >::const_iterator > regexMatch(std::vector< std::string > const &strings, std::regex const &regexp)
Definition: RegexMatch.cc:26
bool returnStatus(edm::HLTGlobalStatus const &trStatus) const
static std::vector< std::string > getEventSelectionVString(edm::ParameterSet const &pset)
bool acceptEvent(edm::TriggerResults const &) const
std::shared_ptr< edm::EventSelector > eventSelector_
std::vector< TreeElement * > children_
std::vector< std::string > Strings