Belle II Software development
reconstruction

Topics

 reconstruction data objects
 
 
 reconstruction modules
 
 

Classes

class  BeamParametersFitter
 Fitter calculating BeamParameters from CollisionBoostVector and CollisionInvariantMass. More...
 
class  BeamSpotAlgorithm
 Class implementing BeamSpot calibration algorithm. More...
 
class  BoostVectorAlgorithm
 Class implementing BoostVector calibration algorithm. More...
 
struct  CalibPars
 The parameters related to single calibration interval. More...
 
struct  CalibrationData
 Parameters and data relevant for single calibration interval. More...
 
class  ChebFitter
 Unbinned Maximum Likelihood fitter with a possibility to use Chebyshev interpolation. More...
 
class  InvariantMassAlgorithm
 Class implementing InvariantMass calibration algorithm. More...
 
struct  Atom
 Very small (few mins) calibration interval which cannot be further divided : Atom. More...
 
struct  ExpRun
 Struct containing exp number and run number. More...
 
struct  ExpRunEvt
 struct with expNum, runNum, evtNum More...
 
class  Splitter
 Class that allows to split runs into the intervals of intended properties given by the lossFunction. More...
 
struct  Spline
 Spline structure for zero-order & linear splines. More...
 
class  EventsOfDoomParameters
 DBObject containing parameters used in EventsOfDoomBuster module. More...
 
class  RootMergeable< T >
 Wrap a root histogram or TNtuple to make it mergeable. More...
 

Typedefs

typedef std::map< std::string, double > Pars
 values of parameters in ML fit
 
typedef std::map< std::string, std::pair< double, double > > Limits
 limits of parameters in ML fit
 

Functions

TMatrixDSym toTMatrixDSym (Eigen::MatrixXd mIn)
 Function that converts Eigen symmetric matrix to ROOT matrix.
 
B2Vector3D toB2Vector3 (Eigen::VectorXd vIn)
 Function that converts Eigen vector to ROOT vector.
 
int getID (const std::vector< double > &breaks, double t)
 get id of the time point t
 
void extrapolateCalibration (std::vector< CalibrationData > &calVec)
 Extrapolate calibration to intervals where it failed.
 
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 1e-6).
 
unsigned decodeNumber (double val)
 Decode the integer number encoded in val.
 
template<typename Evt>
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.
 
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.
 
template<typename Evt, typename Fun>
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
 
template<typename Fun1, typename Fun2>
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.
 
std::pair< double, double > getMinima (const std::vector< std::vector< double > > &vals, int i0, int j0)
 Get minimum inside and outside of the smaller window defined by i0, j0.
 
std::vector< double > getMinimum (std::function< double(double, double)> fun, double xMin, double xMax, double yMin, double yMax)
 Get minimum of 2D function in the rectangular domain defined by xMin,xMax & yMin,yMax.
 
Eigen::VectorXd getWeights (int Size)
 Get the vector of weights to calculate the integral over the Chebyshev nodes The nodes are by definition between 0 and 1, there are Size nodes To get their positions, use getNodes.
 
Eigen::VectorXd getNodes (int Size)
 Get the vector of positions of the Chebyshev nodes The nodes are by definition between 0 and 1, there are Size nodes For the corresponding weights use getWeights.
 
Eigen::VectorXd getPols (int Size, double x)
 Evaluate Chebyshev polynomials up to Size at point x It returns a vector of the P_i(x) for i=0..Size-1 The polynomial is defined for x between 0 and 1.
 
Eigen::VectorXd getPolsSum (int Size, Eigen::VectorXd x)
 Calculate the Chebyshev polynomials of order i=0..Size-1 at points given in vector x_j and sum it over point index j It returns sum_j P_i(x_j) for i=0..Size-1 The Chebyshev polynomials are defined for x between 0 and 1.
 
Eigen::MatrixXd getCoefs (int Size, bool isInverse=false)
 Transformation matrix between Cheb nodes and coefficients of the Cheb polynomials Notice, that there are two alternative ways defining polynomial interpolation:
 
double evalPol (const Eigen::VectorXd &polCoef, double x)
 Evaluate Cheb.
 
Eigen::MatrixXd getCoefsCheb (int oldSize)
 Transformation matrix between Cheb nodes and Cheb coefficients with better normalization of the borders.
 
Eigen::VectorXd interpol (const Eigen::VectorXd &xi, double x)
 Get Interpolation vector k_i for point x from the function values at points xi (polynomial interpolation) In the second step, the function value at x can be evaluated as sum_i vals_i k_i.
 
double interpol (Eigen::VectorXd xi, Eigen::VectorXd vals, double x)
 Get interpolated function value at point x when function values vals at points xi are provided.
 
bool operator!= (ExpRun a, ExpRun b)
 Not equal for ExpRun.
 
bool operator< (ExpRun a, ExpRun b)
 less than for ExpRun
 
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::pair< int, int > getStartEndIndexes (int nIntervals, const std::vector< int > &breaks, int indx)
 get the range of interval with nIntervals and breaks stored in a vector
 
std::vector< Atomslice (std::vector< Atom > vec, int s, int e)
 Slice the vector to contain only elements with indexes s .. e (included)
 
std::vector< std::map< ExpRun, std::pair< double, double > > > breaks2intervalsSep (const std::map< ExpRun, std::pair< double, double > > &runsMap, const std::vector< Atom > &currVec, const std::vector< int > &breaks)
 Get calibration intervals according to the indexes of the breaks.
 
template<typename Evt>
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].
 
template<typename Evt>
ExpRunEvt getPosition (const std::vector< Evt > &events, double tEdge)
 Get the exp-run-evt number from the event time [hours].
 
template<typename Evt>
std::vector< ExpRunEvtconvertSplitPoints (const std::vector< Evt > &events, const std::vector< double > &splitPoints)
 Convert splitPoints [hours] to breakPoints in ExpRunEvt.
 
TString rn ()
 Get random string.
 
std::vector< std::vector< double > > merge (const std::vector< std::vector< std::vector< double > > > &toMerge)
 merge { vector<double> a, vector<double> b} into {a, b}
 
Eigen::VectorXd vec2vec (const std::vector< double > &vec)
 std vector -> ROOT vector
 
std::vector< double > vec2vec (const Eigen::VectorXd &v)
 ROOT vector -> std vector.
 
Eigen::MatrixXd vecs2mat (const std::vector< std::vector< double > > &vecs)
 merge columns (from std::vectors) into ROOT matrix
 
std::vector< double > getRangeLin (int nVals, double xMin, double xMax)
 Equidistant range between xMin and xMax for spline of the first order.
 
std::vector< double > getRangeZero (int nVals, double xMin, double xMax)
 Equidistant range between xMin and xMax for spline of the zero order.
 
std::vector< double > slice (const std::vector< double > &v, unsigned ind, unsigned n)
 put slice of original vector v[ind:ind+n] into new one, n is number of elements
 
double eval (const std::vector< double > &spl, const std::vector< double > &vals, double x)
 Evaluate spline (zero order or first order) in point x.
 
VectorXd getPolsSum (int Size, VectorXd x)
 Calculate the Chebyshev polynomials of order i=0..Size-1 at points given in vector x_j and sum it over point index j It returns sum_j P_i(x_j) for i=0..Size-1 The Chebyshev polynomials are defined for x between 0 and 1.
 
double evalPol (const VectorXd &polCoef, double x)
 Evaluate Cheb.
 
VectorXd interpol (const VectorXd &xi, double x)
 Get Interpolation vector k_i for point x from the function values at points xi (polynomial interpolation) In the second step, the function value at x can be evaluated as sum_i vals_i k_i.
 
double interpol (VectorXd xi, VectorXd vals, double x)
 Get interpolated function value at point x when function values vals at points xi are provided.
 
void plotRuns (const std::vector< std::pair< double, double > > &runs)
 plot runs on time axis
 
void plotSRuns (const std::vector< std::pair< double, double > > &runs, const std::vector< int > &breaks, int offset=2)
 plot clusters or runs on time axis
 
void printBySize (const std::vector< std::pair< double, double > > &runs)
 print sorted lengths of the runs
 
static ExpRun getRun (const std::map< ExpRun, std::pair< double, double > > &runs, double t)
 Get exp number + run number from time.
 
VXDDedxTrack const * getSVDDedxFromParticle (Particle const *particle)
 SVD dEdx value from particle.
 
