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