EventSelector.cc
Go to the documentation of this file.
2 // vim: set sw=2 expandtab :
3 
10 #include "fhiclcpp/ParameterSet.h"
14 #include "range/v3/view.hpp"
15 
16 #include <algorithm>
17 #include <cassert>
18 #include <string>
19 #include <vector>
20 
21 using namespace art;
22 using namespace cet;
23 using namespace std;
24 
26 
27 namespace {
28  unsigned int
29  path_position(vector<string> const& trigger_path_names,
31  {
32  return distance(trigger_path_names.begin(), it);
33  }
34 
35  bool
36  remove_noexception(std::string const& full_path_specifier,
37  std::string& specifier)
38  {
39  string const noexLiteral{"&noexception"};
40  auto const noexception_pos = specifier.find(noexLiteral);
41  if (noexception_pos == string::npos) {
42  return false;
43  }
44 
45  if ((noexception_pos + noexLiteral.length()) < specifier.length()) {
47  << "EventSelector::init, A module is using SelectEvents\n"
48  << "to request a trigger name that has extra characters after "
49  "'&noexception'.\n"
50  << "The improper trigger name is: " << full_path_specifier << "\n";
51  }
52  specifier.erase(noexception_pos);
53  return true;
54  }
55 
56  bool
57  remove_negation(std::string& specifier)
58  {
59  if (specifier[0] != '!') {
60  return false;
61  }
62  specifier.erase(0, 1);
63  return true;
64  }
65 
66  bool
67  remove_exception(std::string const& full_path_specifier,
68  std::string& specifier)
69  {
70  // Remove "exception@"
71  string const exLiteral{"exception@"};
72  auto const pos = specifier.find(exLiteral);
73  if (pos == 0) {
74  specifier.erase(0, exLiteral.length());
75  return true;
76  }
77 
78  // Any other non-npos position is illegal.
79  if (pos != string::npos) {
81  << "EventSelector::init, A module is using SelectEvents\n"
82  << "to request a trigger name that has disallowed characters before "
83  "'exception@'.\n"
84  << "The improper trigger name is: " << full_path_specifier << "\n";
85  }
86  return false;
87  }
88 
89  // Indicate if any bit in the trigger results matches the desired value
90  // at that position, based on the bits array. If s is Exception, this
91  // looks for a Exceptionmatch; otherwise, true-->Pass, false-->Fail.
92  bool
93  any_bit(vector<BitInfo> const& bits,
94  HLTGlobalStatus const& tr,
95  hlt::HLTState const s = hlt::Ready)
96  {
97  bool const check_for_exception = (s == hlt::Exception);
98  return std::any_of(
99  begin(bits), end(bits), [check_for_exception, &tr](auto const& b) {
100  hlt::HLTState const bstate = check_for_exception ?
102  b.accept_state ? hlt::Pass : hlt::Fail;
103  return tr.at(b.pos).state() == bstate;
104  });
105  }
106 
107  // Indicate if *every* bit in the trigger results matches the desired value
108  // at that position, based on the bits array: true-->Pass, false-->Fail.
109  bool
110  all_bits(vector<BitInfo> const& bits, HLTGlobalStatus const& tr)
111  {
112  return std::all_of(begin(bits), end(bits), [&tr](auto const& b) {
113  hlt::HLTState const bstate = b.accept_state ? hlt::Pass : hlt::Fail;
114  return tr.at(b.pos).state() == bstate;
115  });
116  }
117 
118  bool
119  accept_all(vector<string> const& path_specs)
120  {
121  if (empty(path_specs)) {
122  return true;
123  }
124 
125  // The following are for the purpose of establishing accept_all_ by
126  // virtue of an inclusive set of paths.
127  bool unrestricted_star = false;
128  bool negated_star = false;
129  bool exception_star = false;
130 
131  for (string const& pathSpecifier : path_specs) {
132  assert(not art::detail::has_whitespace(pathSpecifier));
133 
134  if (pathSpecifier == "*") {
135  unrestricted_star = true;
136  } else if (pathSpecifier == "!*") {
137  negated_star = true;
138  } else if (pathSpecifier == "exception@*") {
139  exception_star = true;
140  }
141  }
142  return unrestricted_star && negated_star && exception_star;
143  }
144 }
145 
146 namespace art {
147 
148  EventSelector::EventSelector(vector<string> const& pathspecs)
149  : path_specs_{pathspecs}, accept_all_{accept_all(path_specs_)}
150  {
151  acceptors_.expand_to_num_schedules();
152  }
153 
154  // This should be called per new file.
157  {
158  fhicl::ParameterSet pset;
160  // This should never happen
162  << "EventSelector::acceptEvent cannot find the trigger names for\n"
163  << "a process for which the configuration has requested that the\n"
164  << "OutputModule use TriggerResults to select events from. This "
165  "should\n"
166  << "be impossible, please send information to reproduce this problem "
167  "to\n"
168  << "the art developers at artists@fnal.gov.\n";
169  }
170  auto const trigger_path_specs =
171  pset.get<vector<string>>("trigger_paths", {});
172  if (trigger_path_specs.size() != tr.size()) {
174  << "EventSelector::acceptEvent: Trigger names vector and\n"
175  << "TriggerResults are different sizes. This should be impossible,\n"
176  << "please send information to reproduce this problem to\n"
177  << "the art developers.\n";
178  }
179 
180  std::vector<BitInfo> absolute_acceptors;
181  std::vector<BitInfo> conditional_acceptors;
182  std::vector<BitInfo> exception_acceptors;
183  std::vector<std::vector<BitInfo>> all_must_fail;
184  std::vector<std::vector<BitInfo>> all_must_fail_noex;
185 
186  for (string const& pathSpecifier : path_specs_) {
187  string specifier{pathSpecifier};
188 
189  bool const noex_demanded = remove_noexception(pathSpecifier, specifier);
190  bool const negative_criterion = remove_negation(specifier);
191  bool const exception_spec = remove_exception(pathSpecifier, specifier);
192 
193  if (negative_criterion && exception_spec) {
195  << "EventSelector::init, A module is using SelectEvents\n"
196  << "to request a trigger name starting with !exception@.\n"
197  << "This is not supported.\n"
198  << "The improper trigger name is: " << pathSpecifier << "\n";
199  }
200 
201  if (noex_demanded && exception_spec) {
203  << "EventSelector::init, A module is using SelectEvents\n"
204  << "to request a trigger name starting with exception@ "
205  << "and also demanding &noexception.\n"
206  << "The improper trigger name is: " << pathSpecifier << "\n";
207  }
208 
209  // instead of "see if the name can be found in the full list of
210  // paths" we want to find all paths that match this name.
211  //
212  // 'specifier' now corresponds to the real trigger-path name,
213  // free of any decorations.
214  string const& realname{specifier};
215  auto const matches = regexMatch(trigger_path_specs, realname);
216  if (matches.empty()) {
217  if (is_glob(realname)) {
218  mf::LogWarning("Configuration")
219  << "EventSelector::init, A module is using SelectEvents\n"
220  "to request a wildcarded trigger name that "
221  "does not match any trigger.\n"
222  "The wildcarded trigger name is: "
223  << realname
224  << " (from trigger-path specification: " << pathSpecifier << ") \n";
225  } else {
227  << "EventSelector::init, A module is using SelectEvents\n"
228  "to request a trigger name that does not exist.\n"
229  "The unknown trigger name is: "
230  << realname
231  << " (from trigger-path specification: " << pathSpecifier << ") \n";
232  }
233  }
234 
235  auto makeBitInfoPass = [&trigger_path_specs](auto m) {
236  return BitInfo{path_position(trigger_path_specs, m), true};
237  };
238  auto makeBitInfoFail = [&trigger_path_specs](auto m) {
239  return BitInfo{path_position(trigger_path_specs, m), false};
240  };
241 
242  if (!negative_criterion && !noex_demanded && !exception_spec) {
244  matches, back_inserter(absolute_acceptors), makeBitInfoPass);
245  continue;
246  }
247 
248  if (!negative_criterion && noex_demanded) {
250  matches, back_inserter(conditional_acceptors), makeBitInfoPass);
251  continue;
252  }
253 
254  if (exception_spec) {
256  matches, back_inserter(exception_acceptors), makeBitInfoPass);
257  continue;
258  }
259 
260  if (negative_criterion && !noex_demanded) {
261  if (matches.empty()) {
263  << "EventSelector::init, A module is using SelectEvents\n"
264  "to request all fails on a set of trigger names that do not "
265  "exist\n"
266  << "The problematic name is: " << pathSpecifier << "\n";
267  }
268 
269  if (matches.size() == 1) {
270  BitInfo bi{path_position(trigger_path_specs, matches[0]), false};
271  absolute_acceptors.push_back(bi);
272  } else {
273  // We set this to false because that will demand bits are Fail.
274  auto must_fail = matches | ranges::views::transform(makeBitInfoFail) |
275  ranges::to_vector;
276  all_must_fail.push_back(move(must_fail));
277  }
278  continue;
279  }
280 
281  if (negative_criterion && noex_demanded) {
282  if (matches.empty()) {
284  << "EventSelector::init, A module is using SelectEvents\n"
285  "to request all fails on a set of trigger names that do not "
286  "exist\n"
287  << "The problematic name is: " << pathSpecifier << "\n";
288  }
289 
290  if (matches.size() == 1) {
291  BitInfo bi{path_position(trigger_path_specs, matches[0]), false};
292  conditional_acceptors.push_back(bi);
293  } else {
294  auto must_fail = matches | ranges::views::transform(makeBitInfoFail) |
295  ranges::to_vector;
296  all_must_fail_noex.push_back(move(must_fail));
297  }
298  }
299  }
300  return ScheduleData{tr.parameterSetID(),
301  absolute_acceptors,
302  conditional_acceptors,
303  exception_acceptors,
304  all_must_fail,
305  all_must_fail_noex};
306  }
307 
308  bool
310  TriggerResults const& tr) const
311  {
312  if (accept_all_) {
313  return true;
314  }
315 
316  auto& data = acceptors_.at(id);
317  if (data.psetID != tr.parameterSetID()) {
318  data = data_for(tr);
319  }
320  return selectionDecision(data, tr);
321  }
322 
323  bool
325  HLTGlobalStatus const& tr) const
326  {
327  if (accept_all_) {
328  return true;
329  }
330 
331  if (any_bit(data.absolute_acceptors, tr)) {
332  return true;
333  }
334 
335  bool exceptionPresent = false;
336  bool exceptionsLookedFor = false;
337  if (any_bit(data.conditional_acceptors, tr)) {
338  exceptionPresent = tr.error();
339  if (!exceptionPresent) {
340  return true;
341  }
342  exceptionsLookedFor = true;
343  }
344 
345  if (any_bit(data.exception_acceptors, tr, hlt::Exception)) {
346  return true;
347  }
348 
349  for (auto const& f : data.all_must_fail) {
350  if (all_bits(f, tr)) {
351  return true;
352  }
353  }
354 
355  for (auto const& fn : data.all_must_fail_noex) {
356  if (all_bits(fn, tr)) {
357  if (!exceptionsLookedFor) {
358  exceptionPresent = tr.error();
359  }
360  return !exceptionPresent;
361  }
362  }
363  return false;
364  }
365 
366 } // namespace art
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
std::vector< std::string > const path_specs_
Definition: EventSelector.h:26
PerScheduleContainer< ScheduleData > acceptors_
Definition: EventSelector.h:36
std::string string
Definition: nybbler.cc:12
static collection_type const & get() noexcept
STL namespace.
intermediate_table::const_iterator const_iterator
std::vector< std::vector< std::string >::const_iterator > regexMatch(std::vector< std::string > const &strings, std::string const &pattern)
Definition: RegexMatch.cc:25
HLTState
Definition: HLTenums.h:6
std::vector< BitInfo > conditional_acceptors
Definition: EventSelector.h:31
fhicl::ParameterSetID const & parameterSetID() const
std::vector< std::vector< BitInfo > > all_must_fail_noex
Definition: EventSelector.h:34
QAsciiDict< Entry > fn
std::vector< PathSpec > path_specs(std::vector< std::string > const &path_spec_strs)
Definition: PathSpec.cc:34
bool acceptEvent(ScheduleID id, TriggerResults const &tr) const
def move(depos, offset)
Definition: depos.py:107
T get(std::string const &key) const
Definition: ParameterSet.h:271
Strings const trigger_path_names
std::vector< BitInfo > absolute_acceptors
Definition: EventSelector.h:30
bool has_whitespace(std::string const &str)
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
auto transform_all(Container &, OutputIt, UnaryOp)
bool const accept_all_
Definition: EventSelector.h:27
std::vector< std::vector< BitInfo > > all_must_fail
Definition: EventSelector.h:33
std::size_t size() const
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
HLTPathStatus const & at(unsigned const i) const
ScheduleData data_for(TriggerResults const &tr) const
bool selectionDecision(ScheduleData const &data, HLTGlobalStatus const &) const
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
static bool * b
Definition: config.cpp:1043
EventSelector::BitInfo BitInfo
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
hlt::HLTState state() const
std::vector< BitInfo > exception_acceptors
Definition: EventSelector.h:32
static QCString * s
Definition: config.cpp:1042
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:97
bool is_glob(std::string const &pattern)
Definition: RegexMatch.cc:11
EventSelector(std::vector< std::string > const &pathspecs)