Eigen::VectorXd getLogFunction (Pars pars) const
 Get the -2*log(p(x)) on the Cheb nodes.
 
void init (int Size, double xMin, double xMax)
 Initialize the fitter (the Chebyshev coefficients)
 
double getLogLikelihoodSlow (const Pars &pars) const
 Calculate log likelihood using exact formula.
 
double getLogLikelihoodFast (const Pars &pars) const
 Calculate log likelihood using approximation based on Chebyshev polynomials (typically faster)
 
double operator() (const double *par) const
 Evaluate the log likelihood.
 
Eigen::VectorXd getDataGrid () const
 Calculate Chebyshev coefficients for the data set.
 
std::pair< Pars, Eigen::MatrixXd > fitData (const Pars &pars, Limits limits, bool UseCheb=true)
 Fit the data with specified initial values of parameters and limits on them.
 
double lossFunction (const std::vector< Atom > &vec, int s, int e) const
 lossFunction of the calibration interval consisting of several "atoms" stored in vector vec The atoms included in calibration interval have indices between s and e
 
static std::vector< std::pair< double, double > > splitToSmall (const std::map< ExpRun, std::pair< double, double > > &runs, double intSize=1./60)
 Split the runs into small calibration intervals (atoms) of a specified size.
 
double getMinLoss (const std::vector< Atom > &vec, int e, std::vector< int > &breaks)
 Recursive function to evaluate minimal sum of the lossFuctions for the optimal clustering.
 
std::vector< int > dynamicBreaks (const std::vector< Atom > &runs)
 Get optimal break points using algorithm based on dynamic programming.
 
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.
 

Detailed Description

Typedef Documentation

◆ Limits

typedef std::map<std::string, std::pair<double, double> > Limits

limits of parameters in ML fit

Definition at line 28 of file ChebFitter.h.

◆ Pars

typedef std::map<std::string, double> Pars

values of parameters in ML fit

Definition at line 25 of file ChebFitter.h.

Function Documentation

◆ addShortRun()

void addShortRun ( std::vector< CalibrationData > & calVec,
std::pair< ExpRun, std::pair< double, double > > shortRun )
inline

Extrapolate calibration to the very short runs which were filtered before.

Definition at line 151 of file calibTools.h.

152 {
153 double shortStart = shortRun.second.first;
154 double shortEnd = shortRun.second.second;
155
156 double distMin = 1e20;
157 int iMin = -1, jMin = -1;
158
159 for (unsigned i = 0; i < calVec.size(); ++i) {
160 if (calVec[i].isCalibrated == false)
161 continue;
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;
166
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);
170
171 if (dist < distMin) {
172 distMin = dist;
173 iMin = i;
174 jMin = j;
175 }
176 }
177 }
178 }
179
180 B2ASSERT("Must be found", iMin != -1 && jMin != -1);
181 calVec[iMin].subIntervals[jMin].insert(shortRun);
182 }

◆ breaks2intervalsSep()

std::vector< std::map< ExpRun, std::pair< double, double > > > breaks2intervalsSep ( const std::map< ExpRun, std::pair< double, double > > & runsMap,
const std::vector< Atom > & currVec,
const std::vector< int > & breaks )

Get calibration intervals according to the indexes of the breaks.

Parameters
runsMapmap defining the time ranges of the runs
currVecvector with time intervals of the atoms (small non-divisible time intervals)
breaksvector with integer indexes of the breaks
Returns
: a vector of the calib. intervals where each interval is a map with exp-run as a key and start- end-time as a value

Definition at line 284 of file Splitter.cc.

287 {
288 std::vector<std::map<ExpRun, std::pair<double, double>>> splitsNow(breaks.size() + 1);
289 for (int i = 0; i < int(breaks.size()) + 1; ++i) {
290 int s, e;
291 std::tie(s, e) = getStartEndIndexes(currVec.size(), breaks, i);
292
293 // loop over atoms in single calib interval
294 for (int k = s; k <= e; ++k) {
295 ExpRun r = getRun(runsMap, (currVec[k].t1 + currVec[k].t2) / 2.); //runexp of the atom
296 if (splitsNow[i].count(r)) { //if already there
297 splitsNow[i].at(r).first = std::min(splitsNow[i].at(r).first, currVec[k].t1);
298 splitsNow[i].at(r).second = std::max(splitsNow[i].at(r).second, currVec[k].t2);
299 } else { //if new
300 splitsNow[i][r].first = currVec[k].t1;
301 splitsNow[i][r].second = currVec[k].t2;
302 }
303 }
304 }
305
306 return splitsNow;
307 }
std::pair< int, int > getStartEndIndexes(int nIntervals, const std::vector< int > &breaks, int indx)
get the range of interval with nIntervals and breaks stored in a vector
Definition Splitter.cc:83
static ExpRun getRun(const std::map< ExpRun, std::pair< double, double > > &runs, double t)
Get exp number + run number from time.
Definition Splitter.cc:263
Struct containing exp number and run number.
Definition Splitter.h:51

◆ convertSplitPoints()

template<typename Evt>
std::vector< ExpRunEvt > convertSplitPoints ( const std::vector< Evt > & events,
const std::vector< double > & splitPoints )

Convert splitPoints [hours] to breakPoints in ExpRunEvt.

Parameters
eventsvector of events
splitPointsthe vector containing times of the edges of the calibration intervals [hours]
Returns
a vector with calibration break-points in the exp-run-evt format

Definition at line 363 of file Splitter.h.

364 {
365
366 std::vector<ExpRunEvt> breakPos;
367 for (auto p : splitPoints) {
368 auto pos = getPosition(events, p);
369 breakPos.push_back(pos);
370 }
371 return breakPos;
372 }
ExpRunEvt getPosition(const std::vector< Evt > &events, double tEdge)
Get the exp-run-evt number from the event time [hours].
Definition Splitter.h:341

◆ decodeNumber()

unsigned decodeNumber ( double val)
inline

Decode the integer number encoded in val.

Definition at line 208 of file calibTools.h.

209 {
210 double factor = pow(FLT_RADIX, DBL_MANT_DIG);
211 static const long long fEnc = 4294967296; // pow(2, 32), 32 binary digits for encoded number
212
213 int e;
214 double mantisa = std::frexp(val, &e);
215 long long mantisaI = mantisa * factor;
216
217 return (mantisaI % fEnc);
218 }

◆ dynamicBreaks()

std::vector< int > dynamicBreaks ( const std::vector< Atom > & runs)
private

Get optimal break points using algorithm based on dynamic programming.

Parameters
runsVector of atoms, where each atom is an intervals in time
Returns
: Optimal indexes of the break points

Definition at line 242 of file Splitter.cc.

243 {
244 //reset cache
245 cache.resize(runs.size());
246 for (auto& c : cache)
247 c = std::make_pair(-1.0, std::vector<int>({}));
248
249
250 std::vector<int> breaks;
251 getMinLoss(runs, runs.size() - 1, breaks); //the minLoss (output) currently not used, only breaks
252
253 return breaks;
254 }

◆ encodeNumber()

double encodeNumber ( double val,
unsigned num )
inline

Encode integer num into double val such that val is nearly not changed (maximally by a relative shift 1e-6).

It is use to store time information to the payloads

Definition at line 186 of file calibTools.h.

187 {
188 double factor = pow(FLT_RADIX, DBL_MANT_DIG);
189 static const long long fEnc = 4294967296; // pow(2, 32), 32 binary digits for encoded number
190
191 int e; //exponent of the number
192 double mantisa = std::frexp(val, &e);
193 long long mantisaI = mantisa * factor; //mantissa as integer
194
195 if (val != 0)
196 mantisaI = (mantisaI / fEnc) * fEnc + num; //adding encoded number to last digits of mantissa
197 else {
198 mantisaI = factor / 2 + num;
199 e = -100; //if the val is zero, ensure very small number by the exponent
200 }
201
202 double newVal = ldexp(mantisaI / factor, e);
203
204 return newVal;
205 }

◆ eval()

double eval ( const std::vector< double > & spl,
const std::vector< double > & vals,
double x )
inline

Evaluate spline (zero order or first order) in point x.

Definition at line 115 of file tools.h.

