20#include <framework/logging/Logger.h>
23#define B2FATAL(arg) { std::cout << arg << std::endl; std::exit(1);}
24#define B2ASSERT(str, cond) { if((cond) == false) {std::cout << __FILE__ <<", line "<<__LINE__ << std::endl << "" << #cond << " failed" << std::endl; std::exit(1);} }
38 inline TString
rn() {
return Form(
"%d", gRandom->Integer(1000000000)); }
41 inline std::vector<std::vector<double>>
merge(std::vector<std::vector<std::vector<double>>> toMerge)
43 std::vector<std::vector<double>> allVecs;
44 for (
const auto& v : toMerge)
45 allVecs.insert(allVecs.end(), v.begin(), v.end());
51 inline Eigen::VectorXd
vec2vec(std::vector<double> vec)
53 Eigen::VectorXd v(vec.size());
54 for (
unsigned i = 0; i < vec.size(); ++i) {
61 inline std::vector<double>
vec2vec(Eigen::VectorXd v)
63 std::vector<double> vNew(v.rows());
64 for (
int i = 0; i < v.rows(); ++i)
72 inline Eigen::MatrixXd
vecs2mat(std::vector<std::vector<double>> vecs)
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) {
83 inline std::vector<double>
getRangeLin(
int nVals,
double xMin,
double xMax)
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);
94 inline std::vector<double>
getRangeZero(
int nVals,
double xMin,
double xMax)
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);
106 inline std::vector<double>
slice(std::vector<double> v,
unsigned ind,
unsigned n)
108 std::vector<double> vNew;
109 for (
unsigned i = ind; i < ind + n && i < v.size(); ++i)
110 vNew.push_back(v[i]);
115 inline double eval(
const std::vector<double>& spl,
const std::vector<double>& vals,
double x)
120 else if (spl.size() == vals.size() - 1)
122 else if (spl.size() == vals.size())
125 B2FATAL(
"Unknown order of spline");
127 B2ASSERT(
"Spline order should be zero or one", order == 0 || 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());
133 if (x <= spl[0])
return vals[0];
134 if (x >= spl.back())
return vals.back();
137 int i1 = lower_bound(spl.begin(), spl.end(), x) - spl.begin() - 1;
139 if (!(spl[i1] <= x && x <= spl[i1 + 1])) {
140 B2FATAL(
"Wrong place founded : " << spl[i1] <<
" " << x <<
" " << spl[i1 + 1]);
144 double v = ((spl[i1 + 1] - x) * vals[i1] + (x - spl[i1]) * vals[i1 + 1]) / (spl[i1 + 1] - spl[i1]);
146 }
else if (order == 0) {
147 B2ASSERT(
"#values vs #nodes in zero-order spline", spl.size() + 1 == vals.size());
148 if (vals.size() == 1) {
151 double res = vals[0];
152 for (
unsigned i = 0; i < spl.size(); ++i) {
153 if (spl[i] <= x) res = vals[i + 1];
171 double val(
double x)
const {
return eval(nodes, vals, x);}
174 double err(
double x)
const {
return eval(nodes, errs, x);}
179 if (nodes.size() == 0)
181 else if (nodes.size() % 2 == 1)
182 return nodes[nodes.size() / 2];
184 return (nodes[nodes.size() / 2 - 1] + nodes[nodes.size() / 2]) / 2;
190 std::cout << tag <<
" : nodes: ";
191 for (
auto n : nodes) {
192 std::cout << n <<
" ";
194 std::cout << std::endl;
195 std::cout << tag <<
" : vals: ";
196 for (
auto n : vals) {
197 std::cout << n <<
" ";
199 std::cout << std::endl;
201 std::cout << tag <<
" : errs: ";
202 for (
auto n : errs) {
203 std::cout << n <<
" ";
205 std::cout << std::endl;
208 Spline() : nodes{}, vals{0}, errs{0} {}
Eigen::VectorXd vec2vec(std::vector< double > vec)
std vector -> ROOT vector
std::vector< Atom > slice(std::vector< Atom > vec, int s, int e)
Slice the vector to contain only elements with indexes s .. e (included)
double eval(const std::vector< double > &spl, const std::vector< double > &vals, double x)
Evaluate spline (zero order or first order) in point x.
std::vector< std::vector< double > > merge(std::vector< std::vector< std::vector< double > > > toMerge)
merge { vector<double> a, vector<double> b} into {a, b}
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 > getRangeLin(int nVals, double xMin, double xMax)
Equidistant range between xMin and xMax for spline of the first order.
Eigen::MatrixXd vecs2mat(std::vector< std::vector< double > > vecs)
merge columns (from std::vectors) into ROOT matrix
TString rn()
Get random string.
Abstract base class for different kinds of events.
Spline structure for zero-order & linear splines.
double val(double x) const
get value of spline at point x
std::vector< double > nodes
vector of spline nodes
std::vector< double > errs
vector of spline errors
std::vector< double > vals
vector of spline values
void print(TString tag="")
print the spline
double center() const
Get center of the spline domain.
double err(double x) const
get error of spline at point x