LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
EventIDMatcher.cc
Go to the documentation of this file.
1 // vim: set sw=2 :
3 
8 
9 #include <cstdio>
10 #include <regex>
11 #include <sstream>
12 #include <string>
13 #include <vector>
14 
15 using namespace std;
16 
17 namespace art {
18 
19  EventIDMatcher::EventIDMatcher(std::string const& pattern)
20  : pattern_(), parsed_patterns_()
21  {
22  if (pattern.empty()) {
24  << "EventIDMatcher given an empty pattern!";
25  }
26  pattern_.push_back(pattern);
27  parsed_patterns_.resize(1);
28  parse_pattern();
29  }
30 
31  EventIDMatcher::EventIDMatcher(std::vector<std::string> const& patterns)
33  {
34  if (patterns.size() == 0) {
36  << "EventIDMatcher given an empty list of patterns!";
37  }
38  pattern_.reserve(patterns.size());
39  parsed_patterns_.resize(patterns.size());
40  for (auto const& val : patterns) {
41  if (val.empty()) {
43  << "EventIDMatcher given an empty pattern!";
44  }
45  pattern_.push_back(val);
46  }
47  parse_pattern();
48  }
49 
50  void
52  {
53  regex pat( // matches ('*' /*wildcard*/ | digits /*single*/ | digits -
54  // digits /*range*/)(',' /*list*/ | ':' /*part*/ | eol)
55  "(" // 1
56  "[[:blank:]]*"
57  "(" // 2
58  "([*])|" // 3
59  "([0-9]+)|" // 4
60  "([0-9]+)" // 5
61  "[[:blank:]]*-[[:blank:]]*"
62  "([0-9]+)" // 6
63  ")"
64  "[[:blank:]]*"
65  "([,:]|$)" // 7
66  ")");
67  int patno = -1;
68  for (auto const& given_pattern : pattern_) {
69  ++patno;
70  regex_iterator<string::const_iterator> I(
71  given_pattern.cbegin(), given_pattern.cend(), pat);
72  regex_iterator<string::const_iterator> E;
73  auto prev_pos = 0L;
74  auto prev_len = 0L;
75  char prev_sep = '\0';
76  parsed_patterns_[patno].resize(3);
77  // Note: 0: run, 1: subrun, 2: event
78  auto part_num = 0U;
79  for (; I != E; ++I) {
80  auto const& m = *I;
81  char sep = '\0';
82  if (m.str(7).size()) {
83  sep = m.str(7)[0];
84  }
85  if (m.position() != (prev_pos + prev_len)) {
86  // err, non-matching characters between
87  ostringstream buf;
88  buf << '\n';
89  buf << "Illegal character in pattern near here:\n";
90  buf << given_pattern;
91  buf << '\n';
92  for (auto i = 0L; i < (prev_pos + prev_len); ++i) {
93  buf << ' ';
94  }
95  buf << "^\n";
96  throw art::Exception(errors::LogicError) << buf.str();
97  }
98  if (m[3].matched) {
99  // wildcard
100  parsed_patterns_[patno][part_num].push_back({0U, 0U, true});
101  } else if (m[4].matched) {
102  // single num
103  auto num = 0U;
104  for (auto val : m.str(4)) {
105  num = (num * 10U) + (val - '0');
106  }
107  parsed_patterns_[patno][part_num].push_back({num, num, false});
108  } else {
109  // range
110  auto num_low = 0U;
111  for (auto val : m.str(5)) {
112  num_low = (num_low * 10U) + (val - '0');
113  }
114  auto num_high = 0U;
115  for (auto val : m.str(6)) {
116  num_high = (num_high * 10U) + (val - '0');
117  }
118  parsed_patterns_[patno][part_num].push_back(
119  {num_low, num_high, false});
120  }
121  if (sep == ':') {
122  if (part_num == 0U) {
123  // at end of run part
124  } else if (part_num == 1U) {
125  // at end of subrun part
126  } else if (part_num == 2U) {
127  // error, event part ended with a ':'
128  ostringstream buf;
129  buf << '\n';
130  buf
131  << "Syntax error, event part of pattern ended with a ':' here:\n";
132  buf << given_pattern;
133  buf << '\n';
134  for (auto i = 0L; i < m.position(7); ++i) {
135  buf << ' ';
136  }
137  buf << "^\n";
138  throw art::Exception(errors::LogicError) << buf.str();
139  }
140  ++part_num;
141  } else if (sep == ',') {
142  // range continues
143  } else {
144  // at end of event part, and end of string
145  }
146  prev_pos = m.position();
147  prev_len = m.length();
148  prev_sep = sep;
149  }
150  if (prev_sep != '\0') {
151  // err, last match did not finish properly
152  ostringstream buf;
153  buf << '\n';
154  printf("pep: Syntax error, near here:\n");
155  buf << given_pattern;
156  buf << '\n';
157  for (auto i = 0L; i < (prev_pos + prev_len); ++i) {
158  buf << ' ';
159  }
160  buf << "^\n";
161  throw art::Exception(errors::LogicError) << buf.str();
162  }
163  if (static_cast<string::size_type>(prev_pos + prev_len) !=
164  given_pattern.size()) {
165  // err, did not match whole string
166  ostringstream buf;
167  buf << '\n';
168  printf("pep: Syntax error, near here:\n");
169  buf << given_pattern;
170  buf << '\n';
171  for (auto i = 0L; i < (prev_pos + prev_len); ++i) {
172  buf << ' ';
173  }
174  buf << "^\n";
175  throw art::Exception(errors::LogicError) << buf.str();
176  }
177  }
178  }
179 
180  bool
182  {
183  return match(eid);
184  }
185 
186  bool
187  EventIDMatcher::match(EventID const& eid) const
188  {
189  if (!eid.isValid() || eid.isFlush()) {
190  return false;
191  }
192  if (!eid.subRunID().isValid() || eid.subRunID().isFlush()) {
193  return false;
194  }
195  if (!eid.runID().isValid() || eid.runID().isFlush()) {
196  return false;
197  }
198 
199  bool ret = false;
200  for (auto const& parsed_pattern : parsed_patterns_) {
201  for (auto i = 0U; i < 3; ++i) {
202  for (auto const& val : parsed_pattern[i]) {
203  if (val.wildcard) {
204  // Wildcards always match
205  ret = true;
206  break;
207  } else if (val.low == val.high) {
208  // Single value match
209  if (i == 0U) {
210  // run
211  if (eid.run() == val.low) {
212  ret = true;
213  break;
214  }
215  } else if (i == 1U) {
216  // subrun
217  if (eid.subRun() == val.low) {
218  ret = true;
219  break;
220  }
221  } else {
222  // event
223  if (eid.event() == val.low) {
224  ret = true;
225  break;
226  }
227  }
228  } else {
229  // Range match
230  if (i == 0U) {
231  // run
232  if ((eid.run() >= val.low) && (eid.run() <= val.high)) {
233  ret = true;
234  break;
235  }
236  } else if (i == 1U) {
237  // subrun
238  if ((eid.subRun() >= val.low) && (eid.subRun() <= val.high)) {
239  ret = true;
240  break;
241  }
242  } else {
243  // event
244  if ((eid.event() >= val.low) && (eid.event() <= val.high)) {
245  ret = true;
246  break;
247  }
248  }
249  }
250  }
251  if (!ret) {
252  // nothing matched
253  break;
254  }
255  if (i != 2U) {
256  // Reset for next part.
257  ret = false;
258  }
259  }
260  if (ret) {
261  // We matched, return immediately.
262  return ret;
263  }
264  }
265  // We never matched.
266  return ret;
267  }
268 
269 } // namespace art
bool isValid() const
Definition: EventID.h:122
RunID const & runID() const
Definition: EventID.h:92
bool isFlush() const
Definition: RunID.h:76
SubRunID const & subRunID() const
Definition: EventID.h:104
STL namespace.
bool isFlush() const
Definition: EventID.h:128
RunNumber_t run() const
Definition: EventID.h:98
bool isValid() const
Definition: SubRunID.h:97
Float_t E
Definition: plot.C:20
bool match(EventID const &) const
printf("%d Experimental points found\n", nlines)
std::vector< std::string > pattern_
bool operator()(EventID const &) const
bool isFlush() const
Definition: SubRunID.h:103
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
bool isValid() const
Definition: RunID.h:70
Definition: MVAAlg.h:12
EventIDMatcher(std::string const &pattern)
EventNumber_t event() const
Definition: EventID.h:116
std::vector< std::vector< std::vector< PatternRangeElement > > > parsed_patterns_
SubRunNumber_t subRun() const
Definition: EventID.h:110