Logo ROOT  
Reference Guide
RooMinimizer.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 * AL, Alfio Lazzaro, INFN Milan, alfio.lazzaro@mi.infn.it *
9 * PB, Patrick Bos, NL eScience Center, p.bos@esciencecenter.nl *
10 * *
11 * Redistribution and use in source and binary forms, *
12 * with or without modification, are permitted according to the terms *
13 * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
14 *****************************************************************************/
15
16/**
17\file RooMinimizer.cxx
18\class RooMinimizer
19\ingroup Roofitcore
20
21RooMinimizer is a wrapper class around ROOT::Fit:Fitter that
22provides a seamless interface between the minimizer functionality
23and the native RooFit interface.
24By default the Minimizer is MINUIT for classic mode and MINUIT2
25for parallelized mode (activated with the `RooFit::NewStyle(true)`
26parameter or by passing a RooRealL function as the minimization
27target).
28RooMinimizer can minimize any RooAbsReal function with respect to
29its parameters. Usual choices for minimization are RooNLLVar
30and RooChi2Var
31RooMinimizer has methods corresponding to MINUIT functions like
32hesse(), migrad(), minos() etc. In each of these function calls
33the state of the MINUIT engine is synchronized with the state
34of the RooFit variables: any change in variables, change
35in the constant status etc is forwarded to MINUIT prior to
36execution of the MINUIT call. Afterwards the RooFit objects
37are resynchronized with the output state of MINUIT: changes
38parameter values, errors are propagated.
39Various methods are available to control verbosity, profiling,
40automatic PDF optimization.
41**/
42
43#include "RooMinimizer.h"
44
45#include "RooAbsMinimizerFcn.h"
46#include "RooArgSet.h"
47#include "RooArgList.h"
48#include "RooAbsReal.h"
49#include "RooDataSet.h"
50#include "RooRealVar.h"
51#include "RooSentinel.h"
52#include "RooMsgService.h"
53#include "RooPlot.h"
54#include "RooMinimizerFcn.h"
55#include "RooFitResult.h"
59#ifdef R__HAS_ROOFIT_MULTIPROCESS
61#endif
62
63#include "TClass.h"
64#include "Math/Minimizer.h"
65#include "TMarker.h"
66#include "TGraph.h"
67#include "Fit/FitConfig.h"
68
69#include <fstream>
70#include <iostream>
71#include <stdexcept> // logic_error
72
73using namespace std;
74
76;
77
78std::unique_ptr<ROOT::Fit::Fitter> RooMinimizer::_theFitter = {};
79
80////////////////////////////////////////////////////////////////////////////////
81/// Cleanup method called by atexit handler installed by RooSentinel
82/// to delete all global heap objects when the program is terminated
83
85{
86 _theFitter.reset();
87}
88
89////////////////////////////////////////////////////////////////////////////////
90/// Construct MINUIT interface to given function. Function can be anything,
91/// but is typically a -log(likelihood) implemented by RooNLLVar or a chi^2
92/// (implemented by RooChi2Var). Other frequent use cases are a RooAddition
93/// of a RooNLLVar plus a penalty or constraint term. This class propagates
94/// all RooFit information (floating parameters, their values and errors)
95/// to MINUIT before each MINUIT call and propagates all MINUIT information
96/// back to the RooFit object at the end of each call (updated parameter
97/// values, their (asymmetric errors) etc. The default MINUIT error level
98/// for HESSE and MINOS error analysis is taken from the defaultErrorLevel()
99/// value of the input function.
100
101/// Constructor that accepts all configuration in struct with RooAbsReal likelihood
103{
105 auto nll_real = dynamic_cast<RooFit::TestStatistics::RooRealL *>(&function);
106 if (nll_real != nullptr) {
107 if (_cfg.parallelGradient || _cfg.parallelLikelihood) { // new test statistic with multiprocessing library with
108 // parallel likelihood or parallel gradient
109#ifdef R__HAS_ROOFIT_MULTIPROCESS
110 if (!_cfg.parallelGradient) {
111 // Note that this is necessary because there is currently no serial-mode LikelihoodGradientWrapper.
112 // We intend to repurpose RooGradMinimizerFcn to build such a LikelihoodGradientSerial class.
113 coutI(InputArguments) << "New style likelihood detected and likelihood parallelization requested, "
114 << "also setting parallel gradient calculation mode." << std::endl;
115 }
116 _fcn = std::make_unique<RooFit::TestStatistics::MinuitFcnGrad>(
117 nll_real->getRooAbsL(), this, _theFitter->Config().ParamsSettings(),
119 static_cast<RooFit::TestStatistics::LikelihoodMode>(int(_cfg.parallelLikelihood))},
121#else
122 throw std::logic_error(
123 "Parallel likelihood or gradient evaluation requested, but ROOT was not compiled with multiprocessing enabled, "
124 "please recompile with -Droofit_multiprocess=ON for parallel evaluation");
125#endif
126 } else { // new test statistic non parallel
127 coutW(InputArguments) << "Requested new-style likelihood without gradient parallelization, some features such as offsetting "
128 << "may not work yet. Old-style likelihoods are more reliable without parallelization."
129 << std::endl;
130 // The RooRealL that is used in the case where the new style likelihood is being passed to a RooMinimizerFcn does not have
131 // offsetting implemented. Therefore, offsetting will not work in this case. Other features might also not work since the
132 // RooRealL was not intended for minimization. Further development is required to make the MinuitFcnGrad also handle serial gradient
133 // minimization. The MinuitFcnGrad accepts a RooAbsL and has offsetting implemented, thus omitting the need for RooRealL
134 // minimization altogether.
135 _fcn = std::make_unique<RooMinimizerFcn>(&function, this);
136 }
137 } else {
138 if (_cfg.parallelLikelihood || _cfg.parallelGradient) { // Old test statistic with parallel likelihood or gradient
139 throw std::logic_error("In RooMinimizer constructor: Selected likelihood evaluation but an "
140 "old-style likelihood was given. Please supply NewStyle(true) as an "
141 "argument to createNLL for new-style likelihoods to use likelihood "
142 "or gradient parallelization.");
143 }
144 _fcn = std::make_unique<RooMinimizerFcn>(&function, this);
145 }
146 initMinimizerFcnDependentPart(function.defaultErrorLevel());
147};
148
149/// Initialize the part of the minimizer that is independent of the function to be minimized
151{
154
155 _theFitter = std::make_unique<ROOT::Fit::Fitter>();
156 _theFitter->Config().SetMinimizer(_cfg.minimizerType.c_str());
157 setEps(1.0); // default tolerance
158}
159
160/// Initialize the part of the minimizer that is dependent on the function to be minimized
162{
163 // default max number of calls
164 _theFitter->Config().MinimizerOptions().SetMaxIterations(500 * _fcn->getNDim());
165 _theFitter->Config().MinimizerOptions().SetMaxFunctionCalls(500 * _fcn->getNDim());
166
167 // Shut up for now
168 setPrintLevel(-1);
169
170 // Use +0.5 for 1-sigma errors
171 setErrorLevel(defaultErrorLevel);
172
173 // Declare our parameters to MINUIT
174 _fcn->Synchronize(_theFitter->Config().ParamsSettings());
175
176 // Now set default verbosity
177 if (RooMsgService::instance().silentMode()) {
178 setPrintLevel(-1);
179 } else {
180 setPrintLevel(1);
181 }
182
183 // Set user defined and default _fcn config
185
186 // Likelihood holds information on offsetting in old style, so do not set here unless explicitly set by user
187 if (_cfg.offsetting != -1) {
189 }
190}
191
192////////////////////////////////////////////////////////////////////////////////
193/// Destructor
194
196
197////////////////////////////////////////////////////////////////////////////////
198/// Change MINUIT strategy to istrat. Accepted codes
199/// are 0,1,2 and represent MINUIT strategies for dealing
200/// most efficiently with fast FCNs (0), expensive FCNs (2)
201/// and 'intermediate' FCNs (1)
202
204{
205 _theFitter->Config().MinimizerOptions().SetStrategy(istrat);
206}
207
208////////////////////////////////////////////////////////////////////////////////
209/// Change maximum number of MINUIT iterations
210/// (RooMinimizer default 500 * #%parameters)
211
213{
214 _theFitter->Config().MinimizerOptions().SetMaxIterations(n);
215}
216
217////////////////////////////////////////////////////////////////////////////////
218/// Change maximum number of likelihood function calss from MINUIT
219/// (RooMinimizer default 500 * #%parameters)
220
222{
223 _theFitter->Config().MinimizerOptions().SetMaxFunctionCalls(n);
224}
225
226////////////////////////////////////////////////////////////////////////////////
227/// Set the level for MINUIT error analysis to the given
228/// value. This function overrides the default value
229/// that is taken in the RooMinimizer constructor from
230/// the defaultErrorLevel() method of the input function
231
233{
234 _theFitter->Config().MinimizerOptions().SetErrorDef(level);
235}
236
237////////////////////////////////////////////////////////////////////////////////
238/// Change MINUIT epsilon
239
240void RooMinimizer::setEps(double eps)
241{
242 _theFitter->Config().MinimizerOptions().SetTolerance(eps);
243}
244
245////////////////////////////////////////////////////////////////////////////////
246/// Enable internal likelihood offsetting for enhanced numeric precision
247
249{
250 _cfg.offsetting = flag;
251 _fcn->setOffsetting(_cfg.offsetting);
252}
253
254////////////////////////////////////////////////////////////////////////////////
255/// Choose the minimizer algorithm.
256///
257/// Passing an empty string selects the default minimizer type returned by
258/// ROOT::Math::MinimizerOptions::DefaultMinimizerType().
259
260void RooMinimizer::setMinimizerType(std::string const &type)
261{
263
265 std::stringstream ss;
266 ss << "In RooMinimizer::setMinimizerType: only Minuit2 is supported when not using classic function mode!";
267 if (type.empty()) {
268 ss << "\nPlease set it as your default minimizer via "
269 "ROOT::Math::MinimizerOptions::SetDefaultMinimizer(\"Minuit2\").";
270 }
271 throw std::invalid_argument(ss.str());
272 }
273}
274
275////////////////////////////////////////////////////////////////////////////////
276/// Return underlying ROOT fitter object
277
279{
280 return _theFitter.get();
281}
282
283////////////////////////////////////////////////////////////////////////////////
284/// Return underlying ROOT fitter object
285
287{
288 return _theFitter.get();
289}
290
292{
293 return _fcn->fit(*_theFitter);
294}
295
296////////////////////////////////////////////////////////////////////////////////
297/// Minimise the function passed in the constructor.
298/// \param[in] type Type of fitter to use, e.g. "Minuit" "Minuit2". Passing an
299/// empty string will select the default minimizer type of the
300/// RooMinimizer, as returned by
301/// ROOT::Math::MinimizerOptions::DefaultMinimizerType().
302/// \attention This overrides the default fitter of this RooMinimizer.
303/// \param[in] alg Fit algorithm to use. (Optional)
304int RooMinimizer::minimize(const char *type, const char *alg)
305{
306 _fcn->Synchronize(_theFitter->Config().ParamsSettings());
307
309 _theFitter->Config().SetMinimizer(type, alg);
310
311 profileStart();
314
315 bool ret = fitFcn();
316 _status = ((ret) ? _theFitter->Result().Status() : -1);
317
319 profileStop();
320 _fcn->BackProp(_theFitter->Result());
321
322 saveStatus("MINIMIZE", _status);
323
324 return _status;
325}
326
327////////////////////////////////////////////////////////////////////////////////
328/// Execute MIGRAD. Changes in parameter values
329/// and calculated errors are automatically
330/// propagated back the RooRealVars representing
331/// the floating parameters in the MINUIT operation.
332
334{
335 _fcn->Synchronize(_theFitter->Config().ParamsSettings());
336 profileStart();
339
340 _theFitter->Config().SetMinimizer(_cfg.minimizerType.c_str(), "migrad");
341 bool ret = fitFcn();
342 _status = ((ret) ? _theFitter->Result().Status() : -1);
343
345 profileStop();
346 _fcn->BackProp(_theFitter->Result());
347
348 saveStatus("MIGRAD", _status);
349
350 return _status;
351}
352
353////////////////////////////////////////////////////////////////////////////////
354/// Execute HESSE. Changes in parameter values
355/// and calculated errors are automatically
356/// propagated back the RooRealVars representing
357/// the floating parameters in the MINUIT operation.
358
360{
361 if (_theFitter->GetMinimizer() == 0) {
362 coutW(Minimization) << "RooMinimizer::hesse: Error, run Migrad before Hesse!" << endl;
363 _status = -1;
364 } else {
365
366 _fcn->Synchronize(_theFitter->Config().ParamsSettings());
367 profileStart();
370
371 _theFitter->Config().SetMinimizer(_cfg.minimizerType.c_str());
372 bool ret = _theFitter->CalculateHessErrors();
373 _status = ((ret) ? _theFitter->Result().Status() : -1);
374
376 profileStop();
377 _fcn->BackProp(_theFitter->Result());
378
379 saveStatus("HESSE", _status);
380 }
381
382 return _status;
383}
384
385////////////////////////////////////////////////////////////////////////////////
386/// Execute MINOS. Changes in parameter values
387/// and calculated errors are automatically
388/// propagated back the RooRealVars representing
389/// the floating parameters in the MINUIT operation.
390
392{
393 if (_theFitter->GetMinimizer() == 0) {
394 coutW(Minimization) << "RooMinimizer::minos: Error, run Migrad before Minos!" << endl;
395 _status = -1;
396 } else {
397
398 _fcn->Synchronize(_theFitter->Config().ParamsSettings());
399 profileStart();
402
403 _theFitter->Config().SetMinimizer(_cfg.minimizerType.c_str());
404 bool ret = _theFitter->CalculateMinosErrors();
405 _status = ((ret) ? _theFitter->Result().Status() : -1);
406
408 profileStop();
409 _fcn->BackProp(_theFitter->Result());
410
411 saveStatus("MINOS", _status);
412 }
413
414 return _status;
415}
416
417////////////////////////////////////////////////////////////////////////////////
418/// Execute MINOS for given list of parameters. Changes in parameter values
419/// and calculated errors are automatically
420/// propagated back the RooRealVars representing
421/// the floating parameters in the MINUIT operation.
422
423int RooMinimizer::minos(const RooArgSet &minosParamList)
424{
425 if (_theFitter->GetMinimizer() == 0) {
426 coutW(Minimization) << "RooMinimizer::minos: Error, run Migrad before Minos!" << endl;
427 _status = -1;
428 } else if (!minosParamList.empty()) {
429
430 _fcn->Synchronize(_theFitter->Config().ParamsSettings());
431 profileStart();
434
435 // get list of parameters for Minos
436 std::vector<unsigned int> paramInd;
437 for (RooAbsArg *arg : minosParamList) {
438 RooAbsArg *par = _fcn->GetFloatParamList()->find(arg->GetName());
439 if (par && !par->isConstant()) {
440 int index = _fcn->GetFloatParamList()->index(par);
441 paramInd.push_back(index);
442 }
443 }
444
445 if (paramInd.size()) {
446 // set the parameter indeces
447 _theFitter->Config().SetMinosErrors(paramInd);
448
449 _theFitter->Config().SetMinimizer(_cfg.minimizerType.c_str());
450 bool ret = _theFitter->CalculateMinosErrors();
451 _status = ((ret) ? _theFitter->Result().Status() : -1);
452 // to avoid that following minimization computes automatically the Minos errors
453 _theFitter->Config().SetMinosErrors(false);
454 }
455
457 profileStop();
458 _fcn->BackProp(_theFitter->Result());
459
460 saveStatus("MINOS", _status);
461 }
462
463 return _status;
464}
465
466////////////////////////////////////////////////////////////////////////////////
467/// Execute SEEK. Changes in parameter values
468/// and calculated errors are automatically
469/// propagated back the RooRealVars representing
470/// the floating parameters in the MINUIT operation.
471
473{
474 _fcn->Synchronize(_theFitter->Config().ParamsSettings());
475 profileStart();
478
479 _theFitter->Config().SetMinimizer(_cfg.minimizerType.c_str(), "seek");
480 bool ret = fitFcn();
481 _status = ((ret) ? _theFitter->Result().Status() : -1);
482
484 profileStop();
485 _fcn->BackProp(_theFitter->Result());
486
487 saveStatus("SEEK", _status);
488
489 return _status;
490}
491
492////////////////////////////////////////////////////////////////////////////////
493/// Execute SIMPLEX. Changes in parameter values
494/// and calculated errors are automatically
495/// propagated back the RooRealVars representing
496/// the floating parameters in the MINUIT operation.
497
499{
500 _fcn->Synchronize(_theFitter->Config().ParamsSettings());
501 profileStart();
504
505 _theFitter->Config().SetMinimizer(_cfg.minimizerType.c_str(), "simplex");
506 bool ret = fitFcn();
507 _status = ((ret) ? _theFitter->Result().Status() : -1);
508
510 profileStop();
511 _fcn->BackProp(_theFitter->Result());
512
513 saveStatus("SEEK", _status);
514
515 return _status;
516}
517
518////////////////////////////////////////////////////////////////////////////////
519/// Execute IMPROVE. Changes in parameter values
520/// and calculated errors are automatically
521/// propagated back the RooRealVars representing
522/// the floating parameters in the MINUIT operation.
523
525{
526 _fcn->Synchronize(_theFitter->Config().ParamsSettings());
527 profileStart();
530
531 _theFitter->Config().SetMinimizer(_cfg.minimizerType.c_str(), "migradimproved");
532 bool ret = fitFcn();
533 _status = ((ret) ? _theFitter->Result().Status() : -1);
534
536 profileStop();
537 _fcn->BackProp(_theFitter->Result());
538
539 saveStatus("IMPROVE", _status);
540
541 return _status;
542}
543
544////////////////////////////////////////////////////////////////////////////////
545/// Change the MINUIT internal printing level
546
548{
549 _theFitter->Config().MinimizerOptions().SetPrintLevel(newLevel + 1);
550}
551
552////////////////////////////////////////////////////////////////////////////////
553/// Get the MINUIT internal printing level
554
556{
557 return _theFitter->Config().MinimizerOptions().PrintLevel() + 1;
558}
559
560////////////////////////////////////////////////////////////////////////////////
561/// If flag is true, perform constant term optimization on
562/// function being minimized.
563
565{
566 _fcn->setOptimizeConst(flag);
567}
568
569////////////////////////////////////////////////////////////////////////////////
570/// Save and return a RooFitResult snapshot of current minimizer status.
571/// This snapshot contains the values of all constant parameters,
572/// the value of all floating parameters at RooMinimizer construction and
573/// after the last MINUIT operation, the MINUIT status, variance quality,
574/// EDM setting, number of calls with evaluation problems, the minimized
575/// function value and the full correlation matrix.
576
577RooFitResult *RooMinimizer::save(const char *userName, const char *userTitle)
578{
579 if (_theFitter->GetMinimizer() == 0) {
580 coutW(Minimization) << "RooMinimizer::save: Error, run minimization before!" << endl;
581 return nullptr;
582 }
583
584 TString name, title;
585 name = userName ? userName : Form("%s", _fcn->getFunctionName().c_str());
586 title = userTitle ? userTitle : Form("%s", _fcn->getFunctionTitle().c_str());
587 RooFitResult *fitRes = new RooFitResult(name, title);
588
589 // Move eventual fixed parameters in floatList to constList
590 RooArgList saveConstList(*(_fcn->GetConstParamList()));
591 RooArgList saveFloatInitList(*(_fcn->GetInitFloatParamList()));
592 RooArgList saveFloatFinalList(*(_fcn->GetFloatParamList()));
593 for (std::size_t i = 0; i < _fcn->GetFloatParamList()->size(); i++) {
594 RooAbsArg *par = _fcn->GetFloatParamList()->at(i);
595 if (par->isConstant()) {
596 saveFloatInitList.remove(*saveFloatInitList.find(par->GetName()), true);
597 saveFloatFinalList.remove(*par);
598 saveConstList.add(*par);
599 }
600 }
601 saveConstList.sort();
602
603 fitRes->setConstParList(saveConstList);
604 fitRes->setInitParList(saveFloatInitList);
605
606 // The fitter often clones the function. We therefore have to ask it for its copy.
607 const auto fitFcn = dynamic_cast<const RooAbsMinimizerFcn *>(_theFitter->GetFCN());
608 double removeOffset = 0.;
609 if (fitFcn) {
610 fitRes->setNumInvalidNLL(fitFcn->GetNumInvalidNLL());
611 removeOffset = -fitFcn->getOffset();
612 }
613
614 fitRes->setStatus(_status);
615 fitRes->setCovQual(_theFitter->GetMinimizer()->CovMatrixStatus());
616 fitRes->setMinNLL(_theFitter->Result().MinFcnValue() + removeOffset);
617 fitRes->setEDM(_theFitter->Result().Edm());
618 fitRes->setFinalParList(saveFloatFinalList);
619 if (!_extV) {
620 std::vector<double> globalCC;
621 TMatrixDSym corrs(_theFitter->Result().Parameters().size());
622 TMatrixDSym covs(_theFitter->Result().Parameters().size());
623 for (std::size_t ic = 0; ic < _theFitter->Result().Parameters().size(); ic++) {
624 globalCC.push_back(_theFitter->Result().GlobalCC(ic));
625 for (std::size_t ii = 0; ii < _theFitter->Result().Parameters().size(); ii++) {
626 corrs(ic, ii) = _theFitter->Result().Correlation(ic, ii);
627 covs(ic, ii) = _theFitter->Result().CovMatrix(ic, ii);
628 }
629 }
630 fitRes->fillCorrMatrix(globalCC, corrs, covs);
631 } else {
632 fitRes->setCovarianceMatrix(*_extV);
633 }
634
636
637 return fitRes;
638}
639
640////////////////////////////////////////////////////////////////////////////////
641/// Create and draw a TH2 with the error contours in the parameters `var1` and `var2`.
642/// \param[in] var1 The first parameter (x axis).
643/// \param[in] var2 The second parameter (y axis).
644/// \param[in] n1 First contour.
645/// \param[in] n2 Optional contour. 0 means don't draw.
646/// \param[in] n3 Optional contour. 0 means don't draw.
647/// \param[in] n4 Optional contour. 0 means don't draw.
648/// \param[in] n5 Optional contour. 0 means don't draw.
649/// \param[in] n6 Optional contour. 0 means don't draw.
650/// \param[in] npoints Number of points for evaluating the contour.
651///
652/// Up to six contours can be drawn using the arguments `n1` to `n6` to request the desired
653/// coverage in units of \f$ \sigma = n^2 \cdot \mathrm{ErrorDef} \f$.
654/// See ROOT::Math::Minimizer::ErrorDef().
655
656RooPlot *RooMinimizer::contour(RooRealVar &var1, RooRealVar &var2, double n1, double n2, double n3, double n4,
657 double n5, double n6, unsigned int npoints)
658{
659 RooArgList *params = _fcn->GetFloatParamList();
660 std::unique_ptr<RooArgList> paramSave{static_cast<RooArgList *>(params->snapshot())};
661
662 // Verify that both variables are floating parameters of PDF
663 int index1 = _fcn->GetFloatParamList()->index(&var1);
664 if (index1 < 0) {
665 coutE(Minimization) << "RooMinimizer::contour(" << GetName() << ") ERROR: " << var1.GetName()
666 << " is not a floating parameter of " << _fcn->getFunctionName() << endl;
667 return nullptr;
668 }
669
670 int index2 = _fcn->GetFloatParamList()->index(&var2);
671 if (index2 < 0) {
672 coutE(Minimization) << "RooMinimizer::contour(" << GetName() << ") ERROR: " << var2.GetName()
673 << " is not a floating parameter of PDF " << _fcn->getFunctionName() << endl;
674 return nullptr;
675 }
676
677 // create and draw a frame
678 RooPlot *frame = new RooPlot(var1, var2);
679
680 // draw a point at the current parameter values
681 TMarker *point = new TMarker(var1.getVal(), var2.getVal(), 8);
682 frame->addObject(point);
683
684 // check first if a inimizer is available. If not means
685 // the minimization is not done , so do it
686 if (_theFitter->GetMinimizer() == 0) {
687 coutW(Minimization) << "RooMinimizer::contour: Error, run Migrad before contours!" << endl;
688 return frame;
689 }
690
691 // remember our original value of ERRDEF
692 double errdef = _theFitter->GetMinimizer()->ErrorDef();
693
694 double n[6];
695 n[0] = n1;
696 n[1] = n2;
697 n[2] = n3;
698 n[3] = n4;
699 n[4] = n5;
700 n[5] = n6;
701
702 for (int ic = 0; ic < 6; ic++) {
703 if (n[ic] > 0) {
704
705 // set the value corresponding to an n1-sigma contour
706 _theFitter->GetMinimizer()->SetErrorDef(n[ic] * n[ic] * errdef);
707
708 // calculate and draw the contour
709 std::vector<double> xcoor(npoints + 1);
710 std::vector<double> ycoor(npoints + 1);
711 bool ret = _theFitter->GetMinimizer()->Contour(index1, index2, npoints, xcoor.data(), ycoor.data());
712
713 if (!ret) {
714 coutE(Minimization) << "RooMinimizer::contour(" << GetName()
715 << ") ERROR: MINUIT did not return a contour graph for n=" << n[ic] << endl;
716 } else {
717 xcoor[npoints] = xcoor[0];
718 ycoor[npoints] = ycoor[0];
719 TGraph *graph = new TGraph(npoints + 1, xcoor.data(), ycoor.data());
720
721 graph->SetName(Form("contour_%s_n%f", _fcn->getFunctionName().c_str(), n[ic]));
722 graph->SetLineStyle(ic + 1);
723 graph->SetLineWidth(2);
724 graph->SetLineColor(kBlue);
725 frame->addObject(graph, "L");
726 }
727 }
728 }
729
730 // restore the original ERRDEF
731 _theFitter->GetMinimizer()->SetErrorDef(errdef);
732
733 // restore parameter values
734 params->assign(*paramSave);
735
736 return frame;
737}
738
739////////////////////////////////////////////////////////////////////////////////
740/// Start profiling timer
741
743{
744 if (_cfg.profile) {
745 _timer.Start();
746 _cumulTimer.Start(_profileStart ? false : true);
747 _profileStart = true;
748 }
749}
750
751////////////////////////////////////////////////////////////////////////////////
752/// Stop profiling timer and report results of last session
753
755{
756 if (_cfg.profile) {
757 _timer.Stop();
759 coutI(Minimization) << "Command timer: ";
760 _timer.Print();
761 coutI(Minimization) << "Session timer: ";
763 }
764}
765
767{
768 auto *fitterFcn = fitter()->GetFCN();
769 return fitterFcn ? fitterFcn : _fcn->getMultiGenFcn();
770}
771
772////////////////////////////////////////////////////////////////////////////////
773/// Apply results of given external covariance matrix. i.e. propagate its errors
774/// to all RRV parameter representations and give this matrix instead of the
775/// HESSE matrix at the next save() call
776
778{
779 _extV.reset(static_cast<TMatrixDSym *>(V.Clone()));
780 _fcn->ApplyCovarianceMatrix(*_extV);
781}
782
784{
786}
787
789{
790 // Import the results of the last fit performed, interpreting
791 // the fit parameters as the given varList of parameters.
792
793 if (_theFitter == 0 || _theFitter->GetMinimizer() == 0) {
794 oocoutE(nullptr, InputArguments) << "RooMinimizer::save: Error, run minimization before!" << endl;
795 return nullptr;
796 }
797
798 // Verify length of supplied varList
799 if (!varList.empty() && varList.size() != _theFitter->Result().NTotalParameters()) {
800 oocoutE(nullptr, InputArguments)
801 << "RooMinimizer::lastMinuitFit: ERROR: supplied variable list must be either empty " << endl
802 << " or match the number of variables of the last fit ("
803 << _theFitter->Result().NTotalParameters() << ")" << endl;
804 return nullptr;
805 }
806
807 // Verify that all members of varList are of type RooRealVar
808 for (RooAbsArg *arg : varList) {
809 if (!dynamic_cast<RooRealVar *>(arg)) {
810 oocoutE(nullptr, InputArguments) << "RooMinimizer::lastMinuitFit: ERROR: variable '" << arg->GetName()
811 << "' is not of type RooRealVar" << endl;
812 return nullptr;
813 }
814 }
815
816 RooFitResult *res = new RooFitResult("lastMinuitFit", "Last MINUIT fit");
817
818 // Extract names of fit parameters
819 // and construct corresponding RooRealVars
820 RooArgList constPars("constPars");
821 RooArgList floatPars("floatPars");
822
823 unsigned int i;
824 for (i = 0; i < _theFitter->Result().NTotalParameters(); ++i) {
825
826 TString varName(_theFitter->Result().GetParameterName(i));
827 bool isConst(_theFitter->Result().IsParameterFixed(i));
828
829 double xlo = _theFitter->Config().ParSettings(i).LowerLimit();
830 double xhi = _theFitter->Config().ParSettings(i).UpperLimit();
831 double xerr = _theFitter->Result().Error(i);
832 double xval = _theFitter->Result().Value(i);
833
834 std::unique_ptr<RooRealVar> var;
835 if (varList.empty()) {
836
837 if ((xlo < xhi) && !isConst) {
838 var = std::make_unique<RooRealVar>(varName, varName, xval, xlo, xhi);
839 } else {
840 var = std::make_unique<RooRealVar>(varName, varName, xval);
841 }
842 var->setConstant(isConst);
843 } else {
844
845 var.reset(static_cast<RooRealVar *>(varList.at(i)->Clone()));
846 var->setConstant(isConst);
847 var->setVal(xval);
848 if (xlo < xhi) {
849 var->setRange(xlo, xhi);
850 }
851
852 if (varName.CompareTo(var->GetName())) {
853 oocoutI(nullptr, Eval) << "RooMinimizer::lastMinuitFit: fit parameter '" << varName
854 << "' stored in variable '" << var->GetName() << "'" << endl;
855 }
856 }
857
858 if (isConst) {
859 constPars.addOwned(std::move(var));
860 } else {
861 var->setError(xerr);
862 floatPars.addOwned(std::move(var));
863 }
864 }
865
866 res->setConstParList(constPars);
867 res->setInitParList(floatPars);
868 res->setFinalParList(floatPars);
869 res->setMinNLL(_theFitter->Result().MinFcnValue());
870 res->setEDM(_theFitter->Result().Edm());
871 res->setCovQual(_theFitter->GetMinimizer()->CovMatrixStatus());
872 res->setStatus(_theFitter->Result().Status());
873 std::vector<double> globalCC;
874 TMatrixDSym corrs(_theFitter->Result().Parameters().size());
875 TMatrixDSym covs(_theFitter->Result().Parameters().size());
876 for (unsigned int ic = 0; ic < _theFitter->Result().Parameters().size(); ic++) {
877 globalCC.push_back(_theFitter->Result().GlobalCC(ic));
878 for (unsigned int ii = 0; ii < _theFitter->Result().Parameters().size(); ii++) {
879 corrs(ic, ii) = _theFitter->Result().Correlation(ic, ii);
880 covs(ic, ii) = _theFitter->Result().CovMatrix(ic, ii);
881 }
882 }
883 res->fillCorrMatrix(globalCC, corrs, covs);
884
885 return res;
886}
887
888/// Try to recover from invalid function values. When invalid function values
889/// are encountered, a penalty term is returned to the minimiser to make it
890/// back off. This sets the strength of this penalty. \note A strength of zero
891/// is equivalent to a constant penalty (= the gradient vanishes, ROOT < 6.24).
892/// Positive values lead to a gradient pointing away from the undefined
893/// regions. Use ~10 to force the minimiser away from invalid function values.
895{
896 _cfg.recoverFromNaN = strength;
897}
898
899bool RooMinimizer::setLogFile(const char *logf)
900{
901 _cfg.logf = logf;
902 if (_cfg.logf)
903 return _fcn->SetLogFile(_cfg.logf);
904 else
905 return false;
906}
907
909{
910 return _fcn->evalCounter();
911}
913{
914 _fcn->zeroEvalCount();
915}
916
918{
919 return _fcn->getNDim();
920}
921
922std::ofstream *RooMinimizer::logfile()
923{
924 return _fcn->GetLogFile();
925}
927{
928 return _fcn->GetMaxFCN();
929}
930
932{
933#ifdef R__HAS_ROOFIT_MULTIPROCESS
935#else
936 return 0;
937#endif
938}
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
#define coutI(a)
Definition: RooMsgService.h:34
#define coutW(a)
Definition: RooMsgService.h:36
#define oocoutE(o, a)
Definition: RooMsgService.h:52
#define oocoutI(o, a)
Definition: RooMsgService.h:49
#define coutE(a)
Definition: RooMsgService.h:37
#define ClassImp(name)
Definition: Rtypes.h:375
@ kBlue
Definition: Rtypes.h:66
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 char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
Definition: TGX11.cxx:110
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition: TString.cxx:2456
Fitter class, entry point for performing all type of fits.
Definition: Fitter.h:77
ROOT::Math::IMultiGenFunction * GetFCN() const
return pointer to last used objective function (is NULL in case fit is not yet done) This pointer wil...
Definition: Fitter.h:475
Documentation for the abstract class IBaseFunctionMultiDim.
Definition: IFunction.h:62
static const std::string & DefaultMinimizerType()
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
Definition: RooAbsArg.h:71
bool isConstant() const
Check if the "Constant" attribute is set.
Definition: RooAbsArg.h:362
TObject * Clone(const char *newname=nullptr) const override
Make a clone of an object using the Streamer facility.
Definition: RooAbsArg.h:83
virtual bool remove(const RooAbsArg &var, bool silent=false, bool matchByNameOnly=false)
Remove the specified argument from our list.
bool empty() const
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.
void assign(const RooAbsCollection &other) const
Sets the value, cache and constant attribute of any argument in our set that also appears in the othe...
Storage_t::size_type size() const
virtual bool addOwned(RooAbsArg &var, bool silent=false)
Add an argument and transfer the ownership to the collection.
void sort(bool reverse=false)
Sort collection using std::sort and name comparison.
RooAbsArg * find(const char *name) const
Find object with given name in list.
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:62
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition: RooAbsReal.h:91
static void setEvalErrorLoggingMode(ErrorLoggingMode m)
Set evaluation error logging mode.
static void clearEvalErrorLog()
Clear the stack of evaluation error messages.
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:56
RooFitResult is a container class to hold the input and output of a PDF fit to a dataset.
Definition: RooFitResult.h:40
void fillCorrMatrix()
Internal utility method to extract the correlation matrix and the global correlation coefficients fro...
void setCovQual(Int_t val)
Definition: RooFitResult.h:172
void setMinNLL(double val)
Definition: RooFitResult.h:169
void setNumInvalidNLL(Int_t val)
Definition: RooFitResult.h:173
void setStatus(Int_t val)
Definition: RooFitResult.h:171
void setConstParList(const RooArgList &list)
Fill the list of constant parameters.
void setCovarianceMatrix(TMatrixDSym &V)
Store externally provided correlation matrix in this RooFitResult ;.
void setStatusHistory(std::vector< std::pair< std::string, int > > &hist)
Definition: RooFitResult.h:178
void setInitParList(const RooArgList &list)
Fill the list of initial values of the floating parameters.
void setEDM(double val)
Definition: RooFitResult.h:170
void setFinalParList(const RooArgList &list)
Fill the list of final values of the floating parameters.
static unsigned int getDefaultNWorkers()
Definition: Config.cxx:77
RooAbsReal that wraps RooAbsL likelihoods for use in RooFit outside of the RooMinimizer context.
Definition: RooRealL.h:28
RooMinimizer is a wrapper class around ROOT::Fit:Fitter that provides a seamless interface between th...
Definition: RooMinimizer.h:43
void setRecoverFromNaNStrength(double strength)
Try to recover from invalid function values.
static int getPrintLevel()
Get the MINUIT internal printing level.
void optimizeConst(int flag)
If flag is true, perform constant term optimization on function being minimized.
void initMinimizerFirstPart()
Initialize the part of the minimizer that is independent of the function to be minimized.
std::ofstream * logfile()
int simplex()
Execute SIMPLEX.
std::unique_ptr< TMatrixDSym > _extV
Definition: RooMinimizer.h:162
void zeroEvalCount()
void setMinimizerType(std::string const &type)
Choose the minimizer algorithm.
std::vector< std::pair< std::string, int > > _statusHistory
Definition: RooMinimizer.h:168
void profileStart()
Start profiling timer.
RooPlot * contour(RooRealVar &var1, RooRealVar &var2, double n1=1.0, double n2=2.0, double n3=0.0, double n4=0.0, double n5=0.0, double n6=0.0, unsigned int npoints=50)
Create and draw a TH2 with the error contours in the parameters var1 and var2.
bool setLogFile(const char *logf=nullptr)
void initMinimizerFcnDependentPart(double defaultErrorLevel)
Initialize the part of the minimizer that is dependent on the function to be minimized.
void profileStop()
Stop profiling timer and report results of last session.
int minos()
Execute MINOS.
double & maxFCN()
int hesse()
Execute HESSE.
RooFitResult * save(const char *name=nullptr, const char *title=nullptr)
Save and return a RooFitResult snapshot of current minimizer status.
void setErrorLevel(double level)
Set the level for MINUIT error analysis to the given value.
static std::unique_ptr< ROOT::Fit::Fitter > _theFitter
Definition: RooMinimizer.h:166
int migrad()
Execute MIGRAD.
int seek()
Execute SEEK.
void setEps(double eps)
Change MINUIT epsilon.
void setPrintLevel(int newLevel)
Change the MINUIT internal printing level.
static RooFitResult * lastMinuitFit()
int improve()
Execute IMPROVE.
static void cleanup()
Cleanup method called by atexit handler installed by RooSentinel to delete all global heap objects wh...
bool _profileStart
Definition: RooMinimizer.h:156
void setOffsetting(bool flag)
Enable internal likelihood offsetting for enhanced numeric precision.
TStopwatch _timer
Definition: RooMinimizer.h:159
RooMinimizer::Config _cfg
Definition: RooMinimizer.h:172
bool fitFcn() const
void saveStatus(const char *label, int status)
Definition: RooMinimizer.h:123
~RooMinimizer() override
Destructor.
int minimize(const char *type, const char *alg=nullptr)
Minimise the function passed in the constructor.
ROOT::Math::IMultiGenFunction * getMultiGenFcn() const
void setStrategy(int strat)
Change MINUIT strategy to istrat.
RooMinimizer(RooAbsReal &function, Config const &cfg={})
Construct MINUIT interface to given function.
ROOT::Fit::Fitter * fitter()
Return underlying ROOT fitter object.
void setMaxFunctionCalls(int n)
Change maximum number of likelihood function calss from MINUIT (RooMinimizer default 500 * #parameter...
int evalCounter() const
TStopwatch _cumulTimer
Definition: RooMinimizer.h:160
int getNPar() const
void setMaxIterations(int n)
Change maximum number of MINUIT iterations (RooMinimizer default 500 * #parameters)
std::unique_ptr< RooAbsMinimizerFcn > _fcn
Definition: RooMinimizer.h:164
void applyCovarianceMatrix(TMatrixDSym const &V)
Apply results of given external covariance matrix.
static RooMsgService & instance()
Return reference to singleton instance.
A RooPlot is a 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:380
RooRealVar represents a variable that can be changed from the outside.
Definition: RooRealVar.h:40
static void activate()
Install atexit handler that calls CleanupRooFitAtExit() on program termination.
Definition: RooSentinel.cxx:54
A TGraph is an object made of two arrays X and Y with npoints each.
Definition: TGraph.h:41
Manages Markers.
Definition: TMarker.h:22
const char * GetName() const override
Returns name of object.
Definition: TNamed.h:47
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:440
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TObject.cxx:223
void Start(Bool_t reset=kTRUE)
Start the stopwatch.
Definition: TStopwatch.cxx:58
void Stop()
Stop the stopwatch.
Definition: TStopwatch.cxx:77
void Print(Option_t *option="") const override
Print the real and cpu time passed between the start and stop events.
Definition: TStopwatch.cxx:219
Basic string class.
Definition: TString.h:136
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition: TString.cxx:451
RooCmdArg Parameters(const RooArgSet &params)
const Int_t n
Definition: legend1.C:16
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
Definition: RExports.h:167
@ Minimization
Definition: RooGlobalFunc.h:61
@ InputArguments
Definition: RooGlobalFunc.h:62
Definition: graph.py:1
Config argument to RooMinimizer ctor.
Definition: RooMinimizer.h:46
const char * logf
Definition: RooMinimizer.h:52
std::string minimizerType
Definition: RooMinimizer.h:58