116 {
117 int order = -1;
118 if (spl.size() == 0)
119 order = 0;
120 else if (spl.size() == vals.size() - 1)
121 order = 0;
122 else if (spl.size() == vals.size())
123 order = 1;
124 else {
125 B2FATAL("Unknown order of spline");
126 }
127 B2ASSERT("Spline order should be zero or one", order == 0 || order == 1);
128
129 if (order == 1) {
130 B2ASSERT("Linear spline only meaningful for two or more nodes", spl.size() >= 2);
131 B2ASSERT("As nodes as values in lin. spline", spl.size() == vals.size());
132
133 if (x <= spl[0]) return vals[0];
134 if (x >= spl.back()) return vals.back();
135
136 // binary search for position
137 int i1 = lower_bound(spl.begin(), spl.end(), x) - spl.begin() - 1;
138
139 if (!(spl[i1] <= x && x <= spl[i1 + 1])) {
140 B2FATAL("Wrong place founded : " << spl[i1] << " " << x << " " << spl[i1 + 1]);
141 }
142
143 // Linear interpolation between neighbouring nodes
144 double v = ((spl[i1 + 1] - x) * vals[i1] + (x - spl[i1]) * vals[i1 + 1]) / (spl[i1 + 1] - spl[i1]);
145 return v;
146 } else if (order == 0) { //zero order polynomial
147 B2ASSERT("#values vs #nodes in zero-order spline", spl.size() + 1 == vals.size());
148 if (vals.size() == 1) {
149 return vals[0];
150 } else {
151 double res = vals[0]; //by default value from lowest node
152 for (unsigned i = 0; i < spl.size(); ++i) {
153 if (spl[i] <= x) res = vals[i + 1];
154 else break;
155 }
156 return res;
157 }
158 }
159 return -99;
160 }

◆ evalPol() [1/2]

double evalPol ( const Eigen::VectorXd & polCoef,
double x )

Evaluate Cheb.

pol at point x when the coefficients of the expansion are provided

◆ evalPol() [2/2]

double evalPol ( const VectorXd & polCoef,
double x )

Evaluate Cheb.

pol at point x when the coefficients of the expansion are provided

Definition at line 176 of file nodes.cc.

177 {
178 VectorXd pols = getPols(polCoef.size(), x);
179
180 double s = pols.dot(polCoef);
181
182 return s;
183 }
Eigen::VectorXd getPols(int Size, double x)
Evaluate Chebyshev polynomials up to Size at point x It returns a vector of the P_i(x) for i=0....
Definition nodes.cc:77

◆ extrapolateCalibration()

void extrapolateCalibration ( std::vector< CalibrationData > & calVec)
inline

Extrapolate calibration to intervals where it failed.

Definition at line 102 of file calibTools.h.

103 {
104 //put closest neighbor, where the statistic was low or algo failed
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;
108 double Start, End;
109 std::tie(Start, End) = Splitter::getStartEnd(r);
110
111 Eigen::Vector3d ipNow = Eigen::Vector3d::Zero();
112 Eigen::MatrixXd ipeNow;
113 Eigen::MatrixXd sizeMatNow;
114
115 double distMin = 1e20;
116 //Find the closest calibrated interval
117 for (unsigned j = 0; j < calVec.size(); ++j) {
118 if (calVec[j].isCalibrated == false) continue; //skip not-calibrated intervals
119 const auto& rJ = calVec[j].subIntervals;
120 for (unsigned jj = 0; jj < rJ.size(); ++jj) { //loop over subintervals
121 const auto& rNow = rJ[jj];
122 double s = rNow.begin()->second.first;
123 double e = rNow.rbegin()->second.second;
124
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);
128
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;
133 distMin = dist;
134 }
135 }
136 }
137
138 //Store it to vectors
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;
144 }
145 calVec[i].pars.spreadMat = sizeMatNow;
146 }
147
148 }
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.
Definition Splitter.h:120

◆ filter()

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

Definition at line 38 of file Splitter.cc.

40 {
41 std::map<ExpRun, std::pair<double, double>> runsCopy;
42
43 for (auto r : runs) {
44 const auto& I = r.second;
45 double d = I.second - I.first;
46 if (d > cut)
47 runsCopy[r.first] = r.second;
48 else
49 runsRemoved[r.first] = r.second;
50 }
51
52 return runsCopy;
53 }

◆ fitData()

std::pair< Pars, MatrixXd > fitData ( const Pars & pars,
Limits limits,
bool UseCheb = true )

Fit the data with specified initial values of parameters and limits on them.

Definition at line 130 of file ChebFitter.cc.

131 {
132 m_useCheb = UseCheb;
133
134 ROOT::Math::Minimizer* minimum =
135 ROOT::Math::Factory::CreateMinimizer("Minuit2", "");
136
137 // set tolerance , etc...
138 minimum->SetMaxFunctionCalls(10000000); // for Minuit/Minuit2
139 minimum->SetMaxIterations(100000); // for GSL
140 minimum->SetTolerance(10.0);
141 //minimum->SetPrecision(1e-5);
142
143 //minimum->SetPrintLevel(3); //many outputs
144 minimum->SetPrintLevel(0); //few outputs
145 minimum->SetStrategy(2);
146 minimum->SetErrorDef(1);
147
148
149 // Set the free variables to be minimized !
150 m_parNames.clear();
151 int k = 0;
152 for (auto p : pars) {
153 std::string n = p.first;
154 double vCnt = p.second;
155 if (limits.count(n) == 1) {
156 double vMin = limits.at(n).first;
157 double vMax = limits.at(n).second;
158 double step = (vMax - vMin) / 100;
159 minimum->SetLimitedVariable(k, n, vCnt, step, vMin, vMax);
160 } else {
161 double step = 1;
162 minimum->SetVariable(k, n, vCnt, step);
163 }
164 m_parNames.push_back(n);
165 ++k;
166 }
167
168 // create function wrapper for minimizer
169 // a IMultiGenFunction type
170 ROOT::Math::Functor f(*this, pars.size());
171 minimum->SetFunction(f);
172
173
174 // do the minimization
175 minimum->Minimize();
176
177
178 Pars parsF;
179 for (unsigned i = 0; i < m_parNames.size(); ++i)
180 parsF[m_parNames[i]] = minimum->X()[i];
181
182 MatrixXd covMat(parsF.size(), parsF.size());
183 for (unsigned i = 0; i < parsF.size(); ++i)
184 for (unsigned j = 0; j < parsF.size(); ++j)
185 covMat(i, j) = minimum->CovMatrix(i, j);
186
187 // print pars
188 std::stringstream log;
189 log << "Minuit status : " << minimum->Status() << ", ";
190 for (auto p : parsF)
191 log << "\"" << p.first << "\" : " << p.second << ", ";
192
193 B2INFO(log.str());
194
195 delete minimum;
196
197 return std::make_pair(parsF, covMat);
198 }
std::map< std::string, double > Pars
values of parameters in ML fit
Definition ChebFitter.h:25

◆ getCoefs()

MatrixXd getCoefs ( int Size,
bool isInverse = false )

Transformation matrix between Cheb nodes and coefficients of the Cheb polynomials Notice, that there are two alternative ways defining polynomial interpolation:

  • coefficients c_i in of the Cheb polynomials, i.e. f(x) = sum_i c_i P_i(x)
  • Values of the f(x) in the Cheb nodes, i.e. d_j = f(x_j), where x_j are the nodes The Chebyshev polynomials are defined for x between 0 and 1

Definition at line 127 of file nodes.cc.

128 {
129 const int N = Size - 1;
130 assert(N % 2 == 0);
131
132 MatrixXd coef(Size, Size);
133
134 double mul = 1;
135 double C = 1. / N;
136 if (isInverse == true) {C = 1. / 2; }
137
138 for (int k = 0; k <= N; ++k) {
139 if (!isInverse) {
140 coef(k, N) = C;
141 coef(k, 0) = C * (k % 2 == 1 ? -1 : 1);
142 } else {
143 mul = k % 2 == 1 ? -1 : 1;
144 coef(N - k, N) = C * mul;
145 coef(N - k, 0) = C ;
146 }
147
148 for (int n = 1; n <= N - 1; ++n) {
149 double el = cos(n * k * M_PI / N) * 2.*C * mul;
150 if (!isInverse) coef(k, N - n) = el;
151 else coef(N - k, N - n) = el;
152 }
153 }
154
155 return coef;
156 }

◆ getCoefsCheb()

MatrixXd getCoefsCheb ( int oldSize)

Transformation matrix between Cheb nodes and Cheb coefficients with better normalization of the borders.

Definition at line 162 of file nodes.cc.

