Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TBackCompFitter.cxx
Go to the documentation of this file.
1// @(#)root/hist:$Id$
2// Author: Lorenzo Moneta
3
4/*************************************************************************
5 * Copyright (C) 1995-2012, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12////////////////////////////////////////////////////////////////////////////////
13/** \class TBackCompFitter
14 \ingroup Hist
15 \brief Backward compatible implementation of TVirtualFitter
16
17Backward compatible implementation of TVirtualFitter using the
18class ROOT::Fit::Fitter. This class is created after fitting an
19histogram (TH1), TGraph or TTree and provides in addition to the
20methods of the TVirtualFitter hooks to access the fit result class
21(ROOT::Fit::FitResult), the fit configuration
22(ROOT::Fit::FitConfig) or the fit data (ROOT::Fit::FitData) using
23
24~~~~~~~~{.cpp}
25 TBackCompFitter * fitter = (TBackCompFitter *) TVirtualFitter::GetFitter();
26 ROOT::Fit::FitResult & result = fitter->GetFitResult();
27 result.Print(std::cout);
28~~~~~~~~
29
30Methods for getting the confidence level or contours are also
31provided. Note that after a new calls to TH1::Fit (or similar) the
32class will be deleted and all reference to the FitResult, FitConfig
33or minimizer will be invalid. One could eventually copying the
34class before issuing a new fit to avoid deleting this information.
35*///////////////////////////////////////////////////////////////////////////////
36
37#include "TROOT.h"
38#include "TBackCompFitter.h"
39
40#include "Math/Util.h"
41
42#include <iostream>
43#include <cassert>
44
45//needed by GetCondifenceLevel
46#include "Math/IParamFunction.h"
47#include "TH1.h"
48#include "TH2.h"
49#include "TH3.h"
50#include "TMath.h"
51#include "TGraph.h"
52#include "TGraphErrors.h"
53#include "TGraph2DErrors.h"
54#include "TMultiGraph.h"
55#include "HFitInterface.h"
56#include "Math/Minimizer.h"
57#include "Fit/BinData.h"
58#include "Fit/FitConfig.h"
59#include "Fit/UnBinData.h"
62#include "Fit/Chi2FCN.h"
63#include "Fit/FcnAdapter.h"
64#include "TFitResult.h"
65
66//#define DEBUG 1
67
68
70
71
72
73////////////////////////////////////////////////////////////////////////////////
74/// Constructor needed by TVirtualFitter interface. Same behavior as default constructor.
75/// initialize setting name and the global pointer
76
78 fMinimizer(nullptr),
79 fObjFunc(nullptr),
80 fModelFunc(nullptr)
81{
82 SetName("BCFitter");
83}
84
85////////////////////////////////////////////////////////////////////////////////
86/// Constructor used after having fit using directly ROOT::Fit::Fitter
87/// will create a dummy fitter copying configuration and parameter settings
88
89TBackCompFitter::TBackCompFitter(const std::shared_ptr<ROOT::Fit::Fitter> & fitter, const std::shared_ptr<ROOT::Fit::FitData> & data) :
90 fFitData(data),
91 fFitter(fitter),
92 fMinimizer(nullptr),
93 fObjFunc(nullptr),
94 fModelFunc(nullptr)
95{
96 SetName("LastFitter");
97}
98
99////////////////////////////////////////////////////////////////////////////////
100/// Destructor - delete the managed objects
101
103 if (fMinimizer) delete fMinimizer;
104 if (fObjFunc) delete fObjFunc;
105 if (fModelFunc) delete fModelFunc;
106}
107
108////////////////////////////////////////////////////////////////////////////////
109/// Do chisquare calculations in case of likelihood fits
110/// Do evaluation a the minimum only
111
113 const std::vector<double> & minpar = fFitter->Result().Parameters();
114 assert (npar == (int) minpar.size() );
115 double diff = 0;
116 double s = 0;
117 for (int i =0; i < npar; ++i) {
118 diff += std::abs( params[i] - minpar[i] );
119 s += minpar[i];
120 }
121
122 if (diff > s * 1.E-12 ) Warning("Chisquare","given parameter values are not at minimum - chi2 at minimum is returned");
123 return fFitter->Result().Chi2();
124}
125
126////////////////////////////////////////////////////////////////////////////////
127/// Clear resources for consecutive fits
128
130 // need to do something here ??? to be seen
131}
132
133////////////////////////////////////////////////////////////////////////////////
134/// Execute the command (Fortran Minuit compatible interface)
135
136Int_t TBackCompFitter::ExecuteCommand(const char *command, Double_t *args, Int_t nargs) {
137#ifdef DEBUG
138 std::cout<<"Execute command= "<<command<<std::endl;
139#endif
140
141 // set also number of parameters in obj function
143
144 TString scommand(command);
145 scommand.ToUpper();
146
147 // MIGRAD
148 if (scommand.Contains("MIG")) {
149 if (!fObjFunc) {
150 Error("ExecuteCommand","FCN must set before executing this command");
151 return -1;
152 }
153
154 fFitter->Config().SetMinimizer(GetDefaultFitter(), "Migrad");
155 bool ret = fFitter->FitFCN(*fObjFunc);
156 return (ret) ? 0 : -1;
157 }
158
159 //Minimize
160 if (scommand.Contains("MINI")) {
161
162 fFitter->Config().SetMinimizer(GetDefaultFitter(), "Minimize");
163 if (!fObjFunc) {
164 Error("ExecuteCommand","FCN must set before executing this command");
165 return -1;
166 }
167 bool ret = fFitter->FitFCN(*fObjFunc);
168 return (ret) ? 0 : -1;
169 }
170 //Simplex
171 if (scommand.Contains("SIM")) {
172
173 if (!fObjFunc) {
174 Error("ExecuteCommand","FCN must set before executing this command");
175 return -1;
176 }
177
178 fFitter->Config().SetMinimizer(GetDefaultFitter(), "Simplex");
179 bool ret = fFitter->FitFCN(*fObjFunc);
180 return (ret) ? 0 : -1;
181 }
182 //SCan
183 if (scommand.Contains("SCA")) {
184
185 if (!fObjFunc) {
186 Error("ExecuteCommand","FCN must set before executing this command");
187 return -1;
188 }
189
190 fFitter->Config().SetMinimizer(GetDefaultFitter(), "Scan");
191 bool ret = fFitter->FitFCN(*fObjFunc);
192 return (ret) ? 0 : -1;
193 }
194 // MINOS
195 else if (scommand.Contains("MINO")) {
196
197 if (fFitter->Config().MinosErrors() ) return 0;
198
199 if (!fObjFunc) {
200 Error("ExecuteCommand","FCN must set before executing this command");
201 return -1;
202 }
203 // do only MINOS. need access to minimizer. For the moment re-run fitting with minos options
204 fFitter->Config().SetMinosErrors(true);
205 // set new parameter values
206
207 fFitter->Config().SetMinimizer(GetDefaultFitter(), "Migrad"); // redo -minimization with Minos
208 bool ret = fFitter->FitFCN(*fObjFunc);
209 return (ret) ? 0 : -1;
210
211 }
212 //HESSE
213 else if (scommand.Contains("HES")) {
214
215 if (fFitter->Config().ParabErrors() ) return 0;
216
217 if (!fObjFunc) {
218 Error("ExecuteCommand","FCN must set before executing this command");
219 return -1;
220 }
221
222 // do only HESSE. need access to minimizer. For the moment re-run fitting with hesse options
223 fFitter->Config().SetParabErrors(true);
224 fFitter->Config().SetMinimizer(GetDefaultFitter(), "Migrad"); // redo -minimization with Minos
225 bool ret = fFitter->FitFCN(*fObjFunc);
226 return (ret) ? 0 : -1;
227 }
228
229 // FIX
230 else if (scommand.Contains("FIX")) {
231 for(int i = 0; i < nargs; i++) {
232 FixParameter(int(args[i])-1);
233 }
234 return 0;
235 }
236 // SET LIMIT (upper and lower)
237 else if (scommand.Contains("SET LIM")) {
238 if (nargs < 3) {
239 Error("ExecuteCommand","Invalid parameters given in SET LIMIT");
240 return -1;
241 }
242 int ipar = int(args[0]);
243 if (!ValidParameterIndex(ipar) ) return -1;
244 double low = args[1];
245 double up = args[2];
246 fFitter->Config().ParSettings(ipar).SetLimits(low,up);
247 return 0;
248 }
249 // SET PRINT
250 else if (scommand.Contains("SET PRIN")) {
251 if (nargs < 1) return -1;
252 fFitter->Config().MinimizerOptions().SetPrintLevel(int(args[0]) );
253 return 0;
254 }
255 // SET ERR
256 else if (scommand.Contains("SET ERR")) {
257 if (nargs < 1) return -1;
258 fFitter->Config().MinimizerOptions().SetPrintLevel(int( args[0]) );
259 return 0;
260 }
261 // SET STRATEGY
262 else if (scommand.Contains("SET STR")) {
263 if (nargs < 1) return -1;
264 fFitter->Config().MinimizerOptions().SetStrategy(int(args[0]) );
265 return 0;
266 }
267 //SET GRAD (not impl.)
268 else if (scommand.Contains("SET GRA")) {
269 // not yet available
270 // fGradient = true;
271 return -1;
272 }
273 //SET NOW (not impl.)
274 else if (scommand.Contains("SET NOW")) {
275 // no warning (works only for TMinuit)
276 // fGradient = true;
277 return -1;
278 }
279 // CALL FCN
280 else if (scommand.Contains("CALL FCN")) {
281 // call fcn function (global pointer to free function)
282
283 if (nargs < 1 || fFCN == nullptr ) return -1;
284 int npar = fObjFunc->NDim();
285 // use values in fit result if existing otherwise in ParameterSettings
286 std::vector<double> params(npar);
287 for (int i = 0; i < npar; ++i)
288 params[i] = GetParameter(i);
289
290 double fval = 0;
291 (*fFCN)(npar, nullptr, fval, &params[0],int(args[0]) ) ;
292 return 0;
293 }
294 else {
295 // other commands passed
296 Error("ExecuteCommand","Invalid or not supported command given %s",command);
297 return -1;
298 }
299}
300
301////////////////////////////////////////////////////////////////////////////////
302/// Check if ipar is a valid parameter index
303
305 int nps = fFitter->Config().ParamsSettings().size();
306 if (ipar < 0 || ipar >= nps ) {
307 std::string msg = ROOT::Math::Util::ToString(ipar) + " is an invalid Parameter index";
308 Error("ValidParameterIndex","%s",msg.c_str());
309 return false;
310 }
311 return true;
312}
313
314////////////////////////////////////////////////////////////////////////////////
315/// Fix the parameter
316
318 if (ValidParameterIndex(ipar) )
319 fFitter->Config().ParSettings(ipar).Fix();
320}
321
322////////////////////////////////////////////////////////////////////////////////
323/// Computes point-by-point confidence intervals for the fitted function.
324/// \param n number of points
325/// \param ndim dimensions of points
326/// \param x points, at which to compute the intervals, for ndim > 1
327/// should be in order: (x0,y0, x1, y1, ... xn, yn)
328/// \param ci computed intervals are returned in this array
329/// \param cl confidence level, default=0.95
330///
331/// NOTE, that the intervals are approximate for nonlinear(in parameters) models
332
334{
335 if (!fFitter->Result().IsValid()) {
336 Error("GetConfidenceIntervals","Cannot compute confidence intervals with an invalide fit result");
337 return;
338 }
339
340 fFitter->Result().GetConfidenceIntervals(n,ndim,1,x,ci,cl,false);
341}
342
343////////////////////////////////////////////////////////////////////////////////
344/// Computes confidence intervals at level cl. Default is 0.95
345/// The TObject parameter can be a TGraphErrors, a TGraph2DErrors or a TH1,2,3.
346/// For Graphs, confidence intervals are computed for each point,
347/// the value of the graph at that point is set to the function value at that
348/// point, and the graph y-errors (or z-errors) are set to the value of
349/// the confidence interval at that point.
350/// For Histograms, confidence intervals are computed for each bin center
351/// The bin content of this bin is then set to the function value at the bin
352/// center, and the bin error is set to the confidence interval value.
353//
354/// NOTE: confidence intervals are approximate for nonlinear models!
355///
356/// Allowed combinations:
357///
358/// Fitted object | Passed object
359/// --------------------------|------------------
360/// TGraph | TGraphErrors, TH1
361/// TGraphErrors, AsymmErrors | TGraphErrors, TH1
362/// TH1 | TGraphErrors, TH1
363/// TGraph2D | TGraph2DErrors, TH2
364/// TGraph2DErrors | TGraph2DErrors, TH2
365/// TH2 | TGraph2DErrors, TH2
366/// TH3 | TH3
367
369{
370 if (!fFitter->Result().IsValid() ) {
371 Error("GetConfidenceIntervals","Cannot compute confidence intervals with an invalide fit result");
372 return;
373 }
374
375 // get data dimension from fit object
376 int datadim = 1;
377 TObject * fitobj = GetObjectFit();
378 if (!fitobj) {
379 Error("GetConfidenceIntervals","Cannot compute confidence intervals without a fitting object");
380 return;
381 }
382
383 if (fitobj->InheritsFrom(TGraph2D::Class())) datadim = 2;
384 if (fitobj->InheritsFrom(TH1::Class())) {
385 TH1 * h1 = dynamic_cast<TH1*>(fitobj);
386 assert(h1 != nullptr);
387 datadim = h1->GetDimension();
388 }
389
390 if (datadim == 1) {
391 if (!obj->InheritsFrom(TGraphErrors::Class()) && !obj->InheritsFrom(TH1::Class() ) ) {
392 Error("GetConfidenceIntervals", "Invalid object passed for storing confidence level data, must be a TGraphErrors or a TH1");
393 return;
394 }
395 }
396 if (datadim == 2) {
397 if (!obj->InheritsFrom(TGraph2DErrors::Class()) && !obj->InheritsFrom(TH2::Class() ) ) {
398 Error("GetConfidenceIntervals", "Invalid object passed for storing confidence level data, must be a TGraph2DErrors or a TH2");
399 return;
400 }
401 }
402 if (datadim == 3) {
403 if (!obj->InheritsFrom(TH3::Class() ) ) {
404 Error("GetConfidenceIntervals", "Invalid object passed for storing confidence level data, must be a TH3");
405 return;
406 }
407 }
408
409 // fill bin data (for the moment use all ranges) according to object passed
411 data.Opt().fUseEmpty = true; // need to use all bins of given histograms
412 // call appropriate function according to type of object
413 if (obj->InheritsFrom(TGraph::Class()) )
414 ROOT::Fit::FillData(data, dynamic_cast<TGraph *>(obj) );
415 else if (obj->InheritsFrom(TGraph2D::Class()) )
416 ROOT::Fit::FillData(data, dynamic_cast<TGraph2D *>(obj) );
417// else if (obj->InheritsFrom(TMultiGraph::Class()) )
418// ROOT::Fit::FillData(data, dynamic_cast<TMultiGraph *>(obj) );
419 else if (obj->InheritsFrom(TH1::Class()) )
420 ROOT::Fit::FillData(data, dynamic_cast<TH1 *>(obj) );
421
422
423 unsigned int n = data.Size();
424
425 std::vector<double> ci( n );
426
427 fFitter->Result().GetConfidenceIntervals(data,&ci[0],cl,false);
428
429 const ROOT::Math::IParamMultiFunction * func = fFitter->Result().FittedFunction();
430 assert(func != nullptr);
431
432 // fill now the object with cl data
433 for (unsigned int i = 0; i < n; ++i) {
434 const double * x = data.Coords(i);
435 double y = (*func)( x ); // function is evaluated using its parameters
436
437 if (obj->InheritsFrom(TGraphErrors::Class()) ) {
438 TGraphErrors * gr = dynamic_cast<TGraphErrors *> (obj);
439 assert(gr != nullptr);
440 gr->SetPoint(i, *x, y);
441 gr->SetPointError(i, 0, ci[i]);
442 }
443 if (obj->InheritsFrom(TGraph2DErrors::Class()) ) {
444 TGraph2DErrors * gr = dynamic_cast<TGraph2DErrors *> (obj);
445 assert(gr != nullptr);
446 gr->SetPoint(i, x[0], x[1], y);
447 gr->SetPointError(i, 0, 0, ci[i]);
448 }
449 if (obj->InheritsFrom(TH1::Class()) ) {
450 TH1 * h1 = dynamic_cast<TH1 *> (obj);
451 assert(h1 != nullptr);
452 int ibin = 0;
453 if (datadim == 1) ibin = h1->FindBin(*x);
454 if (datadim == 2) ibin = h1->FindBin(x[0],x[1]);
455 if (datadim == 3) ibin = h1->FindBin(x[0],x[1],x[2]);
456 h1->SetBinContent(ibin, y);
457 h1->SetBinError(ibin, ci[i]);
458 }
459 }
460
461}
462
463////////////////////////////////////////////////////////////////////////////////
464/// Get the error matrix in a pointer to a NxN array.
465/// excluding the fixed parameters
466
468 unsigned int nfreepar = GetNumberFreeParameters();
469 unsigned int ntotpar = GetNumberTotalParameters();
470
471 if (fCovar.size() != nfreepar*nfreepar )
472 fCovar.resize(nfreepar*nfreepar);
473
474 if (!fFitter->Result().IsValid() ) {
475 Warning("GetCovarianceMatrix","Invalid fit result");
476 return nullptr;
477 }
478
479 unsigned int l = 0;
480 for (unsigned int i = 0; i < ntotpar; ++i) {
481 if (fFitter->Config().ParSettings(i).IsFixed() ) continue;
482 unsigned int m = 0;
483 for (unsigned int j = 0; j < ntotpar; ++j) {
484 if (fFitter->Config().ParSettings(j).IsFixed() ) continue;
485 unsigned int index = nfreepar*l + m;
486 assert(index < fCovar.size() );
487 fCovar[index] = fFitter->Result().CovMatrix(i,j);
488 m++;
489 }
490 l++;
491 }
492 return &(fCovar.front());
493}
494
495////////////////////////////////////////////////////////////////////////////////
496/// Get error matrix element (return all zero if matrix is not available)
497
499 unsigned int np2 = fCovar.size();
500 unsigned int npar = GetNumberFreeParameters();
501 if ( np2 == 0 || np2 != npar *npar ) {
502 double * c = GetCovarianceMatrix();
503 if (c == nullptr) return 0;
504 }
505 return fCovar[i*npar + j];
506}
507
508////////////////////////////////////////////////////////////////////////////////
509/// Get fit errors
510
511Int_t TBackCompFitter::GetErrors(Int_t ipar,Double_t &eplus, Double_t &eminus, Double_t &eparab, Double_t &globcc) const {
512 if (!ValidParameterIndex(ipar) ) return -1;
513
514 const ROOT::Fit::FitResult & result = fFitter->Result();
515 if (!result.IsValid() ) {
516 Warning("GetErrors","Invalid fit result");
517 return -1;
518 }
519
520 eparab = result.Error(ipar);
521 eplus = result.UpperError(ipar);
522 eminus = result.LowerError(ipar);
523 globcc = result.GlobalCC(ipar);
524 return 0;
525}
526
527////////////////////////////////////////////////////////////////////////////////
528/// Number of total parameters
529
531 return fFitter->Result().NTotalParameters();
532}
534 // number of variable parameters
535 return fFitter->Result().NFreeParameters();
536}
537
538////////////////////////////////////////////////////////////////////////////////
539/// Parameter error
540
542 if (fFitter->Result().IsEmpty() ) {
543 if (ValidParameterIndex(ipar) ) return fFitter->Config().ParSettings(ipar).StepSize();
544 else return 0;
545 }
546 return fFitter->Result().Error(ipar);
547}
548
549////////////////////////////////////////////////////////////////////////////////
550/// Parameter value
551
553 if (fFitter->Result().IsEmpty() ) {
554 if (ValidParameterIndex(ipar) ) return fFitter->Config().ParSettings(ipar).Value();
555 else return 0;
556 }
557 return fFitter->Result().Value(ipar);
558}
559
560////////////////////////////////////////////////////////////////////////////////
561/// Get all parameter info (name, value, errors)
562
564 if (!ValidParameterIndex(ipar) ) {
565 return -1;
566 }
567 const std::string & pname = fFitter->Config().ParSettings(ipar).Name();
568 const char * c = pname.c_str();
569 std::copy(c,c + pname.size(),name);
570
571 if (fFitter->Result().IsEmpty() ) {
572 value = fFitter->Config().ParSettings(ipar).Value();
573 verr = fFitter->Config().ParSettings(ipar).Value(); // error is step size in this case
574 vlow = fFitter->Config().ParSettings(ipar).LowerLimit(); // vlow is lower limit in this case
575 vhigh = fFitter->Config().ParSettings(ipar).UpperLimit(); // vlow is lower limit in this case
576 return 1;
577 }
578 else {
579 value = fFitter->Result().Value(ipar);
580 verr = fFitter->Result().Error(ipar);
581 vlow = fFitter->Result().LowerError(ipar);
582 vhigh = fFitter->Result().UpperError(ipar);
583 }
584 return 0;
585}
586
587////////////////////////////////////////////////////////////////////////////////
588/// Return name of parameter ipar
589
590const char *TBackCompFitter::GetParName(Int_t ipar) const {
591 if (!ValidParameterIndex(ipar) ) {
592 return nullptr;
593 }
594 return fFitter->Config().ParSettings(ipar).Name().c_str();
595}
596
597////////////////////////////////////////////////////////////////////////////////
598/// Get fit statistical information
599
600Int_t TBackCompFitter::GetStats(Double_t &amin, Double_t &edm, Double_t &errdef, Int_t &nvpar, Int_t &nparx) const {
601 const ROOT::Fit::FitResult & result = fFitter->Result();
602 amin = result.MinFcnValue();
603 edm = result.Edm();
604 errdef = fFitter->Config().MinimizerOptions().ErrorDef();
605 nvpar = result.NFreeParameters();
606 nparx = result.NTotalParameters();
607 return 0;
608}
609
610////////////////////////////////////////////////////////////////////////////////
611/// Sum of log (un-needed)
612
614 Warning("GetSumLog","Dummy method - returned 0");
615 return 0.;
616}
617
618////////////////////////////////////////////////////////////////////////////////
619/// Query if parameter ipar is fixed
620
622 if (!ValidParameterIndex(ipar) ) {
623 return false;
624 }
625 return fFitter->Config().ParSettings(ipar).IsFixed();
626}
627
628////////////////////////////////////////////////////////////////////////////////
629/// Print the fit result.
630/// Use PrintResults function in case of Minuit for old -style printing
631
633 if (fFitter->GetMinimizer() && fFitter->Config().MinimizerType() == "Minuit")
634 fFitter->GetMinimizer()->PrintResults();
635 else {
636 if (level > 0) fFitter->Result().Print(std::cout);
637 if (level > 1) fFitter->Result().PrintCovMatrix(std::cout);
638 }
639 // need to print minos errors and globalCC + other info
640}
641
642////////////////////////////////////////////////////////////////////////////////
643/// Release a fit parameter
644
646 if (ValidParameterIndex(ipar) )
647 fFitter->Config().ParSettings(ipar).Release();
648}
649
650////////////////////////////////////////////////////////////////////////////////
651/// Set fit method (chi2 or likelihood).
652/// According to the method the appropriate FCN function will be created
653
655 Info("SetFitMethod","non supported method");
656}
657
658////////////////////////////////////////////////////////////////////////////////
659/// Set (add) a new fit parameter passing initial value, step size (verr) and parameter limits
660/// if vlow > vhigh the parameter is unbounded
661/// if the stepsize (verr) == 0 the parameter is treated as fixed
662
664 std::vector<ROOT::Fit::ParameterSettings> & parlist = fFitter->Config().ParamsSettings();
665 if ( ipar >= (int) parlist.size() ) parlist.resize(ipar+1);
666 ROOT::Fit::ParameterSettings ps(parname, value, verr);
667 if (verr == 0) ps.Fix();
668 if (vlow < vhigh) ps.SetLimits(vlow, vhigh);
669 parlist[ipar] = ps;
670 return 0;
671}
672
673//______________________________________________________________________________
674// static method evaluating FCN
675// void TBackCompFitter::FCN( int &, double * , double & f, double * x , int /* iflag */) {
676// // get static instance of fitter
677// TBackCompFitter * fitter = dynamic_cast<TBackCompFitter *>(TVirtualFitter::GetFitter());
678// assert(fitter);
679// if (fitter->fObjFunc == 0) fitter->RecreateFCN();
680// assert(fitter->fObjFunc);
681// f = (*(fitter.fObjFunc) )(x);
682// }
683
684////////////////////////////////////////////////////////////////////////////////
685/// Recreate a minimizer instance using the function and data
686/// set objective function in minimizers function to re-create FCN from stored data object and fit options
687
689 assert(fFitData.get());
690
691 // case of standard fits (not made fia Fitter::FitFCN)
692 if (fFitter->Result().FittedFunction() != nullptr) {
693
694 if (fModelFunc) delete fModelFunc;
695 fModelFunc = dynamic_cast<ROOT::Math::IParamMultiFunction *>((fFitter->Result().FittedFunction())->Clone());
696 assert(fModelFunc);
697
698 // create fcn functions, should consider also gradient case
699 const ROOT::Fit::BinData * bindata = dynamic_cast<const ROOT::Fit::BinData *>(fFitData.get());
700 if (bindata) {
701 if (GetFitOption().Like )
703 else
705 }
706 else {
707 const ROOT::Fit::UnBinData * unbindata = dynamic_cast<const ROOT::Fit::UnBinData *>(fFitData.get());
708 assert(unbindata);
710 }
711 }
712
713 // recreate the minimizer
714 fMinimizer = fFitter->Config().CreateMinimizer();
715 if (fMinimizer == nullptr) {
716 Error("SetMinimizerFunction","cannot create minimizer %s",fFitter->Config().MinimizerType().c_str() );
717 }
718 else {
719 if (!fObjFunc) {
720 Error("SetMinimizerFunction","Object Function pointer is NULL");
721 }
722 else
724 }
725
726}
727
728////////////////////////////////////////////////////////////////////////////////
729/// Override setFCN to use the Adapter to Minuit2 FCN interface
730/// To set the address of the minimization function
731
733{
734 fFCN = fcn;
735 if (fObjFunc) delete fObjFunc;
738}
739
740
741////////////////////////////////////////////////////////////////////////////////
742/// Set the objective function for fitting
743/// Needed if fitting directly using TBackCompFitter class
744/// The class clones a copy of the function and manages it
745
747 if (fObjFunc) delete fObjFunc;
748 fObjFunc = fcn->Clone();
749}
750
751////////////////////////////////////////////////////////////////////////////////
752/// Private method to set dimension in objective function
753
755 if (!fObjFunc) return;
757 assert(fobj != nullptr);
758 int ndim = fFitter->Config().ParamsSettings().size();
759 if (ndim != 0) fobj->SetDimension(ndim);
760}
761
762////////////////////////////////////////////////////////////////////////////////
763/// Return a pointer to the objective function (FCN)
764/// If fitting directly using TBackCompFitter the pointer is managed by the class,
765/// which has been set previously when calling SetObjFunction or SetFCN
766/// Otherwise if the class is used in the backward compatible mode (e.g. after having fitted a TH1)
767/// the return pointer will be valid after fitting and as long a new fit will not be done.
768
770 if (fObjFunc) return fObjFunc;
771 return fFitter->GetFCN();
772}
773
774////////////////////////////////////////////////////////////////////////////////
775/// Return a pointer to the minimizer.
776/// the return pointer will be valid after fitting and as long a new fit will not be done.
777/// For keeping a minimizer pointer the method ReCreateMinimizer() could eventually be used
778
780 if (fMinimizer) return fMinimizer;
781 return fFitter->GetMinimizer();
782}
783
784////////////////////////////////////////////////////////////////////////////////
785/// Return a new copy of the TFitResult object which needs to be deleted later by the user
786
788 if (!fFitter.get() ) return nullptr;
789 return new TFitResult( fFitter->Result() );
790}
791
792////////////////////////////////////////////////////////////////////////////////
793/// Scan parameter ipar between value of xmin and xmax
794/// A graph must be given which will be on return filled with the scan resul
795/// If the graph size is zero, a default size n = 40 will be used
796
797bool TBackCompFitter::Scan(unsigned int ipar, TGraph * gr, double xmin, double xmax )
798{
799
800 if (!gr) return false;
801 ROOT::Math::Minimizer * minimizer = fFitter->GetMinimizer();
802 if (!minimizer) {
803 Error("Scan","Minimizer is not available - cannot scan before fitting");
804 return false;
805 }
806
807 unsigned int npoints = gr->GetN();
808 if (npoints == 0) {
809 npoints = 40;
810 gr->Set(npoints);
811 }
812 bool ret = minimizer->Scan( ipar, npoints, gr->GetX(), gr->GetY(), xmin, xmax);
813 if ((int) npoints < gr->GetN() ) gr->Set(npoints);
814 return ret;
815}
816
817//______________________________________________________________________________
818// bool TBackCompFitter::Scan2D(unsigned int ipar, unsigned int jpar, TGraph2D * gr,
819// double xmin = 0, double xmax = 0, double ymin = 0, double ymax = 0) {
820// // scan the parameters ipar between values of [xmin,xmax] and
821// // jpar between values of [ymin,ymax] and
822// // a graph2D must be given which will be on return filled with the scan resul
823// // If the graph size is zero, a default size n = 20x20 will be used
824// //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
825
826// if (!gr) return false;
827// if (!fMinimizer) {
828// Error("Scan","Minimizer is not available - cannot scan before fitting");
829// return false;
830// }
831// unsigned int npoints = gr->GetN();
832// if (npoints == 0) {
833// npoints = 40;
834// gr->Set(npoints);
835// }
836// // to be implemented
837// for (unsigned int ix = 0; ix < npoints; ++ix) {
838// return fMinimizer->Scan( ipar, npoints, gr->GetX(), gr->GetY(), xmin, xmax);
839
840// }
841
842////////////////////////////////////////////////////////////////////////////////
843/// Create a 2D contour around the minimum for the parameter ipar and jpar
844/// if a minimum does not exist or is invalid it will return false
845/// on exit a TGraph is filled with the contour points
846/// the number of contour points is determined by the size of the TGraph.
847/// if the size is zero a default number of points = 20 is used
848/// pass optionally the confidence level, default is 0.683
849/// it is assumed that ErrorDef() defines the right error definition
850/// (i.e 1 sigma error for one parameter). If not the confidence level are scaled to new level
851
852bool TBackCompFitter::Contour(unsigned int ipar, unsigned int jpar, TGraph * gr, double confLevel) {
853 if (!gr) return false;
854 ROOT::Math::Minimizer * minimizer = fFitter->GetMinimizer();
855 if (!minimizer) {
856 Error("Scan","Minimizer is not available - cannot scan before fitting");
857 return false;
858 }
859
860 // get error level used for fitting
861 double upScale = fFitter->Config().MinimizerOptions().ErrorDef();
862
863 double upVal = TMath::ChisquareQuantile( confLevel, 2); // 2 is number of parameter we do the contour
864
865 // set required error definition in minimizer
866 minimizer->SetErrorDef (upScale * upVal);
867
868 unsigned int npoints = gr->GetN();
869 if (npoints == 0) {
870 npoints = 40;
871 gr->Set(npoints);
872 }
873 bool ret = minimizer->Contour( ipar, jpar, npoints, gr->GetX(), gr->GetY());
874 if ((int) npoints < gr->GetN() ) gr->Set(npoints);
875
876 // restore the error level used for fitting
877 minimizer->SetErrorDef ( upScale);
878
879 return ret;
880}
881
882
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:382
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 result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
char name[80]
Definition TGX11.cxx:110
float xmin
float xmax
Class describing the binned data sets : vectors of x coordinates, y values and optionally error on y ...
Definition BinData.h:52
Chi2FCN class for binned fits using the least square methods.
Definition Chi2FCN.h:46
void SetDimension(int dim)
Definition FcnAdapter.h:44
class containing the result of the fit and all the related information (fitted parameter values,...
Definition FitResult.h:47
LogLikelihoodFCN class for likelihood fits.
Class, describing value, limits and step size of the parameters Provides functionality also to set/re...
void SetLimits(double low, double up)
set a double side limit, if low == up the parameter is fixed if low > up the limits are removed The c...
void Fix()
fix the parameter
class evaluating the log likelihood for binned Poisson likelihood fits it is template to distinguish ...
Class describing the un-binned data sets (just x coordinates values) of any dimensions.
Definition UnBinData.h:46
Documentation for the abstract class IBaseFunctionMultiDim.
Definition IFunction.h:61
virtual IBaseFunctionMultiDimTempl< T > * Clone() const =0
Clone a function.
virtual unsigned int NDim() const =0
Retrieve the dimension of the function.
Abstract Minimizer class, defining the interface for the various minimizer (like Minuit2,...
Definition Minimizer.h:119
void SetErrorDef(double up)
set scale for calculating the errors
Definition Minimizer.h:347
virtual void SetFunction(const ROOT::Math::IMultiGenFunction &func)=0
set the function to minimize
virtual bool Scan(unsigned int ivar, unsigned int &nstep, double *x, double *y, double xmin=0, double xmax=0)
scan function minimum for variable i.
virtual bool Contour(unsigned int ivar, unsigned int jvar, unsigned int &npoints, double *xi, double *xj)
find the contour points (xi, xj) of the function for parameter ivar and jvar around the minimum The c...
Backward compatible implementation of TVirtualFitter.
const char * GetParName(Int_t ipar) const override
Return name of parameter ipar.
void GetConfidenceIntervals(Int_t n, Int_t ndim, const Double_t *x, Double_t *ci, Double_t cl=0.95) override
Computes point-by-point confidence intervals for the fitted function.
void ReleaseParameter(Int_t ipar) override
Release a fit parameter.
Double_t GetParError(Int_t ipar) const override
Parameter error.
ROOT::Math::Minimizer * fMinimizer
void DoSetDimension()
Private method to set dimension in objective function.
void SetFCN(void(*fcn)(Int_t &, Double_t *, Double_t &f, Double_t *, Int_t)) override
Override setFCN to use the Adapter to Minuit2 FCN interface To set the address of the minimization fu...
ROOT::Math::Minimizer * GetMinimizer() const
Return a pointer to the minimizer.
void Clear(Option_t *option="") override
Clear resources for consecutive fits.
void PrintResults(Int_t level, Double_t amin) const override
Print the fit result.
Int_t GetStats(Double_t &amin, Double_t &edm, Double_t &errdef, Int_t &nvpar, Int_t &nparx) const override
Get fit statistical information.
Int_t GetNumberFreeParameters() const override
TBackCompFitter()
Constructor needed by TVirtualFitter interface.
void FixParameter(Int_t ipar) override
Fix the parameter.
void SetFitMethod(const char *name) override
Set fit method (chi2 or likelihood).
Double_t GetCovarianceMatrixElement(Int_t i, Int_t j) const override
Get error matrix element (return all zero if matrix is not available)
Bool_t IsFixed(Int_t ipar) const override
Query if parameter ipar is fixed.
std::shared_ptr< ROOT::Fit::FitData > fFitData
! Data of the fit
ROOT::Math::IParamMultiFunction * fModelFunc
Int_t GetNumberTotalParameters() const override
Number of total parameters.
Int_t ExecuteCommand(const char *command, Double_t *args, Int_t nargs) override
Execute the command (Fortran Minuit compatible interface)
TFitResult * GetTFitResult() const
Get a copy of the Fit result returning directly a new TFitResult.
void ReCreateMinimizer()
Recreate a minimizer instance using the function and data set objective function in minimizers functi...
std::shared_ptr< ROOT::Fit::Fitter > fFitter
! Pointer to fitter object
Int_t GetErrors(Int_t ipar, Double_t &eplus, Double_t &eminus, Double_t &eparab, Double_t &globcc) const override
Get fit errors.
std::vector< double > fCovar
Cached covariance matrix (NxN)
bool ValidParameterIndex(int ipar) const
Check if ipar is a valid parameter index.
bool Contour(unsigned int ipar, unsigned int jpar, TGraph *gr, double confLevel=0.683)
Create a 2D contour around the minimum for the parameter ipar and jpar if a minimum does not exist or...
Double_t GetSumLog(Int_t i) override
Sum of log (un-needed)
~TBackCompFitter() override
Destructor - delete the managed objects.
Double_t Chisquare(Int_t npar, Double_t *params) const override
Do chisquare calculations in case of likelihood fits Do evaluation a the minimum only.
ROOT::Math::IMultiGenFunction * GetObjFunction() const
Return a pointer to the objective function (FCN) If fitting directly using TBackCompFitter the pointe...
virtual void SetObjFunction(ROOT::Math::IMultiGenFunction *f)
Set the objective function for fitting Needed if fitting directly using TBackCompFitter class The cla...
bool Scan(unsigned int ipar, TGraph *gr, double xmin=0, double xmax=0)
Scan parameter ipar between value of xmin and xmax A graph must be given which will be on return fill...
ROOT::Math::IMultiGenFunction * fObjFunc
Double_t GetParameter(Int_t ipar) const override
Parameter value.
Int_t SetParameter(Int_t ipar, const char *parname, Double_t value, Double_t verr, Double_t vlow, Double_t vhigh) override
Set (add) a new fit parameter passing initial value, step size (verr) and parameter limits if vlow > ...
Double_t * GetCovarianceMatrix() const override
Get the error matrix in a pointer to a NxN array.
Extends the ROOT::Fit::Result class with a TNamed inheritance providing easy possibility for I/O.
Definition TFitResult.h:34
Graph 2D class with errors.
static TClass * Class()
Graphics object made of three arrays X, Y and Z with the same number of points each.
Definition TGraph2D.h:41
static TClass * Class()
A TGraphErrors is a TGraph with error bars.
static TClass * Class()
virtual void SetPointError(Double_t ex, Double_t ey)
Set ex and ey values for point pointed by the mouse.
A TGraph is an object made of two arrays X and Y with npoints each.
Definition TGraph.h:41
static TClass * Class()
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
Set x and y values for point number i.
Definition TGraph.cxx:2347
Double_t * GetY() const
Definition TGraph.h:140
Int_t GetN() const
Definition TGraph.h:132
Double_t * GetX() const
Definition TGraph.h:139
virtual void Set(Int_t n)
Set number of points in the graph Existing coordinates are preserved New coordinates above fNpoints a...
Definition TGraph.cxx:2282
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:59
static TClass * Class()
virtual Int_t GetDimension() const
Definition TH1.h:284
virtual void SetBinError(Int_t bin, Double_t error)
Set the bin Error Note that this resets the bin eror option to be of Normal Type and for the non-empt...
Definition TH1.cxx:9239
virtual void SetBinContent(Int_t bin, Double_t content)
Set bin content see convention for numbering bins in TH1::GetBin In case the bin number is greater th...
Definition TH1.cxx:9255
virtual Int_t FindBin(Double_t x, Double_t y=0, Double_t z=0)
Return Global bin number corresponding to x,y,z.
Definition TH1.cxx:3680
static TClass * Class()
static TClass * Class()
TObject * Clone(const char *newname="") const override
Make a clone of an object using the Streamer facility.
Definition TNamed.cxx:74
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:140
Mother of all ROOT objects.
Definition TObject.h:41
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:991
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:542
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1005
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:979
Basic string class.
Definition TString.h:139
void ToUpper()
Change string to upper case.
Definition TString.cxx:1195
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:632
virtual TObject * GetObjectFit() const
virtual Foption_t GetFitOption() const
static const char * GetDefaultFitter()
static: return the name of the default fitter
void(* fFCN)(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag)
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
TGraphErrors * gr
Definition legend1.C:25
TH1F * h1
Definition legend1.C:5
void FillData(BinData &dv, const TH1 *hist, TF1 *func=nullptr)
fill the data vector from a TH1.
std::string ToString(const T &val)
Utility function for conversion to strings.
Definition Util.h:50
Double_t ChisquareQuantile(Double_t p, Double_t ndf)
Evaluate the quantiles of the chi-squared probability distribution function.
Definition TMath.cxx:2193
int Like
Definition Foption.h:34
TMarker m
Definition textangle.C:8
TLine l
Definition textangle.C:4