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.8.4.1 2011/03/07 11:33:05 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  int brackets_=0;
212  for (size_t k=offset_;k<t_end_;k++) {
213  if (str_.at(k)=='(') brackets_++;
214  if (str_.at(k)==')') brackets_--;
215  if (brackets_<0)
217  << "Syntax Error (brackets)\n";
218  }
219  if (brackets_==0) {
220  std::string next = str_.substr(offset_,t_end_-offset_);
221  children_.push_back(new TreeElement(next,tr,this));
222  occurrences_=true;
223  offset_ = t_end_+2;
224  }
225  else {
226  //operator is inside brackets, find another
227  int bracketcnt_ = 0;
228  for (size_t k=offset_;true;k++) {
229  if (k>=str_.size()) {
230  if (bracketcnt_!=0)
232  << "Syntax Error (brackets)\n";
233  exitloop_=true;
234  if (occurrences_) {
235  children_.push_back(new TreeElement(str_.substr(offset_),tr,this));
236  }
237  break;
238  }
239  //look for another operator
240  if (k>=t_end_+2 && bracketcnt_==0) {
241  std::string temp = str_.substr(k);
242  size_t pos = temp.find(binaryOperators_[opr]);
243  if (pos == std::string::npos) {
244  exitloop_=true;
245  if (occurrences_) {
246  children_.push_back(new TreeElement(str_.substr(offset_),tr,this));
247  }
248  break;
249  }
250  else {
251  int brcount_ = 0;
252  for (size_t s=0;s<pos;s++) {
253  //counting check of brackets from last position to operator
254  if (temp.at(pos)=='(') brcount_++;
255  if (temp.at(pos)==')') brcount_--;
256  if (brcount_<0)
258  << "Syntax error (brackets)\n";
259  }
260  if (brcount_!=0)
262  << "Syntax error (brackets)\n";
263 
264  children_.push_back(new TreeElement(str_.substr(offset_,pos+k),tr,this));
265  offset_=k+pos+2;
266  occurrences_=true;
267  if (offset_>=str_.size())
269  << "Syntax Error (operator is not unary)\n";
270  break;
271  }
272 
273  }
274 
275 
276  if (str_.at(k)=='(') bracketcnt_++;
277  if (str_.at(k)==')') bracketcnt_--;
278 
279  }
280  }
281  }
282 
283  }
284  if (occurrences_) {
285  if (opr==0) op_=OR;
286  else op_=AND;
287  return;
288  }
289  }
290 
291  if (str_.empty()) {
292  op_=AND;
293  if (debug_) std::cout << "warning: empty element (will return true)"<< std::endl;
294  return;
295  }
296 
297  if (str_.at(0)=='!') {
298  op_=NOT;
299  std::string next = str_.substr(1);
300  children_.push_back(new TreeElement(next,tr,this));
301  return;
302  }
303  size_t beginBlock_ =str_.find('(');
304  size_t endBlock_ =str_.rfind(')');
305  bool found_lbracket = (beginBlock_ != std::string::npos);
306  bool found_rbracket = (endBlock_ != std::string::npos);
307 
308  if (found_lbracket != found_rbracket) {
309  throw edm::Exception(edm::errors::Configuration) << "Syntax Error (brackets)\n";
310  }
311  else if (found_lbracket && found_rbracket)
312  {
313  if (beginBlock_>=endBlock_) {
314  throw edm::Exception(edm::errors::Configuration) << "Syntax Error (brackets)\n";
315  }
316  if (beginBlock_!=0 || endBlock_!=str_.size()-1)
317  throw edm::Exception(edm::errors::Configuration) << "Syntax Error (invalid character)\n";
318 
319  std::string next = str_.substr(beginBlock_+1,endBlock_-beginBlock_-1);
320 
321  children_.push_back(new TreeElement(next,tr,this));
322  op_=BR; //a bracket
323  return;
324  }
325  else if (!found_lbracket && !found_rbracket) //assume single trigger or wildcard (parsing)
326  {
327  bool ignore_if_missing = true;
328  size_t chr_pos = str_.find("@");
329  if (chr_pos!= std::string::npos) {
330  ignore_if_missing=false;
331  str_=str_.substr(0,chr_pos);
332  }
333 
334  std::vector<Strings::const_iterator> matches = edm::regexMatch(tr,str_);
335  if (matches.empty()) {
336  if (!ignore_if_missing)// && !edm::is_glob(str_))
337  throw edm::Exception(edm::errors::Configuration) << "Trigger name (or match) not present" << std::endl;
338  else {
339  if (debug_)
340  std::cout << "TriggerSelector: Couldn't match any triggers from: "<< str_<< std::endl
341  << " Node will not be added "<< std::endl;
342  op_=OR;
343  return;
344  }
345  }
346  if (matches.size()==1) {
347  //Single Trigger match
348  trigBit_ = distance(tr.begin(),matches[0]);
349  if (debug_) std::cout << "added trigger path: " << trigBit_ << std::endl;
350  return;
351  }
352  if (matches.size()>1) {
353  op_=OR;
354  for (size_t l=0;l<matches.size();l++)
355  children_.push_back(new TreeElement(*(matches[l]),tr,this));
356  }
357  }
358  }
359 
360  std::string TriggerSelector::trim(std::string input)
361  {
362  if (!input.empty())
363  {
364  std::string::size_type pos = input.find_first_not_of(" ");
365  if (pos != std::string::npos)
366  input.erase(0,pos);
367 
368  pos = input.find_last_not_of(" ");
369  if (pos != std::string::npos)
370  input.erase(pos+1);
371  }
372  return input;
373  }
374 
375  std::string TriggerSelector::makeXMLString(std::string const& input)
376  {
377  std::string output;
378  if (!input.empty()) {
379  for (size_t pos=0;pos<input.size();pos++) {
380  char ch = input.at(pos);
381  if (ch=='&') output.append("&amp;");
382  else output.append(1,ch);
383  }
384  }
385  return output;
386  }
387 
388 
390  (
391  edm::HLTGlobalStatus const& trStatus
392  ) const
393  {
394 
395  if (children_.empty()) {
396 
397  if (op_==OR || op_==NOT) return false;
398  if (op_==AND || op_==BR) return true;
399 
400  if (trigBit_<0 || (unsigned int)trigBit_>=trStatus.size())
402  << "Internal Error: array out of bounds " << std::endl;
403 
404  if ((trStatus[trigBit_]).state() == edm::hlt::Pass) return true;
405  //else if ((trStatus[trigBit]).state() == edm::hlt::Fail) return false;
406 
407  return false;
408  }
409  if (op_==NOT) { //NEGATION
410  return !children_[0]->returnStatus(trStatus);
411  }
412  if (op_==BR) { //BRACKET
413  return children_[0]->returnStatus(trStatus);
414  }
415  if (op_==AND) { //AND
416  bool status = true;
417  for (size_t i=0;i<children_.size();i++) status = status && children_[i]->returnStatus(trStatus);
418  return status;
419  }
420  else if (op_==OR) { //OR
421  bool status = false;
422  for (size_t i=0;i<children_.size();i++) status = status || children_[i]->returnStatus(trStatus);
423  return status;
424  }
425  throw edm::Exception(edm::errors::Configuration) << "Internal error: reached end of returnStatus(...) op:state= " << op_ << std::endl;
426  return false;
427  }
428 
429 
431  {
432  for (std::vector<TreeElement*>::iterator it=children_.begin();it!=children_.end();it++)
433  delete *it;
434  children_.clear();
435  }
436 
437 } // namespace stor
438 
439 
std::vector< TreeElement * > children_
T getParameter(std::string const &) const
bool empty() const
Definition: ParameterSet.h:212
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
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)
tuple pset
Definition: CrabTask.py:85
std::vector< std::vector< std::string >::const_iterator > regexMatch(std::vector< std::string > const &strings, boost::regex const &regexp)
Definition: RegexMatch.cc:22
bool returnStatus(edm::HLTGlobalStatus const &trStatus) const
tuple input
Definition: collect_tpl.py:10
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 config
Definition: cmsDriver.py:17
tuple cout
Definition: gather_cfg.py:41
string s
Definition: asciidump.py:422
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)