163 {
164 auto coef = getCoefs(oldSize);
165
166 coef.row(0) *= 0.5;
167 coef.row(coef.rows() - 1) *= 0.5;
168
169 return coef;
170 }
Eigen::MatrixXd getCoefs(int Size, bool isInverse=false)
Transformation matrix between Cheb nodes and coefficients of the Cheb polynomials Notice,...
Definition nodes.cc:127

◆ getDataGrid()

VectorXd getDataGrid ( ) const
private

Calculate Chebyshev coefficients for the data set.

Definition at line 109 of file ChebFitter.cc.

110 {
111 double a = m_nodes[0];
112 double b = m_nodes[m_nodes.size() - 1];
113
114
115 VectorXd polSum = VectorXd::Zero(m_nodes.size());
116 for (double x : m_data) {
117 double xx = (x - a) / (b - a); //normalize between 0 and 1
118 polSum += getPols(m_nodes.size(), xx);
119 }
120
121
122 //transform to the basis of the cheb m_nodes
123 VectorXd gridVals = m_coefsMat * polSum;
124
125 return gridVals;
126 }

◆ getID()

int getID ( const std::vector< double > & breaks,
double t )
inline

get id of the time point t

Definition at line 60 of file calibTools.h.

61 {
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];
65 if (s <= t && t < e)
66 return i;
67 }
68 return -1;
69 }

◆ getLogFunction()

VectorXd getLogFunction ( Pars pars) const
private

Get the -2*log(p(x)) on the Cheb nodes.

Definition at line 43 of file ChebFitter.cc.

44 {
45 VectorXd fVals(m_nodes.size());
46
47 //calc function values
48 fVals = m_nodes.unaryExpr([&](double x) { return m_myFun(x, pars); });
49
50 //normalize the function
51 double I = fVals.dot(m_weights);
52
53 fVals = -2 * log(fVals.array() / I); //normalize by integral
54
55 return fVals;
56
57 }

◆ getLogLikelihoodFast()

double getLogLikelihoodFast ( const Pars & pars) const
private

Calculate log likelihood using approximation based on Chebyshev polynomials (typically faster)

Definition at line 89 of file ChebFitter.cc.

90 {
91 VectorXd funVals = getLogFunction(pars);
92 double LL = funVals.dot(m_dataGrid);
93
94 return LL;
95 }

◆ getLogLikelihoodSlow()

double getLogLikelihoodSlow ( const Pars & pars) const
private

Calculate log likelihood using exact formula.

Definition at line 76 of file ChebFitter.cc.

77 {
78
79 double L = 0;
80 for (double d : m_data) {
81 double v = m_myFun(d, pars);
82 L += -2 * log(v);
83 }
84
85 return L;
86 }

◆ getMinima()

std::pair< double, double > getMinima ( const std::vector< std::vector< double > > & vals,
int i0,
int j0 )
inline

Get minimum inside and outside of the smaller window defined by i0, j0.

Definition at line 23 of file minimizer.h.

24 {
25 int N = vals.size();
26 int Nzoom = (N + 1) / 2;
27
28
29 double minIn = std::numeric_limits<double>::max();
30 double minOut = std::numeric_limits<double>::max();
31
32 for (int i = 0; i < N; ++i)
33 for (int j = 0; j < N; ++j) {
34 if ((i0 <= i && i < i0 + Nzoom) &&
35 (j0 <= j && j < j0 + Nzoom))
36 minIn = std::min(minIn, vals[i][j]);
37 else
38 minOut = std::min(minOut, vals[i][j]);
39 }
40 return {minIn, minOut};
41 }

◆ getMinimum()

std::vector< double > getMinimum ( std::function< double(double, double)> fun,
double xMin,
double xMax,
double yMin,
double yMax )
inline

Get minimum of 2D function in the rectangular domain defined by xMin,xMax & yMin,yMax.

Definition at line 44 of file minimizer.h.

45 {
46 const int N = 17; //the grid has size N x N
47 const int Nzoom = (N + 1) / 2; // the size of the zoomed rectangle where minimum is
48
49
50 const int kMax = 35; //number of iterations
51
52 std::vector<std::vector<double>> vals(N);
53 for (auto& v : vals) v.resize(N);
54
55 for (int k = 0; k < kMax; ++k) {
56
57 // get values of the function
58 for (int i = 0; i < N; ++i)
59 for (int j = 0; j < N; ++j) {
60 double x = xMin + i * (xMax - xMin) / (N - 1.);
61 double y = yMin + j * (yMax - yMin) / (N - 1.);
62 vals[i][j] = fun(x, y);
63 }
64
65 if (k == kMax - 1) break;
66
67 double mOutMax = - std::numeric_limits<double>::max();
68 int iOpt = -1, jOpt = -1;
69 //find optimal rectangle
70 for (int i = 0; i < N - Nzoom; ++i)
71 for (int j = 0; j < N - Nzoom; ++j) {
72 double mIn, mOut;
73 std::tie(mIn, mOut) = getMinima(vals, i, j);
74
75 if (mOut > mOutMax) {
76 mOutMax = mOut;
77 iOpt = i;
78 jOpt = j;
79 }
80 }
81
82 //Zoom to the optimal rectangle
83 // get values of the function
84
85 double xMinNow = xMin + iOpt * (xMax - xMin) / (N - 1.);
86 double xMaxNow = xMin + (iOpt + Nzoom - 1) * (xMax - xMin) / (N - 1.);
87
88 double yMinNow = yMin + jOpt * (yMax - yMin) / (N - 1.);
89 double yMaxNow = yMin + (jOpt + Nzoom - 1) * (yMax - yMin) / (N - 1.);
90
91 xMin = xMinNow;
92 xMax = xMaxNow;
93 yMin = yMinNow;
94 yMax = yMaxNow;
95
96 }
97
98
99 //get the overall minimum
100 double minTot = std::numeric_limits<double>::max();
101 int iOpt = -1, jOpt = -1;
102
103 for (int i = 0; i < N; ++i)
104 for (int j = 0; j < N; ++j) {
105 if (vals[i][j] < minTot) {
106 minTot = vals[i][j];
107 iOpt = i;
108 jOpt = j;
109 }
110 }
111
112 double xMinNow = xMin + iOpt * (xMax - xMin) / (N - 1.);
113 double yMinNow = yMin + jOpt * (yMax - yMin) / (N - 1.);
114
115 return {xMinNow, yMinNow};
116 }
std::pair< double, double > getMinima(const std::vector< std::vector< double > > &vals, int i0, int j0)
Get minimum inside and outside of the smaller window defined by i0, j0.
Definition minimizer.h:23

◆ getMinLoss()

double getMinLoss ( const std::vector< Atom > & vec,
int e,
std::vector< int > & breaks )
private

Recursive function to evaluate minimal sum of the lossFuctions for the optimal clustering.

It return the minimum of the lossFunction and optimal break points giving such value. It acts only on atoms with indexes between 0 and e

Parameters
vecVector of atoms, where each atom is an intervals in time
ethe index of the last atom included in the optimisation problem
[out]breaksOutput vector with indexes of optimal break points
Returns
: Minimal value of the summed loss function

Definition at line 205 of file Splitter.cc.

206 {
207 // If entry in cache (speed up)
208 if (cache[e].first >= 0) {
209 breaks = cache[e].second;
210 return cache[e].first;
211 }
212
213
214 std::vector<int> breaksOpt;
215 double minVal = 1e30;
216 int iMin = -10;
217 for (int i = -1; i <= e - 1; ++i) {
218 auto breaksNow = breaks;
219 double r1 = 0;
220 if (i != -1)
221 r1 = getMinLoss(vec, i, breaksNow);
222 double r2 = lossFunction(vec, i + 1, e);
223 double tot = r1 + r2;
224
225 if (tot < minVal) { //store minimum
226 minVal = tot;
227 iMin = i;
228 breaksOpt = breaksNow;
229 }
230 }
231
232 if (iMin != -1)
233 breaksOpt.push_back(iMin);
234
235
236 breaks = breaksOpt;
237 cache[e] = std::make_pair(minVal, breaks); //store solution to cache
238 return minVal;
239 }

◆ getNodes()

VectorXd getNodes ( int Size)

Get the vector of positions of the Chebyshev nodes The nodes are by definition between 0 and 1, there are Size nodes For the corresponding weights use getWeights.

Definition at line 65 of file nodes.cc.

