DAS  3.0
Das Analysis System
Step.h
Go to the documentation of this file.
1 #ifndef STEP_HEADER
2 #define STEP_HEADER
3 
4 #include <cassert>
5 #include <cmath>
6 
7 #include <array>
8 #include <deque>
9 #include <iostream>
10 #include <limits>
11 #include <numeric>
12 #include <vector>
13 
14 #include <TF1.h>
15 #include <TH1.h>
16 #include <TH2.h>
17 #include <TVectorD.h>
18 #include <TMatrixD.h>
19 #include <TDecompSVD.h>
20 #include <TMath.h>
21 #include <TRandom3.h>
22 #include <TString.h>
23 
24 #include "Math/VectorUtil.h"
25 #include "Math/Minimizer.h"
26 #include "Math/Factory.h"
27 #include "Math/Functor.h"
28 
31 namespace Step {
32 
33 static const char * green = "\x1B[32m",
34  * red = "\x1B[31m",
35  * bold = "\e[1m",
36  * def = "\e[0m";
37 
38 static const auto eps = std::numeric_limits<double>::epsilon();
39 static const auto inf = std::numeric_limits<double>::infinity();
40 static bool verbose = false;
41 
45 struct Result {
46  const bool valid;
47  /*const*/ double chi2;
48  /*const*/ unsigned int ndf; //<! number of degrees of freedom
49  std::vector<double> X;
50  size_t degree () const { return X.size()-1; }
51  double x2n () const { return chi2/ndf ; }
52  double x2nErr () const { return sqrt(2./ndf); }
53  double prob () const { return TMath::Prob(chi2, ndf); }
54 
55  // replicas
56  std::vector<double> chi2sT,
58  double chi2T () const { return std::accumulate(std::begin(chi2sT), std::end(chi2sT), 0.) / chi2sT.size(); }
59  double chi2V () const { return std::accumulate(std::begin(chi2sV), std::end(chi2sV), 0.) / chi2sV.size(); }
60  double x2nT () const { return chi2T() / ndf ; }
61  double x2nV () const { return chi2V() / (ndf + X.size()); }
62 
63  // get TF1
64  template<typename POL>
65  TF1 * GetTF1 (const char * name, POL pol, double m, double M) const {
66  pol.npars = X.size();
67  auto f = new TF1(name, pol, m, M, pol.npars);
68  f->SetParameters(X.data());
69  f->SetTitle(Form("#chi^{2}_{%zu}/ndf = %.1f/%d", degree(), chi2, ndf));
70  return f;
71  }
72 };
73 
76 std::ostream& operator<< (std::ostream& stream, const Result& result)
77 {
78  using namespace std;
79  if (result.valid) {
80  stream << bold << "Chi2/ndf = " << result.chi2 << " / " << result.ndf
81  << " = " << result.x2n() << "\u00B1" << result.x2nErr()
82  << " (prob = " << result.prob() << ")\n" << def;
83  size_t nrep = result.chi2sT.size();
84  assert(nrep == result.chi2sV.size());
85  stream << result.X.size() << " parameters: ";
86  for (auto x: result.X) stream << std::setw(12) << x;
87  stream << '\n';
88  if (nrep > 0)
89  stream << nrep << " training replicas: Chi2T/" << result.ndf << " = " << result.x2nT() << '\n'
90  << nrep << " validation replicas: Chi2V/" << (result.ndf + result.X.size()) << " = " << result.x2nV() << '\n';
91  }
92  else stream << "Not a fit\n";
93  return stream;
94 }
95 
96 static std::deque<Result> chi2s;
97 static auto bestResult = chi2s.begin();
98 
107 double Ftest (const Result& former, const Result& current)
108 {
109  using namespace std;
110  if (!former.valid || !current.valid) throw -1.;
111  double RSS1 = former.chi2,
112  RSS2 = current.chi2;
113  size_t p1 = former.X.size(),
114  p2 = current.X.size();
115  assert(p2 > p1);
116  int ndf = current.ndf; // = nbins - p2
117  double x = ((RSS1-RSS2)/(p2-p1))/(RSS2/ndf);
118  double pvalue = TMath::FDistI(x, p2-p1, ndf);
119  return pvalue;
120 }
121 
126 double Xval (const Result& current, const Result& former)
127 {
128  if (former.chi2sV.size() != current.chi2sV.size())
129  return 0;
130 
131  size_t nrep = former.chi2sV.size();
132  if (nrep == 0) return 0;
133 
134  int Nf = former .ndf + former .X.size(),
135  Nc = current.ndf + current.X.size();
136  double nBetter = 0;
137  for (size_t i = 0; i < nrep; ++i)
138  if (former.chi2sV[i]/Nf < current.chi2sV[i]/Nc)
139  ++nBetter;
140  nBetter /= nrep;
141  return nBetter;
142 }
143 
146 void PrintAllTests (std::function<double(const Result&, const Result&)> test,
147  std::ostream& stream = std::cout, size_t best = 0)
148 {
149  using namespace std;
150 
151  int nGoodFits = 0;
152  for (auto result = begin(chi2s); result != end(chi2s); ++result)
153  if (result->valid) ++nGoodFits;
154  if (nGoodFits < 2) {
155  stream << red << "Only one valid fit. No test to run.\n" << def;
156  return;
157  }
158  stream << " " << bold;
159  for (auto result = begin(chi2s); result != prev(end(chi2s)); ++result) {
160  // loop over all results except the highest one
161  size_t deg = result->degree();
162  if (deg == best) stream << green;
163  if (!result->valid) stream << red;
164  stream << setw(10) << deg << def;
165  }
166  stream << '\n';
167  for (auto result2 = next(begin(chi2s)); result2 != end(chi2s); ++result2) {
168  // loop over all results
169  size_t deg2 = result2->degree();
170  if (deg2 == best) stream << green;
171  if (!result2->valid) stream << red;
172  stream << setw(3) << deg2 << def;
173  if (deg2 == best) stream << def;
174  stream << setprecision(4);
175  for (auto result1 = begin(chi2s); result1 != result2; ++result1) {
176  // compare to all results with less parameters
177  try { stream << setw(10) << test(*result1, *result2); }
178  catch (double) { stream << red << " -" << def; }
179  }
180  stream << bold << '\n';
181  }
182  stream << def;
183 }
184 
188 double identity (double x) { return x; }
189 
193 
194  unsigned int npars;
195  const double m,
196  M;
197  std::ostream& stream;
198 
199 protected:
200 
203  FunctionalForm (const char * classname, unsigned int Npars, double mi, double Ma, std::ostream& Stream = std::cout) :
204  npars(Npars), m(mi), M(Ma), stream(Stream)
205  {
206  if (verbose)
207  stream << "Declaring a `" << classname << "` with " << npars << " parameters between " << mi << " and " << Ma << '\n';
208  }
209 
210  virtual ~FunctionalForm () = default;
211 
212 public:
213 
216  virtual double operator() (const double *x, const double *p) const = 0;
217 };
218 
221 namespace Basis {
224  double Chebyshev (double x, int i)
225  {
226  if (std::abs(x) > 1) return 0.;
227  switch (i) {
228  case 0: return 1.;
229  case 1: return x;
230  default: return 2*x*Chebyshev(x, i-1)-Chebyshev(x, i-2);
231  }
232  }
233 
236  double Legendre (double x, int i)
237  {
238  if (std::abs(x) > 1) return 0.;
239  switch (i) {
240  case 0: return 1.;
241  case 1: return x;
242  default: return ( (2*i-1)*x*Legendre(x,i-1) - (i-1)*Legendre(x, i-2) )/i;
243  }
244  }
245 }
246 
251 template<double (*T)(double,int) = Basis::Chebyshev,
252  double (*Log)(double) = identity,
253  double (*Exp)(double) = identity>
254 struct Polynomial : public FunctionalForm {
255 
258  Polynomial (unsigned int d, double mi, double Ma, std::ostream& Stream = std::cout) :
259  FunctionalForm(__func__, d+1, mi, Ma, Stream) { }
260 
261  virtual ~Polynomial () = default;
262 
265  double operator() (const double *x, const double *p) const override
266  {
267  double nx = -1 + 2* (Log(*x) - Log(m)) / (Log(M) - Log(m));
268  double result = 0;
269  for (unsigned int i = 0; i < npars; ++i)
270  result += p[i]*T(nx,i);
271  return Exp(result);
272  }
273 };
274 
277 template<typename FunctionalForm>
278 struct Correlator {
279 
280  const int n;
281  TVectorD c,
282  e;
283  TVectorD v,
284  w,
285  s;
286  TMatrixD cov,
287  rot,
289 
291  std::ostream& stream;
292 
298  TH1 * h,
299  TH2 * hcov,
300  int im,
301  int iM,
302  FunctionalForm& ff,
303  std::ostream& Stream = std::cout
304  ) :
305  n(iM-im+1), c(n), e(n+1), v(n), w(n), s(n), cov(n,n), rot(n,n), invcov(n,n), f(ff), stream(Stream)
306  {
307  using namespace std;
308 
309  // sanity checks
310 
311  if (verbose)
312  stream << "n = " << n << '\n';
313 
314  if (verbose)
315  stream << "Checking histogram\n";
316  for (int i = im; i <= iM; ++i) {
317  auto content = h->GetBinContent(i);
318  if (verbose)
319  stream << setw(3) << i
320  << setw(12) << h->GetBinCenter(i)
321  << setw(12) << content << '\n';
322  assert(isnormal(content));
323  }
324 
325  if (hcov != nullptr) {
326  if (verbose)
327  stream << "Checking covariance\n";
328  for (int i = im; i <= iM; ++i)
329  for (int j = im; j <= iM; ++j) {
330  auto content = hcov->GetBinContent(i,j);
331  if (verbose) {
332  stream << setw(12) << content;
333  if (j == iM) stream << '\n';
334  }
335  assert(isfinite(content));
336  }
337  }
338 
339  // conversion for matrix algebra
340 
341  int shift = im;
342  if (verbose)
343  stream << "Converting from histograms to vector and matrix (shift = " << shift << "):";
344  for (int i = 0; i < n; ++i) {
345  e(i) = h->GetBinLowEdge(i+shift);
346  c(i) = h->GetBinCenter (i+shift);
347  v(i) = h->GetBinContent(i+shift);
348  if (verbose)
349  stream << '\n' << setw(5) << i << setw(10) << c(i) << setw(15) << v(i) << setw(15);
350  assert(abs(v(i)) > 0);
351  for (int j = 0; j < n; ++j) {
352  cov(i,j) = hcov != nullptr ? hcov->GetBinContent(i+shift,j+shift)
353  : i == j ? pow(h->GetBinError(i+shift),2) : 0;
354  if (i == j && verbose) stream << (100*sqrt(cov(i,j))/v(i)) << '%';
355  }
356  }
357  e(n) = h->GetBinLowEdge(n+shift);
358  if (verbose)
359  stream << '\n';
360 
361  if (!cov.IsSymmetric()) {
362  if (verbose)
363  stream << "Forcing to be symmetric\n";
364 
365  auto cov2 = cov;
366  cov2.T();
367  cov += cov2;
368  cov *= 0.5;
369  assert(cov.IsSymmetric());
370  }
371 
372  // preparing variables for replicas
373  w = v;
374  rot = cov.EigenVectors(s); // `s` will be modified here, but will be overwritten later
375  if (verbose)
376  stream << "Getting eigenvalues, expect different columns only in case of non-zero bin-to-bin correlations:";
377  for (int k = 0; k < n; ++k) {
378  if (verbose)
379  stream << '\n' << setw(5) << k << setw(15) << s[k] << setw(15) << cov(k,k);
380  s(k) = sqrt(s(k)); // to be used as input of `TRandom3::Gaus()`
381  assert(s[k] > 0);
382  }
383  if (verbose)
384  stream << '\n';
385 
386  // inverting
387  if (verbose)
388  stream << "Inverting...\n";
389  TDecompSVD svd(cov);
390  svd.SetTol(eps);
391  bool status = false;
392  invcov = svd.Invert(status);
393  assert(status);
394 
395  if (verbose)
396  stream << "Ready to fit\n";
397  }
398 
401  double operator() (const double * p)
402  {
403  auto r = w;
404  for (int i = 0; i < n; ++i) {
405  auto y0 = f(&e(i), p),
406  y1 = f(&c(i), p),
407  y2 = f(&e(i+1), p);
408  r(i) -= (y0+4*y1+y2)/6;
409  }
410  return r * (invcov * r);
411  }
412 
413  void SetReplica (UInt_t seed)
414  {
415  TRandom3 r(seed);
416 
417  TVectorD d(n);
418  for (int k = 0; k < n; ++k)
419  d(k) = r.Gaus(0, s(k));
420 
421  w = v + rot*d;
422  }
423 
424  void UnsetReplica ()
425  {
426  w = v;
427  }
428 };
429 
434  xVal
435 };
436 
441 template<double (*T)(double, int) = Basis::Chebyshev,
442  double (*Log)(double) = identity,
443  double (*Exp)(double) = identity>
445  TH1 * h,
446  TH2 * cov,
447  int im,
448  int iM,
449  unsigned int maxdegree,
450  EarlyStopping criterion = None,
451  double stopParam = 1,
452  UInt_t nrep = 0,
453  std::ostream& stream = std::cout
454  )
455 {
456  using namespace std;
457 
458  assert(h != nullptr);
459 
460  if (verbose)
461  stream << "im = " << im << ", iM = " << iM << '\n';
462 
463  unsigned int nbins = iM-im+1;
464  if (verbose)
465  stream << "nbins = " << nbins << '\n';
466  assert(nbins > 2);
467 
468  double m = h->GetBinLowEdge(im),
469  M = h->GetBinLowEdge(iM+1);
470  if (verbose)
471  stream << "m = " << m << ", M = " << M << '\n';
472 
473  Polynomial<T,Log,Exp> pol(maxdegree, m, M, stream);
474  Correlator cor(h, cov, im, iM, pol, stream);
475  ROOT::Math::Functor functor(cor, pol.npars);
476 
477  auto minimiser = ROOT::Math::Factory::CreateMinimizer("Minuit2", "Migrad");
478  const int Ncalls = 1e6;
479  minimiser->SetMaxFunctionCalls(Ncalls);
480  minimiser->SetFunction(functor);
481  minimiser->SetTolerance(0.001);
482  minimiser->SetPrintLevel(verbose);
483 
484  double fm = Log(h->GetBinContent(im)),
485  fM = Log(h->GetBinContent(iM));
486  auto step = 0.001;
487  double p0 = (fM+fm)/2, p1 = (fM-fm)/2;
488  minimiser->SetVariable(0,"p0",p0,step);
489  minimiser->SetVariable(1,"p1",p1,step);
490  for (unsigned int d = 2; d <= maxdegree; ++d) {
491  minimiser->SetVariable(d,Form("p%d", d),0.,step);
492  minimiser->FixVariable(d);
493  }
494 
495  // running
496  chi2s.clear();
497  chi2s.push_back({false, inf, nbins-2, {p0,p1}});
498  bestResult = chi2s.begin();
499  bool found = false;
500  while (chi2s.size() <= maxdegree) {
501  unsigned int degree = chi2s.size();
502  minimiser->ReleaseVariable(degree);
503  bool valid = minimiser->Minimize();
504 
505  const double * X = minimiser->X();
506  assert(X != nullptr);
507  double chi2 = cor(X);
508 
509  assert(isnormal(chi2));
510  unsigned int npars = minimiser->NFree(),
511  ndf = nbins - npars;
512  assert(npars == degree+1);
513 
514  const auto& former = chi2s.back();
515  chi2s.push_back({valid, chi2, ndf, vector<double>(X,X+npars)});
516  auto& current = chi2s.back();
517 
518  switch (minimiser->Status()) {
519  case 0: stream << current;
520  {
521  // check EarlyStopping::Chi2ndf criterion
522  bool plateau = current.x2n() > former.x2n(),
523  goodchi2 = abs(current.x2n()-1) <= stopParam*current.x2nErr();
524  if (plateau)
525  stream << red << "Chi2/ndf has increased.\n" << def;
526  else if (goodchi2)
527  stream << green << "Chi2 ~ ndf.\n" << def;
528 
529  // check EarlyStopping::fTest criterion
530  double ftestRes = 0;
531  if (bestResult != chi2s.begin())
532  try {
533  ftestRes = Ftest(former, current);
534  stream << "F-test result: " << ftestRes << '\n';
535  }
536  catch (double) { stream << red << "No F-test possible.\n" << def; }
537  bool fvalid = ftestRes > stopParam;
538 
539  // check EarlyStopping::xVal criterion
540  double xvalFrac = 0;
541  if (nrep > 0) {
542  current.chi2sT.reserve(nrep);
543  current.chi2sV.reserve(nrep);
544  for (UInt_t seed = 1; seed <= nrep; ++seed) {
545  cor.SetReplica(seed);
546  for (unsigned int i = 0; i <= degree; ++i)
547  minimiser->SetVariableValue(i, current.X[i]);
548  const double * X = minimiser->X();
549  assert(X != nullptr);
550  current.chi2sT.push_back(cor(X));
551  cor.SetReplica(seed+nrep);
552  current.chi2sV.push_back(cor(X));
553  }
554  cor.UnsetReplica();
555  for (unsigned int i = 0; i <= degree; ++i)
556  minimiser->SetVariableValue(i, current.X[i]);
557  X = minimiser->X();
558  xvalFrac = Xval(current, former);
559  }
560  bool xvalid = 1.-xvalFrac > stopParam;
561  if (nrep > 0)
562  stream << "Fraction of validation replicas with better fit Chi2/ndf = " << (xvalid ? green : red) << xvalFrac << def << '\n';
563 
564  // apply early stopping criterion
565  if (!found)
566  switch (criterion) {
568  found = plateau || goodchi2;
569  if (plateau) --bestResult;
570  break;
572  found = !fvalid;
573  break;
574  case EarlyStopping::xVal:
575  assert(nrep > 0);
576  found = !xvalid;
577  break;
578  case EarlyStopping::None:
579  found = false;
580  }
581  }
582  break;
583  case 1: stream << red << "Warning: Fit parameter covariance was made positive defined\n" << def;
584  for (unsigned int i = 0; i < npars; ++i) {
585  for (unsigned int j = 0; j < npars; ++j)
586  stream << setw(12) << minimiser->CovMatrix(i,j);
587  stream << '\n';
588  }
589  break;
590  case 2: stream << red << "Warning: Hesse is invalid\n" << def;
591  {
592  double * hessian = nullptr;
593  minimiser->GetHessianMatrix(hessian);
594  assert(hessian != nullptr);
595  for (unsigned int i = 0; i < npars; ++i) {
596  for (unsigned int j = 0; j < npars; ++j)
597  stream << setw(12) << hessian[i*pol.npars + j];
598  stream << '\n';
599  }
600  }
601  break;
602  case 3: stream << red << "Warning: Expected Distance reached from the Minimum (EDM = " << minimiser->Edm() << ") is above max\n" << def;
603  break;
604  case 4: stream << red << "Warning: Reached call limit (Ncalls = " << Ncalls << ")\n" << def;
605  break;
606  case 5:
607  default: stream << red << "Warning: Unknown failure\n" << def;
608  }
609 
610  if (!found) ++bestResult;
611 
612  if (verbose) {
613  stream << "Correlations of the fit parameters:\n";
614  for (unsigned int i = 0; i < npars; ++i) {
615  for (unsigned int j = 0; j < npars; ++j)
616  stream << setw(12) << minimiser->Correlation(i,j);
617  stream << '\n';
618  }
619  }
620 
621  if (current.ndf == 2) {
622  stream << red << "Only 2 d.o.f. left. Stopping.\n" << def;
623  break;
624  }
625 
626  stream << "---\n";
627  } // end of `while`-loop on number of parameters
628  chi2s.pop_front(); // removing first entry, which is not a fit (chi2 = inf)
629 
630  const char * name = Form("smooth_%s", h->GetName());
631  TF1 * f = bestResult->GetTF1(name, pol, m, M);
632  stream << "Best result: " << f->GetTitle() << "\n-----\n";
633 
634  stream << bold << "Running F-test:\n" << def;
635  PrintAllTests(Ftest, stream, bestResult->degree());
636 
637  if (nrep > 0) {
638  stream << bold << "Running Cross-validation:\n" << def;
639  PrintAllTests(Xval, stream, bestResult->degree());
640  }
641 
642  return f;
643 }
644 
647 template<double (*T)(double, int) = Basis::Chebyshev,
648  double (*Log)(double) = identity,
649  double (*Exp)(double) = identity>
650 TF1 * GetSmoothFit (TH1 * h, TH2 * cov, unsigned int maxdegree,
651  EarlyStopping criterion = EarlyStopping::None, double stopParam = 1, UInt_t nrep = 0,
652  std::ostream& stream = std::cout)
653 {
654  int im = 1, iM = h->GetNbinsX();
655  return GetSmoothFit<T,Log,Exp>(h, cov, im, iM,
656  maxdegree, criterion, stopParam, nrep, stream);
657 }
658 
661 template<double (*T)(double, int) = Basis::Chebyshev,
662  double (*Log)(double) = identity,
663  double (*Exp)(double) = identity>
664 TF1 * GetSmoothFit (TH1 * h, int im, int iM, unsigned int maxdegree,
665  EarlyStopping criterion = EarlyStopping::None, double stopParam = 1, UInt_t nrep = 0,
666  std::ostream& stream = std::cout)
667 {
668  return GetSmoothFit<T,Log,Exp>(h, nullptr, im, iM,
669  maxdegree, criterion, stopParam, nrep, stream);
670 }
671 
675 template<double (*T)(double, int) = Basis::Chebyshev,
676  double (*Log)(double) = identity,
677  double (*Exp)(double) = identity>
678 TF1 * GetSmoothFit (TH1 * h, unsigned int maxdegree,
679  EarlyStopping criterion = EarlyStopping::None, double stopParam = 1, UInt_t nrep = 0,
680  std::ostream& stream = std::cout)
681 {
682  return GetSmoothFit<T,Log,Exp>(h, nullptr,
683  maxdegree, criterion, stopParam, nrep, stream);
684 }
685 
686 
687 } // end of Step namespace
688 #endif
DYToLL_M-50_13TeV_pythia8_cff_GEN_SIM_RECOBEFMIX_DIGI_L1_DIGI2RAW_L1Reco_RECO.name
name
Definition: DYToLL_M-50_13TeV_pythia8_cff_GEN_SIM_RECOBEFMIX_DIGI_L1_DIGI2RAW_L1Reco_RECO.py:48
Step::Xval
double Xval(const Result &current, const Result &former)
Definition: Step.h:126
Step::FunctionalForm::operator()
virtual double operator()(const double *x, const double *p) const =0
operator overloading for the functor to be used with ROOT TF1
Step::Result
Definition: Step.h:45
Step::Result::chi2T
double chi2T() const
Definition: Step.h:58
Step::FunctionalForm::~FunctionalForm
virtual ~FunctionalForm()=default
Step::eps
static const auto eps
Definition: Step.h:38
Step::xVal
@ xVal
include additional parameter as long as cross validation provides a p-value beyond a certain threshol...
Definition: Step.h:434
Step::Result::X
std::vector< double > X
parameters from ROOT Minimizer
Definition: Step.h:49
Step::Result::x2n
double x2n() const
chi2/ndf
Definition: Step.h:51
Step::verbose
static bool verbose
Definition: Step.h:40
Step::Result::x2nV
double x2nV() const
Definition: Step.h:61
Step::Correlator::UnsetReplica
void UnsetReplica()
Definition: Step.h:424
Step::PrintAllTests
void PrintAllTests(std::function< double(const Result &, const Result &)> test, std::ostream &stream=std::cout, size_t best=0)
Print all F-tests based on the direct-fit results stored in Step::chi2s.
Definition: Step.h:146
Step::def
static const char * def
Definition: Step.h:36
Step::Correlator
A class to account for the correlations when fitting.
Definition: Step.h:278
Step::Correlator::SetReplica
void SetReplica(UInt_t seed)
Definition: Step.h:413
Step::Ftest
double Ftest(const Result &former, const Result &current)
Definition: Step.h:107
Ntupliser_cfg.p
p
Definition: Ntupliser_cfg.py:362
Step::Polynomial::Polynomial
Polynomial(unsigned int d, double mi, double Ma, std::ostream &Stream=std::cout)
Constructor.
Definition: Step.h:258
Step::Polynomial
Definition: Step.h:254
Ntupliser_cfg.f
f
Definition: Ntupliser_cfg.py:256
Step::chi2s
static std::deque< Result > chi2s
results from last call of Step::GetSmoothFit()
Definition: Step.h:96
Step::FunctionalForm::m
const double m
lower edge
Definition: Step.h:195
Step::Correlator::c
TVectorD c
bin center
Definition: Step.h:281
DAS::JetEnergy::w
static const float w
Definition: common.h:51
Step::operator<<
std::ostream & operator<<(std::ostream &stream, const Result &result)
Operator overloading to print result from Step::chi2s.
Definition: Step.h:76
Step::FunctionalForm::stream
std::ostream & stream
stream (e.g. cout or file)
Definition: Step.h:197
Step::Correlator::v
TVectorD v
xsection value
Definition: Step.h:283
Step::Result::ndf
unsigned int ndf
Definition: Step.h:48
Step::FunctionalForm::FunctionalForm
FunctionalForm(const char *classname, unsigned int Npars, double mi, double Ma, std::ostream &Stream=std::cout)
Constructor.
Definition: Step.h:203
Step::Correlator::f
FunctionalForm & f
fit function
Definition: Step.h:290
Step::red
static const char * red
Definition: Step.h:34
Step::bestResult
static auto bestResult
best result from last call of Step::GetSmoothFit()
Definition: Step.h:97
Step::Result::GetTF1
TF1 * GetTF1(const char *name, POL pol, double m, double M) const
Definition: Step.h:65
Step::Result::degree
size_t degree() const
degree of polynomial
Definition: Step.h:50
Step::Correlator::e
TVectorD e
bin edge
Definition: Step.h:282
Step::Basis::Chebyshev
double Chebyshev(double x, int i)
Chebyshev of first kind.
Definition: Step.h:224
Step
Smoothness Test with Expansion of Polynmials.
Definition: Step.h:31
Step::Correlator::Correlator
Correlator(TH1 *h, TH2 *hcov, int im, int iM, FunctionalForm &ff, std::ostream &Stream=std::cout)
Definition: Step.h:297
Step::Polynomial::~Polynomial
virtual ~Polynomial()=default
Step::Result::chi2sV
std::vector< double > chi2sV
chi2s from validation replicas
Definition: Step.h:57
Step::green
static const char * green
Definition: Step.h:33
Step::GetSmoothFit
TF1 * GetSmoothFit(TH1 *h, TH2 *cov, int im, int iM, unsigned int maxdegree, EarlyStopping criterion=None, double stopParam=1, UInt_t nrep=0, std::ostream &stream=std::cout)
Definition: Step.h:444
Step::Chi2ndf
@ Chi2ndf
stop as soon as Chi2ndf has reached a plateau, or as soon as it is compatible with 1
Definition: Step.h:432
Step::Result::x2nErr
double x2nErr() const
chi2/ndf error
Definition: Step.h:52
Step::Correlator::rot
TMatrixD rot
rotation matrix
Definition: Step.h:287
Step::Result::chi2V
double chi2V() const
Definition: Step.h:59
Step::Result::chi2
double chi2
chi2
Definition: Step.h:47
Step::fTest
@ fTest
include additional parameter as long as F-test provides a p-value beyond a certain threshold
Definition: Step.h:433
Step::Correlator::n
const int n
#bins
Definition: Step.h:280
Step::None
@ None
iterate until max value is reached
Definition: Step.h:431
Step::Correlator::cov
TMatrixD cov
covariance matrix
Definition: Step.h:286
Step::FunctionalForm
Abstract class for fit function.
Definition: Step.h:192
Step::identity
double identity(double x)
Definition: Step.h:188
Step::Result::chi2sT
std::vector< double > chi2sT
chi2s from training replicas
Definition: Step.h:56
Step::Correlator::s
TVectorD s
sqrt(eigenvalues)
Definition: Step.h:285
Step::Result::valid
const bool valid
output of ROOT::Math::Minimizer::Minimize()
Definition: Step.h:46
Step::Correlator::invcov
TMatrixD invcov
inverse of covariance matrix
Definition: Step.h:288
Step::Result::prob
double prob() const
chi2 fit probability
Definition: Step.h:53
Step::Basis::Legendre
double Legendre(double x, int i)
Legendre.
Definition: Step.h:236
Step::inf
static const auto inf
Definition: Step.h:39
Step::FunctionalForm::npars
unsigned int npars
number of parameters
Definition: Step.h:194
Step::Result::x2nT
double x2nT() const
Definition: Step.h:60
Step::Correlator::stream
std::ostream & stream
stream (e.g. cout or file)
Definition: Step.h:291
Step::EarlyStopping
EarlyStopping
Definition: Step.h:430
Step::Correlator::w
TVectorD w
replica
Definition: Step.h:284
Step::FunctionalForm::M
const double M
upper edge
Definition: Step.h:196
Step::bold
static const char * bold
Definition: Step.h:35