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