66 {
67 assert((Size - 1) % 2 == 0);
68 VectorXd xi = VectorXd::Zero(Size);
69 for (int i = 0; i < Size; ++i) {
70 double Cos = cos(i / (Size - 1.) * M_PI);
71 xi[i] = (1 - Cos) / 2;
72 }
73 return xi;
74 }

◆ getPols()

VectorXd getPols ( int Size,
double x )

Evaluate Chebyshev polynomials up to Size at point x It returns a vector of the P_i(x) for i=0..Size-1 The polynomial is defined for x between 0 and 1.

Definition at line 77 of file nodes.cc.

78 {
79 VectorXd pol(Size);
80 double C = 2 * (2 * x - 1);
81
82 if (Size >= 1) pol[0] = 1;
83 if (Size >= 2) pol[1] = C / 2;
84
85 for (int i = 2; i < Size; ++i)
86 pol[i] = C * pol[i - 1] - pol[i - 2];
87 return pol;
88 }

◆ getPolsSum()

VectorXd getPolsSum ( int Size,
VectorXd x )

Calculate the Chebyshev polynomials of order i=0..Size-1 at points given in vector x_j and sum it over point index j It returns sum_j P_i(x_j) for i=0..Size-1 The Chebyshev polynomials are defined for x between 0 and 1.

Definition at line 96 of file nodes.cc.

97 {
98 assert(Size > 2);
99
100 VectorXd polSum(Size);
101
102 VectorXd pol0 = 0 * x.array() + 1;
103 VectorXd pol1 = 2 * x.array() - 1;
104 VectorXd C = 2 * pol1;
105
106 VectorXd pol2(x.size());
107 for (int i = 2; i < Size; ++i) {
108 polSum(i - 2) = pol0.sum();
109
110 pol2 = C.array() * pol1.array() - pol0.array();
111
112 pol0 = pol1;
113 pol1 = pol2;
114 }
115
116 polSum(Size - 2) = pol0.sum();
117 polSum(Size - 1) = pol1.sum();
118
119 return polSum;
120 }

◆ getPosition()

template<typename Evt>
ExpRunEvt getPosition ( const std::vector< Evt > & events,
double tEdge )
inline

Get the exp-run-evt number from the event time [hours].

Parameters
eventsvector of events
tEdgethe event time of the event of interest [hours]
Returns
the position of the time point in the exp-run-evt format

Definition at line 341 of file Splitter.h.

342 {
343 ExpRunEvt evt(-1, -1, -1);
344 double tBreak = -1e10;
345 for (const auto& e : events) {
346 if (e.t < tEdge) {
347 if (e.t > tBreak) {
348 tBreak = e.t;
349 evt = ExpRunEvt(e.exp, e.run, e.evtNo);
350 }
351 }
352 }
353 return evt;
354 }
struct with expNum, runNum, evtNum
Definition Splitter.h:60

◆ getRangeLin()

std::vector< double > getRangeLin ( int nVals,
double xMin,
double xMax )
inline

Equidistant range between xMin and xMax for spline of the first order.

Definition at line 83 of file tools.h.

84 {
85 B2ASSERT("At least one value in the spline required", nVals >= 1);
86 if (nVals == 1) return {};
87 std::vector<double> v(nVals);
88 for (int i = 0; i < nVals; ++i)
89 v[i] = xMin + i * (xMax - xMin) / (nVals - 1);
90 return v;
91 }

◆ getRangeZero()

std::vector< double > getRangeZero ( int nVals,
double xMin,
double xMax )
inline

Equidistant range between xMin and xMax for spline of the zero order.

Definition at line 94 of file tools.h.

95 {
96 B2ASSERT("At least one value in the spline required", nVals >= 1);
97 if (nVals == 1) return {};
98 std::vector<double> v(nVals - 1);
99 for (int i = 1; i < nVals; ++i)
100 v[i - 1] = xMin + i * (xMax - xMin) / (nVals);
101 return v;
102 }

◆ getRun()

static ExpRun getRun ( const std::map< ExpRun, std::pair< double, double > > & runs,
double t )
static

Get exp number + run number from time.

Parameters
runsmap, where key contain the exp-run number and value the start- and end-time of the run
ttime of interest [hours]
Returns
: the exp-run number at the input time t

Definition at line 263 of file Splitter.cc.

264 {
265 ExpRun rFound(-1, -1);
266 int nFound = 0;
267 for (auto r : runs) { //Linear search over runs
268 if (r.second.first <= t && t < r.second.second) {
269 ++nFound;
270 if (nFound == 2
271 && rFound.run == r.first.run - 1) // to fix corner case when a time is seen in two consecutive runs due to float rounding errors
272 --nFound;
273 rFound = r.first;
274 }
275 }
276
277 B2ASSERT("Exactly one interval should be found", nFound == 1);
278 B2ASSERT("Assert that something was found", rFound != ExpRun(-1, -1));
279 return rFound;
280 }

◆ getRunInfo()

template<typename Evt>
std::map< ExpRun, std::pair< double, double > > getRunInfo ( const std::vector< Evt > & evts)
inline

Get the map of runs, where each run contains pair with start/end time [hours].

Parameters
evtsvector of events
Returns
a map where the key is exp-run and value start/end time of the particular run [hours]

Definition at line 312 of file Splitter.h.

313 {
314 std::map<ExpRun, std::pair<double, double>> runsInfo;
315
316 for (const auto& evt : evts) {
317 int Exp = evt.exp;
318 int Run = evt.run;
319 double time = evt.t;
320 if (runsInfo.count(ExpRun(Exp, Run))) {
321 double tMin, tMax;
322 std::tie(tMin, tMax) = runsInfo.at(ExpRun(Exp, Run));
323 tMin = std::min(tMin, time);
324 tMax = std::max(tMax, time);
325 runsInfo.at(ExpRun(Exp, Run)) = {tMin, tMax};
326 } else {
327 runsInfo[ExpRun(Exp, Run)] = {time, time};
328 }
329
330 }
331 return runsInfo;
332 }

◆ getStartEndIndexes()

std::pair< int, int > getStartEndIndexes ( int nIntervals,
const std::vector< int > & breaks,
int indx )

get the range of interval with nIntervals and breaks stored in a vector

Definition at line 83 of file Splitter.cc.

84 {
85 B2ASSERT("There must be at least one interval", nIntervals >= 1);
86 B2ASSERT("Interval index must be positive", indx >= 0);
87 B2ASSERT("Interval index must be smaller than #breaks", indx < int(breaks.size()) + 1); //There is one more interval than #breaks
88 int s = (indx == 0) ? 0 : breaks[indx - 1] + 1;
89 int e = (indx == int(breaks.size())) ? nIntervals - 1 : breaks[indx];
90 return {s, e};
91 }

◆ getSVDDedxFromParticle()

VXDDedxTrack const * getSVDDedxFromParticle ( Particle const * particle)

SVD dEdx value from particle.

Definition at line 36 of file DedxVariables.cc.

37 {
38 const Track* track = particle->getTrack();
39 if (!track) {
40 return nullptr;
41 }
42
43 const VXDDedxTrack* dedxTrack = track->getRelatedTo<VXDDedxTrack>();
44 if (!dedxTrack) {
45 return nullptr;
46 }
47 return dedxTrack;
48 }
Class that bundles various TrackFitResults.
Definition Track.h:25

◆ getWeights()

VectorXd getWeights ( int Size)

Get the vector of weights to calculate the integral over the Chebyshev nodes The nodes are by definition between 0 and 1, there are Size nodes To get their positions, use getNodes.

Definition at line 29 of file nodes.cc.

30 {
31 const int N = Size - 1;
32 assert(N % 2 == 0);
33
34 std::vector<std::vector<double>> coef(Size);
35 for (auto& el : coef) el.resize(Size);
36
37
38 for (int k = 0; k <= N / 2; ++k) {
39 coef[2 * k][N] = 1. / N;
40 coef[2 * k][0] = 1. / N ;
41
42 coef[2 * k][N / 2] = 2. / N * (2 * ((k + 1) % 2) - 1);
43
44 for (int n = 1; n <= N / 2 - 1; ++n)
45 coef[2 * k][n] = coef[2 * k][N - n] = 2. / N * cos(n * k * M_PI * 2 / N);
46 }
47
48 VectorXd wgt = VectorXd::Zero(Size);
49
50
51 for (int i = 0; i < Size; ++i) {
52 wgt[i] += coef[0][i];
53 wgt[i] += coef[N][i] / (1. - N * N);
54 for (int k = 1; k <= N / 2 - 1; ++k) {
55 double w = 2. / (1 - 4 * k * k);
56 wgt[i] += w * coef[2 * k][i];
57 }
58
59 wgt[i] *= 0.5; //for interval (0,1)
60 }
61 return wgt;
62 }

