19 #include <TGraphErrors.h>
27 #include <tracking/calibration/Splitter.h>
43 map<ExpRun, pair<double, double>>
filter(
const map<
ExpRun, pair<double, double>>& runs,
double cut,
44 map<
ExpRun, pair<double, double>>& runsRemoved)
46 map<ExpRun, pair<double, double>> runsCopy;
50 double d = I.second - I.first;
52 runsCopy[r.first] = r.second;
54 runsRemoved[r.first] = r.second;
62 void plotRuns(vector<pair<double, double>> runs)
64 TGraphErrors* gr =
new TGraphErrors();
68 double m = (r.first + r.second) / 2;
69 double e = (r.second - r.first) / 2;
71 gr->SetPoint(gr->GetN(), m, 1);
72 gr->SetPointError(gr->GetN() - 1, e, 0);
75 gStyle->SetEndErrorSize(6);
78 gr->SetMarkerSize(40);
80 gr->GetYaxis()->SetRangeUser(-10, 10);
81 gr->GetXaxis()->SetRangeUser(0, 256);
83 gr->GetXaxis()->SetTitle(
"time [hours]");
90 B2ASSERT(
"There must be at least one interval", nIntervals >= 1);
91 B2ASSERT(
"Interval index must be positive", indx >= 0);
92 B2ASSERT(
"Interval index must be smaller than #breaks", indx <
int(breaks.size()) + 1);
93 int s = (indx == 0) ? 0 : breaks[indx - 1] + 1;
94 int e = (indx == int(breaks.size())) ? nIntervals - 1 : breaks[indx];
99 void plotSRuns(vector<pair<double, double>> runs, vector<int> breaks,
int offset = 2)
101 TGraphErrors* gr =
new TGraphErrors();
103 for (
int i = 0; i < int(breaks.size()) + 1; ++i) {
106 double a = runs[s].first;
107 double b = runs[e].second;
109 double m = (a + b) / 2;
110 double err = (b - a) / 2;
112 gr->SetPoint(gr->GetN(), m, offset);
113 gr->SetPointError(gr->GetN() - 1, err, 0);
117 gr->SetLineColor(kRed);
118 gr->SetMarkerColor(kRed);
127 for (
auto r : runs) {
128 double d = r.second - r.first;
132 sort(dist.begin(), dist.end());
140 double Splitter::lossFunction(
const vector<Atom>& vec,
int s,
int e)
const
144 double rawTime = vec[e].t2 - vec[s].t1;
148 for (
int i = s; i <= e - 1; ++i) {
149 double d = vec[i + 1].t1 - vec[i].t2;
150 maxGap = max(maxGap, d);
155 for (
int i = s; i <= e; ++i) {
156 netTime += vec[i].t2 - vec[i].t1;
161 for (
int i = s; i <= e; ++i) {
164 if (nEv == 0) nEv = 0.1;
169 lossFun->SetParameters(rawTime, netTime, maxGap, nEv);
170 double lossNew = lossFun->Eval(0);
178 vector<pair<double, double>> Splitter::splitToSmall(map<
ExpRun, pair<double, double>> runs,
double intSize)
181 vector<pair<double, double>> smallRuns;
183 for (
auto r : runs) {
185 double runTime = I.second - I.first;
186 int nSplits = runTime / intSize;
187 nSplits = max(1, nSplits);
189 for (
int i = 0; i < nSplits; ++i) {
190 double L = I.first + i * (runTime / nSplits);
191 double H = I.first + (i + 1) * (runTime / nSplits);
192 smallRuns.push_back({L, H});
204 double Splitter::getMinLoss(
const vector<Atom>& vec,
int e, vector<int>& breaks)
207 if (cache[e].first >= 0) {
208 breaks = cache[e].second;
209 return cache[e].first;
213 vector<int> breaksOpt;
214 double minVal = 1e30;
216 for (
int i = -1; i <= e - 1; ++i) {
217 auto breaksNow = breaks;
220 r1 = getMinLoss(vec, i, breaksNow);
221 double r2 = lossFunction(vec, i + 1, e);
222 double tot = r1 + r2;
227 breaksOpt = breaksNow;
232 breaksOpt.push_back(iMin);
236 cache[e] = make_pair(minVal, breaks);
241 vector<int> Splitter::dynamicBreaks(
const vector<Atom>& runs)
244 cache.resize(runs.size());
245 for (
auto& c : cache)
246 c = make_pair(-1.0, vector<int>({}));
250 getMinLoss(runs, runs.size() - 1, breaks);
266 for (
auto r : runs) {
267 if (r.second.first <= t && t < r.second.second) {
273 B2ASSERT(
"Exactly one interval should be found", nFound == 1);
274 B2ASSERT(
"Assert that something was found", rFound !=
ExpRun(-1, -1));
281 const vector<Atom>& currVec,
const vector<int>& breaks)
283 vector<map<ExpRun, pair<double, double>>> splitsNow(breaks.size() + 1);
284 for (
int i = 0; i < int(breaks.size()) + 1; ++i) {
289 for (
int k = s; k <= e; ++k) {
290 ExpRun r =
getRun(runsMap, (currVec[k].t1 + currVec[k].t2) / 2.);
291 if (splitsNow[i].count(r)) {
292 splitsNow[i].at(r).first = min(splitsNow[i].at(r).first, currVec[k].t1);
293 splitsNow[i].at(r).second = max(splitsNow[i].at(r).second, currVec[k].t2);
295 splitsNow[i][r].first = currVec[k].t1;
296 splitsNow[i][r].second = currVec[k].t2;
305 map<ExpRun, pair<double, double>> Splitter::mergeIntervals(map<
ExpRun, pair<double, double>> I1,
306 map<
ExpRun, pair<double, double>> I2)
308 map<ExpRun, pair<double, double>> I = I1;
311 if (I.count(run) == 0)
314 I.at(run) = make_pair(min(I1.at(run).first, I2.at(run).first), max(I1.at(run).second, I2.at(run).second));