LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
RangeSet.cc
Go to the documentation of this file.
3 #include "cetlib/crc32.h"
4 
5 using namespace art;
6 
7 namespace {
8 
9  auto
10  checksum(std::string const& compact_string)
11  {
12  return cet::crc32{compact_string}.digest();
13  }
14 
15  bool
16  both_valid(RangeSet const& l, RangeSet const& r)
17  {
18  return l.is_valid() && r.is_valid();
19  }
20 
21  bool
22  disjoint(std::vector<EventRange> const& ranges)
23  {
24  if (ranges.size() < 2ull)
25  return true;
26 
27  auto it = ranges.cbegin();
28  auto const end = ranges.cend();
29  for (auto next = std::next(it); next != end; ++it, ++next) {
30  if (!it->is_disjoint(*next))
31  return false;
32  }
33  return true;
34  }
35 }
36 
39 {
40  static EventRange const range{
42  return range;
43 }
44 
47 {
48  return RangeSet{};
49 }
50 
53 {
54  return RangeSet{rid.run(), {detail::full_run_event_range()}};
55 }
56 
59 {
60  return RangeSet{srid.run(), {EventRange::forSubRun(srid.subRun())}};
61 }
62 
64 
66  std::vector<EventRange> const& eventRanges)
67  : run_{r}, ranges_{eventRanges}
68 {
69  sort();
70  collapse();
71 }
72 
73 RangeSet&
75 {
76  if (isCollapsed_) {
77  return *this;
78  }
79 
80  if (ranges_.size() < 2) {
81  isCollapsed_ = true;
82  return *this;
83  }
84 
85  if (!is_sorted())
86  throw art::Exception(art::errors::LogicError, "RangeSet::collapse()")
87  << "A range set must be sorted before it is collapsed.\n";
88 
89  auto processing = ranges_;
90  decltype(ranges_) result;
91  result.reserve(ranges_.size());
92  result.push_back(ranges_.front());
93  for (auto ir = ranges_.cbegin() + 1, e = ranges_.cend(); ir != e; ++ir) {
94  auto const& r = *ir;
95  auto& back = result.back();
96  if (back.is_adjacent(r)) {
97  back.merge(r);
98  } else {
100  result.push_back(r);
101  }
102  }
103  std::swap(ranges_, result);
104  isCollapsed_ = true;
105  return *this;
106 }
107 
108 void
111 {
113  ranges_.assign(b, e);
114 }
115 
116 void
118 {
120  if (ranges_.empty()) {
121  run_ = id.run();
122  ranges_.emplace_back(id.subRun(), id.event(), id.next().event());
123  return;
124  }
125  auto& back = ranges_.back();
126  if (back.subRun() == id.subRun() && back.end() == id.event()) {
127  back.set_end(id.next().event());
128  } else {
129  ranges_.emplace_back(id.subRun(), id.event(), id.next().event());
130  }
131 }
132 
133 RangeSet&
135 {
136  if (!other.is_valid())
137  return *this;
138 
139  if (!is_valid())
140  run_ = other.run();
141 
142  std::vector<EventRange> merged;
143  std::merge(ranges_.begin(),
144  ranges_.end(),
145  other.ranges_.begin(),
146  other.ranges_.end(),
147  std::back_inserter(merged));
148  std::unique(merged.begin(), merged.end());
149  std::swap(ranges_, merged);
150  isCollapsed_ = false;
151  collapse();
152  return *this;
153 }
154 
155 std::pair<RangeSet::const_iterator, bool>
157 {
159  bool did_split{false};
160  auto result = ranges_.end();
161  auto foundRange =
162  std::find_if(ranges_.cbegin(), ranges_.cend(), [s, e](auto const& r) {
163  return r.contains(s, e);
164  });
165 
166  // Split only if:
167  // - the range is found (i.e. the event is contained by the found range)
168  // - the range is valid
169  // - the size of the range is greater than 1
170  if (foundRange != ranges_.cend() && foundRange->is_valid() &&
171  foundRange->size() > 1ull) {
172  auto const begin = foundRange->begin();
173  auto const end = foundRange->end();
174  auto leftIt = ranges_.emplace(foundRange, s, begin, e);
175  result = std::next(leftIt);
176  EventRange right{s, e, end};
177  std::swap(*result, right);
178  did_split = true;
179  }
180  return std::make_pair(result, did_split);
181 }
182 
183 unsigned
185 {
186  // Could cache checksums to improve performance when necessary.
188 }
189 
190 bool
192 {
193  if (isCollapsed_ || is_sorted()) {
194  return ranges_.size() < 2ull ? true : disjoint(ranges_);
195  }
196 
197  RangeSet tmp{*this};
198  tmp.sort();
199  tmp.collapse();
200  return tmp.has_disjoint_ranges();
201 }
202 
203 bool
205 {
206  for (auto const& range : ranges_) {
207  if (!range.empty())
208  return false;
209  }
210  return true;
211 }
212 
213 bool
215  SubRunNumber_t const s,
216  EventNumber_t const e) const
217 {
218  if (run_ != r)
219  return false;
220 
221  for (auto const& range : ranges_) {
222  if (range.contains(s, e))
223  return true;
224  }
225 
226  return false;
227 }
228 
229 bool
231 {
233  return false;
234  }
235  if (is_full_run()) {
236  return true;
237  }
238  for (auto const& range : ranges_) {
239  if (!range.is_valid())
240  return false;
241  }
242  return true;
243 }
244 
245 bool
247 {
248  return ranges_.size() == 1ull &&
250 }
251 
252 bool
254 {
255  return ranges_.size() == 1ull && ranges_.front().is_full_subRun();
256 }
257 
258 bool
260 {
261  return std::is_sorted(ranges_.cbegin(), ranges_.cend());
262 }
263 
264 std::string
266 {
267  using namespace std;
268  string s{to_string(run_)};
269  if (!ranges_.empty())
270  s += ":";
271  for (auto const& r : ranges_) {
272  s += to_string(r.subRun());
273  s += "[";
274  s += to_string(r.begin());
275  s += ",";
276  s += to_string(r.end());
277  s += ")";
278  }
279  return s;
280 }
281 
282 bool
283 art::operator==(RangeSet const& l, RangeSet const& r)
284 {
285  if (!both_valid(l, r))
286  return false;
287  return l.run() == r.run() && l.ranges() == r.ranges();
288 }
289 
290 bool
291 art::same_ranges(RangeSet const& l, RangeSet const& r)
292 {
293  return l == r;
294 }
295 
296 bool
298 {
299  if (!both_valid(l, r))
300  return false;
301 
302  if (!l.has_disjoint_ranges() || !r.has_disjoint_ranges())
303  return false;
304 
305  if (l.run() != r.run())
306  return true;
307 
308  // Empty RangeSets are disjoint wrt. other RangeSets. Must handle
309  // this case separately than l == r case.
310  if (l.empty() || r.empty())
311  return true;
312 
313  // If we get this far, then neither RangeSet is empty.
314  if (l == r)
315  return false;
316 
317  RangeSet ltmp{l};
318  RangeSet rtmp{r};
319  auto const& lranges = ltmp.collapse().ranges();
320  auto const& rranges = rtmp.collapse().ranges();
321 
322  std::vector<EventRange> merged;
323  std::merge(lranges.begin(),
324  lranges.end(),
325  rranges.begin(),
326  rranges.end(),
327  std::back_inserter(merged));
328 
329  return disjoint(merged);
330 }
331 
332 void
334  EventRange const& left,
335  EventRange const& right) noexcept(false)
336 {
337  if (left.is_disjoint(right))
338  return;
340  << "Attempt to merge event ranges that both contain one or more of the "
341  "same events\n"
342  << " Run: " << rn << '\n'
343  << " " << left << " vs.\n"
344  << " " << right;
345 }
346 
347 bool
349 {
350  if (!both_valid(l, r))
351  return false;
352  return !disjoint_ranges(l, r);
353 }
354 
355 std::ostream&
356 art::operator<<(std::ostream& os, RangeSet const& rs)
357 {
358  os << " Run: " << rs.run();
359  if (rs.is_full_run()) {
360  os << " (full run)";
361  return os;
362  }
363  for (auto const& er : rs.ranges()) {
364  os << "\n " << er;
365  }
366  return os;
367 }
std::ostream & operator<<(std::ostream &os, EDAnalyzer::Table< T > const &t)
Definition: EDAnalyzer.h:184
RunNumber_t run_
Definition: RangeSet.h:144
Float_t s
Definition: plot.C:23
RangeSet & collapse()
Definition: RangeSet.cc:74
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:112
std::vector< EventRange >::const_iterator const_iterator
Definition: RangeSet.h:33
auto begin() const
Definition: RangeSet.h:70
unsigned checksum_
Definition: RangeSet.h:149
std::vector< EventRange > ranges_
Definition: RangeSet.h:145
void assign_ranges(const_iterator b, const_iterator e)
Definition: RangeSet.cc:109
STL namespace.
EventRange full_run_event_range()
Definition: RangeSet.cc:38
Float_t tmp
Definition: plot.C:37
bool is_sorted() const
Definition: RangeSet.cc:259
auto end() const
Definition: RangeSet.h:75
RunNumber_t run() const
Definition: RunID.h:63
void throw_if_not_disjoint(RunNumber_t const rn, EventRange const &left, EventRange const &right) noexcept(false)
Definition: RangeSet.cc:333
RunNumber_t run() const
Definition: RangeSet.h:36
RangeSet & merge(RangeSet const &other)
Definition: RangeSet.cc:134
RangeSet()=default
std::vector< EventRange > const & ranges() const
Definition: RangeSet.h:42
bool has_disjoint_ranges() const
Definition: RangeSet.cc:191
bool isCollapsed_
Definition: RangeSet.h:148
static EventRange forSubRun(SubRunNumber_t s)
Definition: EventRange.cc:25
RunNumber_t run() const
Definition: SubRunID.h:84
std::enable_if_t< detail::are_handles< T, U >::value, bool > disjoint_ranges(T const &a, U const &b)
bool is_full_run() const
Definition: RangeSet.cc:246
bool empty() const
Definition: RangeSet.cc:204
IDNumber_t< Level::SubRun > SubRunNumber_t
Definition: IDNumber.h:118
static RangeSet forRun(RunID)
Definition: RangeSet.cc:52
bool is_valid() const
Definition: RangeSet.cc:230
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
bool is_full_subRun() const
Definition: RangeSet.cc:253
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:104
void require_not_full_run()
Definition: RangeSet.h:135
static RangeSet forSubRun(SubRunID)
Definition: RangeSet.cc:58
void update(EventID const &)
Definition: RangeSet.cc:117
bool contains(RunNumber_t, SubRunNumber_t, EventNumber_t) const
Definition: RangeSet.cc:214
void sort()
Definition: RangeSet.h:114
std::string to_compact_string() const
Definition: RangeSet.cc:265
std::enable_if_t< detail::are_handles< T, U >::value, bool > overlapping_ranges(T const &a, U const &b)
static RangeSet invalid()
Definition: RangeSet.cc:46
std::enable_if_t< detail::are_handles< T, U >::value, bool > same_ranges(T const &a, U const &b)
IDNumber_t< Level::Event > EventNumber_t
Definition: IDNumber.h:117
HLT enums.
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
SubRunNumber_t subRun() const
Definition: SubRunID.h:90
std::string to_string(ModuleType mt)
Definition: ModuleType.h:32
bool operator==(Provenance const &a, Provenance const &b)
Definition: Provenance.h:168
Float_t e
Definition: plot.C:34
decltype(auto) back()
Definition: RangeSet.h:88
unsigned checksum() const
Definition: RangeSet.cc:184
Event finding and building.
std::pair< const_iterator, bool > split_range(SubRunNumber_t, EventNumber_t)
Definition: RangeSet.cc:156
IDNumber_t< Level::Run > RunNumber_t
Definition: IDNumber.h:119