◆ init()

void init ( int Size,
double xMin,
double xMax )

Initialize the fitter (the Chebyshev coefficients)

Definition at line 59 of file ChebFitter.cc.

60 {
61 // loading the Cheb nodes
62 m_nodes = (xMax - xMin) * getNodes(Size).array() + xMin;
63
64 // loading the weights for integration
65 m_weights = (xMax - xMin) * getWeights(Size);
66
67
68 // calculate the transformation matrix from pol coefs to grid points
69 m_coefsMat = getCoefsCheb(Size).transpose();
70
71 m_dataGrid = getDataGrid();
72
73 }
Eigen::VectorXd getWeights(int Size)
Get the vector of weights to calculate the integral over the Chebyshev nodes The nodes are by definit...
Definition nodes.cc:29
Eigen::MatrixXd getCoefsCheb(int oldSize)
Transformation matrix between Cheb nodes and Cheb coefficients with better normalization of the borde...
Definition nodes.cc:162
Eigen::VectorXd getNodes(int Size)
Get the vector of positions of the Chebyshev nodes The nodes are by definition between 0 and 1,...
Definition nodes.cc:65

◆ interpol() [1/3]

VectorXd interpol ( const VectorXd & xi,
double x )

Get Interpolation vector k_i for point x from the function values at points xi (polynomial interpolation) In the second step, the function value at x can be evaluated as sum_i vals_i k_i.

Definition at line 189 of file nodes.cc.

190 {
191 double Norm = (xi[xi.size() - 1] - xi[0]) / 2;
192 VectorXd coefs(xi.size());
193 for (int i = 0; i < xi.size(); ++i) {
194 double num = 1, den = 1;
195 for (int j = 0; j < xi.size(); ++j)
196 if (j != i) {
197 num *= (x - xi(j)) / Norm;
198 den *= (xi(i) - xi(j)) / Norm;
199 }
200 coefs(i) = num / den;
201 }
202 return coefs;
203 }

◆ interpol() [2/3]

double interpol ( Eigen::VectorXd xi,
Eigen::VectorXd vals,
double x )

Get interpolated function value at point x when function values vals at points xi are provided.

If the points xi are fixed and only vals are different between interpol calls, use interpol(xi, x) to speed up the evaluation.

◆ interpol() [3/3]

double interpol ( VectorXd xi,
VectorXd vals,
double x )

Get interpolated function value at point x when function values vals at points xi are provided.

If the points xi are fixed and only vals are different between interpol calls, use interpol(xi, x) to speed up the evaluation.

Definition at line 210 of file nodes.cc.

211 {
212 VectorXd coefs = interpol(xi, x);
213 return coefs.dot(vals);
214 }
Eigen::VectorXd interpol(const Eigen::VectorXd &xi, double x)
Get Interpolation vector k_i for point x from the function values at points xi (polynomial interpolat...

◆ lossFunction()

double lossFunction ( const std::vector< Atom > & vec,
int s,
int e ) const
private

lossFunction of the calibration interval consisting of several "atoms" stored in vector vec The atoms included in calibration interval have indices between s and e

the lossFunction formula (it can be modified according to the user's taste)

Parameters
vecVector of atoms, where each atom is an intervals in time
sFirst index of the calib. interval
eLast index of the calib. interval
Returns
: A value of the loss function

Definition at line 135 of file Splitter.cc.

136 {
137
138 //raw time
139 double rawTime = vec[e].t2 - vec[s].t1;
140
141 //max gap
142 double maxGap = 0;
143 for (int i = s; i <= e - 1; ++i) {
144 double d = vec[i + 1].t1 - vec[i].t2;
145 maxGap = std::max(maxGap, d);
146 }
147
148 //net time
149 double netTime = 0;
150 for (int i = s; i <= e; ++i) {
151 netTime += vec[i].t2 - vec[i].t1;
152 }
153
154 // Number of events
155 double nEv = 0;
156 for (int i = s; i <= e; ++i) {
157 nEv += vec[i].nEv;
158 }
159 if (nEv == 0) nEv = 0.1;
160
161 //double loss = (rawTime - tBest) * (rawTime - tBest) + gapPenalty * (maxGap * maxGap);
162 //double loss = 1./nEv + timePenalty * (rawTime * rawTime);
163
164 lossFun->SetParameters(rawTime, netTime, maxGap, nEv);
165 double lossNew = lossFun->Eval(0);
166
167 return lossNew;
168 }

◆ merge()

std::vector< std::vector< double > > merge ( const std::vector< std::vector< std::vector< double > > > & toMerge)
inline

merge { vector<double> a, vector<double> b} into {a, b}

Definition at line 41 of file tools.h.

42 {
43 std::vector<std::vector<double>> allVecs;
44 for (const auto& v : toMerge)
45 allVecs.insert(allVecs.end(), v.begin(), v.end());
46 return allVecs;
47 }

◆ mergeIntervals()

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 )
static

Merge two subintervals into one subinterval.

Parameters
I1First subinterval to merge
I2Second subinterval to merge
Returns
: The resulting subinterval

Definition at line 310 of file Splitter.cc.

312 {
313 std::map<ExpRun, std::pair<double, double>> I = I1;
314 for (auto r : I2) {
315 ExpRun run = r.first;
316 if (I.count(run) == 0)
317 I[run] = r.second;
318 else {
319 I.at(run) = std::make_pair(std::min(I1.at(run).first, I2.at(run).first), std::max(I1.at(run).second, I2.at(run).second));
320 }
321 }
322 return I;
323 }

◆ operator!=()

bool operator!= ( ExpRun a,
ExpRun b )
inline

Not equal for ExpRun.

Definition at line 71 of file Splitter.h.

71{ return (a.exp != b.exp || a.run != b.run); }

◆ operator()()

double operator() ( const double * par) const

Evaluate the log likelihood.

Definition at line 97 of file ChebFitter.cc.

98 {
99 Pars pars;
100 for (unsigned i = 0; i < m_parNames.size(); ++i)
101 pars[m_parNames[i]] = par[i];
102
103 double LL = m_useCheb ? getLogLikelihoodFast(pars) : getLogLikelihoodSlow(pars);
104
105 return LL;
106 }

◆ operator<()

bool operator< ( ExpRun a,
ExpRun b )
inline

less than for ExpRun

Definition at line 74 of file Splitter.h.

74{return ((a.exp < b.exp) || (a.exp == b.exp && a.run < b.run));}

◆ plotRuns()

void plotRuns ( const std::vector< std::pair< double, double > > & runs)

plot runs on time axis

Definition at line 57 of file Splitter.cc.

58 {
59 TGraphErrors* gr = new TGraphErrors();
60
61
62 for (auto r : runs) {
63 double m = (r.first + r.second) / 2;
64 double e = (r.second - r.first) / 2;
65
66 gr->SetPoint(gr->GetN(), m, 1);
67 gr->SetPointError(gr->GetN() - 1, e, 0);
68 }
69
70 gStyle->SetEndErrorSize(6);
71
72 gr->SetLineWidth(1);
73 gr->SetMarkerSize(40);
74 gr->Draw("ape");
75 gr->GetYaxis()->SetRangeUser(-10, 10);
76 gr->GetXaxis()->SetRangeUser(0, 256);
77
78 gr->GetXaxis()->SetTitle("time [hours]");
79
80 }

◆ plotSRuns()

void plotSRuns ( const std::vector< std::pair< double, double > > & runs,
const std::vector< int > & breaks,
int offset = 2 )

plot clusters or runs on time axis

Definition at line 94 of file Splitter.cc.

95 {
96 TGraphErrors* gr = new TGraphErrors();
97
98 for (int i = 0; i < int(breaks.size()) + 1; ++i) {
99 int s, e;
100 std::tie(s, e) = getStartEndIndexes(runs.size(), breaks, i);
101 double a = runs[s].first;
102 double b = runs[e].second;
103
104 double m = (a + b) / 2;
105 double err = (b - a) / 2;
106
107 gr->SetPoint(gr->GetN(), m, offset);
108 gr->SetPointError(gr->GetN() - 1, err, 0);
109
110 }
111
112 gr->SetLineColor(kRed);
113 gr->SetMarkerColor(kRed);
114 gr->Draw("pe same");
115 }

◆ printBySize()

void printBySize ( const std::vector< std::pair< double, double > > & runs)

print sorted lengths of the runs

Definition at line 119 of file Splitter.cc.

120 {
121 std::vector<double> dist;
122 for (auto r : runs) {
123 double d = r.second - r.first;
124 dist.push_back(d);
125 }
126
127 sort(dist.begin(), dist.end());
128
129 for (auto d : dist)
130 B2INFO(d);
131
132 }

◆ rn()

TString rn ( )
inline

Get random string.

Definition at line 38 of file tools.h.

38{return Form("%d", gRandom->Integer(1000000000)); }

◆ runAlgorithm()

template<typename Evt, typename Fun>
CalibrationData runAlgorithm ( const std::vector< Evt > & evts,
std::vector< std::map< ExpRun, std::pair< double, double > > > range,
Fun runCalibAnalysis )
inline

run calibration algorithm for single calibration interval

Definition at line 336 of file calibTools.h.

339 {
340 CalibrationData calD;
341 auto& r = range;
342 double rStart, rEnd;
343 std::tie(rStart, rEnd) = Splitter::getStartEnd(r);
344 B2INFO("Start of loop startTime endTime : " << rStart << " " << rEnd);
345
346 auto breaks = Splitter::getBreaks(r);
347
348 std::vector<Evt> evtsNow;
349
350 std::vector<int> Counts(breaks.size() + 1, 0);
351 // Select events belonging to the interval
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));
356 }
357 }
358
359 B2ASSERT("Number of intervals vs number of breakPoints", r.size() == breaks.size() + 1);
360
361 //Merge smallest interval if with low stat (try it 10times)
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) { //merge with neighbor if possible
365 auto iM = -1;
366 if (iMin == 0)
367 iM = iMin + 1;
368 else if (iMin == int(Counts.size()) - 1)
369 iM = iMin - 1;
370 else {
371 if (Counts[iMin + 1] < Counts[iMin - 1])
372 iM = iMin + 1;
373 else
374 iM = iMin - 1;
375 }
376 B2ASSERT("Number of intervals equal to size of counters", r.size() == Counts.size());
377
378 r.at(iM) = Splitter::mergeIntervals(r[iM], r[iMin]);
379 r.erase(r.begin() + iMin);
380 breaks = Splitter::getBreaks(r);
381 Counts[iM] += Counts[iMin];
382 Counts.erase(Counts.begin() + iMin);
383 }
384 }
385
386 B2INFO("#events " << " : " << evtsNow.size());
387 B2INFO("Breaks size " << " : " << breaks.size());
388
389 calD.breakPoints = convertSplitPoints(evtsNow, breaks);
390
391 calD.subIntervals = r;
392
393 if (breaks.size() > 0)
394 B2INFO("StartOfCalibInterval (run,evtNo,vtxIntervalsSize) " << calD.breakPoints.at(0).run << " " <<
395 calD.breakPoints.at(0).evt << " " << calD.breakPoints.size());
396
397
398 //If too few events, let have the output empty
399 //Will be filled with the closest neighbor at the next stage
400 if (evtsNow.size() < 50) {
401 return calD;
402 }
403
404 // Run the calibration
405 B2INFO("Start of running calibration over calibration interval");
406 tie(calD.pars.cnt, calD.pars.cntUnc, calD.pars.spreadMat) = runCalibAnalysis(evtsNow, breaks);
407 calD.pars.pulls.resize(calD.pars.cnt.size());
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());
411
412 calD.isCalibrated = true;
413
414 return calD;
415 }
static std::vector< double > getBreaks(const std::vector< std::map< ExpRun, std::pair< double, double > > > &res)
Get vector with breaks of the calib.
Definition Splitter.h:131
double sqrt(double a)
sqrt for double
Definition beamHelpers.h:28
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.
Definition Splitter.cc:310
int getID(const std::vector< double > &breaks, double t)
get id of the time point t
Definition calibTools.h:60
std::vector< ExpRunEvt > convertSplitPoints(const std::vector< Evt > &events, const std::vector< double > &splitPoints)
Convert splitPoints [hours] to breakPoints in ExpRunEvt.
Definition Splitter.h:363
std::vector< Eigen::MatrixXd > cntUnc
vector of uncertainties of means for each calib. subinterval
Definition calibTools.h:74
std::vector< double > pulls
vector of pulls between mumu and hadB methods (for eCMS)
Definition calibTools.h:81
Eigen::MatrixXd spreadMat
spread CovMatrix
Definition calibTools.h:75
std::vector< Eigen::VectorXd > cnt
vector of means for each calib. subinterval
Definition calibTools.h:73
Parameters and data relevant for single calibration interval.
Definition calibTools.h:87
std::vector< std::map< ExpRun, std::pair< double, double > > > subIntervals
vector of the start and end times of the calibration subintervals
Definition calibTools.h:89
CalibPars pars
The parameters of the calibration itself.
Definition calibTools.h:93
bool isCalibrated
true if calibration run was successful
Definition calibTools.h:95
std::vector< ExpRunEvt > breakPoints
vector with break points positions
Definition calibTools.h:91

