Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
21Wrapper 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::ModularL(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 ROOFIT_MULTIPROCESS
62#endif
63
64#include "TClass.h"
65#include "Math/Minimizer.h"
66#include "TMarker.h"
67#include "TGraph.h"
68#include "Fit/FitConfig.h"
69
70#include <fstream>
71#include <iostream>
72#include <stdexcept> // logic_error
73
75
76////////////////////////////////////////////////////////////////////////////////
77/// Construct MINUIT interface to given function. Function can be anything,
78/// but is typically a -log(likelihood) implemented by RooNLLVar or a chi^2
79/// (implemented by RooChi2Var). Other frequent use cases are a RooAddition
80/// of a RooNLLVar plus a penalty or constraint term. This class propagates
81/// all RooFit information (floating parameters, their values and errors)
82/// to MINUIT before each MINUIT call and propagates all MINUIT information
83/// back to the RooFit object at the end of each call (updated parameter
84/// values, their (asymmetric errors) etc. The default MINUIT error level
85/// for HESSE and MINOS error analysis is taken from the defaultErrorLevel()
86/// value of the input function.
87
88/// Constructor that accepts all configuration in struct with RooAbsReal likelihood
89RooMinimizer::RooMinimizer(RooAbsReal &function, Config const &cfg) : _cfg(cfg)
90{
92 auto nll_real = dynamic_cast<RooFit::TestStatistics::RooRealL *>(&function);
93 if (nll_real != nullptr) {
94 if (_cfg.parallelize != 0) { // new test statistic with multiprocessing library with
95 // parallel likelihood or parallel gradient
96#ifdef ROOFIT_MULTIPROCESS
98 // Note that this is necessary because there is currently no serial-mode LikelihoodGradientWrapper.
99 // We intend to repurpose RooGradMinimizerFcn to build such a LikelihoodGradientSerial class.
100 coutI(InputArguments) << "Modular likelihood detected and likelihood parallelization requested, "
101 << "also setting parallel gradient calculation mode." << std::endl;
103 }
104 // If _cfg.parallelize is larger than zero set the number of workers to that value. Otherwise do not do
105 // anything and let RooFit::MultiProcess handle the number of workers
106 if (_cfg.parallelize > 0)
109
110 _fcn = std::make_unique<RooFit::TestStatistics::MinuitFcnGrad>(
111 nll_real->getRooAbsL(), this, getConfig().ParamsSettings(),
115#else
116 throw std::logic_error(
117 "Parallel minimization requested, but ROOT was not compiled with multiprocessing enabled, "
118 "please recompile with -Droofit_multiprocess=ON for parallel evaluation");
119#endif
120 } else { // modular test statistic non parallel
121 coutW(InputArguments)
122 << "Requested modular likelihood without gradient parallelization, some features such as offsetting "
123 << "may not work yet. Non-modular likelihoods are more reliable without parallelization." << std::endl;
124 // The RooRealL that is used in the case where the modular likelihood is being passed to a RooMinimizerFcn does
125 // not have offsetting implemented. Therefore, offsetting will not work in this case. Other features might also
126 // not work since the RooRealL was not intended for minimization. Further development is required to make the
127 // MinuitFcnGrad also handle serial gradient minimization. The MinuitFcnGrad accepts a RooAbsL and has
128 // offsetting implemented, thus omitting the need for RooRealL minimization altogether.
129 _fcn = std::make_unique<RooMinimizerFcn>(&function, this);
130 }
131 } else {
132 if (_cfg.parallelize != 0) { // Old test statistic with parallel likelihood or gradient
133 throw std::logic_error("In RooMinimizer constructor: Selected likelihood evaluation but a "
134 "non-modular likelihood was given. Please supply ModularL(true) as an "
135 "argument to createNLL for modular likelihoods to use likelihood "
136 "or gradient parallelization.");
137 }
138 _fcn = std::make_unique<RooMinimizerFcn>(&function, this);
139 }
140 initMinimizerFcnDependentPart(function.defaultErrorLevel());
141};
142
143/// Initialize the part of the minimizer that is independent of the function to be minimized
145{
146 RooSentinel::activate();
148
149 _theFitter = std::make_unique<ROOT::Fit::Fitter>();
151 setEps(1.0); // default tolerance
152}
153
154/// Initialize the part of the minimizer that is dependent on the function to be minimized
156{
157 // default max number of calls
158 getConfig().MinimizerOptions().SetMaxIterations(500 * _fcn->getNDim());
160
161 // Shut up for now
162 setPrintLevel(-1);
163
164 // Use +0.5 for 1-sigma errors
165 setErrorLevel(defaultErrorLevel);
166
167 // Declare our parameters to MINUIT
168 _fcn->Synchronize(getConfig().ParamsSettings());
169
170 // Now set default verbosity
171 setPrintLevel(RooMsgService::instance().silentMode() ? -1 : 1);
172
173 // Set user defined and default _fcn config
175
176 // Likelihood holds information on offsetting in old style, so do not set here unless explicitly set by user
177 if (_cfg.offsetting != -1) {
179 }
180}
181
182////////////////////////////////////////////////////////////////////////////////
183/// Destructor
184
186
187////////////////////////////////////////////////////////////////////////////////
188/// Change MINUIT strategy to istrat. Accepted codes
189/// are 0,1,2 and represent MINUIT strategies for dealing
190/// most efficiently with fast FCNs (0), expensive FCNs (2)
191/// and 'intermediate' FCNs (1)
192
194{
196}
197
198////////////////////////////////////////////////////////////////////////////////
199/// Change maximum number of MINUIT iterations
200/// (RooMinimizer default 500 * #%parameters)
201
203{
205}
206
207////////////////////////////////////////////////////////////////////////////////
208/// Change maximum number of likelihood function class from MINUIT
209/// (RooMinimizer default 500 * #%parameters)
210
212{
214}
215
216////////////////////////////////////////////////////////////////////////////////
217/// Set the level for MINUIT error analysis to the given
218/// value. This function overrides the default value
219/// that is taken in the RooMinimizer constructor from
220/// the defaultErrorLevel() method of the input function
221
223{
225}
226
227////////////////////////////////////////////////////////////////////////////////
228/// Change MINUIT epsilon
229
230void RooMinimizer::setEps(double eps)
231{
233}
234
235////////////////////////////////////////////////////////////////////////////////
236/// Enable internal likelihood offsetting for enhanced numeric precision
237
239{
240 _cfg.offsetting = flag;
241 _fcn->setOffsetting(_cfg.offsetting);
242}
243
244////////////////////////////////////////////////////////////////////////////////
245/// Choose the minimizer algorithm.
246///
247/// Passing an empty string selects the default minimizer type returned by
248/// ROOT::Math::MinimizerOptions::DefaultMinimizerType().
249
250void RooMinimizer::setMinimizerType(std::string const &type)
251{
253
254 if ((_cfg.parallelize != 0) && _cfg.minimizerType != "Minuit2") {
255 std::stringstream ss;
256 ss << "In RooMinimizer::setMinimizerType: only Minuit2 is supported when not using classic function mode!";
257 if (type.empty()) {
258 ss << "\nPlease set it as your default minimizer via "
259 "ROOT::Math::MinimizerOptions::SetDefaultMinimizer(\"Minuit2\").";
260 }
261 throw std::invalid_argument(ss.str());
262 }
263}
264
265void RooMinimizer::determineStatus(bool fitterReturnValue)
266{
267 // Minuit-given status:
268 _status = ((fitterReturnValue) ? getResult().Status() : -1);
269
270 // RooFit-based additional failed state information:
271 if (evalCounter() <= _fcn->GetNumInvalidNLL()) {
272 coutE(Minimization) << "RooMinimizer: all function calls during minimization gave invalid NLL values!"
273 << std::endl;
274 }
275}
276
277////////////////////////////////////////////////////////////////////////////////
278/// Minimise the function passed in the constructor.
279/// \param[in] type Type of fitter to use, e.g. "Minuit" "Minuit2". Passing an
280/// empty string will select the default minimizer type of the
281/// RooMinimizer, as returned by
282/// ROOT::Math::MinimizerOptions::DefaultMinimizerType().
283/// \attention This overrides the default fitter of this RooMinimizer.
284/// \param[in] alg Fit algorithm to use. (Optional)
285int RooMinimizer::minimize(const char *type, const char *alg)
286{
287 if (_cfg.timingAnalysis) {
288#ifdef ROOFIT_MULTIPROCESS
290#else
291 throw std::logic_error("ProcessTimer, but ROOT was not compiled with multiprocessing enabled, "
292 "please recompile with -Droofit_multiprocess=ON for logging with the "
293 "ProcessTimer.");
294#endif
295 }
296 _fcn->Synchronize(getConfig().ParamsSettings());
297
300
301 profileStart();
302 {
303 auto ctx = makeEvalErrorContext();
304
305 bool ret = _theFitter->FitFCN(*_fcn->getMultiGenFcn());
306 determineStatus(ret);
307 }
308 profileStop();
309 _fcn->BackProp(getResult());
310
311 saveStatus("MINIMIZE", _status);
312
313 return _status;
314}
315
316////////////////////////////////////////////////////////////////////////////////
317/// Execute MIGRAD. Changes in parameter values
318/// and calculated errors are automatically
319/// propagated back the RooRealVars representing
320/// the floating parameters in the MINUIT operation.
321
323{
324 return exec("migrad", "MIGRAD");
325}
326
327int RooMinimizer::exec(std::string const &algoName, std::string const &statusName)
328{
329 _fcn->Synchronize(getConfig().ParamsSettings());
330 profileStart();
331 {
332 auto ctx = makeEvalErrorContext();
333
334 bool ret = false;
335 if (algoName == "hesse") {
336 // HESSE has a special entry point in the ROOT::Math::Fitter
338 ret = _theFitter->CalculateHessErrors();
339 } else if (algoName == "minos") {
340 // MINOS has a special entry point in the ROOT::Math::Fitter
342 ret = _theFitter->CalculateMinosErrors();
343 } else {
344 getConfig().SetMinimizer(_cfg.minimizerType.c_str(), algoName.c_str());
345 ret = _theFitter->FitFCN(*_fcn->getMultiGenFcn());
346 }
347 determineStatus(ret);
348 }
349 profileStop();
350 _fcn->BackProp(getResult());
351
352 saveStatus(statusName.c_str(), _status);
353
354 return _status;
355}
356
357////////////////////////////////////////////////////////////////////////////////
358/// Execute HESSE. Changes in parameter values
359/// and calculated errors are automatically
360/// propagated back the RooRealVars representing
361/// the floating parameters in the MINUIT operation.
362
364{
365 if (getMinimizer() == nullptr) {
366 coutW(Minimization) << "RooMinimizer::hesse: Error, run Migrad before Hesse!" << std::endl;
367 _status = -1;
368 return _status;
369 }
370
371 return exec("hesse", "HESSE");
372}
373
374////////////////////////////////////////////////////////////////////////////////
375/// Execute MINOS. Changes in parameter values
376/// and calculated errors are automatically
377/// propagated back the RooRealVars representing
378/// the floating parameters in the MINUIT operation.
379
381{
382 if (getMinimizer() == nullptr) {
383 coutW(Minimization) << "RooMinimizer::minos: Error, run Migrad before Minos!" << std::endl;
384 _status = -1;
385 return _status;
386 }
387
388 return exec("minos", "MINOS");
389}
390
391////////////////////////////////////////////////////////////////////////////////
392/// Execute MINOS for given list of parameters. Changes in parameter values
393/// and calculated errors are automatically
394/// propagated back the RooRealVars representing
395/// the floating parameters in the MINUIT operation.
396
397int RooMinimizer::minos(const RooArgSet &minosParamList)
398{
399 if (getMinimizer() == nullptr) {
400 coutW(Minimization) << "RooMinimizer::minos: Error, run Migrad before Minos!" << std::endl;
401 _status = -1;
402 } else if (!minosParamList.empty()) {
403
404 _fcn->Synchronize(getConfig().ParamsSettings());
405 profileStart();
406 {
407 auto ctx = makeEvalErrorContext();
408
409 // get list of parameters for Minos
410 std::vector<unsigned int> paramInd;
411 for (RooAbsArg *arg : minosParamList) {
412 RooAbsArg *par = _fcn->GetFloatParamList()->find(arg->GetName());
413 if (par && !par->isConstant()) {
414 int index = _fcn->GetFloatParamList()->index(par);
415 paramInd.push_back(index);
416 }
417 }
418
419 if (!paramInd.empty()) {
420 // set the parameter indices
421 getConfig().SetMinosErrors(paramInd);
422
424 bool ret = _theFitter->CalculateMinosErrors();
425 determineStatus(ret);
426 // to avoid that following minimization computes automatically the Minos errors
427 getConfig().SetMinosErrors(false);
428 }
429 }
430 profileStop();
431 _fcn->BackProp(getResult());
432
433 saveStatus("MINOS", _status);
434 }
435
436 return _status;
437}
438
439////////////////////////////////////////////////////////////////////////////////
440/// Execute SEEK. Changes in parameter values
441/// and calculated errors are automatically
442/// propagated back the RooRealVars representing
443/// the floating parameters in the MINUIT operation.
444
446{
447 return exec("seek", "SEEK");
448}
449
450////////////////////////////////////////////////////////////////////////////////
451/// Execute SIMPLEX. Changes in parameter values
452/// and calculated errors are automatically
453/// propagated back the RooRealVars representing
454/// the floating parameters in the MINUIT operation.
455
457{
458 return exec("simplex", "SIMPLEX");
459}
460
461////////////////////////////////////////////////////////////////////////////////
462/// Execute IMPROVE. Changes in parameter values
463/// and calculated errors are automatically
464/// propagated back the RooRealVars representing
465/// the floating parameters in the MINUIT operation.
466
468{
469 return exec("migradimproved", "IMPROVE");
470}
471
472////////////////////////////////////////////////////////////////////////////////
473/// Change the MINUIT internal printing level
474
476{
477 getConfig().MinimizerOptions().SetPrintLevel(newLevel + 1);
478}
479
480////////////////////////////////////////////////////////////////////////////////
481/// Get the MINUIT internal printing level
482
484{
485 return getConfig().MinimizerOptions().PrintLevel() + 1;
486}
487
488////////////////////////////////////////////////////////////////////////////////
489/// If flag is true, perform constant term optimization on
490/// function being minimized.
491
493{
494 _fcn->setOptimizeConst(flag);
495}
496
497////////////////////////////////////////////////////////////////////////////////
498/// Save and return a RooFitResult snapshot of current minimizer status.
499/// This snapshot contains the values of all constant parameters,
500/// the value of all floating parameters at RooMinimizer construction and
501/// after the last MINUIT operation, the MINUIT status, variance quality,
502/// EDM setting, number of calls with evaluation problems, the minimized
503/// function value and the full correlation matrix.
504
505RooFit::OwningPtr<RooFitResult> RooMinimizer::save(const char *userName, const char *userTitle)
506{
507 if (getMinimizer() == nullptr) {
508 coutW(Minimization) << "RooMinimizer::save: Error, run minimization before!" << std::endl;
509 return nullptr;
510 }
511
513 TString title;
514 name = userName ? userName : Form("%s", _fcn->getFunctionName().c_str());
515 title = userTitle ? userTitle : Form("%s", _fcn->getFunctionTitle().c_str());
516 auto fitRes = std::make_unique<RooFitResult>(name, title);
517
518 // Move eventual fixed parameters in floatList to constList
519 RooArgList saveConstList(*(_fcn->GetConstParamList()));
520 RooArgList saveFloatInitList(*(_fcn->GetInitFloatParamList()));
521 RooArgList saveFloatFinalList(*(_fcn->GetFloatParamList()));
522 for (std::size_t i = 0; i < _fcn->GetFloatParamList()->size(); i++) {
523 RooAbsArg *par = _fcn->GetFloatParamList()->at(i);
524 if (par->isConstant()) {
525 saveFloatInitList.remove(*saveFloatInitList.find(par->GetName()), true);
526 saveFloatFinalList.remove(*par);
527 saveConstList.add(*par);
528 }
529 }
530 saveConstList.sort();
531
532 fitRes->setConstParList(saveConstList);
533 fitRes->setInitParList(saveFloatInitList);
534
535 double removeOffset = 0.;
536 fitRes->setNumInvalidNLL(_fcn->GetNumInvalidNLL());
537 removeOffset = -_fcn->getOffset();
538
539 fitRes->setStatus(_status);
540 fitRes->setCovQual(getMinimizer()->CovMatrixStatus());
541 fitRes->setMinNLL(getResult().MinFcnValue() + removeOffset);
542 fitRes->setEDM(getResult().Edm());
543 fitRes->setFinalParList(saveFloatFinalList);
544 if (!_extV) {
545 const std::size_t nParams = getResult().Parameters().size();
546 std::vector<double> globalCC;
547 TMatrixDSym corrs(nParams);
548 TMatrixDSym covs(nParams);
549 for (std::size_t ic = 0; ic < nParams; ic++) {
550 globalCC.push_back(getResult().GlobalCC(ic));
551 for (std::size_t ii = 0; ii < nParams; ii++) {
552 corrs(ic, ii) = getResult().Correlation(ic, ii);
553 covs(ic, ii) = getResult().CovMatrix(ic, ii);
554 }
555 }
556 fitRes->fillCorrMatrix(globalCC, corrs, covs);
557 } else {
558 fitRes->setCovarianceMatrix(*_extV);
559 }
560
561 fitRes->setStatusHistory(_statusHistory);
562
563 return RooFit::makeOwningPtr(std::move(fitRes));
564}
565
566////////////////////////////////////////////////////////////////////////////////
567/// Create and draw a TH2 with the error contours in the parameters `var1` and `var2`.
568/// \param[in] var1 The first parameter (x axis).
569/// \param[in] var2 The second parameter (y axis).
570/// \param[in] n1 First contour.
571/// \param[in] n2 Optional contour. 0 means don't draw.
572/// \param[in] n3 Optional contour. 0 means don't draw.
573/// \param[in] n4 Optional contour. 0 means don't draw.
574/// \param[in] n5 Optional contour. 0 means don't draw.
575/// \param[in] n6 Optional contour. 0 means don't draw.
576/// \param[in] npoints Number of points for evaluating the contour.
577///
578/// Up to six contours can be drawn using the arguments `n1` to `n6` to request the desired
579/// coverage in units of \f$ \sigma = n^2 \cdot \mathrm{ErrorDef} \f$.
580/// See ROOT::Math::Minimizer::ErrorDef().
581
582RooPlot *RooMinimizer::contour(RooRealVar &var1, RooRealVar &var2, double n1, double n2, double n3, double n4,
583 double n5, double n6, unsigned int npoints)
584{
585 RooArgList *params = _fcn->GetFloatParamList();
586 RooArgList paramSave;
587 params->snapshot(paramSave);
588
589 // Verify that both variables are floating parameters of PDF
590 int index1 = _fcn->GetFloatParamList()->index(&var1);
591 if (index1 < 0) {
592 coutE(Minimization) << "RooMinimizer::contour(" << GetName() << ") ERROR: " << var1.GetName()
593 << " is not a floating parameter of " << _fcn->getFunctionName() << std::endl;
594 return nullptr;
595 }
596
597 int index2 = _fcn->GetFloatParamList()->index(&var2);
598 if (index2 < 0) {
599 coutE(Minimization) << "RooMinimizer::contour(" << GetName() << ") ERROR: " << var2.GetName()
600 << " is not a floating parameter of PDF " << _fcn->getFunctionName() << std::endl;
601 return nullptr;
602 }
603
604 // create and draw a frame
605 RooPlot *frame = new RooPlot(var1, var2);
606
607 // draw a point at the current parameter values
608 TMarker *point = new TMarker(var1.getVal(), var2.getVal(), 8);
609 frame->addObject(point);
610
611 // check first if a inimizer is available. If not means
612 // the minimization is not done , so do it
613 if (getMinimizer() == nullptr) {
614 coutW(Minimization) << "RooMinimizer::contour: Error, run Migrad before contours!" << std::endl;
615 return frame;
616 }
617
618 // remember our original value of ERRDEF
619 double errdef = getMinimizer()->ErrorDef();
620
621 double n[6];
622 n[0] = n1;
623 n[1] = n2;
624 n[2] = n3;
625 n[3] = n4;
626 n[4] = n5;
627 n[5] = n6;
628
629 for (int ic = 0; ic < 6; ic++) {
630 if (n[ic] > 0) {
631
632 // set the value corresponding to an n1-sigma contour
633 getMinimizer()->SetErrorDef(n[ic] * n[ic] * errdef);
634
635 // calculate and draw the contour
636 std::vector<double> xcoor(npoints + 1);
637 std::vector<double> ycoor(npoints + 1);
638 bool ret = getMinimizer()->Contour(index1, index2, npoints, xcoor.data(), ycoor.data());
639
640 if (!ret) {
641 coutE(Minimization) << "RooMinimizer::contour(" << GetName()
642 << ") ERROR: MINUIT did not return a contour graph for n=" << n[ic] << std::endl;
643 } else {
644 xcoor[npoints] = xcoor[0];
645 ycoor[npoints] = ycoor[0];
646 TGraph *graph = new TGraph(npoints + 1, xcoor.data(), ycoor.data());
647
648 graph->SetName(Form("contour_%s_n%f", _fcn->getFunctionName().c_str(), n[ic]));
649 graph->SetLineStyle(ic + 1);
650 graph->SetLineWidth(2);
651 graph->SetLineColor(kBlue);
652 frame->addObject(graph, "L");
653 }
654 }
655 }
656
657 // restore the original ERRDEF
658 getMinimizer()->SetErrorDef(errdef);
659
660 // restore parameter values
661 params->assign(paramSave);
662
663 return frame;
664}
665
666////////////////////////////////////////////////////////////////////////////////
667/// Add parameters in metadata field to process timer
668
670{
671#ifdef ROOFIT_MULTIPROCESS
672 // parameter indices for use in timing heat matrix
673 std::vector<std::string> parameter_names;
674 for (auto &&parameter : *_fcn->GetFloatParamList()) {
675 parameter_names.push_back(parameter->GetName());
676 if (_cfg.verbose) {
677 coutI(Minimization) << "parameter name: " << parameter_names.back() << std::endl;
678 }
679 }
681#else
682 coutI(Minimization) << "Not adding parameters to processtimer because multiprocessing is not enabled." << std::endl;
683#endif
684}
685
686////////////////////////////////////////////////////////////////////////////////
687/// Start profiling timer
688
690{
691 if (_cfg.profile) {
692 _timer.Start();
693 _cumulTimer.Start(_profileStart ? false : true);
694 _profileStart = true;
695 }
696}
697
698////////////////////////////////////////////////////////////////////////////////
699/// Stop profiling timer and report results of last session
700
702{
703 if (_cfg.profile) {
704 _timer.Stop();
706 coutI(Minimization) << "Command timer: ";
707 _timer.Print();
708 coutI(Minimization) << "Session timer: ";
710 }
711}
712
714{
715 auto *fitterFcn = _theFitter->GetFCN();
716 return fitterFcn ? fitterFcn : _fcn->getMultiGenFcn();
717}
718
719////////////////////////////////////////////////////////////////////////////////
720/// Apply results of given external covariance matrix. i.e. propagate its errors
721/// to all RRV parameter representations and give this matrix instead of the
722/// HESSE matrix at the next save() call
723
725{
726 _extV.reset(static_cast<TMatrixDSym *>(V.Clone()));
727 _fcn->ApplyCovarianceMatrix(*_extV);
728}
729
731{
733}
734
736{
737 // Import the results of the last fit performed, interpreting
738 // the fit parameters as the given varList of parameters.
739
740 if (_theFitter == nullptr || getMinimizer() == nullptr) {
741 oocoutE(nullptr, InputArguments) << "RooMinimizer::save: Error, run minimization before!" << std::endl;
742 return nullptr;
743 }
744
745 // Verify length of supplied varList
746 if (!varList.empty() && varList.size() != getResult().NTotalParameters()) {
747 oocoutE(nullptr, InputArguments)
748 << "RooMinimizer::lastMinuitFit: ERROR: supplied variable list must be either empty " << std::endl
749 << " or match the number of variables of the last fit ("
750 << getResult().NTotalParameters() << ")" << std::endl;
751 return nullptr;
752 }
753
754 // Verify that all members of varList are of type RooRealVar
755 for (RooAbsArg *arg : varList) {
756 if (!dynamic_cast<RooRealVar *>(arg)) {
757 oocoutE(nullptr, InputArguments) << "RooMinimizer::lastMinuitFit: ERROR: variable '" << arg->GetName()
758 << "' is not of type RooRealVar" << std::endl;
759 return nullptr;
760 }
761 }
762
763 auto res = std::make_unique<RooFitResult>("lastMinuitFit", "Last MINUIT fit");
764
765 // Extract names of fit parameters
766 // and construct corresponding RooRealVars
767 RooArgList constPars("constPars");
768 RooArgList floatPars("floatPars");
769
770 unsigned int i;
771 for (i = 0; i < getResult().NTotalParameters(); ++i) {
772
773 TString varName(getResult().GetParameterName(i));
774 bool isConst(getResult().IsParameterFixed(i));
775
776 double xlo = getConfig().ParSettings(i).LowerLimit();
777 double xhi = getConfig().ParSettings(i).UpperLimit();
778 double xerr = getResult().Error(i);
779 double xval = getResult().Value(i);
780
781 std::unique_ptr<RooRealVar> var;
782 if (varList.empty()) {
783
784 if ((xlo < xhi) && !isConst) {
785 var = std::make_unique<RooRealVar>(varName, varName, xval, xlo, xhi);
786 } else {
787 var = std::make_unique<RooRealVar>(varName, varName, xval);
788 }
789 var->setConstant(isConst);
790 } else {
791
792 var.reset(static_cast<RooRealVar *>(varList.at(i)->Clone()));
793 var->setConstant(isConst);
794 var->setVal(xval);
795 if (xlo < xhi) {
796 var->setRange(xlo, xhi);
797 }
798
799 if (varName.CompareTo(var->GetName())) {
800 oocoutI(nullptr, Eval) << "RooMinimizer::lastMinuitFit: fit parameter '" << varName
801 << "' stored in variable '" << var->GetName() << "'" << std::endl;
802 }
803 }
804
805 if (isConst) {
806 constPars.addOwned(std::move(var));
807 } else {
808 var->setError(xerr);
809 floatPars.addOwned(std::move(var));
810 }
811 }
812
813 res->setConstParList(constPars);
814 res->setInitParList(floatPars);
815 res->setFinalParList(floatPars);
816 res->setMinNLL(getResult().MinFcnValue());
817 res->setEDM(getResult().Edm());
818 res->setCovQual(getMinimizer()->CovMatrixStatus());
819 res->setStatus(getResult().Status());
820 std::vector<double> globalCC;
821 const std::size_t nParams = getResult().Parameters().size();
822 TMatrixDSym corrs(nParams);
823 TMatrixDSym covs(nParams);
824 for (unsigned int ic = 0; ic < nParams; ic++) {
825 globalCC.push_back(getResult().GlobalCC(ic));
826 for (unsigned int ii = 0; ii < nParams; ii++) {
827 corrs(ic, ii) = getResult().Correlation(ic, ii);
828 covs(ic, ii) = getResult().CovMatrix(ic, ii);
829 }
830 }
831 res->fillCorrMatrix(globalCC, corrs, covs);
832
833 return RooFit::makeOwningPtr(std::move(res));
834}
835
836/// Try to recover from invalid function values. When invalid function values
837/// are encountered, a penalty term is returned to the minimiser to make it
838/// back off. This sets the strength of this penalty. \note A strength of zero
839/// is equivalent to a constant penalty (= the gradient vanishes, ROOT < 6.24).
840/// Positive values lead to a gradient pointing away from the undefined
841/// regions. Use ~10 to force the minimiser away from invalid function values.
843{
844 _cfg.recoverFromNaN = strength;
845}
846
847bool RooMinimizer::setLogFile(const char *logf)
848{
849 _cfg.logf = logf;
850 if (_cfg.logf) {
851 return _fcn->SetLogFile(_cfg.logf);
852 } else {
853 return false;
854 }
855}
856
858{
859 return _fcn->evalCounter();
860}
862{
863 _fcn->zeroEvalCount();
864}
865
867{
868 return _fcn->getNDim();
869}
870
871std::ofstream *RooMinimizer::logfile()
872{
873 return _fcn->GetLogFile();
874}
876{
877 return _fcn->GetMaxFCN();
878}
880{
881 return _fcn->getOffset();
882}
883
885{
886#ifdef ROOFIT_MULTIPROCESS
888#else
889 return 0;
890#endif
891}
892
893std::unique_ptr<RooAbsReal::EvalErrorContext> RooMinimizer::makeEvalErrorContext() const
894{
896 // If evaluation error printing is disabled, we don't need to collect the
897 // errors and only need to count them. This significantly reduces the
898 // performance overhead when having evaluation errors.
900 return std::make_unique<RooAbsReal::EvalErrorContext>(m);
901}
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
#define coutI(a)
#define coutW(a)
#define oocoutE(o, a)
#define oocoutI(o, a)
#define coutE(a)
#define ClassImp(name)
Definition Rtypes.h:377
@ 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:2489
void SetMinimizer(const char *type, const char *algo=nullptr)
set minimizer type
Definition FitConfig.h:179
void SetMinosErrors(bool on=true)
set Minos errors computation to be performed after fitting
Definition FitConfig.h:229
const ParameterSettings & ParSettings(unsigned int i) const
get the parameter settings for the i-th parameter (const method)
Definition FitConfig.h:76
ROOT::Math::MinimizerOptions & MinimizerOptions()
access to the minimizer control parameter (non const method)
Definition FitConfig.h:167
double Error(unsigned int i) const
parameter error by index
Definition FitResult.h:179
double CovMatrix(unsigned int i, unsigned int j) const
retrieve covariance matrix element
Definition FitResult.h:215
double Value(unsigned int i) const
parameter value by index
Definition FitResult.h:172
const std::vector< double > & Parameters() const
parameter values (return std::vector)
Definition FitResult.h:167
double Correlation(unsigned int i, unsigned int j) const
retrieve correlation elements
Definition FitResult.h:225
unsigned int NTotalParameters() const
get total number of parameters
Definition FitResult.h:120
int Status() const
minimizer status code
Definition FitResult.h:128
double LowerLimit() const
return lower limit value
double UpperLimit() const
return upper limit value
Documentation for the abstract class IBaseFunctionMultiDim.
Definition IFunction.h:61
void SetMaxFunctionCalls(unsigned int maxfcn)
set maximum of function calls
void SetStrategy(int stra)
set the strategy
void SetMaxIterations(unsigned int maxiter)
set maximum iterations (one iteration can have many function calls)
static const std::string & DefaultMinimizerType()
int PrintLevel() const
non-static methods for retrieving options
void SetErrorDef(double err)
set error def
void SetPrintLevel(int level)
set print level
void SetTolerance(double tol)
set the tolerance
void SetErrorDef(double up)
set scale for calculating the errors
Definition Minimizer.h:364
double ErrorDef() const
return the statistical scale used for calculate the error is typically 1 for Chi2 and 0....
Definition Minimizer.h:334
virtual bool Contour(unsigned int ivar, unsigned int jvar, unsigned int &npoints, double *xi, double *xj)
find the contour points (xi, xj) of the function for parameter ivar and jvar around the minimum The c...
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:79
bool isConstant() const
Check if the "Constant" attribute is set.
Definition RooAbsArg.h:335
TObject * Clone(const char *newname=nullptr) const override
Make a clone of an object using the Streamer facility.
Definition RooAbsArg.h:91
virtual bool remove(const RooAbsArg &var, bool silent=false, bool matchByNameOnly=false)
Remove the specified argument from our list.
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.
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.
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:59
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:103
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:24
static void setDefaultNWorkers(unsigned int N_workers)
Definition Config.cxx:67
static unsigned int getDefaultNWorkers()
Definition Config.cxx:92
static void setTimingAnalysis(bool timingAnalysis)
Definition Config.cxx:78
static void add_metadata(json data)
RooAbsReal that wraps RooAbsL likelihoods for use in RooFit outside of the RooMinimizer context.
Definition RooRealL.h:28
Wrapper class around ROOT::Fit:Fitter that provides a seamless interface between the minimizer functi...
void setRecoverFromNaNStrength(double strength)
Try to recover from invalid function values.
int getPrintLevel()
Get the MINUIT internal printing level.
const ROOT::Fit::FitResult & getResult() const
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
void setMinimizerType(std::string const &type)
Choose the minimizer algorithm.
RooFit::OwningPtr< RooFitResult > save(const char *name=nullptr, const char *title=nullptr)
Save and return a RooFitResult snapshot of current minimizer status.
std::vector< std::pair< std::string, int > > _statusHistory
ROOT::Fit::FitConfig & getConfig() const
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.
double & fcnOffset() const
void profileStop()
Stop profiling timer and report results of last session.
int minos()
Execute MINOS.
double & maxFCN()
int hesse()
Execute HESSE.
void setErrorLevel(double level)
Set the level for MINUIT error analysis to the given value.
void determineStatus(bool fitterReturnValue)
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.
int exec(std::string const &algoName, std::string const &statusName)
int improve()
Execute IMPROVE.
void setOffsetting(bool flag)
Enable internal likelihood offsetting for enhanced numeric precision.
TStopwatch _timer
std::unique_ptr< ROOT::Fit::Fitter > _theFitter
RooMinimizer::Config _cfg
RooFit::OwningPtr< RooFitResult > lastMinuitFit()
void saveStatus(const char *label, int status)
~RooMinimizer() override
Destructor.
int minimize(const char *type, const char *alg=nullptr)
Minimise the function passed in the constructor.
ROOT::Math::IMultiGenFunction * getMultiGenFcn() const
std::unique_ptr< RooAbsReal::EvalErrorContext > makeEvalErrorContext() const
RooMinimizer(RooAbsReal &function, Config const &cfg={})
Construct MINUIT interface to given function.
void setMaxFunctionCalls(int n)
Change maximum number of likelihood function class from MINUIT (RooMinimizer default 500 * #parameter...
void setStrategy(int istrat)
Change MINUIT strategy to istrat.
int evalCounter() const
ROOT::Math::Minimizer * getMinimizer() const
TStopwatch _cumulTimer
int getNPar() const
void setMaxIterations(int n)
Change maximum number of MINUIT iterations (RooMinimizer default 500 * #parameters)
void addParamsToProcessTimer()
Add parameters in metadata field to process timer.
std::unique_ptr< RooAbsMinimizerFcn > _fcn
void applyCovarianceMatrix(TMatrixDSym const &V)
Apply results of given external covariance matrix.
static RooMsgService & instance()
Return reference to singleton instance.
Plot frame and a container for graphics objects within that frame.
Definition RooPlot.h:45
void addObject(TObject *obj, Option_t *drawOptions="", bool invisible=false)
Add a generic object to this plot.
Definition RooPlot.cxx:366
Variable that can be changed from the outside.
Definition RooRealVar.h:37
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:438
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.
void Stop()
Stop the stopwatch.
void Print(Option_t *option="") const override
Print the real and cpu time passed between the start and stop events.
Basic string class.
Definition TString.h:139
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition TString.cxx:457
const Int_t n
Definition legend1.C:16
OwningPtr< T > makeOwningPtr(std::unique_ptr< T > &&ptr)
Internal helper to turn a std::unique_ptr<T> into an OwningPtr.
Definition Config.h:40
T * OwningPtr
An alias for raw pointers for indicating that the return type of a RooFit function is an owning point...
Definition Config.h:35
Definition graph.py:1
Config argument to RooMinimizer constructor.
std::string minimizerType
TMarker m
Definition textangle.C:8