Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
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  * *
10  * Redistribution and use in source and binary forms, *
11  * with or without modification, are permitted according to the terms *
12  * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
13  *****************************************************************************/
14 
15 /**
16 \file RooMinimizer.cxx
17 \class RooMinimizer
18 \ingroup Roofitcore
19 
20 RooMinimizer is a wrapper class around ROOT::Fit:Fitter that
21 provides a seamless interface between the minimizer functionality
22 and the native RooFit interface.
23 By default the Minimizer is MINUIT.
24 RooMinimizer can minimize any RooAbsReal function with respect to
25 its parameters. Usual choices for minimization are RooNLLVar
26 and RooChi2Var
27 RooMinimizer has methods corresponding to MINUIT functions like
28 hesse(), migrad(), minos() etc. In each of these function calls
29 the state of the MINUIT engine is synchronized with the state
30 of the RooFit variables: any change in variables, change
31 in the constant status etc is forwarded to MINUIT prior to
32 execution of the MINUIT call. Afterwards the RooFit objects
33 are resynchronized with the output state of MINUIT: changes
34 parameter values, errors are propagated.
35 Various methods are available to control verbosity, profiling,
36 automatic PDF optimization.
37 **/
38 
39 #ifndef __ROOFIT_NOROOMINIMIZER
40 
41 #include "RooFit.h"
42 #include "Riostream.h"
43 
44 #include "TClass.h"
45 
46 #include <fstream>
47 
48 #include "TH1.h"
49 #include "TH2.h"
50 #include "TMarker.h"
51 #include "TGraph.h"
52 #include "Fit/FitConfig.h"
53 #include "TStopwatch.h"
54 #include "TDirectory.h"
55 #include "TMatrixDSym.h"
56 
57 #include "RooArgSet.h"
58 #include "RooArgList.h"
59 #include "RooAbsReal.h"
60 #include "RooAbsRealLValue.h"
61 #include "RooRealVar.h"
62 #include "RooAbsPdf.h"
63 #include "RooSentinel.h"
64 #include "RooMsgService.h"
65 #include "RooPlot.h"
66 
67 
68 #include "RooMinimizer.h"
69 #include "RooFitResult.h"
70 
71 #include "Math/Minimizer.h"
72 
73 #if (__GNUC__==3&&__GNUC_MINOR__==2&&__GNUC_PATCHLEVEL__==3)
74 char* operator+( streampos&, char* );
75 #endif
76 
77 using namespace std;
78 
79 ClassImp(RooMinimizer);
80 ;
81 
82 ROOT::Fit::Fitter *RooMinimizer::_theFitter = 0 ;
83 
84 
85 
86 ////////////////////////////////////////////////////////////////////////////////
87 /// Cleanup method called by atexit handler installed by RooSentinel
88 /// to delete all global heap objects when the program is terminated
89 
90 void RooMinimizer::cleanup()
91 {
92  if (_theFitter) {
93  delete _theFitter ;
94  _theFitter =0 ;
95  }
96 }
97 
98 
99 
100 ////////////////////////////////////////////////////////////////////////////////
101 /// Construct MINUIT interface to given function. Function can be anything,
102 /// but is typically a -log(likelihood) implemented by RooNLLVar or a chi^2
103 /// (implemented by RooChi2Var). Other frequent use cases are a RooAddition
104 /// of a RooNLLVar plus a penalty or constraint term. This class propagates
105 /// all RooFit information (floating parameters, their values and errors)
106 /// to MINUIT before each MINUIT call and propagates all MINUIT information
107 /// back to the RooFit object at the end of each call (updated parameter
108 /// values, their (asymmetric errors) etc. The default MINUIT error level
109 /// for HESSE and MINOS error analysis is taken from the defaultErrorLevel()
110 /// value of the input function.
111 
112 RooMinimizer::RooMinimizer(RooAbsReal& function)
113 {
114  RooSentinel::activate() ;
115 
116  // Store function reference
117  _extV = 0 ;
118  _func = &function ;
119  _optConst = kFALSE ;
120  _verbose = kFALSE ;
121  _profile = kFALSE ;
122  _profileStart = kFALSE ;
123  _printLevel = 1 ;
124  _minimizerType = "Minuit"; // default minimizer
125 
126  if (_theFitter) delete _theFitter ;
127  _theFitter = new ROOT::Fit::Fitter;
128  _fcn = new RooMinimizerFcn(_func,this,_verbose);
129  _theFitter->Config().SetMinimizer(_minimizerType.c_str());
130  setEps(1.0); // default tolerance
131  // default max number of calls
132  _theFitter->Config().MinimizerOptions().SetMaxIterations(500*_fcn->NDim());
133  _theFitter->Config().MinimizerOptions().SetMaxFunctionCalls(500*_fcn->NDim());
134 
135  // Shut up for now
136  setPrintLevel(-1) ;
137 
138  // Use +0.5 for 1-sigma errors
139  setErrorLevel(_func->defaultErrorLevel()) ;
140 
141  // Declare our parameters to MINUIT
142  _fcn->Synchronize(_theFitter->Config().ParamsSettings(),
143  _optConst,_verbose) ;
144 
145  // Now set default verbosity
146  if (RooMsgService::instance().silentMode()) {
147  setPrintLevel(-1) ;
148  } else {
149  setPrintLevel(1) ;
150  }
151 }
152 
153 
154 
155 ////////////////////////////////////////////////////////////////////////////////
156 /// Destructor
157 
158 RooMinimizer::~RooMinimizer()
159 {
160  if (_extV) {
161  delete _extV ;
162  }
163 
164  if (_fcn) {
165  delete _fcn;
166  }
167 
168 }
169 
170 
171 
172 ////////////////////////////////////////////////////////////////////////////////
173 /// Change MINUIT strategy to istrat. Accepted codes
174 /// are 0,1,2 and represent MINUIT strategies for dealing
175 /// most efficiently with fast FCNs (0), expensive FCNs (2)
176 /// and 'intermediate' FCNs (1)
177 
178 void RooMinimizer::setStrategy(Int_t istrat)
179 {
180  _theFitter->Config().MinimizerOptions().SetStrategy(istrat);
181 
182 }
183 
184 
185 
186 ////////////////////////////////////////////////////////////////////////////////
187 /// Change maximum number of MINUIT iterations
188 /// (RooMinimizer default 500 * #parameters)
189 
190 void RooMinimizer::setMaxIterations(Int_t n)
191 {
192  _theFitter->Config().MinimizerOptions().SetMaxIterations(n);
193 }
194 
195 
196 
197 
198 ////////////////////////////////////////////////////////////////////////////////
199 /// Change maximum number of likelihood function calss from MINUIT
200 /// (RooMinimizer default 500 * #parameters)
201 
202 void RooMinimizer::setMaxFunctionCalls(Int_t n)
203 {
204  _theFitter->Config().MinimizerOptions().SetMaxFunctionCalls(n);
205 }
206 
207 
208 
209 
210 ////////////////////////////////////////////////////////////////////////////////
211 /// Set the level for MINUIT error analysis to the given
212 /// value. This function overrides the default value
213 /// that is taken in the RooMinimizer constructor from
214 /// the defaultErrorLevel() method of the input function
215 
216 void RooMinimizer::setErrorLevel(Double_t level)
217 {
218  _theFitter->Config().MinimizerOptions().SetErrorDef(level);
219 
220 }
221 
222 
223 
224 ////////////////////////////////////////////////////////////////////////////////
225 /// Change MINUIT epsilon
226 
227 void RooMinimizer::setEps(Double_t eps)
228 {
229  _theFitter->Config().MinimizerOptions().SetTolerance(eps);
230 
231 }
232 
233 
234 ////////////////////////////////////////////////////////////////////////////////
235 /// Enable internal likelihood offsetting for enhanced numeric precision
236 
237 void RooMinimizer::setOffsetting(Bool_t flag)
238 {
239  _func->enableOffsetting(flag) ;
240 }
241 
242 
243 
244 
245 ////////////////////////////////////////////////////////////////////////////////
246 /// Choose the minimzer algorithm.
247 
248 void RooMinimizer::setMinimizerType(const char* type)
249 {
250  _minimizerType = type;
251 }
252 
253 
254 
255 
256 ////////////////////////////////////////////////////////////////////////////////
257 /// Return underlying ROOT fitter object
258 
259 ROOT::Fit::Fitter* RooMinimizer::fitter()
260 {
261  return _theFitter ;
262 }
263 
264 
265 ////////////////////////////////////////////////////////////////////////////////
266 /// Return underlying ROOT fitter object
267 
268 const ROOT::Fit::Fitter* RooMinimizer::fitter() const
269 {
270  return _theFitter ;
271 }
272 
273 
274 
275 ////////////////////////////////////////////////////////////////////////////////
276 /// Parse traditional RooAbsPdf::fitTo driver options
277 ///
278 /// m - Run Migrad only
279 /// h - Run Hesse to estimate errors
280 /// v - Verbose mode
281 /// l - Log parameters after each Minuit steps to file
282 /// t - Activate profile timer
283 /// r - Save fit result
284 /// 0 - Run Migrad with strategy 0
285 
286 RooFitResult* RooMinimizer::fit(const char* options)
287 {
288  TString opts(options) ;
289  opts.ToLower() ;
290 
291  // Initial configuration
292  if (opts.Contains("v")) setVerbose(1) ;
293  if (opts.Contains("t")) setProfile(1) ;
294  if (opts.Contains("l")) setLogFile(Form("%s.log",_func->GetName())) ;
295  if (opts.Contains("c")) optimizeConst(1) ;
296 
297  // Fitting steps
298  if (opts.Contains("0")) setStrategy(0) ;
299  migrad() ;
300  if (opts.Contains("0")) setStrategy(1) ;
301  if (opts.Contains("h")||!opts.Contains("m")) hesse() ;
302  if (!opts.Contains("m")) minos() ;
303 
304  return (opts.Contains("r")) ? save() : 0 ;
305 }
306 
307 
308 
309 
310 ////////////////////////////////////////////////////////////////////////////////
311 
312 Int_t RooMinimizer::minimize(const char* type, const char* alg)
313 {
314  _fcn->Synchronize(_theFitter->Config().ParamsSettings(),
315  _optConst,_verbose) ;
316 
317  _theFitter->Config().SetMinimizer(type,alg);
318 
319  profileStart() ;
320  RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::CollectErrors) ;
321  RooAbsReal::clearEvalErrorLog() ;
322 
323  bool ret = _theFitter->FitFCN(*_fcn);
324  _status = ((ret) ? _theFitter->Result().Status() : -1);
325 
326  RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::PrintErrors) ;
327  profileStop() ;
328  _fcn->BackProp(_theFitter->Result());
329 
330  saveStatus("MINIMIZE",_status) ;
331 
332  return _status ;
333 }
334 
335 
336 
337 ////////////////////////////////////////////////////////////////////////////////
338 /// Execute MIGRAD. Changes in parameter values
339 /// and calculated errors are automatically
340 /// propagated back the RooRealVars representing
341 /// the floating parameters in the MINUIT operation
342 
343 Int_t RooMinimizer::migrad()
344 {
345  _fcn->Synchronize(_theFitter->Config().ParamsSettings(),
346  _optConst,_verbose) ;
347  profileStart() ;
348  RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::CollectErrors) ;
349  RooAbsReal::clearEvalErrorLog() ;
350 
351  _theFitter->Config().SetMinimizer(_minimizerType.c_str(),"migrad");
352  bool ret = _theFitter->FitFCN(*_fcn);
353  _status = ((ret) ? _theFitter->Result().Status() : -1);
354 
355  RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::PrintErrors) ;
356  profileStop() ;
357  _fcn->BackProp(_theFitter->Result());
358 
359  saveStatus("MIGRAD",_status) ;
360 
361  return _status ;
362 }
363 
364 
365 
366 ////////////////////////////////////////////////////////////////////////////////
367 /// Execute HESSE. Changes in parameter values
368 /// and calculated errors are automatically
369 /// propagated back the RooRealVars representing
370 /// the floating parameters in the MINUIT operation
371 
372 Int_t RooMinimizer::hesse()
373 {
374  if (_theFitter->GetMinimizer()==0) {
375  coutW(Minimization) << "RooMinimizer::hesse: Error, run Migrad before Hesse!"
376  << endl ;
377  _status = -1;
378  }
379  else {
380 
381  _fcn->Synchronize(_theFitter->Config().ParamsSettings(),
382  _optConst,_verbose) ;
383  profileStart() ;
384  RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::CollectErrors) ;
385  RooAbsReal::clearEvalErrorLog() ;
386 
387  _theFitter->Config().SetMinimizer(_minimizerType.c_str());
388  bool ret = _theFitter->CalculateHessErrors();
389  _status = ((ret) ? _theFitter->Result().Status() : -1);
390 
391  RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::PrintErrors) ;
392  profileStop() ;
393  _fcn->BackProp(_theFitter->Result());
394 
395  saveStatus("HESSE",_status) ;
396 
397  }
398 
399  return _status ;
400 
401 }
402 
403 ////////////////////////////////////////////////////////////////////////////////
404 /// Execute MINOS. Changes in parameter values
405 /// and calculated errors are automatically
406 /// propagated back the RooRealVars representing
407 /// the floating parameters in the MINUIT operation
408 
409 Int_t RooMinimizer::minos()
410 {
411  if (_theFitter->GetMinimizer()==0) {
412  coutW(Minimization) << "RooMinimizer::minos: Error, run Migrad before Minos!"
413  << endl ;
414  _status = -1;
415  }
416  else {
417 
418  _fcn->Synchronize(_theFitter->Config().ParamsSettings(),
419  _optConst,_verbose) ;
420  profileStart() ;
421  RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::CollectErrors) ;
422  RooAbsReal::clearEvalErrorLog() ;
423 
424  _theFitter->Config().SetMinimizer(_minimizerType.c_str());
425  bool ret = _theFitter->CalculateMinosErrors();
426  _status = ((ret) ? _theFitter->Result().Status() : -1);
427 
428  RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::PrintErrors) ;
429  profileStop() ;
430  _fcn->BackProp(_theFitter->Result());
431 
432  saveStatus("MINOS",_status) ;
433 
434  }
435 
436  return _status ;
437 
438 }
439 
440 
441 ////////////////////////////////////////////////////////////////////////////////
442 /// Execute MINOS for given list of parameters. Changes in parameter values
443 /// and calculated errors are automatically
444 /// propagated back the RooRealVars representing
445 /// the floating parameters in the MINUIT operation
446 
447 Int_t RooMinimizer::minos(const RooArgSet& minosParamList)
448 {
449  if (_theFitter->GetMinimizer()==0) {
450  coutW(Minimization) << "RooMinimizer::minos: Error, run Migrad before Minos!"
451  << endl ;
452  _status = -1;
453  }
454  else if (minosParamList.getSize()>0) {
455 
456  _fcn->Synchronize(_theFitter->Config().ParamsSettings(),
457  _optConst,_verbose) ;
458  profileStart() ;
459  RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::CollectErrors) ;
460  RooAbsReal::clearEvalErrorLog() ;
461 
462  // get list of parameters for Minos
463  TIterator* aIter = minosParamList.createIterator() ;
464  RooAbsArg* arg ;
465  std::vector<unsigned int> paramInd;
466  while((arg=(RooAbsArg*)aIter->Next())) {
467  RooAbsArg* par = _fcn->GetFloatParamList()->find(arg->GetName());
468  if (par && !par->isConstant()) {
469  Int_t index = _fcn->GetFloatParamList()->index(par);
470  paramInd.push_back(index);
471  }
472  }
473  delete aIter ;
474 
475  if (paramInd.size()) {
476  // set the parameter indeces
477  _theFitter->Config().SetMinosErrors(paramInd);
478 
479  _theFitter->Config().SetMinimizer(_minimizerType.c_str());
480  bool ret = _theFitter->CalculateMinosErrors();
481  _status = ((ret) ? _theFitter->Result().Status() : -1);
482  // to avoid that following minimization computes automatically the Minos errors
483  _theFitter->Config().SetMinosErrors(kFALSE);
484 
485  }
486 
487  RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::PrintErrors) ;
488  profileStop() ;
489  _fcn->BackProp(_theFitter->Result());
490 
491  saveStatus("MINOS",_status) ;
492 
493  }
494 
495  return _status ;
496 }
497 
498 
499 
500 ////////////////////////////////////////////////////////////////////////////////
501 /// Execute SEEK. Changes in parameter values
502 /// and calculated errors are automatically
503 /// propagated back the RooRealVars representing
504 /// the floating parameters in the MINUIT operation
505 
506 Int_t RooMinimizer::seek()
507 {
508  _fcn->Synchronize(_theFitter->Config().ParamsSettings(),
509  _optConst,_verbose) ;
510  profileStart() ;
511  RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::CollectErrors) ;
512  RooAbsReal::clearEvalErrorLog() ;
513 
514  _theFitter->Config().SetMinimizer(_minimizerType.c_str(),"seek");
515  bool ret = _theFitter->FitFCN(*_fcn);
516  _status = ((ret) ? _theFitter->Result().Status() : -1);
517 
518  RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::PrintErrors) ;
519  profileStop() ;
520  _fcn->BackProp(_theFitter->Result());
521 
522  saveStatus("SEEK",_status) ;
523 
524  return _status ;
525 }
526 
527 
528 
529 ////////////////////////////////////////////////////////////////////////////////
530 /// Execute SIMPLEX. Changes in parameter values
531 /// and calculated errors are automatically
532 /// propagated back the RooRealVars representing
533 /// the floating parameters in the MINUIT operation
534 
535 Int_t RooMinimizer::simplex()
536 {
537  _fcn->Synchronize(_theFitter->Config().ParamsSettings(),
538  _optConst,_verbose) ;
539  profileStart() ;
540  RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::CollectErrors) ;
541  RooAbsReal::clearEvalErrorLog() ;
542 
543  _theFitter->Config().SetMinimizer(_minimizerType.c_str(),"simplex");
544  bool ret = _theFitter->FitFCN(*_fcn);
545  _status = ((ret) ? _theFitter->Result().Status() : -1);
546 
547  RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::PrintErrors) ;
548  profileStop() ;
549  _fcn->BackProp(_theFitter->Result());
550 
551  saveStatus("SEEK",_status) ;
552 
553  return _status ;
554 }
555 
556 
557 
558 ////////////////////////////////////////////////////////////////////////////////
559 /// Execute IMPROVE. Changes in parameter values
560 /// and calculated errors are automatically
561 /// propagated back the RooRealVars representing
562 /// the floating parameters in the MINUIT operation
563 
564 Int_t RooMinimizer::improve()
565 {
566  _fcn->Synchronize(_theFitter->Config().ParamsSettings(),
567  _optConst,_verbose) ;
568  profileStart() ;
569  RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::CollectErrors) ;
570  RooAbsReal::clearEvalErrorLog() ;
571 
572  _theFitter->Config().SetMinimizer(_minimizerType.c_str(),"migradimproved");
573  bool ret = _theFitter->FitFCN(*_fcn);
574  _status = ((ret) ? _theFitter->Result().Status() : -1);
575 
576  RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::PrintErrors) ;
577  profileStop() ;
578  _fcn->BackProp(_theFitter->Result());
579 
580  saveStatus("IMPROVE",_status) ;
581 
582  return _status ;
583 }
584 
585 
586 
587 ////////////////////////////////////////////////////////////////////////////////
588 /// Change the MINUIT internal printing level
589 
590 Int_t RooMinimizer::setPrintLevel(Int_t newLevel)
591 {
592  Int_t ret = _printLevel ;
593  _theFitter->Config().MinimizerOptions().SetPrintLevel(newLevel+1);
594  _printLevel = newLevel+1 ;
595  return ret ;
596 }
597 
598 ////////////////////////////////////////////////////////////////////////////////
599 /// If flag is true, perform constant term optimization on
600 /// function being minimized.
601 
602 void RooMinimizer::optimizeConst(Int_t flag)
603 {
604  RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::CollectErrors) ;
605 
606  if (_optConst && !flag){
607  if (_printLevel>-1) coutI(Minimization) << "RooMinimizer::optimizeConst: deactivating const optimization" << endl ;
608  _func->constOptimizeTestStatistic(RooAbsArg::DeActivate) ;
609  _optConst = flag ;
610  } else if (!_optConst && flag) {
611  if (_printLevel>-1) coutI(Minimization) << "RooMinimizer::optimizeConst: activating const optimization" << endl ;
612  _func->constOptimizeTestStatistic(RooAbsArg::Activate,flag>1) ;
613  _optConst = flag ;
614  } else if (_optConst && flag) {
615  if (_printLevel>-1) coutI(Minimization) << "RooMinimizer::optimizeConst: const optimization already active" << endl ;
616  } else {
617  if (_printLevel>-1) coutI(Minimization) << "RooMinimizer::optimizeConst: const optimization wasn't active" << endl ;
618  }
619 
620  RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::PrintErrors) ;
621 
622 }
623 
624 
625 
626 ////////////////////////////////////////////////////////////////////////////////
627 /// Save and return a RooFitResult snaphot of current minimizer status.
628 /// This snapshot contains the values of all constant parameters,
629 /// the value of all floating parameters at RooMinimizer construction and
630 /// after the last MINUIT operation, the MINUIT status, variance quality,
631 /// EDM setting, number of calls with evaluation problems, the minimized
632 /// function value and the full correlation matrix
633 
634 RooFitResult* RooMinimizer::save(const char* userName, const char* userTitle)
635 {
636  if (_theFitter->GetMinimizer()==0) {
637  coutW(Minimization) << "RooMinimizer::save: Error, run minimization before!"
638  << endl ;
639  return 0;
640  }
641 
642  TString name,title ;
643  name = userName ? userName : Form("%s", _func->GetName()) ;
644  title = userTitle ? userTitle : Form("%s", _func->GetTitle()) ;
645  RooFitResult* fitRes = new RooFitResult(name,title) ;
646 
647  // Move eventual fixed parameters in floatList to constList
648  Int_t i ;
649  RooArgList saveConstList(*(_fcn->GetConstParamList())) ;
650  RooArgList saveFloatInitList(*(_fcn->GetInitFloatParamList())) ;
651  RooArgList saveFloatFinalList(*(_fcn->GetFloatParamList())) ;
652  for (i=0 ; i<_fcn->GetFloatParamList()->getSize() ; i++) {
653  RooAbsArg* par = _fcn->GetFloatParamList()->at(i) ;
654  if (par->isConstant()) {
655  saveFloatInitList.remove(*saveFloatInitList.find(par->GetName()),kTRUE) ;
656  saveFloatFinalList.remove(*par) ;
657  saveConstList.add(*par) ;
658  }
659  }
660  saveConstList.sort() ;
661 
662  fitRes->setConstParList(saveConstList) ;
663  fitRes->setInitParList(saveFloatInitList) ;
664 
665  fitRes->setStatus(_status) ;
666  fitRes->setCovQual(_theFitter->GetMinimizer()->CovMatrixStatus()) ;
667  fitRes->setMinNLL(_theFitter->Result().MinFcnValue()) ;
668  fitRes->setNumInvalidNLL(_fcn->GetNumInvalidNLL()) ;
669  fitRes->setEDM(_theFitter->Result().Edm()) ;
670  fitRes->setFinalParList(saveFloatFinalList) ;
671  if (!_extV) {
672  std::vector<double> globalCC;
673  TMatrixDSym corrs(_theFitter->Result().Parameters().size()) ;
674  TMatrixDSym covs(_theFitter->Result().Parameters().size()) ;
675  for (UInt_t ic=0; ic<_theFitter->Result().Parameters().size(); ic++) {
676  globalCC.push_back(_theFitter->Result().GlobalCC(ic));
677  for (UInt_t ii=0; ii<_theFitter->Result().Parameters().size(); ii++) {
678  corrs(ic,ii) = _theFitter->Result().Correlation(ic,ii);
679  covs(ic,ii) = _theFitter->Result().CovMatrix(ic,ii);
680  }
681  }
682  fitRes->fillCorrMatrix(globalCC,corrs,covs) ;
683  } else {
684  fitRes->setCovarianceMatrix(*_extV) ;
685  }
686 
687  fitRes->setStatusHistory(_statusHistory) ;
688 
689  return fitRes ;
690 
691 }
692 
693 ////////////////////////////////////////////////////////////////////////////////
694 /// Create and draw a TH2 with the error contours in the parameters `var1` and `var2`.
695 /// \param[in] var1 The first parameter (x axis).
696 /// \param[in] var2 The second parameter (y axis).
697 /// \param[in] n1 First contour.
698 /// \param[in] n2 Optional contour. 0 means don't draw.
699 /// \param[in] n3 Optional contour. 0 means don't draw.
700 /// \param[in] n4 Optional contour. 0 means don't draw.
701 /// \param[in] n5 Optional contour. 0 means don't draw.
702 /// \param[in] n6 Optional contour. 0 means don't draw.
703 /// \param[in] npoints Number of points for evaluating the contour.
704 ///
705 /// Up to six contours can be drawn using the arguments `n1` to `n6` to request the desired
706 /// coverage in units of \f$ \sigma = n^2 \cdot \mathrm{ErrorDef} \f$.
707 /// See ROOT::Math::Minimizer::ErrorDef().
708 
709 RooPlot* RooMinimizer::contour(RooRealVar& var1, RooRealVar& var2,
710  Double_t n1, Double_t n2, Double_t n3,
711  Double_t n4, Double_t n5, Double_t n6, unsigned int npoints)
712 {
713 
714 
715  RooArgList* params = _fcn->GetFloatParamList() ;
716  RooArgList* paramSave = (RooArgList*) params->snapshot() ;
717 
718  // Verify that both variables are floating parameters of PDF
719  Int_t index1= _fcn->GetFloatParamList()->index(&var1);
720  if(index1 < 0) {
721  coutE(Minimization) << "RooMinimizer::contour(" << GetName()
722  << ") ERROR: " << var1.GetName()
723  << " is not a floating parameter of "
724  << _func->GetName() << endl ;
725  return 0;
726  }
727 
728  Int_t index2= _fcn->GetFloatParamList()->index(&var2);
729  if(index2 < 0) {
730  coutE(Minimization) << "RooMinimizer::contour(" << GetName()
731  << ") ERROR: " << var2.GetName()
732  << " is not a floating parameter of PDF "
733  << _func->GetName() << endl ;
734  return 0;
735  }
736 
737  // create and draw a frame
738  RooPlot* frame = new RooPlot(var1,var2) ;
739 
740  // draw a point at the current parameter values
741  TMarker *point= new TMarker(var1.getVal(), var2.getVal(), 8);
742  frame->addObject(point) ;
743 
744  // check first if a inimizer is available. If not means
745  // the minimization is not done , so do it
746  if (_theFitter->GetMinimizer()==0) {
747  coutW(Minimization) << "RooMinimizer::contour: Error, run Migrad before contours!"
748  << endl ;
749  return frame;
750  }
751 
752 
753  // remember our original value of ERRDEF
754  Double_t errdef= _theFitter->GetMinimizer()->ErrorDef();
755 
756  Double_t n[6] ;
757  n[0] = n1 ; n[1] = n2 ; n[2] = n3 ; n[3] = n4 ; n[4] = n5 ; n[5] = n6 ;
758 
759  for (Int_t ic = 0 ; ic<6 ; ic++) {
760  if(n[ic] > 0) {
761 
762  // set the value corresponding to an n1-sigma contour
763  _theFitter->GetMinimizer()->SetErrorDef(n[ic]*n[ic]*errdef);
764 
765  // calculate and draw the contour
766  Double_t *xcoor = new Double_t[npoints+1];
767  Double_t *ycoor = new Double_t[npoints+1];
768  bool ret = _theFitter->GetMinimizer()->Contour(index1,index2,npoints,xcoor,ycoor);
769 
770  if (!ret) {
771  coutE(Minimization) << "RooMinimizer::contour("
772  << GetName()
773  << ") ERROR: MINUIT did not return a contour graph for n="
774  << n[ic] << endl ;
775  } else {
776  xcoor[npoints] = xcoor[0];
777  ycoor[npoints] = ycoor[0];
778  TGraph* graph = new TGraph(npoints+1,xcoor,ycoor);
779 
780  graph->SetName(Form("contour_%s_n%f",_func->GetName(),n[ic])) ;
781  graph->SetLineStyle(ic+1) ;
782  graph->SetLineWidth(2) ;
783  graph->SetLineColor(kBlue) ;
784  frame->addObject(graph,"L") ;
785  }
786 
787  delete [] xcoor;
788  delete [] ycoor;
789  }
790  }
791 
792 
793  // restore the original ERRDEF
794  _theFitter->Config().MinimizerOptions().SetErrorDef(errdef);
795 
796  // restore parameter values
797  *params = *paramSave ;
798  delete paramSave ;
799 
800  return frame ;
801 
802 }
803 
804 
805 ////////////////////////////////////////////////////////////////////////////////
806 /// Start profiling timer
807 
808 void RooMinimizer::profileStart()
809 {
810  if (_profile) {
811  _timer.Start() ;
812  _cumulTimer.Start(_profileStart?kFALSE:kTRUE) ;
813  _profileStart = kTRUE ;
814  }
815 }
816 
817 
818 ////////////////////////////////////////////////////////////////////////////////
819 /// Stop profiling timer and report results of last session
820 
821 void RooMinimizer::profileStop()
822 {
823  if (_profile) {
824  _timer.Stop() ;
825  _cumulTimer.Stop() ;
826  coutI(Minimization) << "Command timer: " ; _timer.Print() ;
827  coutI(Minimization) << "Session timer: " ; _cumulTimer.Print() ;
828  }
829 }
830 
831 
832 
833 
834 
835 ////////////////////////////////////////////////////////////////////////////////
836 /// Apply results of given external covariance matrix. i.e. propagate its errors
837 /// to all RRV parameter representations and give this matrix instead of the
838 /// HESSE matrix at the next save() call
839 
840 void RooMinimizer::applyCovarianceMatrix(TMatrixDSym& V)
841 {
842  _extV = (TMatrixDSym*) V.Clone() ;
843  _fcn->ApplyCovarianceMatrix(*_extV);
844 
845 }
846 
847 
848 
849 RooFitResult* RooMinimizer::lastMinuitFit(const RooArgList& varList)
850 {
851  // Import the results of the last fit performed, interpreting
852  // the fit parameters as the given varList of parameters.
853 
854  if (_theFitter==0 || _theFitter->GetMinimizer()==0) {
855  oocoutE((TObject*)0,InputArguments) << "RooMinimizer::save: Error, run minimization before!"
856  << endl ;
857  return 0;
858  }
859 
860  // Verify length of supplied varList
861  if (varList.getSize()>0 && varList.getSize()!=Int_t(_theFitter->Result().NTotalParameters())) {
862  oocoutE((TObject*)0,InputArguments)
863  << "RooMinimizer::lastMinuitFit: ERROR: supplied variable list must be either empty " << endl
864  << " or match the number of variables of the last fit ("
865  << _theFitter->Result().NTotalParameters() << ")" << endl ;
866  return 0 ;
867  }
868 
869 
870  // Verify that all members of varList are of type RooRealVar
871  TIterator* iter = varList.createIterator() ;
872  RooAbsArg* arg ;
873  while((arg=(RooAbsArg*)iter->Next())) {
874  if (!dynamic_cast<RooRealVar*>(arg)) {
875  oocoutE((TObject*)0,InputArguments) << "RooMinimizer::lastMinuitFit: ERROR: variable '"
876  << arg->GetName() << "' is not of type RooRealVar" << endl ;
877  return 0 ;
878  }
879  }
880  delete iter ;
881 
882  RooFitResult* res = new RooFitResult("lastMinuitFit","Last MINUIT fit") ;
883 
884  // Extract names of fit parameters
885  // and construct corresponding RooRealVars
886  RooArgList constPars("constPars") ;
887  RooArgList floatPars("floatPars") ;
888 
889  UInt_t i ;
890  for (i = 0; i < _theFitter->Result().NTotalParameters(); ++i) {
891 
892  TString varName(_theFitter->Result().GetParameterName(i));
893  Bool_t isConst(_theFitter->Result().IsParameterFixed(i)) ;
894 
895  Double_t xlo = _theFitter->Config().ParSettings(i).LowerLimit();
896  Double_t xhi = _theFitter->Config().ParSettings(i).UpperLimit();
897  Double_t xerr = _theFitter->Result().Error(i);
898  Double_t xval = _theFitter->Result().Value(i);
899 
900  RooRealVar* var ;
901  if (varList.getSize()==0) {
902 
903  if ((xlo<xhi) && !isConst) {
904  var = new RooRealVar(varName,varName,xval,xlo,xhi) ;
905  } else {
906  var = new RooRealVar(varName,varName,xval) ;
907  }
908  var->setConstant(isConst) ;
909  } else {
910 
911  var = (RooRealVar*) varList.at(i)->Clone() ;
912  var->setConstant(isConst) ;
913  var->setVal(xval) ;
914  if (xlo<xhi) {
915  var->setRange(xlo,xhi) ;
916  }
917 
918  if (varName.CompareTo(var->GetName())) {
919  oocoutI((TObject*)0,Eval) << "RooMinimizer::lastMinuitFit: fit parameter '" << varName
920  << "' stored in variable '" << var->GetName() << "'" << endl ;
921  }
922 
923  }
924 
925  if (isConst) {
926  constPars.addOwned(*var) ;
927  } else {
928  var->setError(xerr) ;
929  floatPars.addOwned(*var) ;
930  }
931  }
932 
933  res->setConstParList(constPars) ;
934  res->setInitParList(floatPars) ;
935  res->setFinalParList(floatPars) ;
936  res->setMinNLL(_theFitter->Result().MinFcnValue()) ;
937  res->setEDM(_theFitter->Result().Edm()) ;
938  res->setCovQual(_theFitter->GetMinimizer()->CovMatrixStatus()) ;
939  res->setStatus(_theFitter->Result().Status()) ;
940  std::vector<double> globalCC;
941  TMatrixDSym corrs(_theFitter->Result().Parameters().size()) ;
942  TMatrixDSym covs(_theFitter->Result().Parameters().size()) ;
943  for (UInt_t ic=0; ic<_theFitter->Result().Parameters().size(); ic++) {
944  globalCC.push_back(_theFitter->Result().GlobalCC(ic));
945  for (UInt_t ii=0; ii<_theFitter->Result().Parameters().size(); ii++) {
946  corrs(ic,ii) = _theFitter->Result().Correlation(ic,ii);
947  covs(ic,ii) = _theFitter->Result().CovMatrix(ic,ii);
948  }
949  }
950  res->fillCorrMatrix(globalCC,corrs,covs) ;
951 
952  return res;
953 
954 }
955 
956 #endif