Belle II Software  release-05-02-19
IntervalOfValidity.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2015 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Thomas Kuhr *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 #include <framework/database/IntervalOfValidity.h>
12 #include <framework/dataobjects/EventMetaData.h>
13 #include <framework/logging/Logger.h>
14 #include <utility>
15 
16 using namespace Belle2;
17 
18 
19 IntervalOfValidity::IntervalOfValidity(int experimentLow, int runLow, int experimentHigh,
20  int runHigh) : m_experimentLow(experimentLow), m_runLow(runLow), m_experimentHigh(experimentHigh), m_runHigh(runHigh)
21 {
22  // consistency checks
23  if ((experimentLow < 0) && (runLow >= 0)) {
24  B2ERROR("A run number of " << runLow << " is given for an undefined low experiment number. Setting run to undefined, too.");
25  m_runLow = -1;
26  }
27  if ((experimentHigh < 0) && (runHigh >= 0)) {
28  B2ERROR("A run number of " << runHigh << " is given for an undefined high experiment number. Setting run to undefined, too.");
29  m_runHigh = -1;
30  }
31  if ((experimentLow >= 0) && (experimentHigh >= 0)) {
32  if ((experimentLow > experimentHigh) || ((experimentLow == experimentHigh) && (runHigh >= 0) && (runLow > runHigh))) {
33  B2ERROR("The given lower and higher experiment/run numbers of " << experimentLow << "/" << runLow << " and " << experimentHigh <<
34  "/" << runHigh << ", respectively, are in the wrong order, Swapping them.");
36  std::swap(m_runLow, m_runHigh);
37  }
38  }
39 }
40 
41 
42 int IntervalOfValidity::checkLowerBound(int experiment, int run) const
43 {
44  // check for empty interval
45  if (empty()) return false;
46 
47  if ((m_experimentLow == experiment) && (m_runLow == run)) return 0;
48  if (m_experimentLow < 0) return 1;
49  if (experiment < m_experimentLow) return -1;
50  if (experiment == m_experimentLow) {
51  if (run < m_runLow) return -1;
52  }
53  return 1;
54 }
55 
56 int IntervalOfValidity::checkUpperBound(int experiment, int run) const
57 {
58  // check for empty interval
59  if (empty()) return false;
60 
61  if ((m_experimentHigh == experiment) && (m_runHigh == run)) return 0;
62  if (m_experimentHigh < 0) return -1;
63  if ((experiment < 0) || (experiment > m_experimentHigh)) return 1;
64  if (experiment == m_experimentHigh) {
65  if ((m_runHigh >= 0) && ((run > m_runHigh) || (run < 0))) return 1;
66  }
67  return -1;
68 }
69 
71 {
72  if (m_experimentLow < 0) m_runLow = -1;
73  if (m_experimentHigh < 0) m_runHigh = -1;
74  if ((m_experimentLow >= 0) && (m_experimentHigh >= 0)) {
77  }
78  }
79 }
80 
81 
83 {
84  auto experiment = (int) event.getExperiment();
85  auto run = (int) event.getRun();
86 
87  // check for empty interval
88  if (empty()) return false;
89 
90  // check lower bound
91  if (checkLowerBound(experiment, run) < 0) return false;
92  if (checkUpperBound(experiment, run) > 0) return false;
93  return true;
94 }
95 
97 {
98  if (empty() || iov.empty()) return IntervalOfValidity();
99 
100  IntervalOfValidity result(*this);
101  if (checkLowerBound(iov.m_experimentLow, iov.m_runLow) > 0) {
102  result.m_experimentLow = iov.m_experimentLow;
103  result.m_runLow = iov.m_runLow;
104  }
105  if (checkUpperBound(iov.m_experimentHigh, iov.m_runHigh) < 0) {
106  result.m_experimentHigh = iov.m_experimentHigh;
107  result.m_runHigh = iov.m_runHigh;
108  }
109 
110  result.makeValid();
111  return result;
112 }
113 
115 {
116  if (!overlaps(iov)) return true;
117 
118  bool thisOlder = checkLowerBound(iov.m_experimentLow, iov.m_runLow) >= 0;
119  IntervalOfValidity& older = (thisOlder) ? *this : iov;
120  IntervalOfValidity& younger = (thisOlder) ? iov : *this;
121 
122  if (trimOlder) {
123  // check for the case where trimming is not possible because the interval would be split
124  if (older.checkUpperBound(younger.m_experimentHigh, younger.m_runHigh) < 0) return false;
125 
126  older.m_experimentHigh = younger.m_experimentLow;
127  older.m_runHigh = younger.m_runLow - 1;
128  if (older.m_runHigh < 0) {
129  older.m_experimentHigh--;
130  older.m_runHigh = -1;
131  }
132  older.makeValid();
133  } else {
134  younger.m_experimentLow = older.m_experimentHigh;
135  younger.m_runLow = older.m_runHigh + 1;
136  if (younger.m_runLow == 0) {
137  younger.m_experimentLow++;
138  }
139  younger.makeValid();
140  }
141 
142  return true;
143 }
144 
145 
146 namespace Belle2 {
152  std::istream& operator>> (std::istream& input, IntervalOfValidity& iov)
153  {
154  iov = IntervalOfValidity();
155  if (!input.good()) {
156  throw std::runtime_error("cannot read from stream");
157  }
158 
159  std::string str[4];
160  int index = 0;
161  while (input.good()) {
162  auto c = input.peek();
163  if (c == EOF) break;
164  if (((c == ' ') || (c == '\n') || (c == '\t'))) {
165  //ignore whitespace in the beginning
166  if (index == 0 && str[0].empty()) {
167  input.get();
168  continue;
169  }
170  //and stop parsing otherwise
171  break;
172  }
173  if (c == ',') {
174  index++;
175  if (index == 4) break;
176  } else {
177  str[index] += c;
178  }
179  input.get();
180  }
181  if (index != 3) {
182  throw std::invalid_argument("IoV needs to be four values (firstExp,firstRun,finalExp,finalRun)");
183  }
184  try {
185  iov.m_experimentLow = stoi(str[0]);
186  iov.m_runLow = stoi(str[1]);
187  iov.m_experimentHigh = stoi(str[2]);
188  iov.m_runHigh = stoi(str[3]);
189  } catch (std::invalid_argument& e) {
190  throw std::invalid_argument("experiment and run numbers must be integers");
191  }
192 
193  return input;
194  }
195 
196  std::ostream& operator<< (std::ostream& output, const IntervalOfValidity& iov)
197  {
198  output << iov.m_experimentLow << "," << iov.m_runLow << "," << iov.m_experimentHigh << "," << iov.m_runHigh;
199 
200  return output;
201  }
202 
204 }
Belle2::IntervalOfValidity
A class that describes the interval of experiments/runs for which an object in the database is valid.
Definition: IntervalOfValidity.h:35
Belle2::IntervalOfValidity::overlaps
bool overlaps(const IntervalOfValidity &iov) const
Function that checks the validity interval overlaps with another interval of validity.
Definition: IntervalOfValidity.h:103
Belle2::operator<<
std::ostream & operator<<(std::ostream &output, const IntervalOfValidity &iov)
Definition: IntervalOfValidity.cc:196
Belle2::IntervalOfValidity::checkUpperBound
int checkUpperBound(int experiment, int run) const
Helper function to check whether a given experiment/run number is above or below the upper bound of t...
Definition: IntervalOfValidity.cc:56
Belle2::IntervalOfValidity::checkLowerBound
int checkLowerBound(int experiment, int run) const
Helper function to check whether a given experiment/run number is above or below the lower bound of t...
Definition: IntervalOfValidity.cc:42
Belle2::IntervalOfValidity::m_experimentLow
int m_experimentLow
Lowest experiment number.
Definition: IntervalOfValidity.h:178
Belle2::IntervalOfValidity::IntervalOfValidity
IntervalOfValidity()
Default constructor which will create an empty iov.
Definition: IntervalOfValidity.h:38
Belle2::IntervalOfValidity::m_experimentHigh
int m_experimentHigh
Highest experiment number.
Definition: IntervalOfValidity.h:186
Belle2::IntervalOfValidity::overlap
IntervalOfValidity overlap(const IntervalOfValidity &iov) const
Function that determines the overlap of the validity interval with another interval of validity.
Definition: IntervalOfValidity.cc:96
Belle2::IntervalOfValidity::m_runLow
int m_runLow
Lowest run number.
Definition: IntervalOfValidity.h:182
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::IntervalOfValidity::contains
bool contains(const EventMetaData &event) const
Function that checks whether the event is inside the validity interval.
Definition: IntervalOfValidity.cc:82
Belle2::IntervalOfValidity::m_runHigh
int m_runHigh
Highest run number.
Definition: IntervalOfValidity.h:190
Belle2::IntervalOfValidity::trimOverlap
bool trimOverlap(IntervalOfValidity &iov, bool trimOlder=true)
Remove the overlap between two intervals of validity by shortening one of them.
Definition: IntervalOfValidity.cc:114
Belle2::EventMetaData
Store event, run, and experiment numbers.
Definition: EventMetaData.h:43
Belle2::IntervalOfValidity::empty
bool empty() const
Function that checks whether the validity interval is empty.
Definition: IntervalOfValidity.h:65
Belle2::IntervalOfValidity::makeValid
void makeValid()
Helper function to set the interval to empty if the upper bound is below the lower one.
Definition: IntervalOfValidity.cc:70
Belle2::operator>>
std::istream & operator>>(std::istream &input, IntervalOfValidity &iov)
Definition: IntervalOfValidity.cc:152