DAS  3.0
Das Analysis System
Greta.h
Go to the documentation of this file.
1 #ifndef __GRETA__
2 #define __GRETA__
3 #include <cstdlib>
4 #include <vector>
5 #include <iostream>
6 #include <iomanip>
7 #include <cassert>
8 #include <fstream>
9 
10 #include <TF1.h>
11 #include <TH1.h>
12 #include <TString.h>
13 #include <TFitResult.h>
14 
15 using namespace std;
16 
17 static const float feps = numeric_limits<float>::epsilon();
18 static const double deps = numeric_limits<double>::epsilon();
19 static const double dmax = numeric_limits<double>::max();
20 
21 namespace DAS {
22 
23 inline double identity (double x) { return x; };
24 
27 namespace Chebyshev {
28 
31  template<const size_t n> struct Term {
32  static double Eval (const double x)
33  {
34  const size_t m = n-1, k = n-2;
35  return 2*x*Term<m>::Eval(x)-Term<k>::Eval(x);
36  }
37  };
38  template<> struct Term<1> {
39  static double Eval (double x) { return x; }
40  };
41  template<> struct Term<0> {
42  static double Eval (double x) { return 1.; }
43  };
44 
47  template<const size_t n> struct Polynom {
48  static double Eval (double x, const double p[])
49  {
50  const size_t k = n-1;
51  return p[n]*Term<n>::Eval(x) + Polynom<k>::Eval(x,p);
52  }
53  };
54  template<> struct Polynom<0> {
55  static double Eval (double x, const double p[]) { return p[0]; }
56  };
57 
60  template<const size_t maxnPt, const size_t nPt, const size_t nY> struct Polynom2D {
61  static double Eval (double xPt, double xY, const double p[])
62  {
63  const size_t kY = nY-1;
64  const double * pPt = p + nY * maxnPt * sizeof(double);
65  const double q_nY = Polynom<nPt>::Eval(xPt, pPt);
66  return q_nY * Term<nY>::Eval(xY)
67  + Polynom2D<maxnPt, nPt, kY>::Eval(xPt, xY, pPt);
68  }
69  };
70  template<const size_t maxnPt, const size_t nPt> struct Polynom2D<maxnPt,nPt,0> {
71  static double Eval (double xPt, double xY, const double p[])
72  {
73  return Chebyshev::Polynom<nPt>::Eval(xPt, p);
74  }
75  };
76 }
77 
84 template<const size_t d, double (*Log)(double) = log, double (*Exp)(double) = exp>
85 struct Thunberg {
86 
87  const size_t maxdegree, npars;
88  const double m, M;
89 
90  Thunberg (double mi, double Ma) :
91  maxdegree(d), npars(d+1), m(Log(mi)), M(Log(Ma))
92  {
93  static_assert(d > 1, "degree must be greater than 1");
94  }
95 
96  double operator() (const double * x, const double * p)
97  {
98  double nx = -1 + 2* (Log(x[0]) - m) / (M - m);
99  double chebyshev = Chebyshev::Polynom<d>::Eval(nx,p);
100  double result = Exp(chebyshev);
101  return result;
102  }
103 };
104 
105 
110 template<double (*Log)(double) = log, double (*Exp)(double) = exp>
111 struct Greta {
112 
113  const int degree, npars;
114  const double m, M;
115 
120  [[ deprecated ]]
121  Greta (int d, double mi, double Ma) :
122  degree(d), npars(d+1), m(mi), M(Ma)
123  { }
124 
127  static double T (double x, int i)
128  {
129  if (i == 0) return 1.;
130  if (i == 1) return x;
131  return 2*x*T(x, i-1)-T(x, i-2);
132  }
133 
134  static const char * T (const char * x, int i)
135  {
136  if (i == 0) return Form("1.");
137  if (i == 1) return x;
138  const char * t1 = T(x, i-1), * t2 = T(x, i-2);
139  return Form("2*%s*%s-%s", x, t1, t2);
140  }
141 
142  inline double normalise (const double *x) const
143  {
144  return -1 + 2* (Log(*x) - Log(m)) / (Log(M) - Log(m));
145  }
146 
147  double operator() (const double *x, const double *p) const
148  {
149  double nx = normalise(x);
150  double result = 0;
151  for (int i = 0; i <= degree; ++i)
152  result += p[i]*T(nx,i);
153  //result += p[i]*pow(nx,i);
154  return Exp(result);
155  }
156 
157  static const char * formula (double mi, double Ma, int deg)
158  {
159  TString result = "[2]";
160  TString nx = "(-1+2*(log(x)-log([0]))/(log([1])-log([0])))";
161  for (int i = 1; i <= deg; ++i)
162  result += Form("+[%d]*%s", i+2, T(nx, i));
163  result = "exp(" + result + ")";
164  return result.Data();
165  }
166 
167  const char * formula ()
168  {
169  return formula(m, M, degree);
170  }
171 
172 };
173 
176 template<double (*Log)(double) = log, double (*Exp)(double) = exp>
178  double * const p;
180  [[ deprecated ]]
181  GretaPolynomial (double * const pars, int Npars, double m, double M) :
182  p(pars), g(Npars-1, m, M) { }
183  double operator() (double x) const {
184  x = max(g.m, x);
185  x = min(g.M, x);
186  return g(&x,p);
187  }
188 };
189 
198 template<double (*Log)(double) = log, double (*Exp)(double) = exp>
200 
201  vector<double> ymins;
202  vector<GretaPolynomial<Log,Exp>> pols;
203 
204 public:
205  void read (TString fname)
206  {
207  cout << "Reading " << fname << endl;
208  pols.clear();
209  ymins.clear();
210  ifstream infile;
211  infile.open(fname.Data());
212  if (infile.fail()) {
213  cerr << "Failure at opening the file " << fname << '\n';
214  exit(EXIT_FAILURE);
215  }
216 
217  while (infile.good()) {
218 
219  // getting values
220  double ymin, ptmin, ptmax;
221  int Npars;
222  infile >> ymin >> ptmin >> ptmax >> Npars;
223  double * pars = new double[Npars];
224  for (int i = 0; i < Npars; ++i) infile >> pars[i];
225 
226  if (infile.eof()) break;
227 
228  // instantiating
229  if (ymins.size() == 0) { assert(abs(ymin) < deps); }
230  else { assert(ymin > ymins.back()); }
231  ymins.push_back(ymin);
232  GretaPolynomial<Log,Exp> gp(pars, Npars, ptmin, ptmax);
233  pols.push_back(gp);
234  //pols.insert( { ymin, gp } );
235 
236  // print-out
237  cout << std::setw(3) << ymin
238  << std::setw(8) << (int) ptmin
239  << std::setw(8) << (int) ptmax
240  << std::setw(3) << Npars;
241  for (int j = 0; j < Npars; ++j) std::cout << std::setw(15) << pars[j];
242  cout << '\n';
243  }
244  cout << flush;
245 
246  assert(ymins.size() > 0);
247  assert(ymins.size() == pols.size());
248 
249  infile.close();
250  }
251 
252  double operator() (double pt, double y)
253  {
254  y = abs(y);
255  size_t iy = ymins.size();
256  do --iy;
257  while (ymins.at(iy) > y);
258  auto& g = pols.at(iy);
259  return g(pt);
260  }
261 
262 };
263 
264 
265 template<const size_t d>
266 [[ deprecated ]]
267 TF1 * GetSmoothFit (TH1 * h,
268  int ifm,
269  int ifM,
270  int nSigmaStop = 0,
271  const char * options = "Q0SNRE",
272  bool autoStop = false)
273 {
274  assert(ifm > 0);
275  assert(ifM <= h->GetNbinsX());
276  assert(h->GetDimension() == 1);
277 
278  double contentfm = h->GetBinContent(ifm),
279  contentfM = h->GetBinContent(ifM);
280 
281  double m = h->GetBinLowEdge(ifm), M = h->GetBinLowEdge(ifM+1);
282 
283  cout << "From bin " << ifm << " (m = " << m << ", content = " << contentfm << ")"
284  << " to bin " << ifM << " (M = " << M << ", content = " << contentfM << ")" << endl;
285 
286  if (abs(contentfm) <= deps || abs(contentfM) <= deps) {
287  cerr << "Fit cannot start with empty bins\n";
288  //h->Print("all");
289  return nullptr;
290  }
291 
292  double errorfm = h->GetBinError(ifm),
293  errorfM = h->GetBinError(ifM);
294 
295  if (abs(errorfm) <= deps || abs(errorfM) <= deps) {
296  cerr << "There must be uncertainties for the fit\n";
297  //h->Print("all");
298  return nullptr;
299  }
300 
301  double fm = log(contentfm),
302  fM = log(contentfM);
303 
304  double x2n = dmax, error = dmax;
305 
306  static int iname = 0; ++iname;
307  //Greta greta(maxdegree, m, M);
308  Thunberg<d, log, exp> greta(m, M);
309  const size_t maxdegree = greta.maxdegree;
310  TF1 * f = new TF1(Form("greta%d", iname), greta, m, M, greta.npars);
311 
312  // setting initial parameters
313  f->SetParameter(0,(fM+fm)/2);
314  f->SetParameter(1,(fM-fm)/2);
315  for (size_t degree = 2; degree <= maxdegree; ++degree)
316  f->FixParameter(degree,0);
317 
318  auto dump = [f](int degree) {
319  cout << "parameters:\t";
320  for (int i = 0; i <= degree; ++i) cout << f->GetParameter(i) << ' ';
321  cout << endl;
322  };
323 
324  //running
325  for (size_t degree = 2; degree <= maxdegree; ++degree) {
326 
327  dump(degree-1);
328  f->ReleaseParameter(degree);
329 
330  TFitResultPtr r = h->Fit(f, options);
331 
332  double chi2 = r->Chi2();
333  if (!isnormal(chi2)) {
334  h->Print("all");
335  cerr << "Fit aborted (chi2 = " << chi2 << ")\n";
336  continue;
337  }
338  double ndf = r->Ndf();
339 
340  int status = r->Status();
341  if (status != 0) {
342  h->Print("all");
343  cerr << "Fit aborted (status = " << status << ")\n";
344  continue;
345  }
346 
347  auto lastx2n = x2n;
348  x2n = chi2/ndf;
349  error = sqrt(2./ndf);
350  cout << "\e[1m" << degree << ' ' << status << '\t' << chi2 << ' ' << ndf << '\t' << x2n << "\u00B1" << error << "\e[0m" << endl;
351 
352  if (ndf == 2) break;
353  if (autoStop && x2n > lastx2n) {
354  cerr << "Chi2/ndf has increased -- stepping back and stopping!\n";
355  f->FixParameter(degree,0);
356  --degree;
357  h->Fit(f, options);
358  break;
359  }
360  if (abs(x2n-1) <= nSigmaStop*error) break;
361  }
362  dump(maxdegree);
363 
364  return f;
365 }
366 
367 template<const size_t d>
368 [[ deprecated ]]
369 TF1 * GetSmoothFit (TH1 * h,
370  double m,
371  double M,
372  int nSigmaStop = 0,
373  const char * options = "Q0SNRE",
374  bool autoStop = false)
375 {
376  assert(m < M);
377 
378  int ifm = h->FindBin(m+feps),
379  ifM = h->FindBin(M-feps);
380  cout << "Axis interval (" << m << ',' << M << ") to bin interval (" << ifm << ',' << ifM << ')' << endl;
381 
382  assert(ifm < ifM);
383 
384  return GetSmoothFit<d>(h, ifm, ifM, nSigmaStop, options, autoStop);
385 }
386 
387 } // end of DAS namespace
388 #endif
DAS::Greta::m
const double m
Definition: Greta.h:114
metPhiCorrectionExample.infile
string infile
Definition: metPhiCorrectionExample.py:25
identity
VectorXd identity(const VectorXd &x)
Definition: Teddy.cc:19
Ntupliser_cfg.cerr
cerr
Definition: Ntupliser_cfg.py:93
DAS
Definition: applyBTagSF.cc:31
jercExample.fname
fname
Definition: jercExample.py:88
DAS::Chebyshev::Term< 1 >::Eval
static double Eval(double x)
Definition: Greta.h:39
DAS::Greta::M
const double M
Definition: Greta.h:114
DYToLL_M-50_13TeV_pythia8_cff_GEN_SIM_RECOBEFMIX_DIGI_L1_DIGI2RAW_L1Reco_RECO.options
options
Definition: DYToLL_M-50_13TeV_pythia8_cff_GEN_SIM_RECOBEFMIX_DIGI_L1_DIGI2RAW_L1Reco_RECO.py:41
jmarExample.pt
pt
Definition: jmarExample.py:19
DAS::Chebyshev::Term< 0 >::Eval
static double Eval(double x)
Definition: Greta.h:42
dmax
static const double dmax
Definition: Greta.h:19
DAS::GretaPolynomial::GretaPolynomial
GretaPolynomial(double *const pars, int Npars, double m, double M)
Definition: Greta.h:181
DAS::Thunberg
Definition: Greta.h:85
DAS::GretaPolynomial
Alternative to ROOT TF1 (which is terribly slow) to use polynomials.
Definition: Greta.h:177
DAS::Chebyshev::Polynom::Eval
static double Eval(double x, const double p[])
Definition: Greta.h:48
DAS::Chebyshev::Polynom2D< maxnPt, nPt, 0 >::Eval
static double Eval(double xPt, double xY, const double p[])
Definition: Greta.h:71
DAS::GretaPolynomialReader::pols
vector< GretaPolynomial< Log, Exp > > pols
first index for low edge of rap bin
Definition: Greta.h:202
DAS::GretaPolynomial::g
const Greta< Log, Exp > g
Definition: Greta.h:179
DAS::Chebyshev::Polynom2D::Eval
static double Eval(double xPt, double xY, const double p[])
Definition: Greta.h:61
Ntupliser_cfg.p
p
Definition: Ntupliser_cfg.py:362
DAS::Chebyshev::Polynom
Chebyshev Polynoms.
Definition: Greta.h:47
Ntupliser_cfg.f
f
Definition: Ntupliser_cfg.py:256
DAS::Thunberg::Thunberg
Thunberg(double mi, double Ma)
Definition: Greta.h:90
DAS::ymin
static const double ymin
Definition: binnings.h:48
deps
static const double deps
Definition: Greta.h:18
DAS::GretaPolynomialReader::read
void read(TString fname)
Definition: Greta.h:205
DAS::Greta::T
static double T(double x, int i)
Chebyshev of first kind.
Definition: Greta.h:127
DAS::Chebyshev::Term::Eval
static double Eval(const double x)
Definition: Greta.h:32
DAS::Greta::npars
const int npars
Definition: Greta.h:113
DAS::Chebyshev::Polynom< 0 >::Eval
static double Eval(double x, const double p[])
Definition: Greta.h:55
DAS::Greta::normalise
double normalise(const double *x) const
Definition: Greta.h:142
DAS::GetSmoothFit
TF1 * GetSmoothFit(TH1 *h, double m, double M, int nSigmaStop=0, const char *options="Q0SNRE", bool autoStop=false)
Definition: Greta.h:369
feps
static const float feps
Definition: Greta.h:17
DAS::GretaPolynomialReader
Definition: Greta.h:199
DAS::Greta
Definition: Greta.h:111
DAS::Thunberg::npars
const size_t npars
Definition: Greta.h:87
DAS::Thunberg::maxdegree
const size_t maxdegree
Definition: Greta.h:87
Step::Basis::Chebyshev
double Chebyshev(double x, int i)
Chebyshev of first kind.
Definition: Step.h:224
DAS::GretaPolynomial::p
double *const p
Definition: Greta.h:178
DAS::Greta::Greta
Greta(int d, double mi, double Ma)
Definition: Greta.h:121
DAS::ptmin
static const double ptmin
Definition: binnings.h:46
DAS::Greta::T
static const char * T(const char *x, int i)
Definition: Greta.h:134
DAS::ptmax
static const double ptmax
Definition: binnings.h:47
DAS::Greta::formula
static const char * formula(double mi, double Ma, int deg)
Definition: Greta.h:157
DAS::Chebyshev::Polynom2D
2D Chebyshev Polynoms
Definition: Greta.h:60
DAS::Thunberg::m
const double m
Definition: Greta.h:88
DAS::Greta::formula
const char * formula()
Definition: Greta.h:167
DAS::Chebyshev::Term
Chebyshev Terms.
Definition: Greta.h:31
DAS::GretaPolynomialReader::ymins
vector< double > ymins
Definition: Greta.h:201
Ntupliser_cfg.dump
string dump
Definition: Ntupliser_cfg.py:46