Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooFitResult.cxx
Go to the documentation of this file.
1/*****************************************************************************
2 * Project: RooFit *
3 * Package: RooFitCore *
4 * @(#)root/roofitcore:$Id$
5 * Authors: *
6 * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7 * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8 * *
9 * Copyright (c) 2000-2005, Regents of the University of California *
10 * and Stanford University. All rights reserved. *
11 * *
12 * Redistribution and use in source and binary forms, *
13 * with or without modification, are permitted according to the terms *
14 * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15 *****************************************************************************/
16
17//////////////////////////////////////////////////////////////////////////////
18/// \class RooFitResult
19/// RooFitResult is a container class to hold the input and output
20/// of a PDF fit to a dataset. It contains:
21///
22/// * Values of all constant parameters
23/// * Initial and final values of floating parameters with error
24/// * Correlation matrix and global correlation coefficients
25/// * NLL and EDM at minimum
26///
27/// No references to the fitted PDF and dataset are stored
28///
29
30#include <cmath>
31#include <iostream>
32#include <iomanip>
33
34#include "TBuffer.h"
35#include "TMath.h"
36#include "TMarker.h"
37#include "TLine.h"
38#include "TBox.h"
39#include "TGaxis.h"
40#include "TMatrix.h"
41#include "TVector.h"
42#include "TDirectory.h"
43#include "TClass.h"
44#include "RooFitResult.h"
45#include "RooArgSet.h"
46#include "RooArgList.h"
47#include "RooRealVar.h"
48#include "RooPlot.h"
49#include "RooEllipse.h"
50#include "RooRandom.h"
51#include "RooMsgService.h"
52#include "TH2D.h"
53#include "TMatrixDSym.h"
54#include "RooMultiVarGaussian.h"
55
56
57using std::ostream, std::string, std::pair, std::vector, std::setw;
58
59
60
61
62////////////////////////////////////////////////////////////////////////////////
63/// Constructor with name and title
64
65RooFitResult::RooFitResult(const char *name, const char *title) : TNamed(name, title) {}
66
67////////////////////////////////////////////////////////////////////////////////
68/// Copy constructor
69
71 : TNamed(other),
72 RooPrintable(other),
73 RooDirItem(other),
74 _status(other._status),
75 _covQual(other._covQual),
76 _numBadNLL(other._numBadNLL),
77 _minNLL(other._minNLL),
78 _edm(other._edm),
79 _constPars(new RooArgList),
80 _initPars(new RooArgList),
81 _finalPars(new RooArgList),
82 _statusHistory(other._statusHistory)
83{
84
85 other._constPars->snapshot(*_constPars);
86
87 other._initPars->snapshot(*_initPars);
88
89 other._finalPars->snapshot(*_finalPars);
90 if (other._randomPars) {
91 _randomPars = std::make_unique<RooArgList>();
92 other._randomPars->snapshot(*_randomPars);
93 }
94 if (other._Lt)
95 _Lt = std::make_unique<TMatrix>(*other._Lt);
96 if (other._VM) _VM = new TMatrixDSym(*other._VM) ;
97 if (other._CM) _CM = new TMatrixDSym(*other._CM) ;
98 if (other._GC)
99 _GC = new TVectorD(*other._GC);
100}
101
102
103
104////////////////////////////////////////////////////////////////////////////////
105/// Destructor
106
108{
109 if (_constPars) delete _constPars ;
110 if (_initPars) delete _initPars ;
111 if (_finalPars)
112 delete _finalPars;
113 if (_CM) delete _CM ;
114 if (_VM) delete _VM ;
115 if (_GC) delete _GC ;
116
119
120 removeFromDir(this) ;
121}
122
123
124////////////////////////////////////////////////////////////////////////////////
125/// Fill the list of constant parameters
126
128{
129 if (_constPars) delete _constPars ;
131 list.snapshot(*_constPars);
132 for(auto* rrv : dynamic_range_cast<RooRealVar*>(*_constPars)) {
133 if (rrv) {
134 rrv->deleteSharedProperties() ;
135 }
136 }
137}
138
139
140
141////////////////////////////////////////////////////////////////////////////////
142/// Fill the list of initial values of the floating parameters
143
145{
146 if (_initPars) delete _initPars ;
147 _initPars = new RooArgList;
148 list.snapshot(*_initPars);
149 for(auto* rrv : dynamic_range_cast<RooRealVar*>(*_initPars)) {
150 if (rrv) {
151 rrv->deleteSharedProperties() ;
152 }
153 }
154}
155
156
157
158////////////////////////////////////////////////////////////////////////////////
159/// Fill the list of final values of the floating parameters
160
162{
163 if (_finalPars) delete _finalPars ;
165 list.snapshot(*_finalPars);
166
167 for(auto* rrv : dynamic_range_cast<RooRealVar*>(*_finalPars)) {
168 if (rrv) {
169 rrv->deleteSharedProperties() ;
170 }
171 }
172}
173
174
175
176////////////////////////////////////////////////////////////////////////////////
177
179{
180 if (icycle>=_statusHistory.size()) {
181 coutE(InputArguments) << "RooFitResult::statusCodeHistory(" << GetName()
182 << " ERROR request for status history slot "
183 << icycle << " exceeds history count of " << _statusHistory.size() << std::endl ;
184 }
185 return _statusHistory[icycle].second ;
186}
187
188
189
190////////////////////////////////////////////////////////////////////////////////
191
193{
194 if (icycle>=_statusHistory.size()) {
195 coutE(InputArguments) << "RooFitResult::statusLabelHistory(" << GetName()
196 << " ERROR request for status history slot "
197 << icycle << " exceeds history count of " << _statusHistory.size() << std::endl ;
198 }
199 return _statusHistory[icycle].first.c_str() ;
200}
201
202
203
204////////////////////////////////////////////////////////////////////////////////
205/// Add objects to a 2D plot that represent the fit results for the
206/// two named parameters. The input frame with the objects added is
207/// returned, or zero in case of an error. Which objects are added
208/// are determined by the options string which should be a concatenation
209/// of the following (not case sensitive):
210///
211/// * M - a marker at the best fit result
212/// * E - an error ellipse calculated at 39%CL using the error matrix at the minimum
213/// * 1 - the 1-sigma error bar for parameter 1
214/// * 2 - the 1-sigma error bar for parameter 2
215/// * B - the bounding box for the error ellipse
216/// * H - a line and horizontal axis for reading off the correlation coefficient
217/// * V - a line and vertical axis for reading off the correlation coefficient
218/// * A - draw axes for reading off the correlation coefficients with the H or V options
219///
220/// You can change the attributes of objects in the returned RooPlot using the
221/// various `RooPlot::getAttXxx(name)` member functions, e.g.
222/// ```
223/// plot->getAttLine("contour")->SetLineStyle(kDashed);
224/// ```
225/// Use `plot->Print()` for a list of all objects and their names (unfortunately most
226/// of the ROOT builtin graphics objects like TLine are unnamed). Drag the left mouse
227/// button along the labels of either axis button to interactively zoom in a plot.
228
229RooPlot *RooFitResult::plotOn(RooPlot *frame, const char *parName1, const char *parName2,
230 const char *options) const
231{
232 // lookup the input parameters by name: we require that they were floated in our fit
233 const RooRealVar *par1= dynamic_cast<const RooRealVar*>(floatParsFinal().find(parName1));
234 if(nullptr == par1) {
235 coutE(InputArguments) << "RooFitResult::correlationPlot: parameter not floated in fit: " << parName1 << std::endl;
236 return nullptr;
237 }
238 const RooRealVar *par2= dynamic_cast<const RooRealVar*>(floatParsFinal().find(parName2));
239 if(nullptr == par2) {
240 coutE(InputArguments) << "RooFitResult::correlationPlot: parameter not floated in fit: " << parName2 << std::endl;
241 return nullptr;
242 }
243
244 // options are not case sensitive
245 TString opt(options);
246 opt.ToUpper();
247
248 // lookup the 2x2 covariance matrix elements for these variables
249 double x1= par1->getVal();
250 double x2= par2->getVal();
251 double s1= par1->getError();
252 double s2= par2->getError();
253 double rho= correlation(parName1, parName2);
254
255 // add a 39%CL error ellipse, if requested
256 if(opt.Contains("E")) {
257 RooEllipse *contour= new RooEllipse("contour",x1,x2,s1,s2,rho,100,1);
258 contour->SetLineWidth(2) ;
259 frame->addPlotable(contour);
260 }
261
262 // add the error bar for parameter 1, if requested
263 if(opt.Contains("1")) {
264 TLine *hline= new TLine(x1-s1,x2,x1+s1,x2);
265 hline->SetLineColor(kRed);
266 frame->addObject(hline);
267 }
268
269 if(opt.Contains("2")) {
270 TLine *vline= new TLine(x1,x2-s2,x1,x2+s2);
271 vline->SetLineColor(kRed);
272 frame->addObject(vline);
273 }
274
275 if(opt.Contains("B")) {
276 TBox *box= new TBox(x1-s1,x2-s2,x1+s1,x2+s2);
277 box->SetLineStyle(kDashed);
278 box->SetLineColor(kRed);
279 box->SetFillStyle(0);
280 frame->addObject(box);
281 }
282
283 if(opt.Contains("H")) {
284 TLine *line= new TLine(x1-rho*s1,x2-s2,x1+rho*s1,x2+s2);
287 line->SetLineWidth(2) ;
288 frame->addObject(line);
289 if(opt.Contains("A")) {
290 TGaxis *axis= new TGaxis(x1-s1,x2-s2,x1+s1,x2-s2,-1.,+1.,502,"-=");
291 axis->SetLineColor(kBlue);
292 frame->addObject(axis);
293 }
294 }
295
296 if(opt.Contains("V")) {
297 TLine *line= new TLine(x1-s1,x2-rho*s2,x1+s1,x2+rho*s2);
300 line->SetLineWidth(2) ;
301 frame->addObject(line);
302 if(opt.Contains("A")) {
303 TGaxis *axis= new TGaxis(x1-s1,x2-s2,x1-s1,x2+s2,-1.,+1.,502,"-=");
304 axis->SetLineColor(kBlue);
305 frame->addObject(axis);
306 }
307 }
308
309 // add a marker at the fitted value, if requested
310 if(opt.Contains("M")) {
311 TMarker *marker= new TMarker(x1,x2,20);
312 marker->SetMarkerColor(kBlack);
313 frame->addObject(marker);
314 }
315
316 return frame;
317}
318
319
320////////////////////////////////////////////////////////////////////////////////
321/// Return a list of floating parameter values that are perturbed from the final
322/// fit values by random amounts sampled from the covariance matrix. The returned
323/// object is overwritten with each call and belongs to the RooFitResult. Uses
324/// the "square root method" to decompose the covariance matrix, which makes inverting
325/// it unnecessary.
326
328{
329 Int_t nPar= _finalPars->size();
330 if (!_randomPars) { // first-time initialization
331 assert(nullptr != _finalPars);
332 // create the list of random values to fill
333 _randomPars = std::make_unique<RooArgList>();
335 // calculate the elements of the upper-triangular matrix L that gives Lt*L = C
336 // where Lt is the transpose of L (the "square-root method")
337 TMatrix L(nPar, nPar);
338 for (Int_t iPar = 0; iPar < nPar; iPar++) {
339 // calculate the diagonal term first
340 L(iPar, iPar) = covariance(iPar, iPar);
341 for (Int_t k = 0; k < iPar; k++) {
342 double tmp = L(k, iPar);
343 L(iPar, iPar) -= tmp * tmp;
344 }
345 L(iPar, iPar) = sqrt(L(iPar, iPar));
346 // then the off-diagonal terms
347 for (Int_t jPar = iPar + 1; jPar < nPar; jPar++) {
348 L(iPar, jPar) = covariance(iPar, jPar);
349 for (Int_t k = 0; k < iPar; k++) {
350 L(iPar, jPar) -= L(k, iPar) * L(k, jPar);
351 }
352 L(iPar, jPar) /= L(iPar, iPar);
353 }
354 }
355 // remember Lt
356 _Lt = std::make_unique<TMatrix>(TMatrix::kTransposed, L);
357 } else {
358 // reset to the final fit values
359 _randomPars->assign(*_finalPars);
360 }
361
362 // create a vector of unit Gaussian variables
363 TVector g(nPar);
364 for(Int_t k= 0; k < nPar; k++) g(k)= RooRandom::gaussian();
365 // multiply this vector by Lt to introduce the appropriate correlations
366 g*= (*_Lt);
367 // add the mean value offsets and store the results
368 Int_t index(0);
369 for(auto * par : static_range_cast<RooRealVar*>(*_randomPars)) {
370 par->setVal(par->getVal() + g(index++));
371 }
372
373 return *_randomPars;
374}
375
376
377////////////////////////////////////////////////////////////////////////////////
378/// Return the correlation between parameters 'par1' and 'par2'
379
380double RooFitResult::correlation(const char* parname1, const char* parname2) const
381{
382 Int_t idx1 = _finalPars->index(parname1) ;
383 Int_t idx2 = _finalPars->index(parname2) ;
384 if (idx1<0) {
385 coutE(InputArguments) << "RooFitResult::correlation(" << GetName() << ") parameter " << parname1 << " is not a floating fit parameter" << std::endl ;
386 return 0 ;
387 }
388 if (idx2<0) {
389 coutE(InputArguments) << "RooFitResult::correlation(" << GetName() << ") parameter " << parname2 << " is not a floating fit parameter" << std::endl ;
390 return 0 ;
391 }
392 return correlation(idx1,idx2) ;
393}
394
395
396
397////////////////////////////////////////////////////////////////////////////////
398/// Return the set of correlation coefficients of parameter 'par' with
399/// all other floating parameters
400
401const RooArgList* RooFitResult::correlation(const char* parname) const
402{
403 if (_globalCorr==nullptr) {
405 }
406
407 RooAbsArg* arg = _initPars->find(parname) ;
408 if (!arg) {
409 coutE(InputArguments) << "RooFitResult::correlation: variable " << parname << " not a floating parameter in fit" << std::endl ;
410 return nullptr ;
411 }
412 return static_cast<RooArgList*>(_corrMatrix.At(_initPars->index(arg))) ;
413}
414
415
416
417////////////////////////////////////////////////////////////////////////////////
418/// Return the global correlation of the named parameter
419
420double RooFitResult::globalCorr(const char* parname)
421{
423 if (_globalCorr==nullptr) {
425 }
426
427 RooAbsArg* arg = _initPars->find(parname) ;
428 if (!arg) {
429 coutE(InputArguments) << "RooFitResult::globalCorr: variable " << parname << " not a floating parameter in fit" << std::endl ;
430 return 0 ;
431 }
432
433 if (_globalCorr) {
434 return (static_cast<RooAbsReal*>(_globalCorr->at(_initPars->index(arg))))->getVal() ;
435 } else {
436 return 1.0 ;
437 }
438}
439
440
441
442////////////////////////////////////////////////////////////////////////////////
443/// Return the list of all global correlations
444
446{
448 if (_globalCorr==nullptr) {
450 }
451
452 return _globalCorr.get();
453}
454
455
456
457////////////////////////////////////////////////////////////////////////////////
458/// Return a correlation matrix element addressed with numeric indices.
459
461{
462 return (*_CM)(row,col) ;
463}
464
465
466////////////////////////////////////////////////////////////////////////////////
467/// Return the covariance matrix element addressed with numeric indices.
468
470{
471 return (*_VM)(row,col) ;
472}
473
474
475
476////////////////////////////////////////////////////////////////////////////////
477/// Print fit result to stream 'os'. In Verbose mode, the constant parameters and
478/// the initial and final values of the floating parameters are printed.
479/// Standard mode only the final values of the floating parameters are printed
480
481void RooFitResult::printMultiline(ostream& os, Int_t /*contents*/, bool verbose, TString indent) const
482{
483
484 os << std::endl
485 << indent << " RooFitResult: minimized FCN value: " << _minNLL << ", estimated distance to minimum: " << _edm << std::endl
486 << indent << " covariance matrix quality: " ;
487 switch(_covQual) {
488 case -1 : os << "Unknown, matrix was externally provided" ; break ;
489 case 0 : os << "Not calculated at all" ; break ;
490 case 1 : os << "Approximation only, not accurate" ; break ;
491 case 2 : os << "Full matrix, but forced positive-definite" ; break ;
492 case 3 : os << "Full, accurate covariance matrix" ; break ;
493 }
494 os << std::endl ;
495 os << indent << " Status : " ;
496 for (vector<pair<string,int> >::const_iterator iter = _statusHistory.begin() ; iter != _statusHistory.end() ; ++iter) {
497 os << iter->first << "=" << iter->second << " " ;
498 }
499 os << std::endl << std::endl;
500
501 if (verbose) {
502 if (!_constPars->empty()) {
503 os << indent << " Constant Parameter Value " << std::endl
504 << indent << " -------------------- ------------" << std::endl ;
505
506 for (std::size_t i=0 ; i<_constPars->size() ; i++) {
507 os << indent << " " << setw(20) << _constPars->at(i)->GetName() << " " << setw(12);
508 if(RooRealVar* v = dynamic_cast<RooRealVar*>(_constPars->at(i))) {
509 os << TString::Format("%12.4e",v->getVal());
510 } else {
511 _constPars->at(i)->printValue(os); // for anything other than RooRealVar use printValue method to print
512 }
513 os << std::endl ;
514 }
515
516 os << std::endl ;
517 }
518
520 if (_globalCorr == nullptr) {
522 }
523
524 // Has any parameter asymmetric errors?
525 bool doAsymErr(false) ;
526 for (std::size_t i=0 ; i<_finalPars->size() ; i++) {
527 if (static_cast<RooRealVar*>(_finalPars->at(i))->hasAsymError()) {
528 doAsymErr=true ;
529 break ;
530 }
531 }
532
533 if (doAsymErr) {
534 os << indent << " Floating Parameter InitialValue FinalValue (+HiError,-LoError) GblCorr." << std::endl
535 << indent << " -------------------- ------------ ---------------------------------- --------" << std::endl ;
536 } else {
537 os << indent << " Floating Parameter InitialValue FinalValue +/- Error GblCorr." << std::endl
538 << indent << " -------------------- ------------ -------------------------- --------" << std::endl ;
539 }
540
541 for (std::size_t i=0 ; i<_finalPars->size() ; i++) {
542 os << indent << " " << setw(20) << ((RooAbsArg*)_finalPars->at(i))->GetName() ;
543 os << indent << " " << setw(12) << Form("%12.4e",(static_cast<RooRealVar*>(_initPars->at(i)))->getVal())
544 << indent << " " << setw(12) << Form("%12.4e",(static_cast<RooRealVar*>(_finalPars->at(i)))->getVal()) ;
545
546 if ((static_cast<RooRealVar*>(_finalPars->at(i)))->hasAsymError()) {
547 os << setw(21) << Form(" (+%8.2e,-%8.2e)",(static_cast<RooRealVar*>(_finalPars->at(i)))->getAsymErrorHi(),
548 -1*(static_cast<RooRealVar*>(_finalPars->at(i)))->getAsymErrorLo()) ;
549 } else {
550 double err = (static_cast<RooRealVar*>(_finalPars->at(i)))->getError() ;
551 os << (doAsymErr?" ":"") << " +/- " << setw(9) << Form("%9.2e",err) ;
552 }
553
554 if (_globalCorr) {
555 os << " " << setw(8) << Form("%8.6f" ,(static_cast<RooRealVar*>(_globalCorr->at(i)))->getVal()) ;
556 } else {
557 os << " <none>" ;
558 }
559
560 os << std::endl ;
561 }
562
563 } else {
564 os << indent << " Floating Parameter FinalValue +/- Error " << std::endl
565 << indent << " -------------------- --------------------------" << std::endl ;
566
567 for (std::size_t i=0 ; i<_finalPars->size() ; i++) {
568 double err = (static_cast<RooRealVar*>(_finalPars->at(i)))->getError() ;
569 os << indent << " " << setw(20) << ((RooAbsArg*)_finalPars->at(i))->GetName()
570 << " " << setw(12) << Form("%12.4e",(static_cast<RooRealVar*>(_finalPars->at(i)))->getVal())
571 << " +/- " << setw(9) << Form("%9.2e",err)
572 << std::endl ;
573 }
574 }
575
576
577 os << std::endl ;
578}
579
580
581////////////////////////////////////////////////////////////////////////////////
582/// Function called by RooMinimizer
583
584void RooFitResult::fillCorrMatrix(const std::vector<double>& globalCC, const TMatrixDSym& corrs, const TMatrixDSym& covs)
585{
586 // Sanity check
587 if (globalCC.empty() || corrs.GetNoElements() < 1 || covs.GetNoElements() < 1) {
588 coutI(Minimization) << "RooFitResult::fillCorrMatrix: number of floating parameters is zero, correlation matrix not filled" << std::endl ;
589 return ;
590 }
591
592 if (!_initPars) {
593 coutE(Minimization) << "RooFitResult::fillCorrMatrix: ERROR: list of initial parameters must be filled first" << std::endl ;
594 return ;
595 }
596
597 // Delete eventual previous correlation data holders
598 if (_CM) delete _CM ;
599 if (_VM) delete _VM ;
600 if (_GC) delete _GC ;
601
602 // Build holding arrays for correlation coefficients
603 _CM = new TMatrixDSym(corrs) ;
604 _VM = new TMatrixDSym(covs) ;
605 _GC = new TVectorD(_CM->GetNcols()) ;
606 for(int i=0 ; i<_CM->GetNcols() ; i++) {
607 (*_GC)[i] = globalCC[i] ;
608 }
609 //fillLegacyCorrMatrix() ;
610}
611
612
613
614
615
616////////////////////////////////////////////////////////////////////////////////
617/// Compute the global correlation coefficients from the correlation matrix if
618/// they are not available yet. This is the case when the covariance matrix
619/// was provided externally via setCovarianceMatrix(), for example for weighted
620/// fits with the SumW2Error or AsymptoticError corrections. The computation
621/// is deferred to the point where the coefficients are actually requested,
622/// because it requires inverting the correlation matrix, and because
623/// externally provided matrices are often placeholders that are singular.
624///
625/// The coefficients are computed as rho_k^2 = 1 - 1/[V_kk * (V^-1)_kk] = 1 -
626/// 1/(C^-1)_kk, which reproduces the values reported by Minuit for a regular
627/// fit. If the correlation matrix is singular, the coefficients are set to zero
628/// and a warning is emitted.
629
631{
632 if (_GC || !_CM) {
633 return;
634 }
635
636 const Int_t n = _CM->GetNcols();
637 _GC = new TVectorD(n);
638 // Make sure the legacy holders get refilled with the new coefficients
639 _globalCorr.reset();
640
641 if (n == 0) {
642 return;
643 }
644
645 TMatrixDSym invC(*_CM);
646 double det = 0.0;
647 invC.Invert(&det);
648 if (det == 0.0) {
649 coutW(InputArguments) << "RooFitResult::globalCorr(" << GetName()
650 << ") covariance matrix is singular, global correlation coefficients not available"
651 << std::endl;
652 return;
653 }
654
655 for (Int_t i = 0; i < n; i++) {
656 const double rho2 = 1.0 - 1.0 / invC(i, i);
657 (*_GC)[i] = rho2 > 0.0 ? std::sqrt(rho2) : 0.0;
658 }
659}
660
661
662////////////////////////////////////////////////////////////////////////////////
663/// Sanity check
664
666{
667 if (!_CM) return ;
668
669 // Delete eventual previous correlation data holders
671
672 // Build holding arrays for correlation coefficients
673 _globalCorr = std::make_unique<RooArgList>("globalCorrelations");
674
675 for(RooAbsArg* arg : *_initPars) {
676 // Create global correlation value holder
677 std::string argName = arg->GetName();
678 std::string argTitle = arg->GetTitle();
679 std::string gcName = "GC[" + argName + "]";
680 std::string gcTitle = argTitle + " Global Correlation";
681 _globalCorr->addOwned(std::make_unique<RooRealVar>(gcName.c_str(), gcTitle.c_str(), 0.));
682
683 // Create array with correlation holders for this parameter
684 RooArgList *corrMatrixRow = new RooArgList(("C[" + argName + ",*]").c_str());
685 _corrMatrix.Add(corrMatrixRow) ;
686 for(RooAbsArg* arg2 : *_initPars) {
687
688 std::string arg2Name = arg2->GetName();
689 std::string cName = "C[" + argName + "," + arg2Name + "]";
690 std::string cTitle = "Correlation between " + argName + " and " + arg2Name;
691 corrMatrixRow->addOwned(std::make_unique<RooRealVar>(cName.c_str(), cTitle.c_str(), 0.));
692 }
693 }
694
695 if (!_GC) return ;
696
697 for (unsigned int i = 0; i < static_cast<unsigned int>(_corrMatrix.GetSize()) ; ++i) {
698
699 // Find the next global correlation slot to fill, skipping fixed parameters
700 auto& gcVal = static_cast<RooRealVar&>((*_globalCorr)[i]);
701 gcVal.setVal((*_GC)(i)) ; // WVE FIX THIS
702
703 // Fill a row of the correlation matrix
704 auto corrMatrixCol = static_cast<RooArgList const&>(*_corrMatrix.At(i));
705 for (unsigned int it = 0; it < corrMatrixCol.size() ; ++it) {
706 auto& cVal = static_cast<RooRealVar&>(corrMatrixCol[it]);
707 double value = (*_CM)(i,it) ;
708 cVal.setVal(value);
709 (*_CM)(i,it) = value;
710 }
711 }
712}
713
714
715////////////////////////////////////////////////////////////////////////////////
716
718{
719
720 // Delete eventual previous correlation data holders
721 if (_CM)
722 delete _CM;
723 if (_VM)
724 delete _VM;
725 if (_GC)
726 delete _GC;
727
728 // Build holding arrays for correlation coefficients
729 _CM = new TMatrixDSym(_initPars->size());
730 _VM = new TMatrixDSym(_initPars->size());
731 _GC = new TVectorD(_initPars->size());
732
733 for (std::size_t ii = 0; ii < _finalPars->size(); ii++) {
734 (*_CM)(ii, ii) = 1;
735 (*_VM)(ii, ii) = static_cast<RooRealVar *>(_finalPars->at(ii))->getError() * static_cast<RooRealVar *>(_finalPars->at(ii))->getError();
736 (*_GC)(ii) = 0;
737 }
738}
739
740
741namespace {
742
743void isIdenticalErrMsg(std::string const& msgHead, const RooAbsReal* tv, const RooAbsReal* ov, bool verbose) {
744 if(!verbose) return;
745 std::cout << "RooFitResult::isIdentical: " << msgHead << " " << tv->GetName() << " differs in value:\t"
746 << tv->getVal() << " vs.\t" << ov->getVal()
747 << "\t(" << (tv->getVal()-ov->getVal())/ov->getVal() << ")" << std::endl;
748}
749
750void isErrorIdenticalErrMsg(std::string const& msgHead, const RooRealVar* tv, const RooRealVar* ov, bool verbose) {
751 if(!verbose) return;
752 std::cout << "RooFitResult::isIdentical: " << msgHead << " " << tv->GetName() << " differs in error:\t"
753 << tv->getError() << " vs.\t" << ov->getError()
754 << "\t(" << (tv->getError()-ov->getError())/ov->getError() << ")" << std::endl;
755}
756
757} // namespace
758
759
760////////////////////////////////////////////////////////////////////////////////
761/// Return true if this fit result is identical to other within tolerances, ignoring the correlation matrix.
762/// \param[in] other Fit result to test against.
763/// \param[in] tol **Relative** tolerance for parameters and NLL.
764/// \param[in] tolErr **Relative** tolerance for parameter errors.
765/// \param[in] verbose If this function will log to the standard output when comparisons fail.
766
767bool RooFitResult::isIdenticalNoCov(const RooFitResult& other, double tol, double tolErr, bool verbose) const
768{
769 bool ret = true;
770 auto deviation = [](const double left, const double right, double tolerance){
771 return right != 0. ? std::abs((left - right)/right) >= tolerance : std::abs(left) >= tolerance;
772 };
773
774 auto compare = [&](RooArgList const& pars, RooArgList const& otherpars, std::string const& prefix, bool isVerbose) {
775 bool out = true;
776
777 for (auto * tv : static_range_cast<const RooAbsReal*>(pars)) {
778 auto ov = static_cast<const RooAbsReal*>(otherpars.find(tv->GetName())) ;
779
780 // Check in the parameter is in the other fit result
781 if (!ov) {
782 if(verbose) std::cout << "RooFitResult::isIdentical: cannot find " << prefix << " " << tv->GetName() << " in reference" << std::endl ;
783 out = false;
784 }
785
786 // Compare parameter value
787 if (ov && deviation(tv->getVal(), ov->getVal(), tol)) {
788 isIdenticalErrMsg(prefix, tv, ov, isVerbose);
789 out = false;
790 }
791
792 // Compare parameter error if it's a RooRealVar
793 auto * rtv = dynamic_cast<RooRealVar const*>(tv);
794 auto * rov = dynamic_cast<RooRealVar const*>(ov);
795 if(rtv && rov) {
796 if (ov && deviation(rtv->getError(), rov->getError(), tolErr)) {
797 isErrorIdenticalErrMsg(prefix, rtv, rov, isVerbose);
798 out = false;
799 }
800 }
801 }
802
803 return out;
804 };
805
806 if (deviation(_minNLL, other._minNLL, tol)) {
807 if(verbose) std::cout << "RooFitResult::isIdentical: minimized value of -log(L) is different " << _minNLL << " vs. " << other._minNLL << std::endl;
808 ret = false;
809 }
810
811 ret &= compare(*_constPars, *other._constPars, "constant parameter", verbose);
812 ret &= compare(*_initPars, *other._initPars, "initial parameter", verbose);
813 ret &= compare(*_finalPars, *other._finalPars, "final parameter", verbose);
814
815 return ret;
816}
817
818
819////////////////////////////////////////////////////////////////////////////////
820/// Return true if this fit result is identical to other within tolerances.
821/// \param[in] other Fit result to test against.
822/// \param[in] tol **Relative** tolerance for parameters and NLL.
823/// \param[in] tolCorr **absolute** tolerance for correlation coefficients.
824/// \param[in] verbose If this function will log to the standard output when comparisons fail.
825///
826/// As the relative tolerance for the parameter errors, the default value of
827/// `1e-3` will be used.
828
829bool RooFitResult::isIdentical(const RooFitResult& other, double tol, double tolCorr, bool verbose) const
830{
831 bool ret = isIdenticalNoCov(other, tol, 1e-3 /* synced with default parameter*/, verbose);
832
833 auto deviationCorr = [tolCorr](const double left, const double right){
834 return std::abs(left - right) >= tolCorr;
835 };
836
837 // Only examine correlations for cases with >1 floating parameter
838 if (_finalPars->size()>1) {
839
841 other.fillGlobalCorr() ;
843 other.fillLegacyCorrMatrix() ;
844
845 for (std::size_t i=0 ; i<_globalCorr->size() ; i++) {
846 auto tv = static_cast<const RooAbsReal*>(_globalCorr->at(i));
847 auto ov = static_cast<const RooAbsReal*>(other._globalCorr->find(_globalCorr->at(i)->GetName())) ;
848 if (!ov) {
849 if(verbose) std::cout << "RooFitResult::isIdentical: cannot find global correlation coefficient " << tv->GetName() << " in reference" << std::endl ;
850 ret = false ;
851 }
852 if (ov && deviationCorr(tv->getVal(), ov->getVal())) {
853 isIdenticalErrMsg("global correlation coefficient", tv, ov, verbose);
854 ret = false ;
855 }
856 }
857
858 for (Int_t j=0 ; j<_corrMatrix.GetSize() ; j++) {
859 RooArgList* row = static_cast<RooArgList*>(_corrMatrix.At(j)) ;
860 RooArgList* orow = static_cast<RooArgList*>(other._corrMatrix.At(j)) ;
861 for (std::size_t i=0 ; i<row->size() ; i++) {
862 auto tv = static_cast<const RooAbsReal*>(row->at(i));
863 auto ov = static_cast<const RooAbsReal*>(orow->find(tv->GetName())) ;
864 if (!ov) {
865 if(verbose) std::cout << "RooFitResult::isIdentical: cannot find correlation coefficient " << tv->GetName() << " in reference" << std::endl ;
866 ret = false ;
867 }
868 if (ov && deviationCorr(tv->getVal(), ov->getVal())) {
869 isIdenticalErrMsg("correlation coefficient", tv, ov, verbose);
870 ret = false ;
871 }
872 }
873 }
874 }
875
876 return ret ;
877}
878
879
880////////////////////////////////////////////////////////////////////////////////
881/// Import the results of the last fit performed by gMinuit, interpreting
882/// the fit parameters as the given varList of parameters.
883
885{
886 // Verify that all members of varList are of type RooRealVar
887 for(RooAbsArg * arg : paramList) {
888 if (!dynamic_cast<RooRealVar *>(arg)) {
889 oocoutE(nullptr, InputArguments) << "RooFitResult::lastMinuitFit: ERROR: variable '" << arg->GetName()
890 << "' is not of type RooRealVar" << std::endl;
891 return nullptr;
892 }
893 }
894
895 RooFitResult *r = new RooFitResult("lastMinuitFit", "Last MINUIT fit");
896
897 // Extract names of fit parameters from MINUIT
898 // and construct corresponding RooRealVars
899 RooArgList constPars("constPars");
900 RooArgList floatPars("floatPars");
901
902 for(RooAbsArg* arg : paramList) {
903 if (arg->isConstant()) {
904 constPars.addClone(*arg);
905 } else {
906 floatPars.addClone(*arg);
907 }
908 }
909
910 r->setConstParList(constPars);
911 r->setInitParList(floatPars);
912 r->setFinalParList(floatPars);
913 r->setMinNLL(0);
914 r->setEDM(0);
915 r->setCovQual(0);
916 r->setStatus(0);
917 r->fillPrefitCorrMatrix();
918
919 return r;
920}
921
922////////////////////////////////////////////////////////////////////////////////
923/// Store externally provided correlation matrix in this RooFitResult ;
924
926{
927 // Delete any previous matrices
928 if (_VM) {
929 delete _VM ;
930 }
931 if (_CM) {
932 delete _CM ;
933 }
934 if (_GC) {
935 delete _GC;
936 _GC = nullptr;
937 }
938 _globalCorr.reset();
939
940 // Clone input covariance matrix ;
941 _VM = static_cast<TMatrixDSym*>(V.Clone()) ;
942
943 // Now construct correlation matrix from it
944 _CM = static_cast<TMatrixDSym*>(_VM->Clone()) ;
945 for (Int_t i=0 ; i<_CM->GetNrows() ; i++) {
946 for (Int_t j=0 ; j<_CM->GetNcols() ; j++) {
947 if (i!=j) {
948 (*_CM)(i,j) = (*_CM)(i,j) / sqrt((*_CM)(i,i)*(*_CM)(j,j)) ;
949 }
950 }
951 }
952 for (Int_t i=0 ; i<_CM->GetNrows() ; i++) {
953 (*_CM)(i,i) = 1.0 ;
954 }
955
956 // The global correlation coefficients are derived from the correlation
957 // matrix on demand, see fillGlobalCorr().
958
959 _covQual = -1 ;
960}
961
962
963
964////////////////////////////////////////////////////////////////////////////////
965/// Return TH2D of correlation matrix
966
968{
969 Int_t n = _CM->GetNcols() ;
970
971 TH2D* hh = new TH2D(name,name,n,0,n,n,0,n) ;
972
973 for (Int_t i = 0 ; i<n ; i++) {
974 for (Int_t j = 0 ; j<n; j++) {
975 hh->Fill(i+0.5,n-j-0.5,(*_CM)(i,j)) ;
976 }
977 hh->GetXaxis()->SetBinLabel(i+1,_finalPars->at(i)->GetName()) ;
978 hh->GetYaxis()->SetBinLabel(n-i,_finalPars->at(i)->GetName()) ;
979 }
980 hh->SetMinimum(-1) ;
981 hh->SetMaximum(+1) ;
982
983
984 return hh ;
985}
986
987
988
989
990////////////////////////////////////////////////////////////////////////////////
991/// Return covariance matrix
992
994{
995 return *_VM ;
996}
997
998
999
1000
1001////////////////////////////////////////////////////////////////////////////////
1002/// Return a reduced covariance matrix (Note that Vred _is_ a simple sub-matrix of V,
1003/// row/columns are ordered to matched the convention given in input argument 'params'
1004
1006{
1007 const TMatrixDSym& V = covarianceMatrix() ;
1008
1009
1010 // Make sure that all given params were floating parameters in the represented fit
1011 RooArgList params2 ;
1012 for(RooAbsArg* arg : params) {
1013 if (_finalPars->find(arg->GetName())) {
1014 params2.add(*arg) ;
1015 } else {
1016 coutW(InputArguments) << "RooFitResult::reducedCovarianceMatrix(" << GetName() << ") WARNING input variable "
1017 << arg->GetName() << " was not a floating parameters in fit result and is ignored" << std::endl ;
1018 }
1019 }
1020
1021 // fix for bug ROOT-8044
1022 // use same order given bby vector params
1023 vector<int> indexMap(params2.size());
1024 for (std::size_t i=0 ; i<params2.size() ; i++) {
1025 indexMap[i] = _finalPars->index(params2[i].GetName());
1026 assert(indexMap[i] < V.GetNrows());
1027 }
1028
1029 TMatrixDSym Vred(indexMap.size());
1030 for (int i = 0; i < Vred.GetNrows(); ++i) {
1031 for (int j = 0; j < Vred.GetNcols(); ++j) {
1032 Vred(i,j) = V( indexMap[i], indexMap[j]);
1033 }
1034 }
1035 return Vred;
1036}
1037
1038
1039
1040////////////////////////////////////////////////////////////////////////////////
1041/// Return a reduced covariance matrix, which is calculated as
1042/// \f[
1043/// V_\mathrm{red} = \bar{V_{22}} = V_{11} - V_{12} \cdot V_{22}^{-1} \cdot V_{21},
1044/// \f]
1045/// where \f$ V_{11},V_{12},V_{21},V_{22} \f$ represent a block decomposition of the covariance matrix into observables that
1046/// are propagated (labeled by index '1') and that are not propagated (labeled by index '2'), and \f$ \bar{V_{22}} \f$
1047/// is the Shur complement of \f$ V_{22} \f$, calculated as shown above.
1048///
1049/// (Note that \f$ V_\mathrm{red} \f$ is *not* a simple sub-matrix of \f$ V \f$)
1050
1052{
1053 const TMatrixDSym& V = covarianceMatrix() ;
1054
1055 // Handle case where V==Vred here
1056 if (V.GetNcols()==int(params.size())) {
1057 return V ;
1058 }
1059
1060 double det = V.Determinant() ;
1061
1062 if (det<=0) {
1063 coutE(Eval) << "RooFitResult::conditionalCovarianceMatrix(" << GetName() << ") ERROR: covariance matrix is not positive definite (|V|="
1064 << det << ") cannot reduce it" << std::endl ;
1065 throw string("RooFitResult::conditionalCovarianceMatrix() ERROR, input covariance matrix is not positive definite") ;
1066 }
1067
1068 // Make sure that all given params were floating parameters in the represented fit
1069 RooArgList params2 ;
1070 for(RooAbsArg* arg : params) {
1071 if (_finalPars->find(arg->GetName())) {
1072 params2.add(*arg) ;
1073 } else {
1074 coutW(InputArguments) << "RooFitResult::conditionalCovarianceMatrix(" << GetName() << ") WARNING input variable "
1075 << arg->GetName() << " was not a floating parameters in fit result and is ignored" << std::endl ;
1076 }
1077 }
1078
1079 // Need to order params in vector in same order as in covariance matrix
1080 RooArgList params3 ;
1081 for(RooAbsArg* arg : *_finalPars) {
1082 if (params2.find(arg->GetName())) {
1083 params3.add(*arg) ;
1084 }
1085 }
1086
1087 // Find (subset) of parameters that are stored in the covariance matrix
1088 vector<int> map1;
1089 vector<int> map2;
1090 for (std::size_t i=0 ; i<_finalPars->size() ; i++) {
1091 if (params3.find(_finalPars->at(i)->GetName())) {
1092 map1.push_back(i) ;
1093 } else {
1094 map2.push_back(i) ;
1095 }
1096 }
1097
1098 // Rearrange matrix in block form with 'params' first and 'others' last
1099 // (preserving relative order)
1100 TMatrixDSym S11;
1101 TMatrixDSym S22;
1102 TMatrixD S12;
1103 TMatrixD S21;
1104 RooMultiVarGaussian::blockDecompose(V,map1,map2,S11,S12,S21,S22) ;
1105
1106 // Constructed conditional matrix form -1
1107 // F(X1|X2) --> CovI --> S22bar = S11 - S12 S22 S21
1108
1109 // Do eigenvalue decomposition
1110 TMatrixD S22Inv(TMatrixD::kInverted,S22) ;
1111 TMatrixD S22bar = S11 - S12 * (S22Inv * S21) ;
1112
1113 // Convert explicitly to symmetric form
1114 TMatrixDSym Vred(S22bar.GetNcols()) ;
1115 for (int i=0 ; i<Vred.GetNcols() ; i++) {
1116 for (int j=i ; j<Vred.GetNcols() ; j++) {
1117 Vred(i,j) = (S22bar(i,j) + S22bar(j,i))/2 ;
1118 Vred(j,i) = Vred(i,j) ;
1119 }
1120 }
1121
1122 return Vred ;
1123}
1124
1125
1126
1127////////////////////////////////////////////////////////////////////////////////
1128/// Return correlation matrix ;
1129
1131{
1132 return *_CM ;
1133}
1134
1135
1136
1137////////////////////////////////////////////////////////////////////////////////
1138/// Return a p.d.f that represents the fit result as a multi-variate probability densisty
1139/// function on the floating fit parameters, including correlations
1140
1142{
1143 const TMatrixDSym& V = covarianceMatrix() ;
1144 double det = V.Determinant() ;
1145
1146 if (det<=0) {
1147 coutE(Eval) << "RooFitResult::createHessePdf(" << GetName() << ") ERROR: covariance matrix is not positive definite (|V|="
1148 << det << ") cannot construct p.d.f" << std::endl ;
1149 return nullptr ;
1150 }
1151
1152 // Make sure that all given params were floating parameters in the represented fit
1153 RooArgList params2 ;
1154 for(RooAbsArg* arg : params) {
1155 if (_finalPars->find(arg->GetName())) {
1156 params2.add(*arg) ;
1157 } else {
1158 coutW(InputArguments) << "RooFitResult::createHessePdf(" << GetName() << ") WARNING input variable "
1159 << arg->GetName() << " was not a floating parameters in fit result and is ignored" << std::endl ;
1160 }
1161 }
1162
1163 // Need to order params in vector in same order as in covariance matrix
1164 RooArgList params3 ;
1165 for(RooAbsArg* arg : *_finalPars) {
1166 if (params2.find(arg->GetName())) {
1167 params3.add(*arg) ;
1168 }
1169 }
1170
1171
1172 // Handle special case of representing full covariance matrix here
1173 if (params3.size()==_finalPars->size()) {
1174
1175 RooArgList mu ;
1176 for (std::size_t i=0 ; i<_finalPars->size() ; i++) {
1177 RooRealVar* parclone = static_cast<RooRealVar*>(_finalPars->at(i)->Clone(Form("%s_centralvalue",_finalPars->at(i)->GetName()))) ;
1178 parclone->setConstant(true) ;
1179 mu.add(*parclone) ;
1180 }
1181
1182 string name = Form("pdf_%s",GetName()) ;
1183 string title = Form("P.d.f of %s",GetTitle()) ;
1184
1185 // Create p.d.f.
1186 RooAbsPdf* mvg = new RooMultiVarGaussian(name.c_str(),title.c_str(),params3,mu,V) ;
1187 mvg->addOwnedComponents(mu) ;
1188 return mvg ;
1189 }
1190
1191 // -> ->
1192 // Handle case of conditional p.d.f. MVG(p1|p2) here
1193
1194 // Find (subset) of parameters that are stored in the covariance matrix
1195 vector<int> map1;
1196 vector<int> map2;
1197 for (std::size_t i=0 ; i<_finalPars->size() ; i++) {
1198 if (params3.find(_finalPars->at(i)->GetName())) {
1199 map1.push_back(i) ;
1200 } else {
1201 map2.push_back(i) ;
1202 }
1203 }
1204
1205 // Rearrange matrix in block form with 'params' first and 'others' last
1206 // (preserving relative order)
1207 TMatrixDSym S11;
1208 TMatrixDSym S22;
1209 TMatrixD S12;
1210 TMatrixD S21;
1211 RooMultiVarGaussian::blockDecompose(V,map1,map2,S11,S12,S21,S22) ;
1212
1213 // Calculate offset vectors mu1 and mu2
1214 RooArgList mu1 ;
1215 for (UInt_t i=0 ; i<map1.size() ; i++) {
1216 RooRealVar* parclone = static_cast<RooRealVar*>(_finalPars->at(map1[i])->Clone(Form("%s_centralvalue",_finalPars->at(map1[i])->GetName()))) ;
1217 parclone->setConstant(true) ;
1218 mu1.add(*parclone) ;
1219 }
1220
1221 // Constructed conditional matrix form -1
1222 // F(X1|X2) --> CovI --> S22bar = S11 - S12 S22 S21
1223
1224 // Do eigenvalue decomposition
1225 TMatrixD S22Inv(TMatrixD::kInverted,S22) ;
1226 TMatrixD S22bar = S11 - S12 * (S22Inv * S21) ;
1227
1228 // Convert explicitly to symmetric form
1229 TMatrixDSym Vred(S22bar.GetNcols()) ;
1230 for (int i=0 ; i<Vred.GetNcols() ; i++) {
1231 for (int j=i ; j<Vred.GetNcols() ; j++) {
1232 Vred(i,j) = (S22bar(i,j) + S22bar(j,i))/2 ;
1233 Vred(j,i) = Vred(i,j) ;
1234 }
1235 }
1236 string name = Form("pdf_%s",GetName()) ;
1237 string title = Form("P.d.f of %s",GetTitle()) ;
1238
1239 // Create p.d.f.
1240 RooAbsPdf* ret = new RooMultiVarGaussian(name.c_str(),title.c_str(),params3,mu1,Vred) ;
1241 ret->addOwnedComponents(mu1) ;
1242 return ret ;
1243}
1244
1245
1246
1247////////////////////////////////////////////////////////////////////////////////
1248/// Change name of RooFitResult object
1249
1251{
1252 if (_dir) _dir->GetList()->Remove(this);
1254 if (_dir) _dir->GetList()->Add(this);
1255}
1256
1257
1258////////////////////////////////////////////////////////////////////////////////
1259/// Change name and title of RooFitResult object
1260
1261void RooFitResult::SetNameTitle(const char *name, const char* title)
1262{
1263 if (_dir) _dir->GetList()->Remove(this);
1264 TNamed::SetNameTitle(name,title) ;
1265 if (_dir) _dir->GetList()->Add(this);
1266}
1267
1268
1269////////////////////////////////////////////////////////////////////////////////
1270/// Print name of fit result
1271
1272void RooFitResult::printName(ostream& os) const
1273{
1274 os << GetName() ;
1275}
1276
1277
1278////////////////////////////////////////////////////////////////////////////////
1279/// Print title of fit result
1280
1281void RooFitResult::printTitle(ostream& os) const
1282{
1283 os << GetTitle() ;
1284}
1285
1286
1287////////////////////////////////////////////////////////////////////////////////
1288/// Print class name of fit result
1289
1290void RooFitResult::printClassName(ostream& os) const
1291{
1292 os << ClassName() ;
1293}
1294
1295
1296////////////////////////////////////////////////////////////////////////////////
1297/// Print arguments of fit result, i.e. the parameters of the fit
1298
1299void RooFitResult::printArgs(ostream& os) const
1300{
1301 os << "[constPars=" << *_constPars << ",floatPars=" << *_finalPars << "]" ;
1302}
1303
1304
1305
1306////////////////////////////////////////////////////////////////////////////////
1307/// Print the value of the fit result, i.e.g the status, minimized FCN, edm and covariance quality code
1308
1309void RooFitResult::printValue(ostream& os) const
1310{
1311 os << "(status=" << _status << ",FCNmin=" << _minNLL << ",EDM=" << _edm << ",covQual=" << _covQual << ")" ;
1312}
1313
1314
1315////////////////////////////////////////////////////////////////////////////////
1316/// Configure default contents to be printed
1317
1322
1323
1324////////////////////////////////////////////////////////////////////////////////
1325/// Configure mapping of Print() arguments to RooPrintable print styles
1326
1328{
1329 if (!opt || strlen(opt)==0) {
1330 return kStandard ;
1331 }
1333}
1334
1335
1336////////////////////////////////////////////////////////////////////////////////
1337/// Stream an object of class RooFitResult.
1338
1340{
1341 if (R__b.IsReading()) {
1342 UInt_t R__s;
1343 UInt_t R__c;
1344 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
1345 if (R__v>3) {
1346 R__b.ReadClassBuffer(RooFitResult::Class(),this,R__v,R__s,R__c);
1349 } else {
1350 // backward compatibitily streaming
1351 TNamed::Streamer(R__b);
1354 R__b >> _status;
1355 R__b >> _covQual;
1356 R__b >> _numBadNLL;
1357 R__b >> _minNLL;
1358 R__b >> _edm;
1359 R__b >> _constPars;
1360 R__b >> _initPars;
1361 R__b >> _finalPars;
1363 R__b >> globalCorr;
1364 _globalCorr.reset(globalCorr);
1365 _corrMatrix.Streamer(R__b);
1366 R__b.CheckByteCount(R__s, R__c, RooFitResult::IsA());
1367
1368 // Now fill new-style covariance and correlation matrix information
1369 // from legacy form
1370 _CM = new TMatrixDSym(_finalPars->size()) ;
1371 _VM = new TMatrixDSym(_CM->GetNcols()) ;
1372 _GC = new TVectorD(_CM->GetNcols()) ;
1373
1374 for (unsigned int i = 0; i < (unsigned int)_CM->GetNcols() ; ++i) {
1375
1376 // Find the next global correlation slot to fill, skipping fixed parameters
1377 auto& gcVal = static_cast<RooRealVar&>((*_globalCorr)[i]);
1378 (*_GC)(i) = gcVal.getVal() ;
1379
1380 // Fill a row of the correlation matrix
1381 auto corrMatrixCol = static_cast<RooArgList const&>(*_corrMatrix.At(i));
1382 for (unsigned int it = 0; it < (unsigned int)_CM->GetNcols() ; ++it) {
1383 auto& cVal = static_cast<RooRealVar&>(corrMatrixCol[it]);
1384 double value = cVal.getVal() ;
1385 (*_CM)(it,i) = value ;
1386 (*_CM)(i,it) = value;
1387 (*_VM)(it,i) = value*(static_cast<RooRealVar*>(_finalPars->at(i)))->getError()*(static_cast<RooRealVar*>(_finalPars->at(it)))->getError() ;
1388 (*_VM)(i,it) = (*_VM)(it,i) ;
1389 }
1390 }
1391 }
1392
1393 } else {
1394 R__b.WriteClassBuffer(RooFitResult::Class(),this);
1395 }
1396}
1397
#define g(i)
Definition RSha256.hxx:105
#define s1(x)
Definition RSha256.hxx:91
#define e(i)
Definition RSha256.hxx:103
#define coutI(a)
#define coutW(a)
#define oocoutE(o, a)
#define coutE(a)
short Version_t
Class version identifier (short)
Definition RtypesCore.h:80
const char Option_t
Option string (const char)
Definition RtypesCore.h:81
@ kRed
Definition Rtypes.h:66
@ kBlack
Definition Rtypes.h:65
@ kBlue
Definition Rtypes.h:66
@ kDashed
Definition TAttLine.h:54
static void indent(ostringstream &buf, int indent_level)
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
char name[80]
Definition TGX11.cxx:142
TMatrixTSym< Double_t > TMatrixDSym
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2571
TVectorT< Double_t > TVectorD
Definition TVectorDfwd.h:23
TVectorT< Float_t > TVector
Definition TVectorfwd.h:23
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:77
static void ioStreamerPass2Finalize()
Method called by workspace container to finalize schema evolution issues that cannot be handled in a ...
TObject * Clone(const char *newname=nullptr) const override
Make a clone of an object using the Streamer facility.
Definition RooAbsArg.h:89
RooAbsCollection * snapshot(bool deepCopy=true) const
Take a snap shot of current collection contents.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
Int_t index(const RooAbsArg *arg) const
Returns index of given arg, or -1 if arg is not in the collection.
Storage_t::size_type size() const
virtual RooAbsArg * addClone(const RooAbsArg &var, bool silent=false)
Add a clone of the specified argument to list.
RooAbsArg * find(const char *name) const
Find object with given name in list.
Abstract interface for all probability density functions.
Definition RooAbsPdf.h:32
void setConstant(bool value=true)
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:63
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:107
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition RooArgList.h:22
RooAbsArg * at(Int_t idx) const
Return object at given index, or nullptr if index is out of range.
Definition RooArgList.h:110
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:24
Utility base class for RooFit objects that are to be attached to ROOT directories.
Definition RooDirItem.h:22
virtual void Streamer(TBuffer &)
void removeFromDir(TObject *obj)
Remove object from directory it was added to.
TDirectory * _dir
! Associated directory
Definition RooDirItem.h:33
Two-dimensional ellipse that can be used to represent an error contour.
Definition RooEllipse.h:22
RooFitResult is a container class to hold the input and output of a PDF fit to a dataset.
TMatrixDSym conditionalCovarianceMatrix(const RooArgList &params) const
Return a reduced covariance matrix, which is calculated as.
double correlation(const RooAbsArg &par1, const RooAbsArg &par2) const
Return correlation between par1 and par2.
std::unique_ptr< RooArgList > _randomPars
! List of floating parameters with most recent random perturbation applied
~RooFitResult() override
Destructor.
TList _corrMatrix
! Correlation matrix (list of RooArgLists)
std::vector< std::pair< std::string, int > > _statusHistory
History of status codes.
const TMatrixDSym & covarianceMatrix() const
Return covariance matrix.
TMatrixDSym * _CM
Correlation matrix.
bool isIdentical(const RooFitResult &other, double tol=1e-6, double tolCorr=1e-4, bool verbose=true) const
Return true if this fit result is identical to other within tolerances.
void setConstParList(const RooArgList &list)
Fill the list of constant parameters.
Int_t statusCodeHistory(UInt_t icycle) const
void fillGlobalCorr() const
Compute the global correlation coefficients from the correlation matrix if they are not available yet...
void fillCorrMatrix(const std::vector< double > &globalCC, const TMatrixDSym &corrs, const TMatrixDSym &covs)
Function called by RooMinimizer.
double _minNLL
NLL at minimum.
Int_t _numBadNLL
Number calls with bad (zero,negative) likelihood.
TMatrixDSym * _VM
Covariance matrix.
void SetNameTitle(const char *name, const char *title) override
Change name and title of RooFitResult object.
Int_t defaultPrintContents(Option_t *opt) const override
Configure default contents to be printed.
void printClassName(std::ostream &os) const override
Print class name of fit result.
RooArgList * _initPars
List of floating parameters with initial values.
TClass * IsA() const override
RooFitResult(const char *name=nullptr, const char *title=nullptr)
Constructor with name and title.
TMatrixDSym reducedCovarianceMatrix(const RooArgList &params) const
Return a reduced covariance matrix (Note that Vred is a simple sub-matrix of V, row/columns are order...
Int_t _covQual
MINUIT quality code of covariance matrix.
void fillPrefitCorrMatrix()
RooArgList * _constPars
List of constant parameters.
const RooArgList & randomizePars() const
Generate random perturbations of the final parameters using the covariance matrix.
std::unique_ptr< TMatrixF > _Lt
! triangular matrix used for generate random perturbations
const RooArgList * globalCorr()
Return the list of all global correlations.
static RooFitResult * prefitResult(const RooArgList &paramList)
Import the results of the last fit performed by gMinuit, interpreting the fit parameters as the given...
void setCovarianceMatrix(TMatrixDSym &V)
Store externally provided correlation matrix in this RooFitResult ;.
RooArgList * _finalPars
List of floating parameters with final values.
const RooArgList & constPars() const
Return list of constant parameters.
Int_t _status
MINUIT status code.
bool isIdenticalNoCov(const RooFitResult &other, double tol=1e-6, double tolErr=1e-3, bool verbose=true) const
Return true if this fit result is identical to other within tolerances, ignoring the correlation matr...
void SetName(const char *name) override
Change name of RooFitResult object.
std::unique_ptr< RooArgList > _globalCorr
! List of global correlation coefficients
const char * statusLabelHistory(UInt_t icycle) const
static TClass * Class()
void printValue(std::ostream &os) const override
Print the value of the fit result, i.e.g the status, minimized FCN, edm and covariance quality code.
void printTitle(std::ostream &os) const override
Print title of fit result.
TH2 * correlationHist(const char *name="correlation_matrix") const
Return TH2D of correlation matrix.
void fillLegacyCorrMatrix() const
Sanity check.
void setInitParList(const RooArgList &list)
Fill the list of initial values of the floating parameters.
RooPlot * plotOn(RooPlot *frame, const RooAbsArg &par1, const RooAbsArg &par2, const char *options="ME") const
Add objects to a 2D plot.
void Streamer(TBuffer &) override
Stream an object of class RooFitResult.
StyleOption defaultPrintStyle(Option_t *opt) const override
Configure mapping of Print() arguments to RooPrintable print styles.
double covariance(Int_t row, Int_t col) const
Return the covariance matrix element addressed with numeric indices.
const RooArgList & floatParsFinal() const
Return list of floating parameters after fit.
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Print fit result to stream 'os'.
TVectorD * _GC
Global correlation coefficients, computed on demand if not set.
RooAbsPdf * createHessePdf(const RooArgSet &params) const
Return a p.d.f that represents the fit result as a multi-variate probability densisty function on the...
double _edm
Estimated distance to minimum.
void setFinalParList(const RooArgList &list)
Fill the list of final values of the floating parameters.
void printArgs(std::ostream &os) const override
Print arguments of fit result, i.e. the parameters of the fit.
void printName(std::ostream &os) const override
Print name of fit result.
const TMatrixDSym & correlationMatrix() const
Return correlation matrix ;.
Multivariate Gaussian p.d.f.
static void blockDecompose(const TMatrixD &input, const std::vector< int > &map1, const std::vector< int > &map2, TMatrixDSym &S11, TMatrixD &S12, TMatrixD &S21, TMatrixDSym &S22)
Block decomposition of covI according to given maps of observables.
Plot frame and a container for graphics objects within that frame.
Definition RooPlot.h:43
void addObject(TObject *obj, Option_t *drawOptions="", bool invisible=false)
Add a generic object to this plot.
Definition RooPlot.cxx:326
void addPlotable(RooPlotable *plotable, Option_t *drawOptions="", bool invisible=false, bool refreshNorm=false)
Add the specified plotable object to our plot.
Definition RooPlot.cxx:476
A 'mix-in' base class that define the standard RooFit plotting and printing methods.
virtual StyleOption defaultPrintStyle(Option_t *opt) const
virtual void Streamer(TBuffer &)
virtual void printValue(std::ostream &os) const
Interface to print value of object.
static double gaussian(TRandom *generator=randomGenerator())
Return a Gaussian random variable with mean 0 and variance 1.
Variable that can be changed from the outside.
Definition RooRealVar.h:37
void setVal(double value) override
Set value of variable to 'value'.
bool hasAsymError(bool allowZero=true) const
Definition RooRealVar.h:65
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition TAttLine.h:46
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition TAttLine.h:47
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition TAttLine.h:44
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Create a Box.
Definition TBox.h:22
Buffer base class used for serializing objects.
Definition TBuffer.h:43
virtual void RemoveAll(TCollection *col)
Remove all objects in collection col from this collection.
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
virtual TList * GetList() const
Definition TDirectory.h:223
The axis painter class.
Definition TGaxis.h:26
2-D histogram with a double per channel (see TH1 documentation)
Definition TH2.h:400
Service class for 2-D histogram classes.
Definition TH2.h:30
Use the TLine constructor to create a simple line.
Definition TLine.h:22
void Streamer(TBuffer &) override
Stream all objects in the collection to or from the I/O buffer.
Definition TList.cxx:1323
void Add(TObject *obj) override
Definition TList.h:81
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:600
TObject * At(Int_t idx) const override
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx:487
Manages Markers.
Definition TMarker.h:22
Int_t GetNrows() const
Int_t GetNcols() const
TMatrixT.
Definition TMatrixT.h:40
@ kTransposed
Definition TMatrixT.h:59
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
void Streamer(TBuffer &) override
Stream an object of class TObject.
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:149
virtual void SetNameTitle(const char *name, const char *title)
Set all the TNamed parameters (name and title).
Definition TNamed.cxx:163
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition TObject.cxx:242
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:226
Basic string class.
Definition TString.h:137
void ToUpper()
Change string to upper case.
Definition TString.cxx:1203
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2460
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:642
TLine * line
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition fillpatterns.C:1
const Int_t n
Definition legend1.C:16