CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
EventSelector.cc
Go to the documentation of this file.
1 // Change Log
2 //
3 // 1 - M Fischler 2/8/08 Enable partial wildcards, as in HLT* or !CAL*
4 // A version of this code with cerr debugging traces has
5 // been placed in the doc area.
6 // See ../doc/EventSelector-behavior.doc for details of
7 // reactions to Ready or Exception states.
8 // 1a M Fischler 2/13/08 Clear the all_must_fail_ array at the start of initPathNames.
9 // This is needed in the case of paths with wildcards,
10 // on explicit processes other than a current process
11 // (in which case initPathNames() is called whenever the trigger
12 // PSetID changes, and we don't want the old array
13 // contents to stick around.
14 //
15 // 2 - M Fischler 2/21/08 (In preparation for "exception-awareness" features):
16 // Factored out the decision making logic from the
17 // two forms of acceptEvent, into the single routine
18 // selectionDecision().
19 //
20 // 3 - M Fischler 2/25/08 (Toward commit of "exception-awareness" features):
21 // @exception and noexception& features
22 //
23 // 4- M Fischler 2/28/08 Repair ommision in selectionIsValid when pathspecs
24 // is just "!*"
25 //
26 // 5- M Fischler 3/3/08 testSelectionOverlap and maskTriggerResults appropriate
27 // for the new forms of pathspecs
28 //
29 // 6 - K Biery 03/24/08 modified maskTriggerResults (no longer static) to
30 // avoid performance penalty of creating a new
31 // EventSelector instance for each call (in static case)
32 //
33 
34 
42 
43 #include "boost/algorithm/string.hpp"
44 
45 #include <algorithm>
46 #include <cassert>
47 
48 namespace edm
49 {
52  Strings const& pathNames):
53  pathspecs_(initPathSpecs(pathspecs)),
54  results_from_current_process_(true),
55  accept_all_(initAcceptAll()),
56  absolute_acceptors_(),
57  conditional_acceptors_(),
58  exception_acceptors_(),
59  all_must_fail_(),
60  all_must_fail_noex_(),
61  psetID_(),
62  nPathNames_(0)
63  {
64  initPathNames(pathNames);
65  }
66 
68  pathspecs_(initPathSpecs(pathspecs)),
69  results_from_current_process_(false),
70  accept_all_(initAcceptAll()),
71  absolute_acceptors_(),
72  conditional_acceptors_(),
73  exception_acceptors_(),
74  all_must_fail_(),
75  all_must_fail_noex_(),
76  psetID_(),
77  nPathNames_(0)
78  {
79  }
80 
82  pathspecs_(config.empty() ? Strings() : initPathSpecs(config.getParameter<Strings>("SelectEvents"))),
83  results_from_current_process_(true),
84  accept_all_(initAcceptAll()),
85  absolute_acceptors_(),
86  conditional_acceptors_(),
87  exception_acceptors_(),
88  all_must_fail_(),
89  all_must_fail_noex_(),
90  psetID_(),
91  nPathNames_(0)
92  {
93  initPathNames(pathNames);
94  }
95 
96  Strings
98  Strings trimmedPathSpecs(pathSpecs);
99  for(auto& pathspecifier : trimmedPathSpecs) {
100  boost::erase_all(pathspecifier, " \t"); // whitespace eliminated
101  }
102  // Return value optimization should avoid another copy;
103  return trimmedPathSpecs;
104  }
105 
106  bool
108  if (pathspecs_.empty()) {
109  return true;
110  }
111  // The following are for the purpose of establishing accept_all_ by
112  // virtue of an inclusive set of paths:
113  bool unrestricted_star = false;
114  bool negated_star = false;
115  bool exception_star = false;
116 
117  for(auto const& pathspecifier : pathspecs_) {
118  if (pathspecifier == "*") unrestricted_star = true;
119  if (pathspecifier == "!*") negated_star = true;
120  if (pathspecifier == "exception@*") exception_star = true;
121  }
122  return (unrestricted_star && negated_star && exception_star);
123  }
124 
125  void
127  if(accept_all_) {
128  return;
129  }
130  // std::cerr << "### init entered\n";
131  absolute_acceptors_.clear(),
132  conditional_acceptors_.clear(),
133  exception_acceptors_.clear(),
134  all_must_fail_.clear();
135  all_must_fail_noex_.clear();
136  nPathNames_ = pathNames.size();
137 
138  for(auto const& pathspecifier : pathspecs_) {
139  std::string basePathSpec(pathspecifier);
140  bool noex_demanded = false;
142  and_noexception = pathspecifier.find("&noexception");
143  if (and_noexception != std::string::npos) {
144  basePathSpec = pathspecifier.substr(0,and_noexception);
145  noex_demanded = true;
146  }
147  std::string::size_type and_noex = pathspecifier.find("&noex");
148  if (and_noex != std::string::npos) {
149  basePathSpec = pathspecifier.substr(0,and_noexception);
150  noex_demanded = true;
151  }
152  and_noexception = basePathSpec.find("&noexception");
153  and_noex = basePathSpec.find("&noex");
154  if (and_noexception != std::string::npos ||
155  and_noex != std::string::npos)
157  << "EventSelector::init, An OutputModule is using SelectEvents\n"
158  "to request a trigger name, but specifying &noexceptions twice\n"
159  << "The improper trigger name is: " << pathspecifier << "\n";
160 
161  std::string realname(basePathSpec);
162  bool negative_criterion = false;
163  if (basePathSpec[0] == '!') {
164  negative_criterion = true;
165  realname = basePathSpec.substr(1,std::string::npos);
166  }
167  bool exception_spec = false;
168  if (realname.find("exception@") == 0) {
169  exception_spec = true;
170  realname = realname.substr(10, std::string::npos);
171  // strip off 10 chars, which is length of "exception@"
172  }
173  if (negative_criterion && exception_spec)
175  << "EventSelector::init, An OutputModule is using SelectEvents\n"
176  "to request a trigger name starting with !exception@.\n"
177  "This is not supported.\n"
178  << "The improper trigger name is: " << pathspecifier << "\n";
179  if (noex_demanded && exception_spec)
181  << "EventSelector::init, An OutputModule is using SelectEvents\n"
182  "to request a trigger name starting with exception@ "
183  "and also demanding no &exceptions.\n"
184  << "The improper trigger name is: " << pathspecifier << "\n";
185 
186 
187  // instead of "see if the name can be found in the full list of paths"
188  // we want to find all paths that match this name.
189  std::vector<Strings::const_iterator> matches =
190  regexMatch(pathNames, realname);
191 
192  if (matches.empty() && !is_glob(realname))
193  {
195  << "EventSelector::init, An OutputModule is using SelectEvents\n"
196  "to request a trigger name that does not exist\n"
197  << "The unknown trigger name is: " << realname << "\n";
198  }
199  if (matches.empty() && is_glob(realname))
200  {
201  LogWarning("Configuration")
202  << "EventSelector::init, An OutputModule is using SelectEvents\n"
203  "to request a wildcarded trigger name that does not match any trigger \n"
204  << "The wildcarded trigger name is: " << realname << "\n";
205  }
206 
207  if (!negative_criterion && !noex_demanded && !exception_spec) {
208  for (unsigned int t = 0; t != matches.size(); ++t) {
209  BitInfo bi(distance(pathNames.begin(),matches[t]), true);
210  absolute_acceptors_.push_back(bi);
211  }
212  } else if (!negative_criterion && noex_demanded) {
213  for (unsigned int t = 0; t != matches.size(); ++t) {
214  BitInfo bi(distance(pathNames.begin(),matches[t]), true);
215  conditional_acceptors_.push_back(bi);
216  }
217  } else if (exception_spec) {
218  for (unsigned int t = 0; t != matches.size(); ++t) {
219  BitInfo bi(distance(pathNames.begin(),matches[t]), true);
220  exception_acceptors_.push_back(bi);
221  }
222  } else if (negative_criterion && !noex_demanded) {
223  if (matches.empty()) {
225  << "EventSelector::init, An OutputModule is using SelectEvents\n"
226  "to request all fails on a set of trigger names that do not exist\n"
227  << "The problematic name is: " << pathspecifier << "\n";
228 
229  } else if (matches.size() == 1) {
230  BitInfo bi(distance(pathNames.begin(),matches[0]), false);
231  absolute_acceptors_.push_back(bi);
232  } else {
233  Bits mustfail;
234  for (unsigned int t = 0; t != matches.size(); ++t) {
235  BitInfo bi(distance(pathNames.begin(),matches[t]), false);
236  // We set this to false because that will demand bits are Fail.
237  mustfail.push_back(bi);
238  }
239  all_must_fail_.push_back(mustfail);
240  }
241  } else if (negative_criterion && noex_demanded) {
242  if (matches.empty()) {
244  << "EventSelector::init, An OutputModule is using SelectEvents\n"
245  "to request all fails on a set of trigger names that do not exist\n"
246  << "The problematic name is: " << pathspecifier << "\n";
247 
248  } else if (matches.size() == 1) {
249  BitInfo bi(distance(pathNames.begin(),matches[0]), false);
250  conditional_acceptors_.push_back(bi);
251  } else {
252  Bits mustfail;
253  for (unsigned int t = 0; t != matches.size(); ++t) {
254  BitInfo bi(distance(pathNames.begin(),matches[t]), false);
255  mustfail.push_back(bi);
256  }
257  all_must_fail_noex_.push_back(mustfail);
258  }
259  }
260  } // end of the for loop on pathspecs
261 
262  // std::cerr << "### init exited\n";
263 
264  } // EventSelector::init
265 
267  if (accept_all_) return true;
268 
270  // The path names for prior processes may be different in different runs.
271  // Check for this, and modify the selector accordingly if necessary.
272  if (!psetID_.isValid() || psetID_ != tr.parameterSetID()) {
273  Strings pathNames;
274  bool fromPSetRegistry = false;
276  if (tns->getTrigPaths(tr, pathNames, fromPSetRegistry)) {
277  initPathNames(pathNames);
278  if (fromPSetRegistry) {
279  psetID_ = tr.parameterSetID();
280  } else {
281  // This can only happen for very old data, when the path names were stored
282  // in TriggerResults itself, rather than in the parameter set registry.
283  psetID_.reset();
284  }
285  } else {
286  // This should never happen
288  << "EventSelector::acceptEvent cannot find the trigger names for\n"
289  "a process for which the configuration has requested that the\n"
290  "OutputModule use TriggerResults to select events from. This should\n"
291  "be impossible, please send information to reproduce this problem to\n"
292  "the edm developers.\n";
293  }
294  }
295  }
296 
297  // Now make the decision, based on the supplied TriggerResults tr,
298  // which of course can be treated as an HLTGlobalStatus by inheritance
299 
300  return selectionDecision(tr);
301 
302  } // acceptEvent(TriggerResults const& tr)
303 
304  bool
305  EventSelector::acceptEvent(unsigned char const* array_of_trigger_results,
306  int number_of_trigger_paths) const
307  {
308 
309  // This should never occur unless someone uses this function in
310  // an incorrect way ...
313  << "\nEventSelector.cc::acceptEvent, you are attempting to\n"
314  << "use a bit array for trigger results instead of the\n"
315  << "TriggerResults object for a previous process. This\n"
316  << "will not work and ought to be impossible\n";
317  }
318 
319  if (accept_all_) return true;
320 
321  // Form HLTGlobalStatus object to represent the array_of_trigger_results
322  HLTGlobalStatus tr(number_of_trigger_paths);
323  int byteIndex = 0;
324  int subIndex = 0;
325  for (int pathIndex = 0; pathIndex < number_of_trigger_paths; ++pathIndex)
326  {
327  int state = array_of_trigger_results[byteIndex] >> (subIndex * 2);
328  state &= 0x3;
329  HLTPathStatus pathStatus(static_cast<hlt::HLTState>(state));
330  tr[pathIndex] = pathStatus;
331  ++subIndex;
332  if (subIndex == 4) {
333  ++byteIndex;
334  subIndex = 0;
335  }
336  }
337 
338  // Now make the decision, based on the HLTGlobalStatus tr,
339  // which we have created from the supplied array of results
340 
341  return selectionDecision(tr);
342 
343  } // acceptEvent(array_of_trigger_results, number_of_trigger_paths)
344 
345  bool
347  {
348  if (accept_all_) return true;
349 
350  bool exceptionPresent = false;
351  bool exceptionsLookedFor = false;
352 
353  if (acceptOneBit(absolute_acceptors_, tr)) return true;
355  exceptionPresent = containsExceptions(tr);
356  if (!exceptionPresent) return true;
357  exceptionsLookedFor = true;
358  }
359  if (acceptOneBit(exception_acceptors_, tr, hlt::Exception)) return true;
360 
361  for (auto const& bit : all_must_fail_)
362  {
363  if (acceptAllBits(bit, tr)) return true;
364  }
365  for (auto const& bitn : all_must_fail_noex_)
366  {
367  if (acceptAllBits(bitn, tr)) {
368  if (!exceptionsLookedFor) exceptionPresent = containsExceptions(tr);
369  return (!exceptionPresent);
370  }
371  }
372 
373  // If we have not accepted based on any of the acceptors, nor on any one of
374  // the all_must_fail_ collections, then we reject this event.
375 
376  return false;
377 
378  } // selectionDecision()
379 
380 // Obsolete...
382  BitInfo const& pathInfo) const
383  {
384  return (((pathStatus.state()==hlt::Pass) && (pathInfo.accept_state_)) ||
385  ((pathStatus.state()==hlt::Fail) && !(pathInfo.accept_state_)) ||
386  ((pathStatus.state()==hlt::Exception)));
387  }
388 
389  // Indicate if any bit in the trigger results matches the desired value
390  // at that position, based on the Bits array. If s is Exception, this
391  // looks for a Exceptionmatch; otherwise, true-->Pass, false-->Fail.
392  bool
394  HLTGlobalStatus const& tr,
395  hlt::HLTState const& s) const
396  {
397  bool lookForException = (s == hlt::Exception);
398  for(auto const& bit : b) {
399  hlt::HLTState bstate =
400  lookForException ? hlt::Exception
401  : bit.accept_state_ ? hlt::Pass
402  : hlt::Fail;
403  if (tr[bit.pos_].state() == bstate) return true;
404  }
405  return false;
406  } // acceptOneBit
407 
408  // Indicate if *every* bit in the trigger results matches the desired value
409  // at that position, based on the Bits array: true-->Pass, false-->Fail.
410  bool
412  HLTGlobalStatus const& tr) const
413  {
414  for(auto const& bit : b) {
415  hlt::HLTState bstate = bit.accept_state_ ? hlt::Pass : hlt::Fail;
416  if (tr[bit.pos_].state() != bstate) return false;
417  }
418  return true;
419  } // acceptAllBits
420 
437  Strings const& fullPathList)
438  {
439  // an empty selection list is not valid
440  // (we default an empty "SelectEvents" parameter to {"*","!*"} in
441  // the getEventSelectionVString method below to help avoid this)
442  if (pathspecs.empty())
443  {
444  return false;
445  }
446 
447  // loop over each element in the selection list
448  for (unsigned int idx = 0; idx < pathspecs.size(); idx++)
449  {
450  Strings workingList;
451  workingList.push_back(pathspecs[idx]);
452 
453  // catch exceptions from the EventSelector constructor
454  // (and anywhere else) and mark those as failures.
455  // The EventSelector constructor seems to do the work of
456  // checking if the selection is outside the full trigger list.
457  try
458  {
459  // create an EventSelector instance for this selection
460  EventSelector evtSelector(workingList, fullPathList);
461 
462  // create the TriggerResults instance that we'll use for testing
463  unsigned int fullPathCount = fullPathList.size();
464  HLTGlobalStatus hltGS(fullPathCount);
465  TriggerResults sampleResults(hltGS, fullPathList);
466 
467  // loop over each path
468  bool oneResultMatched = false;
469  for (unsigned int iPath = 0; iPath < fullPathCount; iPath++)
470  {
471  // loop over the possible values for the path status
472  for (int iState = static_cast<int>(hlt::Pass);
473  iState <= static_cast<int>(hlt::Exception);
474  iState++)
475  {
476  sampleResults[iPath] = HLTPathStatus(static_cast<hlt::HLTState>(iState), 0);
477  if (evtSelector.wantAll() || evtSelector.acceptEvent(sampleResults))
478  {
479  oneResultMatched = true;
480  break;
481  }
482 
483  sampleResults.reset(iPath);
484  }
485 
486  if (oneResultMatched) break;
487  }
488 
489  // Finally, check in case the selection element was a wildcarded
490  // negative such as "!*":
491 
492  if (!oneResultMatched) {
493  for (unsigned int iPath = 0; iPath < fullPathCount; iPath++) {
494  sampleResults[iPath] = HLTPathStatus(hlt::Fail, 0);
495  }
496  if (evtSelector.acceptEvent(sampleResults)) {
497  oneResultMatched = true;
498  }
499  }
500 
501  // if none of the possible trigger results matched the
502  // selection element, then we declare the whole selection
503  // list invalid
504  if (!oneResultMatched)
505  {
506  return false;
507  }
508  }
509  catch (edm::Exception const&)
510  {
511  return false;
512  }
513  }
514 
515  // if we made it to this point, then it must have been possible
516  // to satisfy every selection element one way or another
517  return true;
518  }
519 
520 
533  Strings const& pathspec2,
534  Strings const& fullPathList)
535  {
536  bool overlap = false;
537 
538  // first, test that the selection lists are valid
539  if (!selectionIsValid(pathspec1, fullPathList) ||
540  !selectionIsValid(pathspec2, fullPathList))
541  {
543  }
544 
545  // catch exceptions from the EventSelector constructor
546  // (and anywhere else) and mark those as failures
547  try
548  {
549  // create an EventSelector instance for each selection list
550  EventSelector a(pathspec1, fullPathList);
551  EventSelector b(pathspec2, fullPathList);
552 
553  unsigned int N = fullPathList.size();
554 
555  // create the expanded masks for the various decision lists in a and b
556  std::vector<bool>
557  aPassAbs = expandDecisionList(a.absolute_acceptors_,true,N);
558  std::vector<bool>
559  aPassCon = expandDecisionList(a.conditional_acceptors_,true,N);
560  std::vector<bool>
561  aFailAbs = expandDecisionList(a.absolute_acceptors_,false,N);
562  std::vector<bool>
563  aFailCon = expandDecisionList(a.conditional_acceptors_,false,N);
564  std::vector<bool>
565  aExc = expandDecisionList(a.exception_acceptors_,true,N);
566  std::vector< std::vector<bool> > aMustFail;
567  for (unsigned int m = 0; m != a.all_must_fail_.size(); ++m) {
568  aMustFail.push_back(expandDecisionList(a.all_must_fail_[m],false,N));
569  }
570  std::vector< std::vector<bool> > aMustFailNoex;
571  for (unsigned int m = 0; m != a.all_must_fail_noex_.size(); ++m) {
572  aMustFailNoex.push_back
574  }
575 
576  std::vector<bool>
577  bPassAbs = expandDecisionList(b.absolute_acceptors_,true,N);
578  std::vector<bool>
579  bPassCon = expandDecisionList(b.conditional_acceptors_,true,N);
580  std::vector<bool>
581  bFailAbs = expandDecisionList(b.absolute_acceptors_,false,N);
582  std::vector<bool>
583  bFailCon = expandDecisionList(b.conditional_acceptors_,false,N);
584  std::vector<bool>
585  bExc = expandDecisionList(b.exception_acceptors_,true,N);
586  std::vector< std::vector<bool> > bMustFail;
587  for (unsigned int m = 0; m != b.all_must_fail_.size(); ++m) {
588  bMustFail.push_back(expandDecisionList(b.all_must_fail_[m],false,N));
589  }
590  std::vector< std::vector<bool> > bMustFailNoex;
591  for (unsigned int m = 0; m != b.all_must_fail_noex_.size(); ++m) {
592  bMustFailNoex.push_back
594  }
595 
596  std::vector<bool> aPass = combine(aPassAbs, aPassCon);
597  std::vector<bool> bPass = combine(bPassAbs, bPassCon);
598  std::vector<bool> aFail = combine(aFailAbs, aFailCon);
599  std::vector<bool> bFail = combine(bFailAbs, bFailCon);
600 
601  // Check for overlap in the primary masks
602  overlap = overlapping(aPass, bPass) ||
603  overlapping(aFail, bFail) ||
604  overlapping(aExc, bExc);
605  if (overlap) return identical(a,b,N) ? evtSel::ExactMatch
607 
608  // Check for overlap of a primary fail mask with a must fail mask
609  for (unsigned int f = 0; f != aMustFail.size(); ++f) {
610  overlap = overlapping(aMustFail[f], bFail);
611  if (overlap) return evtSel::PartialOverlap;
612  for (unsigned int g = 0; g != bMustFail.size(); ++g) {
613  overlap = subset(aMustFail[f], bMustFail[g]);
614  if (overlap) return evtSel::PartialOverlap;
615  }
616  for (unsigned int g = 0; g != bMustFailNoex.size(); ++g) {
617  overlap = subset(aMustFail[f], bMustFailNoex[g]);
618  if (overlap) return evtSel::PartialOverlap;
619  }
620  }
621  for (unsigned int f = 0; f != aMustFailNoex.size(); ++f) {
622  overlap = overlapping(aMustFailNoex[f], bFail);
623  if (overlap) return evtSel::PartialOverlap;
624  for (unsigned int g = 0; g != bMustFail.size(); ++g) {
625  overlap = subset(aMustFailNoex[f], bMustFail[g]);
626  if (overlap) return evtSel::PartialOverlap;
627  }
628  for (unsigned int g = 0; g != bMustFailNoex.size(); ++g) {
629  overlap = subset(aMustFailNoex[f], bMustFailNoex[g]);
630  if (overlap) return evtSel::PartialOverlap;
631  }
632  }
633  for (unsigned int g = 0; g != bMustFail.size(); ++g) {
634  overlap = overlapping(bMustFail[g], aFail);
635  if (overlap) return evtSel::PartialOverlap;
636  }
637  for (unsigned int g = 0; g != bMustFailNoex.size(); ++g) {
638  overlap = overlapping(bMustFail[g], aFail);
639  if (overlap) return evtSel::PartialOverlap;
640  }
641 
642  }
643  catch (edm::Exception const&)
644  {
646  }
647 
648  // If we get to here without overlap becoming true, there is no overlap
649 
650  return evtSel::NoOverlap;
651 
652  } // testSelectionOverlap
653 
654 #ifdef REMOVE
655 
667  Strings const& pathspec2,
668  Strings const& fullPathList)
669  {
670  // first, test that the selection lists are valid
671  if (!selectionIsValid(pathspec1, fullPathList) ||
672  !selectionIsValid(pathspec2, fullPathList))
673  {
675  }
676 
677  // initialize possible states
678  bool noOverlap = true;
679  bool exactMatch = true;
680 
681  // catch exceptions from the EventSelector constructor
682  // (and anywhere else) and mark those as failures
683  try
684  {
685  // create an EventSelector instance for each selection list
686  EventSelector selector1(pathspec1, fullPathList);
687  EventSelector selector2(pathspec2, fullPathList);
688 
689  // create the TriggerResults instance that we'll use for testing
690  unsigned int fullPathCount = fullPathList.size();
691  HLTGlobalStatus hltGS(fullPathCount);
692  TriggerResults sampleResults(hltGS, fullPathList);
693 
694  // loop over each path
695  for (unsigned int iPath = 0; iPath < fullPathCount; iPath++)
696  {
697  // loop over the possible values for the path status
698  for (int iState = static_cast<int>(hlt::Pass);
699  iState <= static_cast<int>(hlt::Exception);
700  iState++)
701  {
702  sampleResults[iPath] =
703  HLTPathStatus(static_cast<hlt::HLTState>(iState), 0);
704  bool accept1 = selector1.wantAll() ||
705  selector1.acceptEvent(sampleResults);
706  bool accept2 = selector2.wantAll() ||
707  selector2.acceptEvent(sampleResults);
708  if (accept1 != accept2)
709  {
710  exactMatch = false;
711  }
712  if (accept1 && accept2)
713  {
714  noOverlap = false;
715  }
716  sampleResults.reset(iPath);
717  }
718  }
719  }
720  catch (edm::Exception const& excpt)
721  {
723  }
724 
725  if (exactMatch) {return evtSel::ExactMatch;}
726  if (noOverlap) {return evtSel::NoOverlap;}
727  return evtSel::PartialOverlap;
728  }
729 #endif
730 
747  std::shared_ptr<TriggerResults>
749  {
750  // fetch and validate the total number of paths
751  unsigned int fullPathCount = nPathNames_;
752  unsigned int N = fullPathCount;
753  if (fullPathCount != inputResults.size())
754  {
756  << "EventSelector::maskTriggerResults, the TriggerResults\n"
757  << "size (" << inputResults.size()
758  << ") does not match the number of paths in the\n"
759  << "full trigger list (" << fullPathCount << ").\n";
760  }
761 
762  // create a suitable global status object to work with, all in Ready state
763  HLTGlobalStatus mask(fullPathCount);
764 
765  // Deal with must_fail acceptors that would cause selection
766  for (unsigned int m = 0; m < this->all_must_fail_.size(); ++m) {
767  std::vector<bool>
768  f = expandDecisionList(this->all_must_fail_[m],false,N);
769  bool all_fail = true;
770  for (unsigned int ipath = 0; ipath < N; ++ipath) {
771  if ((f[ipath]) && (inputResults [ipath].state() != hlt::Fail)) {
772  all_fail = false;
773  break;
774  }
775  }
776  if (all_fail) {
777  for (unsigned int ipath = 0; ipath < N; ++ipath) {
778  if (f[ipath]) {
779  mask[ipath] = hlt::Fail;
780  }
781  }
782  }
783  }
784  for (unsigned int m = 0; m < this->all_must_fail_noex_.size(); ++m) {
785  std::vector<bool>
786  f = expandDecisionList(this->all_must_fail_noex_[m],false,N);
787  bool all_fail = true;
788  for (unsigned int ipath = 0; ipath < N; ++ipath) {
789  if ((f[ipath]) && (inputResults [ipath].state() != hlt::Fail)) {
790  all_fail = false;
791  break;
792  }
793  }
794  if (all_fail) {
795  for (unsigned int ipath = 0; ipath < N; ++ipath) {
796  if (f[ipath]) {
797  mask[ipath] = hlt::Fail;
798  }
799  }
800  }
801  } // factoring opportunity - work done for fail_noex_ is same as for fail_
802 
803  // Deal with normal acceptors that would cause selection
804  std::vector<bool>
805  aPassAbs = expandDecisionList(this->absolute_acceptors_,true,N);
806  std::vector<bool>
807  aPassCon = expandDecisionList(this->conditional_acceptors_,true,N);
808  std::vector<bool>
809  aFailAbs = expandDecisionList(this->absolute_acceptors_,false,N);
810  std::vector<bool>
811  aFailCon = expandDecisionList(this->conditional_acceptors_,false,N);
812  std::vector<bool>
813  aExc = expandDecisionList(this->exception_acceptors_,true,N);
814  for (unsigned int ipath = 0; ipath < N; ++ipath) {
815  hlt::HLTState s = inputResults [ipath].state();
816  if (((aPassAbs[ipath]) && (s == hlt::Pass))
817  ||
818  ((aPassCon[ipath]) && (s == hlt::Pass))
819  ||
820  ((aFailAbs[ipath]) && (s == hlt::Fail))
821  ||
822  ((aFailCon[ipath]) && (s == hlt::Fail))
823  ||
824  ((aExc[ipath]) && (s == hlt::Exception)))
825  {
826  mask[ipath] = s;
827  }
828  }
829 
830  // Based on the global status for the mask, create and return a
831  // TriggerResults
832  auto maskedResults = std::make_shared<TriggerResults>(mask, inputResults.parameterSetID());
833  return maskedResults;
834  } // maskTriggerResults
835 
836 
837 
838 
839 
840 #ifdef REMOVE
841 
859  std::shared_ptr<TriggerResults>
861  TriggerResults const& inputResults,
862  Strings const& fullPathList)
863  {
864  // fetch and validate the total number of paths
865  unsigned int fullPathCount = fullPathList.size();
866  if (fullPathCount != inputResults.size())
867  {
869  << "EventSelector::maskTriggerResults, the TriggerResults\n"
870  << "size (" << inputResults.size()
871  << ") does not match the number of paths in the\n"
872  << "full trigger list (" << fullPathCount << ").\n";
873  }
874 
875  // create a working copy of the TriggerResults object
876  HLTGlobalStatus hltGS(fullPathCount);
877  auto maskedResults = std::make_shared<TriggerResults>(hltGS, inputResults.parameterSetID());
878  for (unsigned int iPath = 0; iPath < fullPathCount; iPath++)
879  {
880  (*maskedResults)[iPath] = inputResults[iPath];
881  }
882 
883  // create an EventSelector to use when testing if a path status passes
884  EventSelector selector(pathspecs, fullPathList);
885 
886  // create the TriggerResults instance that we'll use for testing
887  HLTGlobalStatus hltGS2(fullPathCount);
888  TriggerResults sampleResults(hltGS2, fullPathList);
889 
890  // loop over each path and reset the path status if needed
891  for (unsigned int iPath = 0; iPath < fullPathCount; iPath++)
892  {
893  sampleResults[iPath] = (*maskedResults)[iPath];
894  if (!selector.wantAll() && !selector.acceptEvent(sampleResults))
895  {
896  maskedResults->reset(iPath);
897  }
898  sampleResults.reset(iPath);
899  }
900  return maskedResults;
901  }
902 #endif
903 
912  std::vector<std::string>
914  {
915  // default the selection to everything (wildcard)
917  selection.push_back("*");
918  selection.push_back("!*");
919  selection.push_back("exception@*");
920 
921  // the SelectEvents parameter is a ParameterSet within
922  // a ParameterSet, so we have to pull it out twice
923  ParameterSet selectEventsParamSet =
924  pset.getUntrackedParameter("SelectEvents", ParameterSet());
925  if (!selectEventsParamSet.empty()) {
926  Strings path_specs =
927  selectEventsParamSet.getParameter<Strings>("SelectEvents");
928  if (!path_specs.empty()) {
929  selection = path_specs;
930  }
931  }
932 
933  // return the result
934  return selection;
935  }
936 
938  {
939  unsigned int e = tr.size();
940  for (unsigned int i = 0; i < e; ++i) {
941  if (tr[i].state() == hlt::Exception) return true;
942  }
943  return false;
944  }
945 
946  // The following routines are helpers for testSelectionOverlap
947 
948  bool
949  EventSelector::identical(std::vector<bool> const& a,
950  std::vector<bool> const& b) {
951  unsigned int n = a.size();
952  if (n != b.size()) return false;
953  for (unsigned int i=0; i!=n; ++i) {
954  if (a[i] != b[i]) return false;
955  }
956  return true;
957  }
958 
959  bool
961  EventSelector const& b,
962  unsigned int N)
963  {
964  // create the expanded masks for the various decision lists in a and b
967  return false;
970  return false;
973  return false;
976  return false;
979  return false;
980  if (a.all_must_fail_.size() != b.all_must_fail_.size()) return false;
981 
982  std::vector< std::vector<bool> > aMustFail;
983  for (unsigned int m = 0; m != a.all_must_fail_.size(); ++m) {
984  aMustFail.push_back(expandDecisionList(a.all_must_fail_[m],false,N));
985  }
986  std::vector< std::vector<bool> > aMustFailNoex;
987  for (unsigned int m = 0; m != a.all_must_fail_noex_.size(); ++m) {
988  aMustFailNoex.push_back
990  }
991  std::vector< std::vector<bool> > bMustFail;
992  for (unsigned int m = 0; m != b.all_must_fail_.size(); ++m) {
993  bMustFail.push_back(expandDecisionList(b.all_must_fail_[m],false,N));
994  }
995  std::vector< std::vector<bool> > bMustFailNoex;
996  for (unsigned int m = 0; m != b.all_must_fail_noex_.size(); ++m) {
997  bMustFailNoex.push_back
999  }
1000 
1001  for (unsigned int m = 0; m != aMustFail.size(); ++m) {
1002  bool match = false;
1003  for (unsigned int k = 0; k != bMustFail.size(); ++k) {
1004  if (identical(aMustFail[m],bMustFail[k])) {
1005  match = true;
1006  break;
1007  }
1008  }
1009  if (!match) return false;
1010  }
1011  for (unsigned int m = 0; m != aMustFailNoex.size(); ++m) {
1012  bool match = false;
1013  for (unsigned int k = 0; k != bMustFailNoex.size(); ++k) {
1014  if (identical(aMustFailNoex[m],bMustFailNoex[k])) {
1015  match = true;
1016  break;
1017  }
1018  }
1019  if (!match) return false;
1020  }
1021 
1022  return true;
1023 
1024  } // identical (EventSelector, EventSelector, N);
1025 
1026  std::vector<bool>
1028  bool PassOrFail,
1029  unsigned int n)
1030  {
1031  std::vector<bool> x(n, false);
1032  for (unsigned int i = 0; i != b.size(); ++i) {
1033  if (b[i].accept_state_ == PassOrFail) x[b[i].pos_] = true;
1034  }
1035  return x;
1036  } // expandDecisionList
1037 
1038  // Determines whether a and b share a true bit at any position
1039  bool EventSelector::overlapping(std::vector<bool> const& a,
1040  std::vector<bool> const& b)
1041  {
1042  if (a.size() != b.size()) return false;
1043  for (unsigned int i = 0; i != a.size(); ++i) {
1044  if (a[i] && b[i]) return true;
1045  }
1046  return false;
1047  } // overlapping
1048 
1049  // determines whether the true bits of a are a non-empty subset of those of b,
1050  // or vice-versa. The subset need not be proper.
1051  bool EventSelector::subset(std::vector<bool> const& a,
1052  std::vector<bool> const& b)
1053  {
1054  if (a.size() != b.size()) return false;
1055  // First test whether a is a non-empty subset of b
1056  bool aPresent = false;
1057  bool aSubset = true;
1058  for (unsigned int i = 0; i != a.size(); ++i) {
1059  if (a[i]) {
1060  aPresent = true;
1061  if (!b[i]) {
1062  aSubset = false;
1063  break;
1064  }
1065  }
1066  }
1067  if (!aPresent) return false;
1068  if (aSubset) return true;
1069 
1070  // Now test whether b is a non-empty subset of a
1071  bool bPresent = false;
1072  bool bSubset = true;
1073  for (unsigned int i = 0; i != b.size(); ++i) {
1074  if (b[i]) {
1075  bPresent = true;
1076  if (!a[i]) {
1077  bSubset = false;
1078  break;
1079  }
1080  }
1081  }
1082  if (!bPresent) return false;
1083  if (bSubset) return true;
1084 
1085  return false;
1086  } // subset
1087 
1088  // Creates a vector of bits which is the OR of a and b
1089  std::vector<bool>
1090  EventSelector::combine(std::vector<bool> const& a,
1091  std::vector<bool> const& b)
1092  {
1093  assert(a.size() == b.size());
1094  std::vector<bool> x(a.size());
1095  for (unsigned int i = 0; i != a.size(); ++i) {
1096  x[i] = a[i] || b[i];
1097  } // a really sharp compiler will optimize the hell out of this,
1098  // exploiting word-size OR operations.
1099  return x;
1100  } // combine
1101 
1102  void
1104  ParameterSetDescription selector;
1105  selector.addOptional<std::vector<std::string> >("SelectEvents");
1106  desc.addUntracked<ParameterSetDescription>("SelectEvents", selector);
1107  }
1108 
1109 }
std::vector< Bits > all_must_fail_noex_
Definition: EventSelector.h:96
EventSelector(Strings const &pathspecs, Strings const &names)
T getParameter(std::string const &) const
void initPathNames(Strings const &pathNames)
bool empty() const
Definition: ParameterSet.h:218
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
ParameterDescriptionBase * addOptional(U const &iLabel, T const &value)
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
static bool selectionIsValid(Strings const &pathspec, Strings const &fullPathList)
std::vector< std::string > Strings
Definition: EventSelector.h:44
EventSelector::Strings Strings
bool const accept_all_
Definition: EventSelector.h:88
HLTState
status of a trigger path
Definition: HLTenums.h:18
assert(m_qm.get())
bool is_glob(std::string const &pattern)
Definition: RegexMatch.cc:18
selection
main part
Definition: corrVsCorr.py:98
reject
Definition: HLTenums.h:20
std::vector< BitInfo > Bits
Definition: EventSelector.h:90
static std::vector< bool > combine(std::vector< bool > const &a, std::vector< bool > const &b)
uint16_t size_type
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
bool overlap(const reco::Muon &muon1, const reco::Muon &muon2, double pullX=1.0, double pullY=1.0, bool checkAdjacentChambers=false)
Strings initPathSpecs(Strings const &pathSpecs)
T x() const
Cartesian x coordinate.
bool acceptAllBits(Bits const &b, HLTGlobalStatus const &tr) const
bool acceptEvent(TriggerResults const &)
std::vector< Bits > all_must_fail_
Definition: EventSelector.h:95
accept
Definition: HLTenums.h:19
void reset()
Reset status for all paths.
unsigned int size() const
Get number of paths stored.
Strings const pathspecs_
Definition: EventSelector.h:86
static std::vector< std::string > getEventSelectionVString(edm::ParameterSet const &pset)
bool acceptOneBit(Bits const &b, HLTGlobalStatus const &tr, hlt::HLTState const &s=hlt::Ready) const
bool acceptTriggerPath(HLTPathStatus const &, BitInfo const &) const
double f[11][100]
static void fillDescription(ParameterSetDescription &desc)
bool wantAll() const
Definition: EventSelector.h:55
hlt::HLTState state() const
get state of path
Definition: HLTPathStatus.h:51
static bool overlapping(std::vector< bool > const &a, std::vector< bool > const &b)
static evtSel::OverlapResult testSelectionOverlap(Strings const &pathspec1, Strings const &pathspec2, Strings const &fullPathList)
bool selectionDecision(HLTGlobalStatus const &tr) const
static bool subset(std::vector< bool > const &a, std::vector< bool > const &b)
#define N
Definition: blowfish.cc:9
tuple idx
DEBUGGING if hasattr(process,&quot;trackMonIterativeTracking2012&quot;): print &quot;trackMonIterativeTracking2012 D...
double b
Definition: hdecay.h:120
A selector of events.
Definition: EventSelector.h:16
ParameterSetID psetID_
Definition: EventSelector.h:98
std::vector< std::vector< std::string >::const_iterator > regexMatch(std::vector< std::string > const &strings, std::regex const &regexp)
Definition: RegexMatch.cc:30
static bool identical(std::vector< bool > const &a, std::vector< bool > const &b)
bool isValid() const
Definition: Hash.h:150
double a
Definition: hdecay.h:121
static std::vector< bool > expandDecisionList(Bits const &b, bool PassOrFail, unsigned int n)
bool const results_from_current_process_
Definition: EventSelector.h:87
volatile std::atomic< bool > shutdown_flag false
std::shared_ptr< TriggerResults > maskTriggerResults(TriggerResults const &inputResults)
void reset()
Definition: Hash.h:143
const ParameterSetID & parameterSetID() const
Get stored parameter set id.
bool containsExceptions(HLTGlobalStatus const &tr) const
hlt::HLTState state(const unsigned int i) const
Get status of ith path.
std::string match(BranchDescription const &a, BranchDescription const &b, std::string const &fileName)