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