15 #include <tracking/calibration/Splitter.h>
16 #include <TMatrixDSym.h>
22 #include <framework/database/EventDependency.h>
23 #include <framework/datastore/StoreArray.h>
24 #include <calibration/CalibrationAlgorithm.h>
26 #include <Eigen/Dense>
49 TMatrixDSym mOut(mIn.rows());
50 for (
int i = 0; i < mIn.rows(); ++i)
51 for (
int j = 0; j < mIn.cols(); ++j)
52 mOut(i, j) = (mIn(i, j) + mIn(j, i)) / 2.;
57 inline TVector3
toTVector3(Eigen::VectorXd vIn)
59 return TVector3(vIn(0), vIn(1), vIn(2));
63 inline int getID(
const std::vector<double>& breaks,
double t)
65 for (
int i = 0; i < int(breaks.size()) + 1; ++i) {
66 double s = (i == 0) ? 0 : breaks[i - 1];
67 double e = (i == int(breaks.size())) ? 1e20 : breaks[i];
76 std::vector<Eigen::VectorXd>
cnt;
77 std::vector<Eigen::MatrixXd>
cntUnc;
79 int size()
const {
return cnt.size();}
86 std::vector<std::map<ExpRun, std::pair<double, double>>>
subIntervals;
102 for (
unsigned i = 0; i < calVec.size(); ++i) {
103 if (calVec[i].pars.cnt.size() != 0)
continue;
104 const auto& r = calVec[i].subIntervals;
108 Eigen::Vector3d ipNow;
109 Eigen::MatrixXd ipeNow;
110 Eigen::MatrixXd sizeMatNow;
112 double distMin = 1e20;
114 for (
unsigned j = 0; j < calVec.size(); ++j) {
115 if (calVec[j].isCalibrated ==
false)
continue;
116 const auto& rJ = calVec[j].subIntervals;
117 for (
unsigned jj = 0; jj < rJ.size(); ++jj) {
118 const auto& rNow = rJ[jj];
119 double s = rNow.begin()->second.first;
120 double e = rNow.rbegin()->second.second;
122 double dist1 = (s - End >= 0) ? (s - End) : 1e20;
123 double dist2 = (Start - e >= 0) ? (Start - e) : 1e20;
124 double dist = std::min(dist1, dist2);
126 if (dist < distMin) {
127 ipNow = calVec[j].pars.cnt.at(jj);
128 ipeNow = calVec[j].pars.cntUnc.at(jj);
129 sizeMatNow = calVec[j].pars.spreadMat;
136 calVec[i].pars.cnt.resize(r.size());
137 calVec[i].pars.cntUnc.resize(r.size());
138 for (
unsigned ii = 0; ii < r.size(); ++ii) {
139 calVec[i].pars.cnt.at(ii) = ipNow;
140 calVec[i].pars.cntUnc.at(ii) = ipeNow;
142 calVec[i].pars.spreadMat = sizeMatNow;
148 inline void addShortRun(std::vector<CalibrationData>& calVec, std::pair<ExpRun, std::pair<double, double>> shortRun)
150 double shortStart = shortRun.second.first;
151 double shortEnd = shortRun.second.second;
153 double distMin = 1e20;
154 int iMin = -1, jMin = -1;
156 for (
unsigned i = 0; i < calVec.size(); ++i) {
157 if (calVec[i].isCalibrated ==
false)
159 for (
unsigned j = 0; j < calVec[i].subIntervals.size(); ++j) {
160 for (
auto I : calVec[i].subIntervals[j]) {
161 double s = I.second.first;
162 double e = I.second.second;
164 double dist1 = (s - shortEnd >= 0) ? (s - shortEnd) : 1e20;
165 double dist2 = (shortStart - e >= 0) ? (shortStart - e) : 1e20;
166 double dist = std::min(dist1, dist2);
168 if (dist < distMin) {
177 B2ASSERT(
"Must be found", iMin != -1 && jMin != -1);
178 calVec[iMin].subIntervals[jMin].insert(shortRun);
185 double factor = pow(FLT_RADIX, DBL_MANT_DIG);
186 static const long long fEnc = pow(2, 32);
189 double mantisa = std::frexp(val, &e);
190 long long mantisaI = mantisa * factor;
193 mantisaI = (mantisaI / fEnc) * fEnc + num;
195 mantisaI = factor / 2 + num;
199 double newVal = ldexp(mantisaI / factor, e);
207 double factor = pow(FLT_RADIX, DBL_MANT_DIG);
208 static const long long fEnc = pow(2, 32);
211 double mantisa = std::frexp(val, &e);
212 long long mantisaI = mantisa * factor;
214 return (mantisaI % fEnc);
221 template<
typename Evt>
222 inline void storePayloads(
const std::vector<Evt>& evts, std::vector<CalibrationData>& calVec, std::string objName,
223 std::function<TObject*(Eigen::VectorXd, Eigen::MatrixXd, Eigen::MatrixXd) > getCalibObj)
227 ExpRun exprunLast(-1, -1);
228 EventDependency* intraRun =
nullptr;
231 for (
unsigned i = 0; i < calVec.size(); ++i) {
232 const auto& r = calVec[i].subIntervals;
234 for (
int k = 0; k < int(r.size()); ++k) {
236 for (
auto I : r[k]) {
240 if (calVec[i].pars.cntUnc.at(k).rows() == 3) {
241 calVec[i].pars.cntUnc.at(k)(0, 1) = calVec[i].pars.cntUnc.at(k)(1, 0) =
encodeNumber(calVec[i].pars.cntUnc.at(k)(0, 1),
242 round(I.second.first * 3600));
243 calVec[i].pars.cntUnc.at(k)(0, 2) = calVec[i].pars.cntUnc.at(k)(2, 0) =
encodeNumber(calVec[i].pars.cntUnc.at(k)(0, 2),
244 round(I.second.second * 3600));
246 calVec[i].pars.cntUnc.at(k)(0, 0) =
encodeNumber(calVec[i].pars.cntUnc.at(k)(0, 0), round(I.second.first * 3600));
247 calVec[i].pars.spreadMat(0, 0) =
encodeNumber(calVec[i].pars.spreadMat(0, 0), round(I.second.first * 3600));
250 TObject* obj = getCalibObj(calVec[i].pars.cnt.at(k), calVec[i].pars.cntUnc.at(k), calVec[i].pars.spreadMat);
251 if (exprun != exprunLast) {
253 auto m_iov =
IntervalOfValidity(exprunLast.exp, exprunLast.run, exprunLast.exp, exprunLast.run);
261 breakPoint = calVec[i].breakPoints.at(k - 1).evt;
262 B2ASSERT(
"Payload saving consistency", calVec[i].breakPoints.at(k - 1).run == exprun.
run);
264 B2ASSERT(
"Payload saving consistency", i != 0);
268 breakPoint = pos.evt;
269 B2ASSERT(
"Payload saving consistency", pos.run == exprun.
run);
271 intraRun->add(breakPoint, obj);
280 auto m_iov = IntervalOfValidity(exprunLast.exp, exprunLast.run, exprunLast.exp, exprunLast.run);
285 template<
typename Evt,
typename Fun>
286 inline CalibrationData
runAlgorithm(
const std::vector<Evt>& evts, std::vector<std::map<ExpRun, std::pair<double, double>>> range,
290 CalibrationData calD;
294 B2INFO(
"Start of loop startTime endTime : " << rStart <<
" " << rEnd);
298 std::vector<Evt> evtsNow;
300 std::vector<int> Counts(breaks.size() + 1, 0);
302 for (
const auto& ev : evts) {
303 if (rStart <= ev.t && ev.t < rEnd) {
304 evtsNow.push_back(ev);
305 ++Counts.at(
getID(breaks, ev.t));
309 B2ASSERT(
"Number of intervals vs number of breakPoints", r.size() == breaks.size() + 1);
312 for (
int k = 0; k < 10; ++k) {
313 int iMin = min_element(Counts.begin(), Counts.end()) - Counts.begin();
314 if (Counts.size() >= 2 && Counts[iMin] < 50) {
318 else if (iMin ==
int(Counts.size()) - 1)
321 if (Counts[iMin + 1] < Counts[iMin - 1])
326 B2ASSERT(
"Number of intervals equal to size of counters", r.size() == Counts.size());
329 r.erase(r.begin() + iMin);
331 Counts[iM] += Counts[iMin];
332 Counts.erase(Counts.begin() + iMin);
336 B2INFO(
"#events " <<
" : " << evtsNow.size());
337 B2INFO(
"Breaks size " <<
" : " << breaks.size());
341 calD.subIntervals = r;
343 if (breaks.size() > 0)
344 B2INFO(
"StartOfCalibInterval (run,evtNo,vtxIntervalsSize) " << calD.breakPoints.at(0).run <<
" " <<
345 calD.breakPoints.at(0).evt <<
" " << calD.breakPoints.size());
350 if (evtsNow.size() < 50) {
355 B2INFO(
"Start of running calibration over calibration interval");
356 tie(calD.pars.cnt, calD.pars.cntUnc, calD.pars.spreadMat) = runCalibAnalysis(evtsNow, breaks);
357 B2INFO(
"End of running analysis - SpreadMatX : " << sqrt(abs(calD.pars.spreadMat(0, 0))));
358 B2ASSERT(
"All subintervals have calibration of the mean value", calD.pars.cnt.size() == r.size());
359 B2ASSERT(
"All subintervals have calibration of the unc. of mean", calD.pars.cntUnc.size() == r.size());
361 calD.isCalibrated =
true;
377 template<
typename Fun1,
typename Fun2>
379 std::function<TObject*(Eigen::VectorXd, Eigen::MatrixXd, Eigen::MatrixXd)> calibObjCreator,
380 TString m_lossFunctionOuter, TString m_lossFunctionInner)
383 if (!tracks || tracks->GetEntries() < 15) {
385 B2WARNING(
"Too few data : " << tracks->GetEntries());
386 return CalibrationAlgorithm::EResult::c_NotEnoughData;
388 B2INFO(
"Number of tracks: " << tracks->GetEntries());
391 auto evts = GetEvents(tracks);
394 std::map<ExpRun, std::pair<double, double>> runsInfoOrg =
getRunInfo(evts);
395 std::map<ExpRun, std::pair<double, double>> runsRemoved;
396 auto runsInfo =
filter(runsInfoOrg, 2. / 60, runsRemoved);
399 if (runsInfo.size() == 0) {
400 B2WARNING(
"Too short run");
401 return CalibrationAlgorithm::EResult::c_NotEnoughData;
406 auto splits = splt.getIntervals(runsInfo, evts, m_lossFunctionOuter, m_lossFunctionInner);
409 std::vector<CalibrationData> calVec;
410 for (
auto s : splits) {
411 CalibrationData calD =
runAlgorithm(evts, s, calibAnalysis);
412 calVec.push_back(calD);
419 for (
auto shortRun : runsRemoved) {
426 return CalibrationAlgorithm::EResult::c_OK;