14 #ifndef __ROOFIT_NOROOMINIMIZER
43 RooMinimizerFcn::RooMinimizerFcn(RooAbsReal *funct, RooMinimizer* context,
45 _funct(funct), _context(context),
47 _maxFCN(-1e30), _numBadNLL(0),
48 _printEvalErrors(10), _doEvalErrorWall(kTRUE),
49 _nDim(0), _logfile(0),
56 RooArgSet* paramSet = _funct->getParameters(RooArgSet());
57 RooArgList paramList(*paramSet);
60 _floatParamList = (RooArgList*) paramList.selectByAttrib(
"Constant",kFALSE);
61 if (_floatParamList->getSize()>1) {
62 _floatParamList->sort();
64 _floatParamList->setName(
"floatParamList");
66 _constParamList = (RooArgList*) paramList.selectByAttrib(
"Constant",kTRUE);
67 if (_constParamList->getSize()>1) {
68 _constParamList->sort();
70 _constParamList->setName(
"constParamList");
73 TIterator* pIter = _floatParamList->createIterator();
75 while ((arg=(RooAbsArg*)pIter->Next())) {
76 if (!arg->IsA()->InheritsFrom(RooAbsRealLValue::Class())) {
77 oocoutW(_context,Minimization) <<
"RooMinimizerFcn::RooMinimizerFcn: removing parameter "
79 <<
" from list because it is not of type RooRealVar" << endl;
80 _floatParamList->remove(*arg);
85 _nDim = _floatParamList->getSize();
90 _initFloatParamList = (RooArgList*) _floatParamList->snapshot(kFALSE) ;
91 _initConstParamList = (RooArgList*) _constParamList->snapshot(kFALSE) ;
97 RooMinimizerFcn::RooMinimizerFcn(
const RooMinimizerFcn& other) : ROOT::Math::IBaseFunctionMultiDim(other),
98 _evalCounter(other._evalCounter),
100 _context(other._context),
101 _maxFCN(other._maxFCN),
102 _numBadNLL(other._numBadNLL),
103 _printEvalErrors(other._printEvalErrors),
104 _doEvalErrorWall(other._doEvalErrorWall),
106 _logfile(other._logfile),
107 _verbose(other._verbose),
108 _floatParamVec(other._floatParamVec)
110 _floatParamList =
new RooArgList(*other._floatParamList) ;
111 _constParamList =
new RooArgList(*other._constParamList) ;
112 _initFloatParamList = (RooArgList*) other._initFloatParamList->snapshot(kFALSE) ;
113 _initConstParamList = (RooArgList*) other._initConstParamList->snapshot(kFALSE) ;
117 RooMinimizerFcn::~RooMinimizerFcn()
119 delete _floatParamList;
120 delete _initFloatParamList;
121 delete _constParamList;
122 delete _initConstParamList;
126 ROOT::Math::IBaseFunctionMultiDim* RooMinimizerFcn::Clone()
const
128 return new RooMinimizerFcn(*
this) ;
132 Bool_t RooMinimizerFcn::Synchronize(std::vector<ROOT::Fit::ParameterSettings>& parameters,
133 Bool_t optConst, Bool_t verbose)
139 Bool_t constValChange(kFALSE) ;
140 Bool_t constStatChange(kFALSE) ;
145 for(index= 0; index < _constParamList->getSize() ; index++) {
147 RooRealVar *par=
dynamic_cast<RooRealVar*
>(_constParamList->at(index)) ;
150 RooRealVar *oldpar=
dynamic_cast<RooRealVar*
>(_initConstParamList->at(index)) ;
151 if (!oldpar) continue ;
154 if (!par->isConstant()) {
157 _constParamList->remove(*par) ;
158 _floatParamList->add(*par) ;
159 _initFloatParamList->addClone(*oldpar) ;
160 _initConstParamList->remove(*oldpar) ;
161 constStatChange=kTRUE ;
165 oocoutI(_context,Minimization) <<
"RooMinimizerFcn::synchronize: parameter "
166 << par->GetName() <<
" is now floating." << endl ;
171 if (par->getVal()!= oldpar->getVal()) {
172 constValChange=kTRUE ;
174 oocoutI(_context,Minimization) <<
"RooMinimizerFcn::synchronize: value of constant parameter "
176 <<
" changed from " << oldpar->getVal() <<
" to "
177 << par->getVal() << endl ;
184 *_initConstParamList = *_constParamList ;
188 for(index= 0; index < _floatParamList->getSize(); index++) {
189 RooRealVar *par=
dynamic_cast<RooRealVar*
>(_floatParamList->at(index)) ;
197 if(!par->isConstant()) {
200 if (!par->IsA()->InheritsFrom(RooRealVar::Class())) {
201 oocoutW(_context,Minimization) <<
"RooMinimizerFcn::fit: Error, non-constant parameter "
203 <<
" is not of type RooRealVar, skipping" << endl ;
204 _floatParamList->remove(*par);
212 pmin = par->getMin();
214 pmax = par->getMax();
217 pstep = par->getError();
220 if (par->hasMin() && par->hasMax()) {
221 pstep= 0.1*(pmax-pmin);
224 if (pmax - par->getVal() < 2*pstep) {
225 pstep = (pmax - par->getVal())/2 ;
226 }
else if (par->getVal() - pmin < 2*pstep) {
227 pstep = (par->getVal() - pmin )/2 ;
232 pstep= 0.1*(pmax-pmin);
239 oocoutW(_context,Minimization) <<
"RooMinimizerFcn::synchronize: WARNING: no initial error estimate available for "
240 << par->GetName() <<
": using " << pstep << endl;
244 pmin = par->getVal() ;
245 pmax = par->getVal() ;
249 if (index>=Int_t(parameters.size())) {
251 if (par->hasMin() && par->hasMax()) {
252 parameters.push_back(ROOT::Fit::ParameterSettings(par->GetName(),
258 parameters.push_back(ROOT::Fit::ParameterSettings(par->GetName(),
262 parameters.back().SetLowerLimit(pmin);
263 else if (par->hasMax() )
264 parameters.back().SetUpperLimit(pmax);
271 Bool_t oldFixed = parameters[index].IsFixed();
272 Double_t oldVar = parameters[index].Value();
273 Double_t oldVerr = parameters[index].StepSize();
274 Double_t oldVlo = parameters[index].LowerLimit();
275 Double_t oldVhi = parameters[index].UpperLimit();
277 if (par->isConstant() && !oldFixed) {
280 if (oldVar!=par->getVal()) {
281 parameters[index].SetValue(par->getVal());
283 oocoutI(_context,Minimization) <<
"RooMinimizerFcn::synchronize: value of parameter "
284 << par->GetName() <<
" changed from " << oldVar
285 <<
" to " << par->getVal() << endl ;
288 parameters[index].Fix();
289 constStatChange=kTRUE ;
291 oocoutI(_context,Minimization) <<
"RooMinimizerFcn::synchronize: parameter "
292 << par->GetName() <<
" is now fixed." << endl ;
295 }
else if (par->isConstant() && oldFixed) {
298 if (oldVar!=par->getVal()) {
299 parameters[index].SetValue(par->getVal());
300 constValChange=kTRUE ;
303 oocoutI(_context,Minimization) <<
"RooMinimizerFcn::synchronize: value of fixed parameter "
304 << par->GetName() <<
" changed from " << oldVar
305 <<
" to " << par->getVal() << endl ;
311 if (!par->isConstant() && oldFixed) {
312 parameters[index].Release();
313 constStatChange=kTRUE ;
316 oocoutI(_context,Minimization) <<
"RooMinimizerFcn::synchronize: parameter "
317 << par->GetName() <<
" is now floating." << endl ;
322 if (oldVar!=par->getVal() || oldVlo!=pmin || oldVhi != pmax || oldVerr!=pstep) {
323 parameters[index].SetValue(par->getVal());
324 parameters[index].SetStepSize(pstep);
325 if (par->hasMin() && par->hasMax() )
326 parameters[index].SetLimits(pmin,pmax);
327 else if (par->hasMin() )
328 parameters[index].SetLowerLimit(pmin);
329 else if (par->hasMax() )
330 parameters[index].SetUpperLimit(pmax);
337 if (oldVar!=par->getVal()) {
338 oocoutI(_context,Minimization) <<
"RooMinimizerFcn::synchronize: value of parameter "
339 << par->GetName() <<
" changed from " << oldVar <<
" to "
340 << par->getVal() << endl ;
342 if (oldVlo!=pmin || oldVhi!=pmax) {
343 oocoutI(_context,Minimization) <<
"RooMinimizerFcn::synchronize: limits of parameter "
344 << par->GetName() <<
" changed from [" << oldVlo <<
"," << oldVhi
345 <<
"] to [" << pmin <<
"," << pmax <<
"]" << endl ;
349 if (oldVerr!=pstep && oldVerr!=0) {
350 oocoutI(_context,Minimization) <<
"RooMinimizerFcn::synchronize: error/step size of parameter "
351 << par->GetName() <<
" changed from " << oldVerr <<
" to " << pstep << endl ;
358 if (constStatChange) {
360 RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::CollectErrors) ;
362 oocoutI(_context,Minimization) <<
"RooMinimizerFcn::synchronize: set of constant parameters changed, rerunning const optimizer" << endl ;
363 _funct->constOptimizeTestStatistic(RooAbsArg::ConfigChange) ;
364 }
else if (constValChange) {
365 oocoutI(_context,Minimization) <<
"RooMinimizerFcn::synchronize: constant parameter values changed, rerunning const optimizer" << endl ;
366 _funct->constOptimizeTestStatistic(RooAbsArg::ValueChange) ;
369 RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::PrintErrors) ;
379 Double_t RooMinimizerFcn::GetPdfParamVal(Int_t index)
383 return ((RooRealVar*)_floatParamList->at(index))->getVal() ;
386 Double_t RooMinimizerFcn::GetPdfParamErr(Int_t index)
389 return ((RooRealVar*)_floatParamList->at(index))->getError() ;
393 void RooMinimizerFcn::SetPdfParamErr(Int_t index, Double_t value)
397 ((RooRealVar*)_floatParamList->at(index))->setError(value) ;
402 void RooMinimizerFcn::ClearPdfParamAsymErr(Int_t index)
406 ((RooRealVar*)_floatParamList->at(index))->removeAsymError() ;
410 void RooMinimizerFcn::SetPdfParamErr(Int_t index, Double_t loVal, Double_t hiVal)
414 ((RooRealVar*)_floatParamList->at(index))->setAsymError(loVal,hiVal) ;
418 void RooMinimizerFcn::BackProp(
const ROOT::Fit::FitResult &results)
422 for (Int_t index= 0; index < _nDim; index++) {
423 Double_t value = results.Value(index);
424 SetPdfParamVal(index, value);
427 Double_t err = results.Error(index);
428 SetPdfParamErr(index, err);
430 Double_t eminus = results.LowerError(index);
431 Double_t eplus = results.UpperError(index);
433 if(eplus > 0 || eminus < 0) {
435 SetPdfParamErr(index, eminus,eplus);
438 ClearPdfParamAsymErr(index) ;
444 Bool_t RooMinimizerFcn::SetLogFile(
const char* inLogfile)
451 oocoutI(_context,Minimization) <<
"RooMinimizerFcn::setLogFile: closing previous log file" << endl ;
456 _logfile =
new ofstream(inLogfile) ;
457 if (!_logfile->good()) {
458 oocoutI(_context,Minimization) <<
"RooMinimizerFcn::setLogFile: cannot open file " << inLogfile << endl ;
469 void RooMinimizerFcn::ApplyCovarianceMatrix(TMatrixDSym& V)
475 for (Int_t i=0 ; i<_nDim ; i++) {
477 if (_floatParamList->at(i)->isConstant()) {
480 SetPdfParamErr(i, sqrt(V(i,i))) ;
486 Bool_t RooMinimizerFcn::SetPdfParamVal(
const Int_t &index,
const Double_t &value)
const
489 RooRealVar* par = (RooRealVar*)_floatParamVec[index] ;
491 if (par->getVal()!=value) {
492 if (_verbose) cout << par->GetName() <<
"=" << value <<
", " ;
505 void RooMinimizerFcn::updateFloatVec()
507 _floatParamVec.clear() ;
508 RooFIter iter = _floatParamList->fwdIterator() ;
510 _floatParamVec = std::vector<RooAbsArg*>(_floatParamList->getSize()) ;
512 while((arg=iter.next())) {
513 _floatParamVec[i++] = arg ;
519 double RooMinimizerFcn::DoEval(
const double *x)
const
523 for (
int index = 0; index < _nDim; index++) {
524 if (_logfile) (*_logfile) << x[index] <<
" " ;
525 SetPdfParamVal(index,x[index]);
529 RooAbsReal::setHideOffset(kFALSE) ;
530 double fvalue = _funct->getVal();
531 RooAbsReal::setHideOffset(kTRUE) ;
533 if (RooAbsReal::numEvalErrors()>0 || fvalue > 1e30) {
535 if (_printEvalErrors>=0) {
537 if (_doEvalErrorWall) {
538 oocoutW(_context,Minimization) <<
"RooMinimizerFcn: Minimized function has error status." << endl
539 <<
"Returning maximum FCN so far (" << _maxFCN
540 <<
") to force MIGRAD to back out of this region. Error log follows" << endl ;
542 oocoutW(_context,Minimization) <<
"RooMinimizerFcn: Minimized function has error status but is ignored" << endl ;
545 Bool_t first(kTRUE) ;
546 ooccoutW(_context,Minimization) <<
"Parameter values: " ;
547 for (
const auto par : *_floatParamList) {
548 auto var =
static_cast<const RooRealVar*
>(par);
549 if (first) { first = kFALSE ; }
else ooccoutW(_context,Minimization) <<
", " ;
550 ooccoutW(_context,Minimization) << var->GetName() <<
"=" << var->getVal() ;
552 ooccoutW(_context,Minimization) << endl ;
554 RooAbsReal::printEvalErrors(ooccoutW(_context,Minimization),_printEvalErrors) ;
555 ooccoutW(_context,Minimization) << endl ;
558 if (_doEvalErrorWall) {
562 RooAbsReal::clearEvalErrorLog() ;
565 _maxFCN = std::max(fvalue, _maxFCN);
570 (*_logfile) << setprecision(15) << fvalue << setprecision(4) << endl;
572 cout <<
"\nprevFCN" << (_funct->isOffsetting()?
"-offset":
"") <<
" = " << setprecision(10)
573 << fvalue << setprecision(4) <<
" " ;