Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
HFitImpl.cxx
Go to the documentation of this file.
1// new HFit function
2//______________________________________________________________________________
3
4
5#include "TH1.h"
6#include "TF1.h"
7#include "TF2.h"
8#include "TF3.h"
9#include "TError.h"
10#include "TGraph.h"
11#include "TMultiGraph.h"
12#include "TGraph2D.h"
13#include "THnBase.h"
14
15#include "Fit/Fitter.h"
16#include "Fit/FitConfig.h"
17#include "Fit/BinData.h"
18#include "Fit/UnBinData.h"
19#include "Fit/Chi2FCN.h"
21#include "HFitInterface.h"
23#include "Math/Minimizer.h"
24
25#include "Math/WrappedTF1.h"
27
28#include "TList.h"
29#include "TMath.h"
30#include "TROOT.h"
31
32#include "TVirtualPad.h" // for gPad
33
34#include "TBackCompFitter.h"
35#include "TFitResultPtr.h"
36#include "TFitResult.h"
37
38#include <cstdlib>
39#include <cmath>
40#include <memory>
41#include <limits>
42
43//#define DEBUG
44
45// utility functions used in TH1::Fit
46
47namespace HFit {
48
49
50 int GetDimension(const TH1 * h1) { return h1->GetDimension(); }
51 int GetDimension(const TGraph * ) { return 1; }
52 int GetDimension(const TMultiGraph * ) { return 1; }
53 int GetDimension(const TGraph2D * ) { return 2; }
54 int GetDimension(const THnBase * s1) { return s1->GetNdimensions(); }
55
56 int CheckFitFunction(const TF1 * f1, int hdim);
57
58
60
62
64
65
71
72
73 template <class FitObject>
75
76 template <class FitObject>
77 void StoreAndDrawFitFunction(FitObject * h1, TF1 * f1, const ROOT::Fit::DataRange & range, bool, bool, const char *goption);
78
79 template <class FitObject>
80 double ComputeChi2(const FitObject & h1, TF1 &f1, bool useRange, ROOT::Fit::EChisquareType type, bool useIntegral = false);
81
82
83
84}
85
86int HFit::CheckFitFunction(const TF1 * f1, int dim) {
87 // Check validity of fitted function
88 if (!f1) {
89 Error("Fit", "function may not be null pointer");
90 return -1;
91 }
92 if (f1->IsZombie()) {
93 Error("Fit", "function is zombie");
94 return -2;
95 }
96
97 int npar = f1->GetNpar();
98 if (npar <= 0) {
99 Error("Fit", "function %s has illegal number of parameters = %d", f1->GetName(), npar);
100 return -3;
101 }
102
103 // Check that function has same dimension as histogram
104 if (f1->GetNdim() > dim) {
105 Error("Fit","function %s dimension, %d, is greater than fit object dimension, %d",
106 f1->GetName(), f1->GetNdim(), dim);
107 return -4;
108 }
109 if (f1->GetNdim() < dim-1) {
110 Error("Fit","function %s dimension, %d, is smaller than fit object dimension -1, %d",
111 f1->GetName(), f1->GetNdim(), dim);
112 return -5;
113 }
114
115 return 0;
116
117}
118
119
121 // get the range form the function and fill and return the DataRange object
124 // support only one range - so add only if was not set before
125 if (range.Size(0) == 0) range.AddRange(0,fxmin,fxmax);
126 if (range.Size(1) == 0) range.AddRange(1,fymin,fymax);
127 if (range.Size(2) == 0) range.AddRange(2,fzmin,fzmax);
128 return;
129}
130
131
132template<class FitObject>
134{
135 // perform fit of histograms, or graphs using new fitting classes
136 // use same routines for fitting both graphs and histograms
137
138#ifdef DEBUG
139 printf("fit function %s\n",f1->GetName() );
140#endif
141
142 // replacement function using new fitter
145 if (iret != 0) return iret;
146
147
148
149 // integral option is not supported in this case
150 if (f1->GetNdim() < hdim ) {
151 if (fitOption.Integral) Info("Fit","Ignore Integral option. Model function dimension is less than the data object dimension");
152 if (fitOption.Like) Info("Fit","Ignore Likelihood option. Model function dimension is less than the data object dimension");
153 fitOption.Integral = 0;
154 fitOption.Like = 0;
155 }
156
159 Int_t npar = f1->GetNpar();
160 if (special==299+npar) linear = kTRUE; // for polynomial functions
161 // do not use linear fitter in these case
162 if (fitOption.Bound || fitOption.Like || fitOption.Errors || fitOption.Gradient || fitOption.More || fitOption.User|| fitOption.Integral || fitOption.Minuit)
163 linear = kFALSE;
164
165 // create an empty TFitResult
166 std::shared_ptr<TFitResult> tfr(new TFitResult() );
167 // create the fitter from an empty fit result
168 std::shared_ptr<ROOT::Fit::Fitter> fitter(new ROOT::Fit::Fitter(std::static_pointer_cast<ROOT::Fit::FitResult>(tfr) ) );
169 ROOT::Fit::FitConfig & fitConfig = fitter->Config();
170
171 // create options
173 opt.fIntegral = fitOption.Integral;
174 opt.fUseRange = fitOption.Range;
175 opt.fExpErrors = fitOption.PChi2; // pearson chi2 with expected errors
176 if (fitOption.Like || fitOption.PChi2) opt.fUseEmpty = true; // use empty bins in log-likelihood fits
177 if (special==300) opt.fCoordErrors = false; // no need to use coordinate errors in a pol0 fit
178 if (fitOption.NoErrX) opt.fCoordErrors = false; // do not use coordinate errors when requested
179 if (fitOption.W1 ) opt.fErrors1 = true;
180 if (fitOption.W1 > 1) opt.fUseEmpty = true; // use empty bins with weight=1
181 if (fitOption.PChi2 == 1) {
182 opt.fErrors1 = true; // we are not using errors in chi2, it is like setting = 1
183 } else if (fitOption.PChi2 == 2) {
184 opt.fErrors1 = false; // we need the errors in weighted likelihood fit
185 }
186
187 if (fitOption.BinVolume) {
188 opt.fBinVolume = true; // scale by bin volume
189 if (fitOption.BinVolume == 2) opt.fNormBinVolume = true; // scale by normalized bin volume
190 }
191
192 if (opt.fUseRange) {
193#ifdef DEBUG
194 printf("use range \n" );
195#endif
197 }
198#ifdef DEBUG
199 printf("range size %d\n", range.Size(0) );
200 if (range.Size(0)) {
201 double x1; double x2; range.GetRange(0,x1,x2);
202 printf(" range in x = [%f,%f] \n",x1,x2);
203 }
204#endif
205
206 // fill data
207 std::shared_ptr<ROOT::Fit::BinData> fitdata(new ROOT::Fit::BinData(opt,range) );
209 if (fitdata->Size() == 0 ) {
210 Warning("Fit","Fit data is empty ");
211 return -1;
212 }
213
214#ifdef DEBUG
215 printf("HFit:: data size is %d \n",fitdata->Size());
216 for (unsigned int i = 0; i < fitdata->Size(); ++i) {
217 if (fitdata->NDim() == 1) printf(" x[%d] = %f - value = %f \n", i,*(fitdata->Coords(i)),fitdata->Value(i) );
218 }
219#endif
220
221 // switch off linear fitting in case data has coordinate errors and the option is set
222 if (fitdata->GetErrorType() == ROOT::Fit::BinData::kCoordError && fitdata->Opt().fCoordErrors ) linear = false;
223 // linear fit cannot be done also in case of asymmetric errors
224 if (fitdata->GetErrorType() == ROOT::Fit::BinData::kAsymError && fitdata->Opt().fAsymErrors ) linear = false;
225
226 // this functions use the TVirtualFitter
227 if (special != 0 && !fitOption.Bound && !linear) {
228 if (special == 100) ROOT::Fit::InitGaus (*fitdata,f1); // gaussian
229 else if (special == 110 || special == 112) ROOT::Fit::Init2DGaus(*fitdata,f1); // 2D gaussians ( xygaus or bigaus)
230 else if (special == 400) ROOT::Fit::InitGaus (*fitdata,f1); // landau (use the same)
231 else if (special == 410) ROOT::Fit::Init2DGaus(*fitdata,f1); // 2D landau (use the same)
232
233 else if (special == 200) ROOT::Fit::InitExpo (*fitdata, f1); // exponential
234
235 // A polN reaches this point only because coordinate errors turned the
236 // linear fitter off above, so it needs a starting point like the others.
237 else if (special == 299 + npar)
239 }
240
241
242 // set the fit function
243 // if option grad is specified use gradient
244 if ( (linear || fitOption.Gradient) )
245 fitter->SetFunction(ROOT::Math::WrappedMultiTF1(*f1));
246#ifdef R__HAS_STD_EXPERIMENTAL_SIMD
247 else if(f1->IsVectorized())
249#endif
250 else
251 fitter->SetFunction(static_cast<const ROOT::Math::IParamMultiFunction &>(ROOT::Math::WrappedMultiTF1(*f1) ) );
252
253 // error normalization in case of zero error in the data
254 if (fitdata->GetErrorType() == ROOT::Fit::BinData::kNoError) fitConfig.SetNormErrors(true);
255 // error normalization also in case of W or WW options (weights = 1)
256 if (fitdata->Opt().fErrors1) fitConfig.SetNormErrors(true);
257 // normalize errors also in case you are fitting a Ndim histo with a N-1 function
258 if (int(fitdata->NDim()) == hdim -1 ) fitConfig.SetNormErrors(true);
259
260
261 // here need to get some static extra information (like max iterations, error def, etc...)
262
263
264 // parameter settings and transfer the parameters values, names and limits from the functions
265 // is done automatically in the Fitter.cxx
266 for (int i = 0; i < npar; ++i) {
268
269 // check limits
270 double plow,pup;
272 if (plow*pup != 0 && plow >= pup) { // this is a limitation - cannot fix a parameter to zero value
273 parSettings.Fix();
274 }
275 else if (plow < pup ) {
277 parSettings.SetLowerLimit(plow);
278 else if (!TMath::Finite(plow) && TMath::Finite(pup) )
279 parSettings.SetUpperLimit(pup);
280 else
281 parSettings.SetLimits(plow,pup);
282 }
283
284 // set the parameter step size (by default are set to 0.3 of value)
285 // if function provides meaningful error values
286 double err = f1->GetParError(i);
287 if ( err > 0)
288 parSettings.SetStepSize(err);
289 else if (plow < pup && TMath::Finite(plow) && TMath::Finite(pup) ) { // in case of limits improve step sizes
290 double step = 0.1 * (pup - plow);
291 // check if value is not too close to limit otherwise trim value
292 if ( parSettings.Value() < pup && pup - parSettings.Value() < 2 * step )
293 step = (pup - parSettings.Value() ) / 2;
294 else if ( parSettings.Value() > plow && parSettings.Value() - plow < 2 * step )
295 step = (parSettings.Value() - plow ) / 2;
296
297 parSettings.SetStepSize(step);
298 }
299
300
301 }
302
303 // needed for setting precision ?
304 // - Compute sum of squares of errors in the bin range
305 // should maybe use stat[1] ??
306 // Double_t ey, sumw2=0;
307// for (i=hxfirst;i<=hxlast;i++) {
308// ey = GetBinError(i);
309// sumw2 += ey*ey;
310// }
311
312
313 // set all default minimizer options (tolerance, max iterations, etc..)
315
316 // specific print level options
317 if (fitOption.Verbose) fitConfig.MinimizerOptions().SetPrintLevel(fitOption.Verbose + 1);
318 if (fitOption.Quiet) fitConfig.MinimizerOptions().SetPrintLevel(0);
319
320 // specific minimizer options depending on minimizer
321 if (linear) {
322 if (fitOption.Robust ) {
323 // robust fitting
324 std::string type = "Robust";
325 // if an h is specified print out the value adding to the type
326 if (fitOption.hRobust > 0 && fitOption.hRobust < 1.)
327 type += " (h=" + ROOT::Math::Util::ToString(fitOption.hRobust) + ")";
328 fitConfig.SetMinimizer("Linear",type.c_str());
329 fitConfig.MinimizerOptions().SetTolerance(fitOption.hRobust); // use tolerance for passing robust parameter
330 }
331 else
332 fitConfig.SetMinimizer("Linear","");
333 }
334 else {
335 if (fitOption.More) fitConfig.SetMinimizer("Minuit","MigradImproved");
336 }
337
338
339 // check if Error option (run Hesse and Minos) then
340 if (fitOption.Errors) {
341 // run Hesse and Minos
342 fitConfig.SetParabErrors(true);
343 fitConfig.SetMinosErrors(true);
344 }
345
346
347 // do fitting
348
349#ifdef DEBUG
350 if (fitOption.Like) printf("do likelihood fit...\n");
351 if (linear) printf("do linear fit...\n");
352 printf("do now fit...\n");
353#endif
354
355 bool fitok = false;
356
357
358 // check if can use option user
360 // option user is enabled only when running in serial mode
361 if (fitOption.User && TVirtualFitter::GetFitter() ) {
362 userFcn = (TVirtualFitter::GetFitter())->GetFCN();
363 (TVirtualFitter::GetFitter())->SetUserFunc(f1);
364 }
365
366
367 if (fitOption.User && userFcn) // user provided fit objective function
368 fitok = fitter->FitFCN( userFcn );
369 else if (fitOption.Like) {// likelihood fit
370 // perform a weighted likelihood fit by applying weight correction to errors
371 bool weight = ((fitOption.Like & 2) == 2);
372 fitConfig.SetWeightCorrection(weight);
373 bool extended = ((fitOption.Like & 4 ) != 4 );
374 //if (!extended) Info("HFitImpl","Do a not -extended binned fit");
375
376 // pass fitdata as a shared pointer so ownership is shared with Fitter and FitResult class
377 fitok = fitter->LikelihoodFit(fitdata, extended, fitOption.ExecPolicy);
378 }
379 else{ // standard least square fit
380 fitok = fitter->Fit(fitdata, fitOption.ExecPolicy);
381 }
382 if ( !fitok && !fitOption.Quiet )
383 Warning("Fit","Abnormal termination of minimization.");
384 iret |= !fitok;
385
386
387 const ROOT::Fit::FitResult & fitResult = fitter->Result();
388 // one could set directly the fit result in TF1
389 iret = fitResult.Status();
390 if (!fitResult.IsEmpty() ) {
391 // set in f1 the result of the fit
392 f1->SetChisquare(fitResult.Chi2() );
393 f1->SetNDF(fitResult.Ndf() );
394 f1->SetNumberFitPoints(fitdata->Size() );
395
396 assert((Int_t)fitResult.Parameters().size() >= f1->GetNpar() );
397 f1->SetParameters( const_cast<double*>(&(fitResult.Parameters().front())));
398 if ( int( fitResult.Errors().size()) >= f1->GetNpar() )
399 f1->SetParErrors( &(fitResult.Errors().front()) );
400
401
402 }
403
404// - Store fitted function in histogram functions list and draw
405 if (!fitOption.Nostore) {
408 }
409
410 // print the result
411 // if using Fitter class must be done here
412 // use old style Minuit for TMinuit and if no corrections have been applied
413 if (!fitOption.Quiet) {
415 if (fitter->GetMinimizer() && fitConfig.MinimizerType() == "Minuit" &&
416 !fitConfig.NormalizeErrors() && fitOption.Like <= 1) {
417 fitter->GetMinimizer()->PrintResults(); // use old style Minuit
418 }
419 else {
420 // print using FitResult class
421 if (fitOption.Verbose) fitResult.PrintCovMatrix(std::cout);
422 fitResult.Print(std::cout);
423 }
424 }
425
426 // store result in the backward compatible TVirtualFitter
427 {
431 bcfitter->SetFitOption(fitOption);
432 bcfitter->SetObjectFit(h1);
433 bcfitter->SetUserFunc(f1);
435 if (userFcn) {
436 bcfitter->SetFCN(userFcn);
437 // for interpreted FCN functions
438 if (lastFitter->GetMethodCall() ) bcfitter->SetMethodCall(lastFitter->GetMethodCall() );
439 }
440
441 // delete last fitter if it has been created here before
442 if (lastFitter) {
445 delete lastBCFitter;
446 }
447 //N.B= this might create a memory leak if user does not delete the fitter they create
449 }
450
451 if (fitOption.StoreResult)
452 {
453 TString name = "TFitResult-";
454 name = name + h1->GetName() + "-" + f1->GetName();
455 TString title = "TFitResult-";
456 title += h1->GetTitle();
457 tfr->SetName(name);
458 tfr->SetTitle(title);
459 return TFitResultPtr(tfr);
460 }
461 else
462 return TFitResultPtr(iret);
463}
464
465
467 // get range from histogram and update the DataRange class
468 // if a ranges already exist in that dimension use that one
469
470 Int_t ndim = GetDimension(h1);
471
472 double xmin = 0, xmax = 0, ymin = 0, ymax = 0, zmin = 0, zmax = 0;
473 if (range.Size(0) == 0) {
474 TAxis & xaxis = *(h1->GetXaxis());
475 Int_t hxfirst = xaxis.GetFirst();
476 Int_t hxlast = xaxis.GetLast();
477 Double_t binwidx = xaxis.GetBinWidth(hxlast);
478 xmin = xaxis.GetBinLowEdge(hxfirst);
479 xmax = xaxis.GetBinLowEdge(hxlast) +binwidx;
480 range.AddRange(xmin,xmax);
481 }
482
483 if (ndim > 1) {
484 if (range.Size(1) == 0) {
485 TAxis & yaxis = *(h1->GetYaxis());
486 Int_t hyfirst = yaxis.GetFirst();
487 Int_t hylast = yaxis.GetLast();
488 Double_t binwidy = yaxis.GetBinWidth(hylast);
489 ymin = yaxis.GetBinLowEdge(hyfirst);
490 ymax = yaxis.GetBinLowEdge(hylast) +binwidy;
491 range.AddRange(1,ymin,ymax);
492 }
493 }
494 if (ndim > 2) {
495 if (range.Size(2) == 0) {
496 TAxis & zaxis = *(h1->GetZaxis());
497 Int_t hzfirst = zaxis.GetFirst();
498 Int_t hzlast = zaxis.GetLast();
499 Double_t binwidz = zaxis.GetBinWidth(hzlast);
500 zmin = zaxis.GetBinLowEdge(hzfirst);
501 zmax = zaxis.GetBinLowEdge(hzlast) +binwidz;
502 range.AddRange(2,zmin,zmax);
503 }
504 }
505#ifdef DEBUG
506 std::cout << "xmin,xmax" << xmin << " " << xmax << std::endl;
507#endif
508
509}
510
512 // get range for graph (used sub-set histogram)
513 // N.B. : this is different than in previous implementation of TGraph::Fit where range used was from xmin to xmax.
514 TH1 * h1 = gr->GetHistogram();
515 // an histogram is normally always returned for a TGraph
517}
519 // get range for multi-graph (used sub-set histogram)
520 // N.B. : this is different than in previous implementation of TMultiGraph::Fit where range used was from data xmin to xmax.
521 TH1 * h1 = mg->GetHistogram();
522 if (h1) {
524 }
525 else if (range.Size(0) == 0) {
526 // compute range from all the TGraph's belonging to the MultiGraph
527 double xmin = std::numeric_limits<double>::infinity();
528 double xmax = -std::numeric_limits<double>::infinity();
529 TIter next(mg->GetListOfGraphs() );
530 TGraph * g = nullptr;
531 while ( (g = (TGraph*) next() ) ) {
532 double x1 = 0, x2 = 0, y1 = 0, y2 = 0;
533 g->ComputeRange(x1,y1,x2,y2);
534 if (x1 < xmin) xmin = x1;
535 if (x2 > xmax) xmax = x2;
536 }
537 range.AddRange(xmin,xmax);
538 }
539}
541 // get range for graph2D (used sub-set histogram)
542 // N.B. : this is different than in previous implementation of TGraph2D::Fit. There range used was always(0,0)
543 // cannot use TGraph2D::GetHistogram which makes an interpolation
544 //TH1 * h1 = gr->GetHistogram();
545 //if (h1) HFit::GetDrawingRange(h1, range);
546 // not very efficient (t.b.i.)
547 if (range.Size(0) == 0) {
548 double xmin = gr->GetXmin();
549 double xmax = gr->GetXmax();
550 range.AddRange(0,xmin,xmax);
551 }
552 if (range.Size(1) == 0) {
553 double ymin = gr->GetYmin();
554 double ymax = gr->GetYmax();
555 range.AddRange(1,ymin,ymax);
556 }
557}
558
560 // get range from histogram and update the DataRange class
561 // if a ranges already exist in that dimension use that one
562
563 Int_t ndim = GetDimension(s1);
564
565 for ( int i = 0; i < ndim; ++i ) {
566 if ( range.Size(i) == 0 ) {
567 TAxis *axis = s1->GetAxis(i);
568 range.AddRange(i, axis->GetXmin(), axis->GetXmax());
569 }
570 }
571}
572
573template<class FitObject>
575// - Store fitted function in histogram functions list and draw
576// should have separate functions for 1,2,3d ? t.b.d in case
577
578#ifdef DEBUG
579 std::cout <<"draw and store fit function " << f1->GetName() << std::endl;
580#endif
581
582
583 Int_t ndim = GetDimension(h1);
584 double xmin = 0, xmax = 0, ymin = 0, ymax = 0, zmin = 0, zmax = 0;
585 if (range.Size(0) ) range.GetRange(0,xmin,xmax);
586 if (range.Size(1) ) range.GetRange(1,ymin,ymax);
587 if (range.Size(2) ) range.GetRange(2,zmin,zmax);
588
589
590#ifdef DEBUG
591 std::cout <<"draw and store fit function " << f1->GetName()
592 << " Range in x = [ " << xmin << " , " << xmax << " ]" << std::endl;
593#endif
594
595 TList * funcList = h1->GetListOfFunctions();
596 if (funcList == nullptr){
597 Error("StoreAndDrawFitFunction","Function list has not been created - cannot store the fitted function");
598 return;
599 }
600
601 // delete the function in the list only if
602 // the function we are fitting is not in that list
603 // If this is the case we re-use that function object and
604 // we do not create a new one (if delOldFunction is true)
605 bool reuseOldFunction = false;
606 if (delOldFunction) {
607 TIter next(funcList, kIterBackward);
608 TObject *obj;
609 while ((obj = next())) {
610 if (obj->InheritsFrom(TF1::Class())) {
611 if (obj != f1) {
612 funcList->Remove(obj);
613 delete obj;
614 }
615 else {
616 reuseOldFunction = true;
617 }
618 }
619 }
620 }
621
622 TF1 *fnew1 = nullptr;
623 TF2 *fnew2 = nullptr;
624 TF3 *fnew3 = nullptr;
625
626 // copy TF1 using TClass to avoid slicing in case of derived classes
627 if (ndim < 2) {
628 if (!reuseOldFunction) {
629 fnew1 = (TF1*)f1->IsA()->New();
631 f1->Copy(*fnew1);
632 funcList->Add(fnew1);
633 }
634 else {
635 fnew1 = f1;
636 }
637 fnew1->SetParent( h1 );
638 fnew1->SetRange(xmin,xmax);
639 fnew1->Save(xmin,xmax,0,0,0,0);
640 if (!drawFunction) fnew1->SetBit(TF1::kNotDraw);
641 fnew1->AddToGlobalList(false);
642 } else if (ndim < 3) {
643 if (!reuseOldFunction) {
644 fnew2 = (TF2*)f1->IsA()->New();
646 f1->Copy(*fnew2);
647 funcList->Add(fnew2);
648 }
649 else {
650 fnew2 = dynamic_cast<TF2*>(f1);
652 }
653 fnew2->SetRange(xmin,ymin,xmax,ymax);
654 fnew2->SetParent( h1 );
655 fnew2->Save(xmin,xmax,ymin,ymax,0,0);
656 if (!drawFunction) fnew2->SetBit(TF1::kNotDraw);
657 fnew2->AddToGlobalList(false);
658 } else {
659 if (!reuseOldFunction) {
660 fnew3 = (TF3*)f1->IsA()->New();
662 f1->Copy(*fnew3);
663 funcList->Add(fnew3);
664 }
665 else {
666 fnew3 = dynamic_cast<TF3*>(f1);
668 }
669 fnew3->SetRange(xmin,ymin,zmin,xmax,ymax,zmax);
670 fnew3->SetParent( h1 );
671 fnew3->Save(xmin,xmax,ymin,ymax,zmin,zmax);
672 if (!drawFunction) fnew3->SetBit(TF1::kNotDraw);
673 fnew3->AddToGlobalList(false);
674 }
675 if (h1->TestBit(kCanDelete)) return;
676 // draw only in case of histograms
677 if (drawFunction && ndim < 3 && h1->InheritsFrom(TH1::Class() ) ) {
678 // no need to re-draw the histogram if the histogram is already in the pad
679 // in that case the function will be just drawn (if option N is not set)
680 if (!gPad || (gPad && gPad->GetListOfPrimitives()->FindObject(h1) == nullptr ) )
681 h1->Draw(goption);
682 }
683 if (gPad) gPad->Modified(); // this is not in TH1 code (needed ??)
684
685 return;
686}
687
688
690 // - Decode list of options into fitOption (used by both TGraph and TH1)
691 // works for both histograms and graph depending on the enum FitObjectType defined in HFit
694 }
695
696 if (option == nullptr) return;
697 if (!option[0]) return;
698
699 TString opt = option;
700 opt.ToUpper();
701
702 // Parse the execution policy options first and strip them from the option
703 // string, so that the remaining letters (e.g. the "T", "E", "R" in
704 // "MULTITHREAD") are not mistaken for single-letter options below.
705 if (opt.Contains("SERIAL")) {
707 opt.ReplaceAll("SERIAL", "");
708 }
709 if (opt.Contains("MULTITHREAD")) {
711 opt.ReplaceAll("MULTITHREAD", "");
712 }
713
714 // parse firt the specific options
715 if (type == EFitObjectType::kHistogram) {
716
717 if (opt.Contains("WIDTH")) {
718 fitOption.BinVolume = 1; // scale content by the bin width
719 if (opt.Contains("NORMWIDTH")) {
720 // for variable bins: scale content by the bin width normalized by a reference value (typically the minimum bin)
721 // this option is for variable bin widths
722 fitOption.BinVolume = 2;
723 opt.ReplaceAll("NORMWIDTH","");
724 }
725 else
726 opt.ReplaceAll("WIDTH","");
727 }
728
729 // if (opt.Contains("MULTIPROC")) {
730 // fitOption.ExecPolicy = ROOT::Fit::kMultiprocess;
731 // opt.ReplaceAll("MULTIPROC","");
732 // }
733
734 if (opt.Contains("I")) fitOption.Integral= 1; // integral of function in the bin (no sense for graph)
735 if (opt.Contains("W")) fitOption.W1 = 1; // all non-empty bins or points have weight =1 (for chi2 fit)
736 if (opt.Contains("WW")) fitOption.W1 = 2; //all bins have weight=1, even empty bins
737 if (opt.Contains("L")) fitOption.Like = 1;
738 if (opt.Contains("X")) fitOption.Chi2 = 1;
739 if (opt.Contains("P")) {
740 fitOption.PChi2 = 1;
741 if (fitOption.W1) { // option contains also w is a weighted Pearson chi2 fit
742 fitOption.PChi2 = 2;
743 fitOption.W1 = 0; // does not make sense to have errors=1 in Pearson chi2 fits
744 }
745 }
746
747 // specific likelihood fit options
748 if (fitOption.Like == 1) {
749 //if (opt.Contains("LL")) fitOption.Like = 2;
750 if (opt.Contains("W")){ fitOption.Like = 2; fitOption.W1=0;}// (weighted likelihood)
751 if (opt.Contains("MULTI")) {
752 if (fitOption.Like == 2) fitOption.Like = 6; // weighted multinomial
753 else fitOption.Like = 4; // multinomial likelihood fit instead of Poisson
754 opt.ReplaceAll("MULTI","");
755 }
756 // give precedence for likelihood options
757 if (fitOption.Chi2 || fitOption.PChi2 )
758 Warning("Fit","Cannot use P or X option in combination of L. Ignore the chi2 option and perform a likelihood fit");
759 }
760 }
761 // specific Graph options (need to be parsed before)
762 else if (type == EFitObjectType::kGraph) {
763 opt.ReplaceAll("ROB", "H");
764 opt.ReplaceAll("EX0", "T");
765
766 //for robust fitting, see if # of good points is defined
767 // decode parameters for robust fitting
768 Double_t h=0;
769 constexpr auto length = std::char_traits<char>::length;
770 if (opt.Contains("H=0.")) {
771 int start = opt.Index("H=0.");
772 int numpos = start + length("H=0.");
773 int numlen = 0;
774 int len = opt.Length();
775 while( (numpos+numlen<len) && isdigit(opt[numpos+numlen]) ) numlen++;
776 TString num = opt(numpos,numlen);
777 opt.Remove(start+length("H"),length("=0.")+numlen);
778 h = atof(num.Data());
779 h*=TMath::Power(10, -numlen);
780 }
781
782 if (opt.Contains("H")) { fitOption.Robust = 1; fitOption.hRobust = h; }
783 if (opt.Contains("T")) fitOption.NoErrX = 1; // no error in X
784 if (opt.Contains("W")) fitOption.W1 = 1; // ignorer all point errors when fitting
785 }
786
787 if (opt.Contains("U")) {
788 // user option can work only when not running in multiple threads
790 fitOption.User = 1;
791 } else {
792 Warning("FitOptionsMake","Cannot use User (U) fit option when running in multi-thread mode. The option is ignored");
793 fitOption.User = 0;
794 }
795 }
796
797 // in case of Q and V options V has precedence
798 if (opt.Contains("VVV") || opt.Contains("DEBUG")) { fitOption.Verbose = 3; }
799 else if (opt.Contains("VV")) {fitOption.Verbose = 2; }
800 else if (opt.Contains("V")) {fitOption.Verbose = 1; }
801 else if (opt.Contains("Q")) {fitOption.Quiet = 1; }
802
803
804 if (opt.Contains("E")) fitOption.Errors = 1;
805 if (opt.Contains("R")) fitOption.Range = 1;
806 if (opt.Contains("G")) fitOption.Gradient= 1;
807 if (opt.Contains("M")) fitOption.More = 1;
808 if (opt.Contains("N")) fitOption.Nostore = 1;
809 if (opt.Contains("0")) fitOption.Nograph = 1;
810 if (opt.Contains("+")) fitOption.Plus = 1;
811 if (opt.Contains("B")) fitOption.Bound = 1;
812 if (opt.Contains("C")) fitOption.Nochisq = 1;
813 if (opt.Contains("F")) fitOption.Minuit = 1;
814 if (opt.Contains("S")) fitOption.StoreResult = 1;
815
816}
817
819 if (foption.Like) {
820 Info("CheckGraphFitOptions","L (Log Likelihood fit) is an invalid option when fitting a graph. It is ignored");
821 foption.Like = 0;
822 }
823 if (foption.Integral) {
824 Info("CheckGraphFitOptions","I (use function integral) is an invalid option when fitting a graph. It is ignored");
825 foption.Integral = 0;
826 }
827 return;
828}
829
830// implementation of unbin fit function (defined in HFitInterface)
831
833 // do unbin fit, ownership of fitdata is passed later to the TBackFitter class
834
835 // create a shared pointer to the fit data to managed it
836 std::shared_ptr<ROOT::Fit::UnBinData> fitdata(data);
837
838#ifdef DEBUG
839 printf("tree data size is %d \n",fitdata->Size());
840 for (unsigned int i = 0; i < fitdata->Size(); ++i) {
841 if (fitdata->NDim() == 1) printf(" x[%d] = %f \n", i,*(fitdata->Coords(i) ) );
842 }
843#endif
844 if (fitdata->Size() == 0 ) {
845 Warning("Fit","Fit data is empty ");
846 return -1;
847 }
848
849 // create an empty TFitResult
850 std::shared_ptr<TFitResult> tfr(new TFitResult() );
851 // create the fitter
852 std::shared_ptr<ROOT::Fit::Fitter> fitter(new ROOT::Fit::Fitter(tfr) );
853 ROOT::Fit::FitConfig & fitConfig = fitter->Config();
854
855 // dimension is given by data because TF1 pointer can have wrong one
856 unsigned int dim = fitdata->NDim();
857
858 // set the fit function
859 // if option grad is specified use gradient
860 // need to create a wrapper for an automatic normalized TF1 ???
861 if ( fitOption.Gradient ) {
862 assert ( (int) dim == fitfunc->GetNdim() );
863 fitter->SetFunction(ROOT::Math::WrappedMultiTF1(*fitfunc) );
864 }
865 else
866 fitter->SetFunction(static_cast<const ROOT::Math::IParamMultiFunction &>(ROOT::Math::WrappedMultiTF1(*fitfunc, dim) ) );
867
868 // parameter setting is done automaticaly in the Fitter class
869 // need only to set limits
870 int npar = fitfunc->GetNpar();
871 for (int i = 0; i < npar; ++i) {
873 double plow,pup;
874 fitfunc->GetParLimits(i,plow,pup);
875 // this is a limitation of TF1 interface - cannot fix a parameter to zero value
876 if (plow*pup != 0 && plow >= pup) {
877 parSettings.Fix();
878 }
879 else if (plow < pup ) {
881 parSettings.SetLowerLimit(plow);
882 else if (!TMath::Finite(plow) && TMath::Finite(pup) )
883 parSettings.SetUpperLimit(pup);
884 else
885 parSettings.SetLimits(plow,pup);
886 }
887
888 // set the parameter step size (by default are set to 0.3 of value)
889 // if function provides meaningful error values
890 double err = fitfunc->GetParError(i);
891 if ( err > 0)
892 parSettings.SetStepSize(err);
893 else if (plow < pup && TMath::Finite(plow) && TMath::Finite(pup) ) { // in case of limits improve step sizes
894 double step = 0.1 * (pup - plow);
895 // check if value is not too close to limit otherwise trim value
896 if ( parSettings.Value() < pup && pup - parSettings.Value() < 2 * step )
897 step = (pup - parSettings.Value() ) / 2;
898 else if ( parSettings.Value() > plow && parSettings.Value() - plow < 2 * step )
899 step = (parSettings.Value() - plow ) / 2;
900
901 parSettings.SetStepSize(step);
902 }
903
904 }
905
907
908 if (fitOption.Verbose) fitConfig.MinimizerOptions().SetPrintLevel(fitOption.Verbose+1);
909 if (fitOption.Quiet) fitConfig.MinimizerOptions().SetPrintLevel(0);
910
911 // more
912 if (fitOption.More) fitConfig.SetMinimizer("Minuit","MigradImproved");
913
914 // chech if Minos or more options
915 if (fitOption.Errors) {
916 // run Hesse and Minos
917 fitConfig.SetParabErrors(true);
918 fitConfig.SetMinosErrors(true);
919 }
920 // use weight correction
921 if ( (fitOption.Like & 2) == 2)
922 fitConfig.SetWeightCorrection(true);
923
924 bool extended = (fitOption.Like & 1) == 1;
925
926 bool fitok = false;
927 fitok = fitter->LikelihoodFit(fitdata, extended, fitOption.ExecPolicy);
928 if ( !fitok && !fitOption.Quiet )
929 Warning("UnBinFit","Abnormal termination of minimization.");
930
931 const ROOT::Fit::FitResult & fitResult = fitter->Result();
932 // one could set directly the fit result in TF1
933 int iret = fitResult.Status();
934 if (!fitResult.IsEmpty() ) {
935 // set in fitfunc the result of the fit
936 fitfunc->SetNDF(fitResult.Ndf() );
937 fitfunc->SetNumberFitPoints(fitdata->Size() );
938
939 assert( (Int_t)fitResult.Parameters().size() >= fitfunc->GetNpar() );
940 fitfunc->SetParameters( const_cast<double*>(&(fitResult.Parameters().front())));
941 if ( int( fitResult.Errors().size()) >= fitfunc->GetNpar() )
942 fitfunc->SetParErrors( &(fitResult.Errors().front()) );
943
944 }
945
946 // store fitting result in the backward compatible TVirtualFitter object
947 // lock in case running in a multi-thread enabled mode
948 {
952 // cannot use anymore now fitdata (given away ownership)
953 fitdata = nullptr;
954 bcfitter->SetFitOption(fitOption);
955 bcfitter->SetUserFunc(fitfunc);
956 // delete previous fitter and replace with the new one
957 if (lastFitter) delete lastFitter;
959
960 // print results
961 if (fitOption.Verbose) fitResult.PrintCovMatrix(std::cout);
962 else if (!fitOption.Quiet) fitResult.Print(std::cout);
963 }
964
965
966 if (fitOption.StoreResult)
967 {
968 TString name = "TFitResult-";
969 name = name + "UnBinData-" + fitfunc->GetName();
970 TString title = "TFitResult-";
971 title += name;
972 tfr->SetName(name);
973 tfr->SetTitle(title);
974 return TFitResultPtr(tfr);
975 }
976 else
977 return TFitResultPtr(iret);
978}
979
980
981// implementations of ROOT::Fit::FitObject functions (defined in HFitInterface) in terms of the template HFit::Fit
982
984moption, const char *goption, ROOT::Fit::DataRange & range) {
985 // check fit options
986 // check if have weights in case of weighted likelihood
987 if ( ((foption.Like & 2) == 2) && h1->GetSumw2N() == 0) {
988 Warning("HFit::FitObject","A weighted likelihood fit is requested but histogram is not weighted - do a standard Likelihood fit");
989 foption.Like = 1;
990 }
991 // histogram fitting
993}
994
996 // exclude options not valid for graphs
998 // TGraph fitting
1000}
1001
1003 // exclude options not valid for graphs
1005 // TMultiGraph fitting
1007}
1008
1010 // exclude options not valid for graphs
1012 // TGraph2D fitting
1014}
1015
1020
1021
1022
1023// Int_t TGraph2D::DoFit(TF2 *f2 ,Option_t *option ,Option_t *goption) {
1024// // internal graph2D fitting methods
1025// Foption_t fitOption;
1026// ROOT::Fit::FitOptionsMake(option,fitOption);
1027
1028// // create range and minimizer options with default values
1029// ROOT::Fit::DataRange range(2);
1030// ROOT::Math::MinimizerOptions minOption;
1031// return ROOT::Fit::FitObject(this, f2 , fitOption , minOption, goption, range);
1032// }
1033
1034
1035// function to compute the simple chi2 for graphs and histograms
1036
1037
1041
1045
1046template<class FitObject>
1047double HFit::ComputeChi2(const FitObject & obj, TF1 & f1, bool useRange, ROOT::Fit::EChisquareType type, bool useIntegral ) {
1048
1049 // implement using the fitting classes
1051 opt.fUseEmpty = (type != ROOT::Fit::EChisquareType::kNeyman); // use empty bin when not using Neyman chisquare (observed error)
1053 opt.fErrors1 = (type == ROOT::Fit::EChisquareType::kPearson); // not using observed errors in Pearson chi2
1054 opt.fIntegral = useIntegral; // use bin integral instead of value at bin center
1055
1057 // get range of function
1059 // fill the data set
1061 ROOT::Fit::FillData(data, &obj, &f1);
1062 if (data.Size() == 0 ) {
1063 Warning("Chisquare","data set is empty - return -1");
1064 return -1;
1065 }
1068 // use the poisson log-lokelihood (Baker-Cousins chi2)
1070 return 2.* nll( f1.GetParameters() ) ;
1071 }
1073 return chi2(f1.GetParameters() );
1074
1075}
#define g(i)
Definition RSha256.hxx:105
#define s1(x)
Definition RSha256.hxx:91
#define h(i)
Definition RSha256.hxx:106
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
const Bool_t kIterBackward
Definition TCollection.h:43
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:241
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:252
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Option_t Option_t TPoint TPoint const char y1
char name[80]
Definition TGX11.cxx:148
float xmin
float ymin
float xmax
float ymax
@ kCanDelete
Definition TObject.h:375
R__EXTERN TVirtualMutex * gROOTMutex
Definition TROOT.h:63
R__EXTERN TVirtualMutex * gGlobalMutex
#define R__LOCKGUARD(mutex)
#define gPad
Class describing the binned data sets : vectors of x coordinates, y values and optionally error on y ...
Definition BinData.h:52
class describing the range in the coordinates it supports multiple range in a coordinate.
Definition DataRange.h:35
Class describing the configuration of the fit, options and parameter settings using the ROOT::Fit::Pa...
Definition FitConfig.h:49
void SetMinimizer(const char *type, const char *algo=nullptr)
set minimizer type and algorithm
Definition FitConfig.h:183
void SetMinosErrors(bool on=true)
set Minos errors computation to be performed after fitting
Definition FitConfig.h:233
void SetNormErrors(bool on=true)
set the option to normalize the error on the result according to chi2/ndf
Definition FitConfig.h:227
bool NormalizeErrors() const
flag to check if resulting errors are be normalized according to chi2/ndf
Definition FitConfig.h:206
void SetMinimizerOptions(const ROOT::Math::MinimizerOptions &minopt)
set all the minimizer options using class ROOT::Math::MinimizerOptions
void SetWeightCorrection(bool on=true)
apply the weight correction for error matrix computation
Definition FitConfig.h:236
void SetParabErrors(bool on=true)
set parabolic errors
Definition FitConfig.h:230
const std::string & MinimizerType() const
return type of minimizer package
Definition FitConfig.h:191
const ParameterSettings & ParSettings(unsigned int i) const
get the parameter settings for the i-th parameter (const method)
Definition FitConfig.h:78
ROOT::Math::MinimizerOptions & MinimizerOptions()
access to the minimizer control parameter (non const method)
Definition FitConfig.h:169
class containing the result of the fit and all the related information (fitted parameter values,...
Definition FitResult.h:44
bool IsEmpty() const
True if a fit result does not exist (even invalid) with parameter values.
Definition FitResult.h:102
const std::vector< double > & Errors() const
parameter errors (return st::vector)
Definition FitResult.h:156
const std::vector< double > & Parameters() const
parameter values (return std::vector)
Definition FitResult.h:161
unsigned int Ndf() const
Number of degree of freedom.
Definition FitResult.h:150
double Chi2() const
Return the Chi2 value after fitting In case of unbinned fits (or not defined one, see the documentati...
Definition FitResult.h:147
void Print(std::ostream &os, bool covmat=false) const
print the result and optionally covariance matrix and correlations
void PrintCovMatrix(std::ostream &os) const
print error matrix and correlations
int Status() const
minimizer status code
Definition FitResult.h:122
Fitter class, entry point for performing all type of fits.
Definition Fitter.h:78
Class, describing value, limits and step size of the parameters Provides functionality also to set/re...
Class describing the un-binned data sets (just x coordinates values) of any dimensions.
Definition UnBinData.h:46
void SetPrintLevel(int level)
set print level
void SetTolerance(double tol)
set the tolerance
Class to Wrap a ROOT Function class (like TF1) in a IParamMultiFunction interface of multi-dimensions...
Class to manage histogram axis.
Definition TAxis.h:32
Double_t GetXmax() const
Definition TAxis.h:142
Double_t GetXmin() const
Definition TAxis.h:141
Backward compatible implementation of TVirtualFitter.
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition TClass.cxx:5048
1-Dim function class
Definition TF1.h:182
virtual Int_t GetNumber() const
Definition TF1.h:463
virtual void GetParLimits(Int_t ipar, Double_t &parmin, Double_t &parmax) const
Return limits for parameter ipar.
Definition TF1.cxx:1990
virtual void SetNDF(Int_t ndf)
Set the number of degrees of freedom ndf should be the number of points used in a fit - the number of...
Definition TF1.cxx:3474
virtual Double_t GetParError(Int_t ipar) const
Return value of parameter number ipar.
Definition TF1.cxx:1980
static TClass * Class()
virtual void SetChisquare(Double_t chi2)
Definition TF1.h:581
virtual Int_t GetNpar() const
Definition TF1.h:446
virtual void SetParErrors(const Double_t *errors)
Set errors for all active parameters when calling this function, the array errors must have at least ...
Definition TF1.cxx:3545
virtual Double_t * GetParameters() const
Definition TF1.h:485
void Copy(TObject &f1) const override
Copy this F1 to a new F1.
Definition TF1.cxx:1006
virtual void SetNumberFitPoints(Int_t npfits)
Definition TF1.h:593
@ kNotDraw
Definition TF1.h:297
virtual void GetRange(Double_t *xmin, Double_t *xmax) const
Return range of a generic N-D function.
Definition TF1.cxx:2329
virtual Bool_t IsLinear() const
Definition TF1.h:571
bool IsVectorized()
Definition TF1.h:404
virtual void SetParameters(const Double_t *params)
Definition TF1.h:618
TClass * IsA() const override
Definition TF1.h:694
virtual Int_t GetNdim() const
Definition TF1.h:450
A 2-Dim function with parameters.
Definition TF2.h:29
TF3 defines a 3D Function with Parameters.
Definition TF3.h:28
Provides an indirection to the TFitResult class and with a semantics identical to a TFitResult pointe...
Extends the ROOT::Fit::Result class with a TNamed inheritance providing easy possibility for I/O.
Definition TFitResult.h:34
Graphics object made of three arrays X, Y and Z with the same number of points each.
Definition TGraph2D.h:41
A TGraph is an object made of two arrays X and Y with npoints each.
Definition TGraph.h:41
virtual TH1F * GetHistogram() const
Returns a pointer to the histogram used to draw the axis Takes into account the two following cases.
Definition TGraph.cxx:1460
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:109
TAxis * GetZaxis()
Definition TH1.h:573
static TClass * Class()
virtual Int_t GetDimension() const
Definition TH1.h:527
TAxis * GetXaxis()
Definition TH1.h:571
TAxis * GetYaxis()
Definition TH1.h:572
void Draw(Option_t *option="") override
Draw this histogram with options.
Definition TH1.cxx:3193
TList * GetListOfFunctions() const
Definition TH1.h:488
virtual Int_t GetSumw2N() const
Definition TH1.h:562
Multidimensional histogram base.
Definition THnBase.h:45
A doubly linked list.
Definition TList.h:38
void Add(TObject *obj) override
Definition TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:952
A TMultiGraph is a collection of TGraph (or derived) objects.
Definition TMultiGraph.h:34
TList * GetListOfGraphs() const
Definition TMultiGraph.h:67
TH1F * GetHistogram()
Returns a pointer to the histogram used to draw the axis.
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
Mother of all ROOT objects.
Definition TObject.h:42
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:204
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition TObject.h:161
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:548
Basic string class.
Definition TString.h:138
Ssiz_t Length() const
Definition TString.h:427
const char * Data() const
Definition TString.h:386
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:715
void ToUpper()
Change string to upper case.
Definition TString.cxx:1202
TString & Remove(Ssiz_t pos)
Definition TString.h:696
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:643
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:662
Abstract Base Class for Fitting.
void(* FCNFunc_t)(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag)
static TVirtualFitter * GetFitter()
static: return the current Fitter
static void SetFitter(TVirtualFitter *fitter, Int_t maxpar=25)
Static function to set an alternative fitter.
TGraphErrors * gr
Definition legend1.C:25
TH1F * h1
Definition legend1.C:5
TF1 * f1
Definition legend1.C:11
void GetDrawingRange(TH1 *h1, ROOT::Fit::DataRange &range)
Definition HFitImpl.cxx:466
void GetFunctionRange(const TF1 &f1, ROOT::Fit::DataRange &range)
Definition HFitImpl.cxx:120
int CheckFitFunction(const TF1 *f1, int hdim)
Definition HFitImpl.cxx:86
TFitResultPtr Fit(FitObject *h1, TF1 *f1, Foption_t &option, const ROOT::Math::MinimizerOptions &moption, const char *goption, ROOT::Fit::DataRange &range)
Definition HFitImpl.cxx:133
void FitOptionsMake(const char *option, Foption_t &fitOption)
void CheckGraphFitOptions(Foption_t &fitOption)
Definition HFitImpl.cxx:818
void StoreAndDrawFitFunction(FitObject *h1, TF1 *f1, const ROOT::Fit::DataRange &range, bool, bool, const char *goption)
Definition HFitImpl.cxx:574
double ComputeChi2(const FitObject &h1, TF1 &f1, bool useRange, ROOT::Fit::EChisquareType type, bool useIntegral=false)
int GetDimension(const TH1 *h1)
Definition HFitImpl.cxx:50
void InitPolynom(const ROOT::Fit::BinData &data, TF1 *f1)
compute initial parameter for a polynomial function given the fit data Set the parameters to an unwei...
TFitResultPtr FitObject(TH1 *h1, TF1 *f1, Foption_t &option, const ROOT::Math::MinimizerOptions &moption, const char *goption, ROOT::Fit::DataRange &range)
fitting function for a TH1 (called from TH1::Fit)
Definition HFitImpl.cxx:983
double Chisquare(const TH1 &h1, TF1 &f1, bool useRange, EChisquareType type, bool useIntegral=false)
compute the chi2 value for an histogram given a function (see TH1::Chisquare for the documentation)
void FitOptionsMake(EFitObjectType type, const char *option, Foption_t &fitOption)
Decode list of options into fitOption.
Definition HFitImpl.cxx:689
void Init2DGaus(const ROOT::Fit::BinData &data, TF1 *f1)
compute initial parameter for 2D gaussian function given the fit data Set the sigma limits for zero t...
TFitResultPtr UnBinFit(ROOT::Fit::UnBinData *data, TF1 *f1, Foption_t &option, const ROOT::Math::MinimizerOptions &moption)
fit an unbin data set (from tree or from histogram buffer) using a TF1 pointer and fit options.
Definition HFitImpl.cxx:832
void FillData(BinData &dv, const TH1 *hist, TF1 *func=nullptr)
fill the data vector from a TH1.
void InitExpo(const ROOT::Fit::BinData &data, TF1 *f1)
compute initial parameter for an exponential function given the fit data Set the constant and slope a...
void InitGaus(const ROOT::Fit::BinData &data, TF1 *f1)
compute initial parameter for gaussian function given the fit data Set the sigma limits for zero top ...
std::string ToString(const T &val)
Utility function for conversion to strings.
Definition Util.h:64
Bool_t IsImplicitMTEnabled()
Returns true if the implicit multi-threading in ROOT is enabled.
Definition TROOT.cxx:669
Int_t Finite(Double_t x)
Check if it is finite with a mask in order to be consistent in presence of fast math.
Definition TMath.h:783
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition TMath.h:734
DataOptions : simple structure holding the options on how the data are filled.
Definition DataOptions.h:28
bool fErrors1
use all errors equal to 1, i.e. fit without errors (default is false)
Definition DataOptions.h:52
bool fNormBinVolume
normalize data by a normalized the bin volume (bin volume divided by a reference value)
Definition DataOptions.h:49
bool fUseRange
use the function range when creating the fit data (default is false)
Definition DataOptions.h:51
bool fUseEmpty
use empty bins (default is false) with a fixed error of 1
Definition DataOptions.h:50
bool fIntegral
use integral of bin content instead of bin center (default is false)
Definition DataOptions.h:47
bool fExpErrors
use expected errors from the function and not from the data
Definition DataOptions.h:53
bool fBinVolume
normalize data by the bin volume (it is used in the Poisson likelihood fits)
Definition DataOptions.h:48
bool fCoordErrors
use errors on the x coordinates when available (default is true)
Definition DataOptions.h:54