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;
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 = pow(2, 32);
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 = pow(2, 32);
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, std::string objName,
226 std::function<TObject*(Eigen::VectorXd, Eigen::MatrixXd, Eigen::MatrixXd) > getCalibObj)
228 auto calVec = calVecConst;
231 ExpRun exprunLast(-1, -1);
235 for (
unsigned i = 0; i < calVec.size(); ++i) {
236 const auto& r = calVec[i].subIntervals;
238 for (
int k = 0; k < int(r.size()); ++k) {
240 for (
auto I : r[k]) {
244 if (calVec[i].pars.cntUnc.at(k).rows() == 3) {
245 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),
246 round(I.second.first * 3600));
247 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),
248 round(I.second.second * 3600));
250 calVec[i].pars.cntUnc.at(k)(0, 0) =
encodeNumber(calVec[i].pars.cntUnc.at(k)(0, 0), round(I.second.first * 3600));
251 calVec[i].pars.spreadMat(0, 0) =
encodeNumber(calVec[i].pars.spreadMat(0, 0), round(I.second.second * 3600));
254 TObject* obj = getCalibObj(calVec[i].pars.cnt.at(k), calVec[i].pars.cntUnc.at(k), calVec[i].pars.spreadMat);
255 if (exprun != exprunLast) {
265 breakPoint = calVec[i].breakPoints.at(k - 1).evt;
266 B2ASSERT(
"Payload saving consistency", calVec[i].breakPoints.at(k - 1).run == exprun.run);
268 B2ASSERT(
"Payload saving consistency", i != 0);
272 breakPoint = pos.evt;
273 B2ASSERT(
"Payload saving consistency", pos.run == exprun.run);
275 intraRun->
add(breakPoint, obj);
291 std::function<TObject*(Eigen::VectorXd, Eigen::MatrixXd, Eigen::MatrixXd) > getCalibObj)
293 auto calVec = calVecConst;
296 std::set<ExpRun> existingRuns;
297 for (
unsigned i = 0; i < calVec.size(); ++i) {
298 const auto& r = calVec[i].subIntervals;
300 for (
int k = 0; k < int(r.size()); ++k) {
302 for (
auto I : r[k]) {
305 if (existingRuns.count(exprun) != 0)
306 B2FATAL(
"Intra-run dependence exists");
307 existingRuns.insert(exprun);
314 for (
unsigned i = 0; i < calVec.size(); ++i) {
315 const auto& r = calVec[i].subIntervals;
317 for (
unsigned k = 0; k < r.size(); ++k) {
319 TObject* obj = getCalibObj(calVec[i].pars.cnt.at(k), calVec[i].pars.cntUnc.at(k), calVec[i].pars.spreadMat);
321 ExpRun start = (r[k].cbegin()->first);
322 ExpRun last = (r[k].crbegin()->first);
334 template<
typename Evt,
typename Fun>
343 B2INFO(
"Start of loop startTime endTime : " << rStart <<
" " << rEnd);
347 std::vector<Evt> evtsNow;
349 std::vector<int> Counts(breaks.size() + 1, 0);
351 for (
const auto& ev : evts) {
352 if (rStart <= ev.t && ev.t < rEnd) {
353 evtsNow.push_back(ev);
354 ++Counts.at(
getID(breaks, ev.t));
358 B2ASSERT(
"Number of intervals vs number of breakPoints", r.size() == breaks.size() + 1);
361 for (
int k = 0; k < 10; ++k) {
362 int iMin = min_element(Counts.begin(), Counts.end()) - Counts.begin();
363 if (Counts.size() >= 2 && Counts[iMin] < 50) {
367 else if (iMin ==
int(Counts.size()) - 1)
370 if (Counts[iMin + 1] < Counts[iMin - 1])
375 B2ASSERT(
"Number of intervals equal to size of counters", r.size() == Counts.size());
378 r.erase(r.begin() + iMin);
380 Counts[iM] += Counts[iMin];
381 Counts.erase(Counts.begin() + iMin);
385 B2INFO(
"#events " <<
" : " << evtsNow.size());
386 B2INFO(
"Breaks size " <<
" : " << breaks.size());
392 if (breaks.size() > 0)
393 B2INFO(
"StartOfCalibInterval (run,evtNo,vtxIntervalsSize) " << calD.
breakPoints.at(0).run <<
" " <<
399 if (evtsNow.size() < 50) {
404 B2INFO(
"Start of running calibration over calibration interval");
407 B2INFO(
"End of running analysis - SpreadMatX : " <<
sqrt(abs(calD.
pars.
spreadMat(0, 0))));
408 B2ASSERT(
"All subintervals have calibration of the mean value", calD.
pars.
cnt.size() == r.size());
409 B2ASSERT(
"All subintervals have calibration of the unc. of mean", calD.
pars.
cntUnc.size() == r.size());
427 template<
typename Fun1,
typename Fun2>
429 std::function<TObject*(Eigen::VectorXd, Eigen::MatrixXd, Eigen::MatrixXd)> calibObjCreator,
430 TString m_lossFunctionOuter, TString m_lossFunctionInner)
433 if (!tracks || tracks->GetEntries() < 15) {
435 B2WARNING(
"Too few data : " << tracks->GetEntries());
438 B2INFO(
"Number of tracks: " << tracks->GetEntries());
441 auto evts = GetEvents(tracks);
444 std::map<ExpRun, std::pair<double, double>> runsInfoOrg =
getRunInfo(evts);
445 std::map<ExpRun, std::pair<double, double>> runsRemoved;
446 auto runsInfo =
filter(runsInfoOrg, 2. / 60, runsRemoved);
449 if (runsInfo.size() == 0) {
450 B2WARNING(
"Too short run");
456 auto splits = splt.
getIntervals(runsInfo, evts, m_lossFunctionOuter, m_lossFunctionInner);
459 std::vector<CalibrationData> calVec;
460 for (
auto s : splits) {
462 calVec.push_back(calD);
469 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(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
static std::map< ExpRun, std::pair< double, double > > mergeIntervals(std::map< ExpRun, std::pair< double, double > > I1, std::map< ExpRun, std::pair< double, double > > I2)
Merge two subintervals into one subinterval.
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.
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 storePayloadsNoIntraRun(const std::vector< CalibrationData > &calVecConst, 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.
int getID(const std::vector< double > &breaks, double t)
get id of the time point t
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.
void storePayloads(const std::vector< Evt > &evts, const std::vector< CalibrationData > &calVecConst, std::string objName, std::function< TObject *(Eigen::VectorXd, Eigen::MatrixXd, Eigen::MatrixXd) > getCalibObj)
Store payloads to files.
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::vector< ExpRunEvt > convertSplitPoints(const std::vector< Evt > &events, std::vector< double > splitPoints)
Convert splitPoints [hours] to breakPoints in ExpRunEvt.
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.