Logo ROOT   6.19/01
Reference Guide
FitResult.cxx
Go to the documentation of this file.
1 // @(#)root/mathcore:$Id$
2 // Author: L. Moneta Wed Aug 30 11:05:34 2006
3 
4 /**********************************************************************
5  * *
6  * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT *
7  * *
8  * *
9  **********************************************************************/
10 
11 // Implementation file for class FitResult
12 
13 #include "Fit/FitResult.h"
14 
15 #include "Fit/FitConfig.h"
16 
17 #include "Fit/BinData.h"
18 
19 //#include "Fit/Chi2FCN.h"
20 
21 #include "Math/Minimizer.h"
22 
23 #include "Math/IParamFunction.h"
25 
26 #include "Math/ProbFuncMathCore.h"
27 #include "Math/QuantFuncMathCore.h"
28 
29 #include "TMath.h"
31 #include "Math/Error.h"
32 
33 #include <cassert>
34 #include <cmath>
35 #include <iostream>
36 #include <iomanip>
37 
38 namespace ROOT {
39 
40  namespace Fit {
41 
42 
43 const int gInitialResultStatus = -99; // use this special convention to flag it when printing result
44 
46  fValid(false), fNormalized(false), fNFree(0), fNdf(0), fNCalls(0),
47  fStatus(-1), fCovStatus(0), fVal(0), fEdm(-1), fChi2(-1)
48 {
49  // Default constructor implementation.
50 }
51 
52 FitResult::FitResult(const FitConfig & fconfig) :
53  fValid(false),
54  fNormalized(false),
55  fNFree(0),
56  fNdf(0),
57  fNCalls(0),
58  fStatus(gInitialResultStatus),
59  fCovStatus(0),
60  fVal(0),
61  fEdm(-1),
62  fChi2(-1),
63  fFitFunc(0),
64  fParams(std::vector<double>( fconfig.NPar() ) ),
65  fErrors(std::vector<double>( fconfig.NPar() ) ),
66  fParNames(std::vector<std::string> ( fconfig.NPar() ) )
67 {
68  // create a Fit result from a fit config (i.e. with initial parameter values
69  // and errors equal to step values
70  // The model function is NULL in this case
71 
72  // set minimizer type and algorithm
73  fMinimType = fconfig.MinimizerType();
74  // append algorithm name for minimizer that support it
75  if ( (fMinimType.find("Fumili") == std::string::npos) &&
76  (fMinimType.find("GSLMultiFit") == std::string::npos)
77  ) {
78  if (fconfig.MinimizerAlgoType() != "") fMinimType += " / " + fconfig.MinimizerAlgoType();
79  }
80 
81  // get parameter values and errors (step sizes)
82  unsigned int npar = fconfig.NPar();
83  for (unsigned int i = 0; i < npar; ++i ) {
84  const ParameterSettings & par = fconfig.ParSettings(i);
85  fParams[i] = par.Value();
86  fErrors[i] = par.StepSize();
87  fParNames[i] = par.Name();
88  if (par.IsFixed() ) fFixedParams[i] = true;
89  else fNFree++;
90  if (par.IsBound() ) {
91  double lower = (par.HasLowerLimit()) ? par.LowerLimit() : - std::numeric_limits<double>::infinity() ;
92  double upper = (par.HasUpperLimit()) ? par.UpperLimit() : std::numeric_limits<double>::infinity() ;
93  fBoundParams[i] = fParamBounds.size();
94  fParamBounds.push_back(std::make_pair(lower,upper));
95  }
96  }
97  std::cout << "create fit result from config - nfree " << fNFree << std::endl;
98 }
99 
100 void FitResult::FillResult(const std::shared_ptr<ROOT::Math::Minimizer> & min, const FitConfig & fconfig, const std::shared_ptr<IModelFunction> & func,
101  bool isValid, unsigned int sizeOfData, bool binnedFit, const ROOT::Math::IMultiGenFunction * chi2func, unsigned int ncalls )
102 {
103  // Fill the FitResult after minimization using result from Minimizers
104 
105  // minimizer must exist
106  assert(min);
107 
108  fValid = isValid;
109  fNFree= min->NFree();
110  fNCalls = min->NCalls();
111  fStatus = min->Status();
112  fCovStatus= min->CovMatrixStatus();
113  fVal = min->MinValue();
114  fEdm = min->Edm();
115 
116  fMinimizer= min;
117  fFitFunc = func;
118 
119  fMinimType = fconfig.MinimizerName();
120 
121  // replace ncalls if minimizer does not support it (they are taken then from the FitMethodFunction)
122  if (fNCalls == 0) fNCalls = ncalls;
123 
124  const unsigned int npar = min->NDim();
125  if (npar == 0) return;
126 
127  if (min->X() )
128  fParams = std::vector<double>(min->X(), min->X() + npar);
129  else {
130  // case minimizer does not provide minimum values (it failed) take from configuration
131  fParams.resize(npar);
132  for (unsigned int i = 0; i < npar; ++i ) {
133  fParams[i] = ( fconfig.ParSettings(i).Value() );
134  }
135  }
136 
137  if (sizeOfData > min->NFree() ) fNdf = sizeOfData - min->NFree();
138 
139 
140  // set right parameters in function (in case minimizer did not do before)
141  // do also when fit is not valid
142  if (func ) {
143  // I think we can avoid cloning the model function
144  //fFitFunc = dynamic_cast<IModelFunction *>( func->Clone() );
145  //assert(fFitFunc);
146  fFitFunc->SetParameters(&fParams.front());
147  }
148  else {
149  // when no fFitFunc is present take parameters from FitConfig
150  fParNames.reserve( npar );
151  for (unsigned int i = 0; i < npar; ++i ) {
152  fParNames.push_back( fconfig.ParSettings(i).Name() );
153  }
154  }
155 
156 
157  // check for fixed or limited parameters
158  unsigned int nfree = 0;
159  for (unsigned int ipar = 0; ipar < npar; ++ipar) {
160  const ParameterSettings & par = fconfig.ParSettings(ipar);
161  if (par.IsFixed() ) fFixedParams[ipar] = true;
162  else nfree++;
163  if (par.IsBound() ) {
164  double lower = (par.HasLowerLimit()) ? par.LowerLimit() : - std::numeric_limits<double>::infinity() ;
165  double upper = (par.HasUpperLimit()) ? par.UpperLimit() : std::numeric_limits<double>::infinity() ;
166  fBoundParams[ipar] = fParamBounds.size();
167  fParamBounds.push_back(std::make_pair(lower,upper));
168  }
169  }
170  // check if nfree (from FitConfig) and fNFree (from minimizer) are consistent
171  if (nfree != fNFree ) {
172  MATH_ERROR_MSG("FitResult","FitConfiguration and Minimizer result are not consistent");
173  std::cout << "Number of free parameters from FitConfig = " << nfree << std::endl;
174  std::cout << "Number of free parameters from Minimizer = " << fNFree << std::endl;
175  }
176 
177  // if flag is binned compute a chi2 when a chi2 function is given
178  if (binnedFit) {
179  if (chi2func == 0)
180  fChi2 = fVal;
181  else {
182  // compute chi2 equivalent for likelihood fits
183  // NB: empty bins are considered
184  fChi2 = (*chi2func)(&fParams[0]);
185  }
186  }
187 
188  // fill error matrix
189  // if minimizer provides error provides also error matrix
190  if (min->Errors() != 0) {
191 
192  fErrors = std::vector<double>(min->Errors(), min->Errors() + npar ) ;
193 
194  if (fCovStatus != 0) {
195  unsigned int r = npar * ( npar + 1 )/2;
196  fCovMatrix.reserve(r);
197  for (unsigned int i = 0; i < npar; ++i)
198  for (unsigned int j = 0; j <= i; ++j)
199  fCovMatrix.push_back(min->CovMatrix(i,j) );
200  }
201  // minos errors are set separetly when calling Fitter::CalculateMinosErrors()
202 
203  // globalCC
204  fGlobalCC.reserve(npar);
205  for (unsigned int i = 0; i < npar; ++i) {
206  double globcc = min->GlobalCC(i);
207  if (globcc < 0) break; // it is not supported by that minimizer
208  fGlobalCC.push_back(globcc);
209  }
210 
211  }
212 
213 }
214 
216  // destructor. FitResult manages the fit Function pointer
217  //if (fFitFunc) delete fFitFunc;
218 }
219 
221  fFitFunc(0)
222 {
223  // Implementation of copy constructor
224  (*this) = rhs;
225 }
226 
228  // Implementation of assignment operator.
229  if (this == &rhs) return *this; // time saving self-test
230 
231  // Manages the fitted function
232  // if (fFitFunc) delete fFitFunc;
233  // fFitFunc = 0;
234  // if (rhs.fFitFunc != 0 ) {
235  // fFitFunc = dynamic_cast<IModelFunction *>( (rhs.fFitFunc)->Clone() );
236  // assert(fFitFunc != 0);
237  // }
238 
239  // copy all other data members
240  fValid = rhs.fValid;
241  fNormalized = rhs.fNormalized;
242  fNFree = rhs.fNFree;
243  fNdf = rhs.fNdf;
244  fNCalls = rhs.fNCalls;
245  fCovStatus = rhs.fCovStatus;
246  fStatus = rhs.fStatus;
247  fVal = rhs.fVal;
248  fEdm = rhs.fEdm;
249  fChi2 = rhs.fChi2;
250  fMinimizer = rhs.fMinimizer;
251  fObjFunc = rhs.fObjFunc;
252  fFitFunc = rhs.fFitFunc;
253 
257  fParams = rhs.fParams;
258  fErrors = rhs.fErrors;
259  fCovMatrix = rhs.fCovMatrix;
260  fGlobalCC = rhs.fGlobalCC;
262 
263  fMinimType = rhs.fMinimType;
264  fParNames = rhs.fParNames;
265 
266  return *this;
267 
268 }
269 
270 bool FitResult::Update(const std::shared_ptr<ROOT::Math::Minimizer> & min, const ROOT::Fit::FitConfig & fconfig, bool isValid, unsigned int ncalls) {
271  // update fit result with new status from minimizer
272  // ncalls if it is not zero is used instead of value from minimizer
273 
274  fMinimizer = min;
275 
276  // in case minimizer changes
277  fMinimType = fconfig.MinimizerName();
278 
279  const unsigned int npar = fParams.size();
280  if (min->NDim() != npar ) {
281  MATH_ERROR_MSG("FitResult::Update","Wrong minimizer status ");
282  return false;
283  }
284  if (min->X() == 0 ) {
285  MATH_ERROR_MSG("FitResult::Update","Invalid minimizer status ");
286  return false;
287  }
288  //fNFree = min->NFree();
289  if (fNFree != min->NFree() ) {
290  MATH_ERROR_MSG("FitResult::Update","Configuration has changed ");
291  return false;
292  }
293 
294  fValid = isValid;
295  // update minimum value
296  fVal = min->MinValue();
297  fEdm = min->Edm();
298  fStatus = min->Status();
299  fCovStatus = min->CovMatrixStatus();
300 
301  // update number of function calls
302  if ( min->NCalls() > 0) fNCalls = min->NCalls();
303  else fNCalls = ncalls;
304 
305  // copy parameter value and errors
306  std::copy(min->X(), min->X() + npar, fParams.begin());
307 
308 
309  // set parameters in fit model function
310  if (fFitFunc) fFitFunc->SetParameters(&fParams.front());
311 
312  if (min->Errors() != 0) {
313 
314  if (fErrors.size() != npar) fErrors.resize(npar);
315 
316  std::copy(min->Errors(), min->Errors() + npar, fErrors.begin() ) ;
317 
318  if (fCovStatus != 0) {
319 
320  // update error matrix
321  unsigned int r = npar * ( npar + 1 )/2;
322  if (fCovMatrix.size() != r) fCovMatrix.resize(r);
323  unsigned int l = 0;
324  for (unsigned int i = 0; i < npar; ++i) {
325  for (unsigned int j = 0; j <= i; ++j)
326  fCovMatrix[l++] = min->CovMatrix(i,j);
327  }
328  }
329 
330  // update global CC
331  if (fGlobalCC.size() != npar) fGlobalCC.resize(npar);
332  for (unsigned int i = 0; i < npar; ++i) {
333  double globcc = min->GlobalCC(i);
334  if (globcc < 0) {
335  fGlobalCC.clear();
336  break; // it is not supported by that minimizer
337  }
338  fGlobalCC[i] = globcc;
339  }
340 
341  }
342  return true;
343 }
344 
346  // normalize errors and covariance matrix according to chi2 value
347  if (fNdf == 0 || fChi2 <= 0) return;
348  double s2 = fChi2/fNdf;
349  double s = std::sqrt(fChi2/fNdf);
350  for (unsigned int i = 0; i < fErrors.size() ; ++i)
351  fErrors[i] *= s;
352  for (unsigned int i = 0; i < fCovMatrix.size() ; ++i)
353  fCovMatrix[i] *= s2;
354 
355  fNormalized = true;
356 }
357 
358 
359 double FitResult::Prob() const {
360  // fit probability
361  return ROOT::Math::chisquared_cdf_c(fChi2, static_cast<double>(fNdf) );
362 }
363 
364 bool FitResult::HasMinosError(unsigned int i) const {
365  // query if the parameter i has the Minos error
366  std::map<unsigned int, std::pair<double,double> >::const_iterator itr = fMinosErrors.find(i);
367  return (itr != fMinosErrors.end() );
368 }
369 
370 
371 double FitResult::LowerError(unsigned int i) const {
372  // return lower Minos error for parameter i
373  // return the parabolic error if Minos error has not been calculated for the parameter i
374  std::map<unsigned int, std::pair<double,double> >::const_iterator itr = fMinosErrors.find(i);
375  return ( itr != fMinosErrors.end() ) ? itr->second.first : Error(i) ;
376 }
377 
378 double FitResult::UpperError(unsigned int i) const {
379  // return upper Minos error for parameter i
380  // return the parabolic error if Minos error has not been calculated for the parameter i
381  std::map<unsigned int, std::pair<double,double> >::const_iterator itr = fMinosErrors.find(i);
382  return ( itr != fMinosErrors.end() ) ? itr->second.second : Error(i) ;
383 }
384 
385 void FitResult::SetMinosError(unsigned int i, double elow, double eup) {
386  // set the Minos error for parameter i
387  fMinosErrors[i] = std::make_pair(elow,eup);
388 }
389 
390 int FitResult::Index(const std::string & name) const {
391  // find index for given parameter name
392  if (! fFitFunc) return -1;
393  unsigned int npar = fParams.size();
394  for (unsigned int i = 0; i < npar; ++i)
395  if ( fFitFunc->ParameterName(i) == name) return i;
396 
397  return -1; // case name is not found
398 }
399 
400 bool FitResult::IsParameterBound(unsigned int ipar) const {
401  return fBoundParams.find(ipar) != fBoundParams.end();
402 }
403 
404 bool FitResult::IsParameterFixed(unsigned int ipar) const {
405  return fFixedParams.find(ipar) != fFixedParams.end();
406 }
407 
408 bool FitResult::ParameterBounds(unsigned int ipar, double & lower, double & upper) const {
409  std::map<unsigned int, unsigned int>::const_iterator itr = fBoundParams.find(ipar);
410  if (itr == fBoundParams.end() ) {
411  lower = -std::numeric_limits<Double_t>::infinity();
412  upper = std::numeric_limits<Double_t>::infinity();
413  return false;
414  }
415  assert(itr->second < fParamBounds.size() );
416  lower = fParamBounds[itr->second].first;
417  upper = fParamBounds[itr->second].second;
418  return false;
419 }
420 
421 std::string FitResult::ParName(unsigned int ipar) const {
422  // return parameter name
423  if (fFitFunc) return fFitFunc->ParameterName(ipar);
424  else if (ipar < fParNames.size() ) return fParNames[ipar];
425  return "param_" + ROOT::Math::Util::ToString(ipar);
426 }
427 
428 void FitResult::Print(std::ostream & os, bool doCovMatrix) const {
429  // print the result in the given stream
430  // need to add also minos errors , globalCC, etc..
431  unsigned int npar = fParams.size();
432  if (npar == 0) {
433  os << "<Empty FitResult>\n";
434  return;
435  }
436  os << "\n****************************************\n";
437  if (!fValid) {
438  if (fStatus != gInitialResultStatus) {
439  os << " Invalid FitResult";
440  os << " (status = " << fStatus << " )";
441  }
442  else {
443  os << " FitResult before fitting";
444  }
445  os << "\n****************************************\n";
446  }
447 
448  //os << " FitResult \n\n";
449  os << "Minimizer is " << fMinimType << std::endl;
450  const unsigned int nw = 25; // spacing for text
451  const unsigned int nn = 12; // spacing for numbers
452  const std::ios_base::fmtflags prFmt = os.setf(std::ios::left,std::ios::adjustfield); // set left alignment
453 
454  if (fVal != fChi2 || fChi2 < 0)
455  os << std::left << std::setw(nw) << "MinFCN" << " = " << std::right << std::setw(nn) << fVal << std::endl;
456  if (fChi2 >= 0)
457  os << std::left << std::setw(nw) << "Chi2" << " = " << std::right << std::setw(nn) << fChi2 << std::endl;
458  os << std::left << std::setw(nw) << "NDf" << " = " << std::right << std::setw(nn) << fNdf << std::endl;
459  if (fMinimType.find("Linear") == std::string::npos) { // no need to print this for linear fits
460  if (fEdm >=0) os << std::left << std::setw(nw) << "Edm" << " = " << std::right << std::setw(nn) << fEdm << std::endl;
461  os << std::left << std::setw(nw) << "NCalls" << " = " << std::right << std::setw(nn) << fNCalls << std::endl;
462  }
463  for (unsigned int i = 0; i < npar; ++i) {
464  os << std::left << std::setw(nw) << GetParameterName(i);
465  os << " = " << std::right << std::setw(nn) << fParams[i];
466  if (IsParameterFixed(i) )
467  os << std::setw(9) << " " << std::setw(nn) << " " << " \t (fixed)";
468  else {
469  if (fErrors.size() != 0)
470  os << " +/- " << std::left << std::setw(nn) << fErrors[i] << std::right;
471  if (HasMinosError(i))
472  os << " " << std::left << std::setw(nn) << LowerError(i) << " +" << std::setw(nn) << UpperError(i)
473  << " (Minos) ";
474  if (IsParameterBound(i))
475  os << " \t (limited)";
476  }
477  os << std::endl;
478  }
479 
480  // restore stremam adjustfield
481  if (prFmt != os.flags() ) os.setf(prFmt, std::ios::adjustfield);
482 
483  if (doCovMatrix) PrintCovMatrix(os);
484 }
485 
486 void FitResult::PrintCovMatrix(std::ostream &os) const {
487  // print the covariance and correlation matrix
488  if (!fValid) return;
489  if (fCovMatrix.size() == 0) return;
490 // os << "****************************************\n";
491  os << "\nCovariance Matrix:\n\n";
492  unsigned int npar = fParams.size();
493  const int kPrec = 5;
494  const int kWidth = 8;
495  const int parw = 12;
496  const int matw = kWidth+4;
497 
498  // query previous precision and format flags
499  int prevPrec = os.precision(kPrec);
500  const std::ios_base::fmtflags prevFmt = os.flags();
501 
502  os << std::setw(parw) << " " << "\t";
503  for (unsigned int i = 0; i < npar; ++i) {
504  if (!IsParameterFixed(i) ) {
505  os << std::right << std::setw(matw) << GetParameterName(i) ;
506  }
507  }
508  os << std::endl;
509  for (unsigned int i = 0; i < npar; ++i) {
510  if (!IsParameterFixed(i) ) {
511  os << std::left << std::setw(parw) << GetParameterName(i) << "\t";
512  for (unsigned int j = 0; j < npar; ++j) {
513  if (!IsParameterFixed(j) ) {
514  os.precision(kPrec); os.width(kWidth); os << std::right << std::setw(matw) << CovMatrix(i,j);
515  }
516  }
517  os << std::endl;
518  }
519  }
520 // os << "****************************************\n";
521  os << "\nCorrelation Matrix:\n\n";
522  os << std::setw(parw) << " " << "\t";
523  for (unsigned int i = 0; i < npar; ++i) {
524  if (!IsParameterFixed(i) ) {
525  os << std::right << std::setw(matw) << GetParameterName(i) ;
526  }
527  }
528  os << std::endl;
529  for (unsigned int i = 0; i < npar; ++i) {
530  if (!IsParameterFixed(i) ) {
531  os << std::left << std::setw(parw) << std::left << GetParameterName(i) << "\t";
532  for (unsigned int j = 0; j < npar; ++j) {
533  if (!IsParameterFixed(j) ) {
534  os.precision(kPrec); os.width(kWidth); os << std::right << std::setw(matw) << Correlation(i,j);
535  }
536  }
537  os << std::endl;
538  }
539  }
540  // restore alignment and precision
541  os.setf(prevFmt, std::ios::adjustfield);
542  os.precision(prevPrec);
543 }
544 
545 void FitResult::GetConfidenceIntervals(unsigned int n, unsigned int stride1, unsigned int stride2, const double * x, double * ci, double cl, bool norm ) const {
546  // stride1 stride in coordinate stride2 stride in dimension space
547  // i.e. i-th point in k-dimension is x[ stride1 * i + stride2 * k]
548  // compute the confidence interval of the fit on the given data points
549  // the dimension of the data points must match the dimension of the fit function
550  // confidence intervals are returned in array ci
551 
552  if (!fFitFunc) {
553  // check if model function exists
554  MATH_ERROR_MSG("FitResult::GetConfidenceIntervals","Cannot compute Confidence Intervals without fit model function");
555  return;
556  }
557  assert(fFitFunc);
558 
559  // use student quantile in case of normalized errors
560  double corrFactor = 1;
561  if (fChi2 <= 0 || fNdf == 0) norm = false;
562  if (norm)
563  corrFactor = TMath::StudentQuantile(0.5 + cl/2, fNdf) * std::sqrt( fChi2/fNdf );
564  else
565  // value to go up in chi2 (1: 1 sigma error(CL=0.683) , 4: 2 sigma errors
566  corrFactor = ROOT::Math::chisquared_quantile(cl, 1);
567 
568 
569 
570  unsigned int ndim = fFitFunc->NDim();
571  unsigned int npar = fFitFunc->NPar();
572 
573  std::vector<double> xpoint(ndim);
574  std::vector<double> grad(npar);
575  std::vector<double> vsum(npar);
576 
577  // loop on the points
578  for (unsigned int ipoint = 0; ipoint < n; ++ipoint) {
579 
580  for (unsigned int kdim = 0; kdim < ndim; ++kdim) {
581  unsigned int i = ipoint * stride1 + kdim * stride2;
582  assert(i < ndim*n);
583  xpoint[kdim] = x[i];
584  }
585 
586  // calculate gradient of fitted function w.r.t the parameters
588  for (unsigned int ipar = 0; ipar < npar; ++ipar) {
589  if (!IsParameterFixed(ipar)) {
591  d.SetFunction(fadapter);
592  // compute step size as a small fraction of the error
593  // (see numerical recipes in C 5.7.8) 1.E-5 is ~ (eps)^1/3
594  if ( fErrors[ipar] > 0 )
595  d.SetStepSize( std::max( fErrors[ipar]*1.E-5, 1.E-15) );
596  else
597  d.SetStepSize( std::min(std::max(fParams[ipar]*1.E-5, 1.E-15), 0.0001 ) );
598 
599  grad[ipar] = d(fParams[ipar] ); // evaluate df/dp
600  }
601  else
602  grad[ipar] = 0.; // for fixed parameters
603  }
604 
605  // multiply covariance matrix with gradient
606  vsum.assign(npar,0.0);
607  for (unsigned int ipar = 0; ipar < npar; ++ipar) {
608  for (unsigned int jpar = 0; jpar < npar; ++jpar) {
609  vsum[ipar] += CovMatrix(ipar,jpar) * grad[jpar];
610  }
611  }
612  // multiply gradient by vsum
613  double r2 = 0;
614  for (unsigned int ipar = 0; ipar < npar; ++ipar) {
615  r2 += grad[ipar] * vsum[ipar];
616  }
617  double r = std::sqrt(r2);
618  ci[ipoint] = r * corrFactor;
619  }
620 }
621 
622 void FitResult::GetConfidenceIntervals(const BinData & data, double * ci, double cl, bool norm ) const {
623  // implement confidence intervals from a given bin data sets
624  // currently copy the data from Bindata.
625  // could implement otherwise directly
626  unsigned int ndim = data.NDim();
627  unsigned int np = data.NPoints();
628  std::vector<double> xdata( ndim * np );
629  for (unsigned int i = 0; i < np ; ++i) {
630  const double * x = data.Coords(i);
631  std::vector<double>::iterator itr = xdata.begin()+ ndim * i;
632  std::copy(x,x+ndim,itr);
633  }
634  // points are arraned as x0,y0,z0, ....xN,yN,zN (stride1=ndim, stride2=1)
635  GetConfidenceIntervals(np,ndim,1,&xdata.front(),ci,cl,norm);
636 }
637 
638 std::vector<double> FitResult::GetConfidenceIntervals(double cl, bool norm ) const {
639  // implement confidence intervals using stored data sets (if can be retrieved from objective function)
640  // it works only in case of chi2 or binned likelihood fits
641  const BinData * data = FittedBinData();
642  std::vector<double> result;
643  if (data) {
644  result.resize(data->NPoints() );
645  GetConfidenceIntervals(*data, result.data(), cl, norm);
646  }
647  else {
648  MATH_ERROR_MSG("FitResult::GetConfidenceIntervals","Cannot compute Confidence Intervals without the fit bin data");
649  }
650  return result;
651 }
652 
653 // const BinData * GetFitBinData() const {
654 // // return a pointer to the binned data used in the fit
655 // // works only for chi2 or binned likelihood fits
656 // // thus when the objective function stored is a Chi2Func or a PoissonLikelihood
657 // ROOT::Math::IMultiGenFunction * f = fObjFunc->get();
658 // Chi2Function * chi2func = dynamic_cast<Chi2Function*>(f);
659 // if (chi2func) return &(chi2func->Data());
660 // PoissonLLFunction * pllfunc = dynamic_cast<PoissonLLFunction*>(f);
661 // if (pllfunc) return &(pllfunc->Data());
662 // Chi2GradFunction * chi2gradfunc = dynamic_cast<Chi2GradFunction*>(f);
663 // if (chi2gradfunc) return &(chi2gradfunc->Data());
664 // PoissonLLGradFunction * pllgradfunc = dynamic_cast<PoissonLLFunction*>(f);
665 // if (pllgradfunc) return &(pllgradfunc->Data());
666 // MATH_WARN_MSG("FitResult::GetFitBinData","Cannot retrun fit bin data set if objective function is not of a known type");
667 // return nullptr;
668 // }
669 
671  return dynamic_cast<const BinData*> ( fFitData.get() );
672 }
673 
674 ////////////////////////////////////////////////////////////////////////////////
675 /// Scan parameter ipar between value of xmin and xmax
676 /// A array for x and y points should be provided
677 
678 bool FitResult::Scan(unsigned int ipar, unsigned int &npoints, double *pntsx, double *pntsy, double xmin, double xmax)
679 {
680  if (!pntsx || !pntsy || !npoints)
681  return false;
682 
683  if (!fMinimizer) {
684  MATH_ERROR_MSG("FitResult::Scan", "Minimizer is not available - cannot Scan");
685  return false;
686  }
687 
688  return fMinimizer->Scan(ipar, npoints, pntsx, pntsy, xmin, xmax);
689 }
690 
691 ////////////////////////////////////////////////////////////////////////////////
692 /// Create a 2D contour around the minimum for the parameter ipar and jpar
693 /// if a minimum does not exist or is invalid it will return false
694 /// A array for x and y points should be provided
695 /// Pass optionally the confidence level, default is 0.683
696 /// it is assumed that ErrorDef() defines the right error definition
697 /// (i.e 1 sigma error for one parameter). If not the confidence level are scaled to new level
698 
699 bool FitResult::Contour(unsigned int ipar, unsigned int jpar, unsigned int &npoints, double *pntsx, double *pntsy, double confLevel)
700 {
701  if (!pntsx || !pntsy || !npoints)
702  return false;
703 
704  if (!fMinimizer) {
705  MATH_ERROR_MSG("FitResult::Contour", "Minimizer is not available - cannot produce Contour");
706  return false;
707  }
708 
709  // get error level used for fitting
710  double upScale = fMinimizer->ErrorDef();
711 
712  double upVal = TMath::ChisquareQuantile(confLevel, 2); // 2 is number of parameter we do the contour
713 
714  // set required error definition in minimizer
715  fMinimizer->SetErrorDef(upScale * upVal);
716 
717  bool ret = fMinimizer->Contour(ipar, jpar, npoints, pntsx, pntsy);
718 
719  // restore the error level used for fitting
720  fMinimizer->SetErrorDef(upScale);
721 
722  return ret;
723 }
724 
725  } // end namespace Fit
726 
727 } // end namespace ROOT
int Index(const std::string &name) const
get index for parameter name (return -1 if not found)
Definition: FitResult.cxx:390
bool IsFixed() const
check if is fixed
std::string ParName(unsigned int i) const
name of the parameter
Definition: FitResult.cxx:421
float xmin
Definition: THbookFile.cxx:93
std::shared_ptr< ROOT::Math::IMultiGenFunction > fObjFunc
minimizer object used for fitting
Definition: FitResult.h:356
VSD Structures.
Definition: StringConv.hxx:21
double CovMatrix(unsigned int i, unsigned int j) const
retrieve covariance matrix element
Definition: FitResult.h:217
double Error(unsigned int i) const
parameter error by index
Definition: FitResult.h:187
Class, describing value, limits and step size of the parameters Provides functionality also to set/re...
Double_t StudentQuantile(Double_t p, Double_t ndf, Bool_t lower_tail=kTRUE)
Computes quantiles of the Student&#39;s t-distribution 1st argument is the probability, at which the quantile is computed 2nd argument - the number of degrees of freedom of the Student distribution When the 3rd argument lower_tail is kTRUE (default)- the algorithm returns such x0, that.
Definition: TMath.cxx:2640
void GetConfidenceIntervals(unsigned int n, unsigned int stride1, unsigned int stride2, const double *x, double *ci, double cl=0.95, bool norm=false) const
get confidence intervals for an array of n points x.
Definition: FitResult.cxx:545
const int gInitialResultStatus
Definition: FitResult.cxx:43
double Value() const
copy constructor and assignment operators (leave them to the compiler)
unsigned int NPar() const
number of parameters settings
Definition: FitConfig.h:95
void FillResult(const std::shared_ptr< ROOT::Math::Minimizer > &min, const FitConfig &fconfig, const std::shared_ptr< IModelFunction > &f, bool isValid, unsigned int sizeOfData=0, bool binFit=true, const ROOT::Math::IMultiGenFunction *chi2func=0, unsigned int ncalls=0)
Fill the fit result from a Minimizer instance after fitting Run also Minos if requested from the conf...
Definition: FitResult.cxx:100
FitResult & operator=(const FitResult &rhs)
Assignment operator.
Definition: FitResult.cxx:227
double Prob() const
p value of the fit (chi2 probability)
Definition: FitResult.cxx:359
STL namespace.
const ParameterSettings & ParSettings(unsigned int i) const
get the parameter settings for the i-th parameter (const method)
Definition: FitConfig.h:75
bool HasMinosError(unsigned int i) const
query if parameter i has the Minos error
Definition: FitResult.cxx:364
std::map< unsigned int, bool > fFixedParams
data set used in the fit
Definition: FitResult.h:359
unsigned int fNCalls
Definition: FitResult.h:349
const double * Coords(unsigned int ipoint) const
return a pointer to the coordinates data for the given fit point
Definition: FitData.h:246
std::vector< double > fErrors
Definition: FitResult.h:363
unsigned int fNdf
Definition: FitResult.h:348
double sqrt(double)
Double_t ChisquareQuantile(Double_t p, Double_t ndf)
Evaluate the quantiles of the chi-squared probability distribution function.
Definition: TMath.cxx:2164
Double_t x[n]
Definition: legend1.C:17
bool Scan(unsigned int ipar, unsigned int &npoints, double *pntsx, double *pntsy, double xmin=0, double xmax=0)
scan likelihood value of parameter and fill the given graph.
Definition: FitResult.cxx:678
std::shared_ptr< FitData > fFitData
model function resulting from the fit.
Definition: FitResult.h:358
virtual ~FitResult()
Destructor.
Definition: FitResult.cxx:215
std::string GetParameterName(unsigned int ipar) const
get name of parameter (deprecated)
Definition: FitResult.h:329
double LowerError(unsigned int i) const
lower Minos error. If Minos has not run for parameter i return the parabolic error ...
Definition: FitResult.cxx:371
static constexpr double s
double StepSize() const
return step size
#define MATH_ERROR_MSG(loc, str)
Definition: Error.h:82
std::string MinimizerName() const
return Minimizer full name (type / algorithm)
Definition: FitConfig.cxx:238
bool Update(const std::shared_ptr< ROOT::Math::Minimizer > &min, const ROOT::Fit::FitConfig &fconfig, bool isValid, unsigned int ncalls=0)
Update the fit result with a new minimization status To be run only if same fit is performed with sam...
Definition: FitResult.cxx:270
std::shared_ptr< ROOT::Math::Minimizer > fMinimizer
Definition: FitResult.h:355
Documentation for the abstract class IBaseFunctionMultiDim.
Definition: IFunction.h:62
std::shared_ptr< IModelFunction > fFitFunc
objective function used for fitting
Definition: FitResult.h:357
double Correlation(unsigned int i, unsigned int j) const
retrieve correlation elements
Definition: FitResult.h:227
std::map< unsigned int, std::pair< double, double > > fMinosErrors
Definition: FitResult.h:366
ROOT::R::TRInterface & r
Definition: Object.C:4
void SetMinosError(unsigned int i, double elow, double eup)
set the Minos errors for parameter i (called by the Fitter class when running Minos) ...
Definition: FitResult.cxx:385
bool HasUpperLimit() const
check if parameter has upper limit
Class describing the binned data sets : vectors of x coordinates, y values and optionally error on y ...
Definition: BinData.h:53
float xmax
Definition: THbookFile.cxx:93
double UpperError(unsigned int i) const
upper Minos error. If Minos has not run for parameter i return the parabolic error ...
Definition: FitResult.cxx:378
OneDimParamFunctionAdapter class to wrap a multi-dim parameteric function in one dimensional one...
constexpr Double_t E()
Base of natural log: .
Definition: TMath.h:97
#define d(i)
Definition: RSha256.hxx:102
double UpperLimit() const
return upper limit value
unsigned int fNFree
Definition: FitResult.h:347
class containg the result of the fit and all the related information (fitted parameter values...
Definition: FitResult.h:48
void PrintCovMatrix(std::ostream &os) const
print error matrix and correlations
Definition: FitResult.cxx:486
const std::string & Name() const
return name
void NormalizeErrors()
normalize errors using chi2/ndf for chi2 fits
Definition: FitResult.cxx:345
std::string fMinimType
Definition: FitResult.h:367
TFitResultPtr Fit(FitObject *h1, TF1 *f1, Foption_t &option, const ROOT::Math::MinimizerOptions &moption, const char *goption, ROOT::Fit::DataRange &range)
Definition: HFitImpl.cxx:134
bool IsParameterFixed(unsigned int ipar) const
query if a parameter is fixed
Definition: FitResult.cxx:404
const std::string & MinimizerType() const
return type of minimizer package
Definition: FitConfig.h:188
std::vector< std::pair< double, double > > fParamBounds
Definition: FitResult.h:361
std::vector< std::string > fParNames
Definition: FitResult.h:368
void Print(std::ostream &os, bool covmat=false) const
print the result and optionaly covariance matrix and correlations
Definition: FitResult.cxx:428
const BinData * FittedBinData() const
return BinData used in the fit (return a nullptr in case a different fit is done or the data are not ...
Definition: FitResult.cxx:670
std::string ToString(const T &val)
Utility function for conversion to strings.
Definition: Util.h:50
double chisquared_cdf_c(double x, double r, double x0=0)
Complement of the cumulative distribution function of the distribution with degrees of freedom (upp...
auto * l
Definition: textangle.C:4
std::vector< double > fGlobalCC
Definition: FitResult.h:365
FitResult()
Default constructor for an empty (non valid) fit result.
Definition: FitResult.cxx:45
std::vector< double > fCovMatrix
Definition: FitResult.h:364
double LowerLimit() const
return lower limit value
std::map< unsigned int, unsigned int > fBoundParams
Definition: FitResult.h:360
bool ParameterBounds(unsigned int ipar, double &lower, double &upper) const
retrieve parameter bounds - return false if parameter is not bound
Definition: FitResult.cxx:408
std::vector< double > fParams
Definition: FitResult.h:362
unsigned int NPoints() const
return number of fit points
Definition: FitData.h:295
unsigned int NDim() const
return coordinate data dimension
Definition: FitData.h:311
bool IsBound() const
check if is bound
bool Contour(unsigned int ipar, unsigned int jpar, unsigned int &npoints, double *pntsx, double *pntsy, double confLevel=0.683)
create contour of two parameters around the minimum pass as option confidence level: default is a val...
Definition: FitResult.cxx:699
const Int_t n
Definition: legend1.C:16
User class for calculating the derivatives of a function.
char name[80]
Definition: TGX11.cxx:109
double chisquared_quantile(double z, double r)
Inverse ( ) of the cumulative distribution function of the lower tail of the distribution with degr...
bool IsParameterBound(unsigned int ipar) const
query if a parameter is bound
Definition: FitResult.cxx:400
bool HasLowerLimit() const
check if parameter has lower limit
Class describing the configuration of the fit, options and parameter settings using the ROOT::Fit::Pa...
Definition: FitConfig.h:46
const std::string & MinimizerAlgoType() const
return type of minimizer algorithms
Definition: FitConfig.h:193