CMS 3D CMS Logo

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