◆ runCalibration()

template<typename Fun1, typename Fun2>
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.

Parameters
tracksTTree object with mu-mu events
calibNamename of the calibration payload
GetEventsfunction that transforms TTree to std::vector
calibAnalysisfunction that performs the calibration on a single calibration interval
calibObjCreatorfunction that stores results to the payload class which inherits from TObject
m_lossFunctionOuterLost function for the calibration intervals of the spread parameters
m_lossFunctionInnerLost function for the calibration subintervals (for the mean value parameters)
Returns
State of the calibration run, i.e. EResult::c_OK if everything OK

Definition at line 429 of file calibTools.h.

432 {
433 // Check that there are at least some data
434 if (!tracks || tracks->GetEntries() < 15) {
435 if (tracks)
436 B2WARNING("Too few data : " << tracks->GetEntries());
438 }
439 B2INFO("Number of tracks: " << tracks->GetEntries());
440
441 // Tree to vector of Events
442 auto evts = GetEvents(tracks);
443
444 //Time range for each ExpRun
445 std::map<ExpRun, std::pair<double, double>> runsInfoOrg = getRunInfo(evts);
446 std::map<ExpRun, std::pair<double, double>> runsRemoved; //map with time intervals of very short runs
447 auto runsInfo = filter(runsInfoOrg, 2. / 60, runsRemoved); //include only runs longer than 2mins
448
449 // If nothing remains
450 if (runsInfo.size() == 0) {
451 B2WARNING("Too short run");
453 }
454
455 // Get intervals based on the input loss functions
456 Splitter splt;
457 auto splits = splt.getIntervals(runsInfo, evts, m_lossFunctionOuter, m_lossFunctionInner);
458
459 //Loop over all calibration intervals
460 std::vector<CalibrationData> calVec;
461 for (const auto& s : splits) {
462 CalibrationData calD = runAlgorithm(evts, s, calibAnalysis); // run the calibration over the interval s
463 calVec.push_back(calD);
464 }
465
466 // extrapolate results to the low-stat intervals
468
469 // Include removed short runs
470 for (auto shortRun : runsRemoved) {
471 addShortRun(calVec, shortRun);
472 }
473
474 // Store Payloads to files
475 storePayloads(evts, calVec, calibName, calibObjCreator);
476
478 }
@ c_OK
Finished successfully =0 in Python.
@ c_NotEnoughData
Needs more data =2 in Python.
Class that allows to split runs into the intervals of intended properties given by the lossFunction.
Definition Splitter.h:108
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.
Definition Splitter.h:163
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.
Definition calibTools.h:151
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.
Definition calibTools.h:225
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
Definition Splitter.cc:38
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].
Definition Splitter.h:312
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
Definition calibTools.h:336
void extrapolateCalibration(std::vector< CalibrationData > &calVec)
Extrapolate calibration to intervals where it failed.
Definition calibTools.h:102

◆ slice() [1/2]

std::vector< double > slice ( const std::vector< double > & v,
unsigned ind,
unsigned n )
inline

put slice of original vector v[ind:ind+n] into new one, n is number of elements

Definition at line 106 of file tools.h.

