13#include <reconstruction/calibration/BeamSpotBoostInvMass/Splitter.h>
14#include <TMatrixDSym.h>
18#include <framework/database/EventDependency.h>
19#include <framework/datastore/StoreArray.h>
20#include <framework/geometry/B2Vector3.h>
21#include <calibration/CalibrationAlgorithm.h>
46 TMatrixDSym mOut(mIn.rows());
47 for (
int i = 0; i < mIn.rows(); ++i)
48 for (
int j = 0; j < mIn.cols(); ++j)
49 mOut(i, j) = (mIn(i, j) + mIn(j, i)) / 2.;
60 inline int getID(
const std::vector<double>& breaks,
double t)
62 for (
int i = 0; i < int(breaks.size()) + 1; ++i) {
63 double s = (i == 0) ? 0 : breaks[i - 1];
64 double e = (i == int(breaks.size())) ? 1e20 : breaks[i];
73 std::vector<Eigen::VectorXd>
cnt;
77 double spreadUnc = std::numeric_limits<double>::quiet_NaN();
79 std::numeric_limits<double>::quiet_NaN();
80 double shiftUnc = std::numeric_limits<double>::quiet_NaN();
89 std::vector<std::map<ExpRun, std::pair<double, double>>>
subIntervals;
105 for (
unsigned i = 0; i < calVec.size(); ++i) {
106 if (calVec[i].pars.cnt.size() != 0)
continue;
107 const auto& r = calVec[i].subIntervals;
111 Eigen::Vector3d ipNow = Eigen::Vector3d::Zero();
112 Eigen::MatrixXd ipeNow;
113 Eigen::MatrixXd sizeMatNow;
115 double distMin = 1e20;
117 for (
unsigned j = 0; j < calVec.size(); ++j) {
118 if (calVec[j].isCalibrated ==
false)
continue;
119 const auto& rJ = calVec[j].subIntervals;
120 for (
unsigned jj = 0; jj < rJ.size(); ++jj) {
121 const auto& rNow = rJ[jj];
122 double s = rNow.begin()->second.first;
123 double e = rNow.rbegin()->second.second;
125 double dist1 = (s - End >= 0) ? (s - End) : 1e20;
126 double dist2 = (Start - e >= 0) ? (Start - e) : 1e20;
127 double dist = std::min(dist1, dist2);
129 if (dist < distMin) {
130 ipNow = calVec[j].pars.cnt.at(jj);
131 ipeNow = calVec[j].pars.cntUnc.at(jj);
132 sizeMatNow = calVec[j].pars.spreadMat;
139 calVec[i].pars.cnt.resize(r.size());
140 calVec[i].pars.cntUnc.resize(r.size());
141 for (
unsigned ii = 0; ii < r.size(); ++ii) {
142 calVec[i].pars.cnt.at(ii) = ipNow;
143 calVec[i].pars.cntUnc.at(ii) = ipeNow;
145 calVec[i].pars.spreadMat = sizeMatNow;
151 inline void addShortRun(std::vector<CalibrationData>& calVec, std::pair<
ExpRun, std::pair<double, double>> shortRun)
153 double shortStart = shortRun.second.first;
154 double shortEnd = shortRun.second.second;
156 double distMin = 1e20;
157 int iMin = -1, jMin = -1;
159 for (
unsigned i = 0; i < calVec.size(); ++i) {
160 if (calVec[i].isCalibrated ==
false)
162 for (
unsigned j = 0; j < calVec[i].subIntervals.size(); ++j) {
163 for (
auto I : calVec[i].subIntervals[j]) {
164 double s = I.second.first;
165 double e = I.second.second;
167 double dist1 = (s - shortEnd >= 0) ? (s - shortEnd) : 1e20;
168 double dist2 = (shortStart - e >= 0) ? (shortStart - e) : 1e20;
169 double dist = std::min(dist1, dist2);
171 if (dist < distMin) {
180 B2ASSERT(
"Must be found", iMin != -1 && jMin != -1);
181 calVec[iMin].subIntervals[jMin].insert(shortRun);
188 double factor = pow(FLT_RADIX, DBL_MANT_DIG);
189 static const long long fEnc = 4294967296;
192 double mantisa = std::frexp(val, &e);
193 long long mantisaI = mantisa * factor;
196 mantisaI = (mantisaI / fEnc) * fEnc + num;
198 mantisaI = factor / 2 + num;
202 double newVal = ldexp(mantisaI / factor, e);
210 double factor = pow(FLT_RADIX, DBL_MANT_DIG);
211 static const long long fEnc = 4294967296;
214 double mantisa = std::frexp(val, &e);
215 long long mantisaI = mantisa * factor;
217 return (mantisaI % fEnc);
224 template<
typename Evt>
225 inline void storePayloads(
const std::vector<Evt>& evts,
const std::vector<CalibrationData>& calVecConst,
226 const std::string& objName,
227 std::function<TObject*(Eigen::VectorXd, Eigen::MatrixXd, Eigen::MatrixXd) > getCalibObj)
229 auto calVec = calVecConst;
232 ExpRun exprunLast(-1, -1);
236 for (
unsigned i = 0; i < calVec.size(); ++i) {
237 const auto& r = calVec[i].subIntervals;
239 for (
int k = 0; k < int(r.size()); ++k) {
241 for (
auto I : r[k]) {
245 if (calVec[i].pars.cntUnc.at(k).rows() == 3) {
246 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),
247 round(I.second.first * 3600));
248 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),
249 round(I.second.second * 3600));
251 calVec[i].pars.cntUnc.at(k)(0, 0) =
encodeNumber(calVec[i].pars.cntUnc.at(k)(0, 0), round(I.second.first * 3600));
252 calVec[i].pars.spreadMat(0, 0) =
encodeNumber(calVec[i].pars.spreadMat(0, 0), round(I.second.second * 3600));
255 TObject* obj = getCalibObj(calVec[i].pars.cnt.at(k), calVec[i].pars.cntUnc.at(k), calVec[i].pars.spreadMat);
256 if (exprun != exprunLast) {
266 breakPoint = calVec[i].breakPoints.at(k - 1).evt;
267 B2ASSERT(
"Payload saving consistency", calVec[i].breakPoints.at(k - 1).run == exprun.run);
269 B2ASSERT(
"Payload saving consistency", i != 0);
273 breakPoint = pos.evt;
274 B2ASSERT(
"Payload saving consistency", pos.run == exprun.run);
276 intraRun->
add(breakPoint, obj);
292 std::function<TObject*(Eigen::VectorXd, Eigen::MatrixXd, Eigen::MatrixXd) > getCalibObj)
294 auto calVec = calVecConst;
297 std::set<ExpRun> existingRuns;
298 for (
unsigned i = 0; i < calVec.size(); ++i) {
299 const auto& r = calVec[i].subIntervals;
301 for (
int k = 0; k < int(r.size()); ++k) {
303 for (
auto I : r[k]) {
306 if (existingRuns.count(exprun) != 0)
307 B2FATAL(
"Intra-run dependence exists");
308 existingRuns.insert(exprun);
315 for (
unsigned i = 0; i < calVec.size(); ++i) {
316 const auto& r = calVec[i].subIntervals;
318 for (
unsigned k = 0; k < r.size(); ++k) {
320 TObject* obj = getCalibObj(calVec[i].pars.cnt.at(k), calVec[i].pars.cntUnc.at(k), calVec[i].pars.spreadMat);
322 ExpRun start = (r[k].cbegin()->first);
323 ExpRun last = (r[k].crbegin()->first);
335 template<
typename Evt,
typename Fun>
344 B2INFO(
"Start of loop startTime endTime : " << rStart <<
" " << rEnd);
348 std::vector<Evt> evtsNow;
350 std::vector<int> Counts(breaks.size() + 1, 0);
352 for (
const auto& ev : evts) {
353 if (rStart <= ev.t && ev.t < rEnd) {
354 evtsNow.push_back(ev);
355 ++Counts.at(
getID(breaks, ev.t));
359 B2ASSERT(
"Number of intervals vs number of breakPoints", r.size() == breaks.size() + 1);
362 for (
int k = 0; k < 10; ++k) {
363 int iMin = min_element(Counts.begin(), Counts.end()) - Counts.begin();
364 if (Counts.size() >= 2 && Counts[iMin] < 50) {
368 else if (iMin ==
int(Counts.size()) - 1)
371 if (Counts[iMin + 1] < Counts[iMin - 1])
376 B2ASSERT(
"Number of intervals equal to size of counters", r.size() == Counts.size());
379 r.erase(r.begin() + iMin);
381 Counts[iM] += Counts[iMin];
382 Counts.erase(Counts.begin() + iMin);
386 B2INFO(
"#events " <<
" : " << evtsNow.size());
387 B2INFO(
"Breaks size " <<
" : " << breaks.size());
393 if (breaks.size() > 0)
394 B2INFO(
"StartOfCalibInterval (run,evtNo,vtxIntervalsSize) " << calD.
breakPoints.at(0).run <<
" " <<
400 if (evtsNow.size() < 50) {
405 B2INFO(
"Start of running calibration over calibration interval");
408 B2INFO(
"End of running analysis - SpreadMatX : " <<
sqrt(abs(calD.
pars.
spreadMat(0, 0))));
409 B2ASSERT(
"All subintervals have calibration of the mean value", calD.
pars.
cnt.size() == r.size());
410 B2ASSERT(
"All subintervals have calibration of the unc. of mean", calD.
pars.
cntUnc.size() == r.size());
428 template<
typename Fun1,
typename Fun2>
430 std::function<TObject*(Eigen::VectorXd, Eigen::MatrixXd, Eigen::MatrixXd)> calibObjCreator,
431 TString m_lossFunctionOuter, TString m_lossFunctionInner)
434 if (!tracks || tracks->GetEntries() < 15) {
436 B2WARNING(
"Too few data : " << tracks->GetEntries());
439 B2INFO(
"Number of tracks: " << tracks->GetEntries());
442 auto evts = GetEvents(tracks);
445 std::map<ExpRun, std::pair<double, double>> runsInfoOrg =
getRunInfo(evts);
446 std::map<ExpRun, std::pair<double, double>> runsRemoved;
447 auto runsInfo =
filter(runsInfoOrg, 2. / 60, runsRemoved);
450 if (runsInfo.size() == 0) {
451 B2WARNING(
"Too short run");
457 auto splits = splt.
getIntervals(runsInfo, evts, m_lossFunctionOuter, m_lossFunctionInner);
460 std::vector<CalibrationData> calVec;
461 for (
const auto& s : splits) {
463 calVec.push_back(calD);
470 for (
auto shortRun : runsRemoved) {
EResult
The result of calibration.
@ c_OK
Finished successfully =0 in Python.
@ c_NotEnoughData
Needs more data =2 in Python.
Class for handling changing conditions as a function of event number.
void add(unsigned int event, TObject *object)
Add an object to the intra run dependency.
A class that describes the interval of experiments/runs for which an object in the database is valid.
Class that allows to split runs into the intervals of intended properties given by the lossFunction.
static std::vector< double > getBreaks(const std::vector< std::map< ExpRun, std::pair< double, double > > > &res)
Get vector with breaks of the calib.
static std::pair< double, double > getStartEnd(std::vector< std::map< ExpRun, std::pair< double, double > > > res)
Get the start/end time of the calibration interval (vector of the calib.
std::vector< std::vector< std::map< ExpRun, std::pair< double, double > > > > getIntervals(const std::map< ExpRun, std::pair< double, double > > &runs, std::vector< Evt > evts, TString lossFunctionOuter, TString lossFunctionInner, double atomSize=3./60)
Function to merge/divide runs into the calibration intervals of given characteristic length.
static Database & Instance()
Instance of a singleton Database.
bool storeData(const std::string &name, TObject *object, const IntervalOfValidity &iov)
Store an object in the database.
B2Vector3< double > B2Vector3D
typedef for common usage with double
double sqrt(double a)
sqrt for double
void addShortRun(std::vector< CalibrationData > &calVec, std::pair< ExpRun, std::pair< double, double > > shortRun)
Extrapolate calibration to the very short runs which were filtered before.
static std::map< ExpRun, std::pair< double, double > > mergeIntervals(const std::map< ExpRun, std::pair< double, double > > &I1, const std::map< ExpRun, std::pair< double, double > > &I2)
Merge two subintervals into one subinterval.
double encodeNumber(double val, unsigned num)
Encode integer num into double val such that val is nearly not changed (maximally by a relative shift...
void storePayloads(const std::vector< Evt > &evts, const std::vector< CalibrationData > &calVecConst, const std::string &objName, std::function< TObject *(Eigen::VectorXd, Eigen::MatrixXd, Eigen::MatrixXd) > getCalibObj)
Store payloads to files.
int getID(const std::vector< double > &breaks, double t)
get id of the time point t
void storePayloadsNoIntraRun(const std::vector< CalibrationData > &calVecConst, const std::string &objName, std::function< TObject *(Eigen::VectorXd, Eigen::MatrixXd, Eigen::MatrixXd) > getCalibObj)
Store payloads to files, where calib data have no intra-run dependence.
TMatrixDSym toTMatrixDSym(Eigen::MatrixXd mIn)
Function that converts Eigen symmetric matrix to ROOT matrix.
unsigned decodeNumber(double val)
Decode the integer number encoded in val.
std::vector< ExpRunEvt > convertSplitPoints(const std::vector< Evt > &events, const std::vector< double > &splitPoints)
Convert splitPoints [hours] to breakPoints in ExpRunEvt.
std::map< ExpRun, std::pair< double, double > > filter(const std::map< ExpRun, std::pair< double, double > > &runs, double cut, std::map< ExpRun, std::pair< double, double > > &runsRemoved)
filter events to remove runs shorter than cut, it stores removed runs in runsRemoved
std::map< ExpRun, std::pair< double, double > > getRunInfo(const std::vector< Evt > &evts)
Get the map of runs, where each run contains pair with start/end time [hours].
CalibrationData runAlgorithm(const std::vector< Evt > &evts, std::vector< std::map< ExpRun, std::pair< double, double > > > range, Fun runCalibAnalysis)
run calibration algorithm for single calibration interval
CalibrationAlgorithm::EResult runCalibration(TTree *tracks, const std::string &calibName, Fun1 GetEvents, Fun2 calibAnalysis, std::function< TObject *(Eigen::VectorXd, Eigen::MatrixXd, Eigen::MatrixXd)> calibObjCreator, TString m_lossFunctionOuter, TString m_lossFunctionInner)
Run the the calibration over the whole event sample.
ExpRunEvt getPosition(const std::vector< Evt > &events, double tEdge)
Get the exp-run-evt number from the event time [hours].
B2Vector3D toB2Vector3(Eigen::VectorXd vIn)
Function that converts Eigen vector to ROOT vector.
void extrapolateCalibration(std::vector< CalibrationData > &calVec)
Extrapolate calibration to intervals where it failed.
Abstract base class for different kinds of events.
The parameters related to single calibration interval.
std::vector< Eigen::MatrixXd > cntUnc
vector of uncertainties of means for each calib. subinterval
std::vector< double > pulls
vector of pulls between mumu and hadB methods (for eCMS)
Eigen::MatrixXd spreadMat
spread CovMatrix
double shift
difference between eCMS for hadronic B decay method and mumu method, i.e. hadB - mumu
std::vector< Eigen::VectorXd > cnt
vector of means for each calib. subinterval
double shiftUnc
stat uncertainty of the shift
int size() const
number of the subintervals
double spreadUnc
stat uncertainty of the spread (for eCMS)
Parameters and data relevant for single calibration interval.
std::vector< std::map< ExpRun, std::pair< double, double > > > subIntervals
vector of the start and end times of the calibration subintervals
CalibPars pars
The parameters of the calibration itself.
bool isCalibrated
true if calibration run was successful
std::vector< ExpRunEvt > breakPoints
vector with break points positions
Struct containing exp number and run number.