107 {
108 std::vector<double> vNew;
109 for (unsigned i = ind; i < ind + n && i < v.size(); ++i)
110 vNew.push_back(v[i]);
111 return vNew;
112 }

◆ slice() [2/2]

std::vector< Atom > slice ( std::vector< Atom > vec,
int s,
int e )
inline

Slice the vector to contain only elements with indexes s .. e (included)

Definition at line 85 of file Splitter.h.

86 {
87 return std::vector<Atom>(vec.begin() + s, vec.begin() + e + 1);
88 }

◆ splitToSmall()

std::vector< std::pair< double, double > > splitToSmall ( const std::map< ExpRun, std::pair< double, double > > & runs,
double intSize = 1. / 60 )
staticprivate

Split the runs into small calibration intervals (atoms) of a specified size.

By definition each of these intervals spans only over single run. These will be clustered into larger intervals in the next steps

Parameters
runsRuns to split into the atoms
intSizeIntended size of the small intervals
Returns
: A vector with resulting time boundaries of the atoms

Definition at line 173 of file Splitter.cc.

175 {
176 // split into small intervals
177 std::vector<std::pair<double, double>> smallRuns;
178
179 for (auto r : runs) {
180 const auto& I = r.second;
181 if (intSize < 0) {
182 smallRuns.push_back(I);
183 continue;
184 }
185
186 double runTime = I.second - I.first;
187 int nSplits = runTime / intSize; //1-m intervals
188 nSplits = std::max(1, nSplits); //at least 1 interval
189
190 for (int i = 0; i < nSplits; ++i) {
191 double L = I.first + i * (runTime / nSplits);
192 double H = I.first + (i + 1) * (runTime / nSplits);
193 smallRuns.push_back({L, H});
194 }
195 }
196 return smallRuns;
197 }

◆ storePayloads()

template<typename Evt>
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 )
inline

Store payloads to files.

Definition at line 225 of file calibTools.h.

228 {
229 auto calVec = calVecConst;
230
231 // Loop to store payloads
232 ExpRun exprunLast(-1, -1); //last exprun
233 EventDependency* intraRun = nullptr;
234
235 // Loop over calibration intervals
236 for (unsigned i = 0; i < calVec.size(); ++i) {
237 const auto& r = calVec[i].subIntervals; // splits[i];
238 // Loop over calibration subintervals
239 for (int k = 0; k < int(r.size()); ++k) {
240
241 for (auto I : r[k]) { //interval required to be within single run
242 ExpRun exprun = I.first;
243
244 //Encode Start+End time in seconds of the payload
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));
250 } else {
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));
253 }
254
255 TObject* obj = getCalibObj(calVec[i].pars.cnt.at(k), calVec[i].pars.cntUnc.at(k), calVec[i].pars.spreadMat);
256 if (exprun != exprunLast) { //if new run
257 if (intraRun) { //if not first -> store
258 auto m_iov = IntervalOfValidity(exprunLast.exp, exprunLast.run, exprunLast.exp, exprunLast.run);
259 Database::Instance().storeData(objName, intraRun, m_iov);
260 }
261
262 intraRun = new EventDependency(obj);
263 } else {
264 int breakPoint;
265 if (k - 1 >= 0) {
266 breakPoint = calVec[i].breakPoints.at(k - 1).evt;
267 B2ASSERT("Payload saving consistency", calVec[i].breakPoints.at(k - 1).run == exprun.run);
268 } else {
269 B2ASSERT("Payload saving consistency", i != 0);
270 double rStart, rEnd;
271 std::tie(rStart, rEnd) = Splitter::getStartEnd(r);
272 auto pos = getPosition(evts, rStart);
273 breakPoint = pos.evt;
274 B2ASSERT("Payload saving consistency", pos.run == exprun.run);
275 }
276 intraRun->add(breakPoint, obj);
277 }
278 exprunLast = exprun;
279 }
280 } //end loop over calibration subintervals
281
282 } //end loop over calibration intervals
283
284 //Store the last entry
285 auto m_iov = IntervalOfValidity(exprunLast.exp, exprunLast.run, exprunLast.exp, exprunLast.run);
286 Database::Instance().storeData(objName, intraRun, m_iov);
287 }
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.
static Database & Instance()
Instance of a singleton Database.
Definition Database.cc:42
bool storeData(const std::string &name, TObject *object, const IntervalOfValidity &iov)
Store an object in the database.
Definition Database.cc:141
double encodeNumber(double val, unsigned num)
Encode integer num into double val such that val is nearly not changed (maximally by a relative shift...
Definition calibTools.h:186

◆ storePayloadsNoIntraRun()

void storePayloadsNoIntraRun ( const std::vector< CalibrationData > & calVecConst,
const std::string & objName,
std::function< TObject *(Eigen::VectorXd, Eigen::MatrixXd, Eigen::MatrixXd) > getCalibObj )
inline

Store payloads to files, where calib data have no intra-run dependence.

Definition at line 291 of file calibTools.h.

293 {
294 auto calVec = calVecConst;
295
296 // Check that there is no intra-run dependence
297 std::set<ExpRun> existingRuns;
298 for (unsigned i = 0; i < calVec.size(); ++i) {
299 const auto& r = calVec[i].subIntervals;
300 // Loop over calibration subintervals
301 for (int k = 0; k < int(r.size()); ++k) {
302
303 for (auto I : r[k]) {
304 ExpRun exprun = I.first;
305 // make sure that the run isn't already in the list, to avoid duplicity
306 if (existingRuns.count(exprun) != 0)
307 B2FATAL("Intra-run dependence exists");
308 existingRuns.insert(exprun);
309 }
310 }
311 }
312
313
314 // Loop over calibration intervals
315 for (unsigned i = 0; i < calVec.size(); ++i) {
316 const auto& r = calVec[i].subIntervals; // splits[i];
317 // Loop over calibration subintervals
318 for (unsigned k = 0; k < r.size(); ++k) {
319
320 TObject* obj = getCalibObj(calVec[i].pars.cnt.at(k), calVec[i].pars.cntUnc.at(k), calVec[i].pars.spreadMat);
321
322 ExpRun start = (r[k].cbegin()->first);
323 ExpRun last = (r[k].crbegin()->first);
324
325 auto iov = IntervalOfValidity(start.exp, start.run, last.exp, last.run);
326 Database::Instance().storeData(objName, obj, iov);
327
328
329 } //end loop over calibration subintervals
330 } //end loop over calibration intervals
331
332 }

◆ toB2Vector3()

B2Vector3D toB2Vector3 ( Eigen::VectorXd vIn)
inline

Function that converts Eigen vector to ROOT vector.

Definition at line 54 of file calibTools.h.

55 {
56 return B2Vector3D(vIn(0), vIn(1), vIn(2));
57 }
B2Vector3< double > B2Vector3D
typedef for common usage with double
Definition B2Vector3.h:522

◆ toTMatrixDSym()

TMatrixDSym toTMatrixDSym ( Eigen::MatrixXd mIn)
inline

Function that converts Eigen symmetric matrix to ROOT matrix.

Definition at line 44 of file calibTools.h.

45 {
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.;
50 return mOut;
51 }

◆ vec2vec() [1/2]

std::vector< double > vec2vec ( const Eigen::VectorXd & v)
inline

ROOT vector -> std vector.

Definition at line 61 of file tools.h.

62 {
63 std::vector<double> vNew(v.rows());
64 for (int i = 0; i < v.rows(); ++i)
65 vNew[i] = v(i);
66 return vNew;
67 }

◆ vec2vec() [2/2]

Eigen::VectorXd vec2vec ( const std::vector< double > & vec)
inline

std vector -> ROOT vector

Definition at line 51 of file tools.h.

52 {
53 Eigen::VectorXd v(vec.size());
54 for (unsigned i = 0; i < vec.size(); ++i) {
55 v[i] = vec[i];
56 }
57 return v;
58 }

◆ vecs2mat()

Eigen::MatrixXd vecs2mat ( const std::vector< std::vector< double > > & vecs)
inline

merge columns (from std::vectors) into ROOT matrix

Definition at line 72 of file tools.h.

73 {
74 Eigen::MatrixXd m(vecs[0].size(), vecs.size());
75 for (unsigned i = 0; i < vecs[0].size(); ++i)
76 for (unsigned j = 0; j < vecs.size(); ++j) {
77 m(i, j) = vecs[j][i];
78 }
79 return m;
80 }