00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef __ROOFIT_NOROOMINIMIZER
00015
00016
00017
00018
00019
00020
00021
00022 #include <iostream>
00023
00024 #include "RooFit.h"
00025 #include "RooMinimizerFcn.h"
00026
00027 #include "Riostream.h"
00028
00029 #include "TIterator.h"
00030 #include "TClass.h"
00031
00032 #include "RooAbsArg.h"
00033 #include "RooAbsPdf.h"
00034 #include "RooArgSet.h"
00035 #include "RooRealVar.h"
00036 #include "RooAbsRealLValue.h"
00037 #include "RooMsgService.h"
00038
00039 #include "RooMinimizer.h"
00040
00041 RooMinimizerFcn::RooMinimizerFcn(RooAbsReal *funct, RooMinimizer* context,
00042 bool verbose) :
00043 _funct(funct), _context(context),
00044
00045 _maxFCN(-1e30), _numBadNLL(0),
00046 _printEvalErrors(10), _doEvalErrorWall(kTRUE),
00047 _nDim(0), _logfile(0),
00048 _verbose(verbose)
00049 {
00050
00051
00052 RooArgSet* paramSet = _funct->getParameters(RooArgSet());
00053 RooArgList paramList(*paramSet);
00054 delete paramSet;
00055
00056 _floatParamList = (RooArgList*) paramList.selectByAttrib("Constant",kFALSE);
00057 if (_floatParamList->getSize()>1) {
00058 _floatParamList->sort();
00059 }
00060 _floatParamList->setName("floatParamList");
00061
00062 _constParamList = (RooArgList*) paramList.selectByAttrib("Constant",kTRUE);
00063 if (_constParamList->getSize()>1) {
00064 _constParamList->sort();
00065 }
00066 _constParamList->setName("constParamList");
00067
00068
00069 TIterator* pIter = _floatParamList->createIterator();
00070 RooAbsArg* arg;
00071 while ((arg=(RooAbsArg*)pIter->Next())) {
00072 if (!arg->IsA()->InheritsFrom(RooAbsRealLValue::Class())) {
00073 oocoutW(_context,Minimization) << "RooMinimizerFcn::RooMinimizerFcn: removing parameter "
00074 << arg->GetName()
00075 << " from list because it is not of type RooRealVar" << endl;
00076 _floatParamList->remove(*arg);
00077 }
00078 }
00079 delete pIter;
00080
00081 _nDim = _floatParamList->getSize();
00082
00083
00084 _initFloatParamList = (RooArgList*) _floatParamList->snapshot(kFALSE) ;
00085 _initConstParamList = (RooArgList*) _constParamList->snapshot(kFALSE) ;
00086
00087 }
00088
00089 RooMinimizerFcn::~RooMinimizerFcn()
00090 {
00091 delete _floatParamList;
00092 delete _initFloatParamList;
00093 delete _constParamList;
00094 delete _initConstParamList;
00095 }
00096
00097 ROOT::Math::IBaseFunctionMultiDim* RooMinimizerFcn::Clone() const
00098 {
00099 return new RooMinimizerFcn(_funct,_context,_verbose);
00100 }
00101
00102 Bool_t RooMinimizerFcn::Synchronize(std::vector<ROOT::Fit::ParameterSettings>& parameters,
00103 Bool_t optConst, Bool_t verbose)
00104 {
00105
00106
00107
00108
00109 Bool_t constValChange(kFALSE) ;
00110 Bool_t constStatChange(kFALSE) ;
00111
00112 Int_t index(0) ;
00113
00114
00115 for(index= 0; index < _constParamList->getSize() ; index++) {
00116
00117 RooRealVar *par= dynamic_cast<RooRealVar*>(_constParamList->at(index)) ;
00118 if (!par) continue ;
00119
00120 RooRealVar *oldpar= dynamic_cast<RooRealVar*>(_initConstParamList->at(index)) ;
00121 if (!oldpar) continue ;
00122
00123
00124 if (!par->isConstant()) {
00125
00126
00127 _constParamList->remove(*par) ;
00128 _floatParamList->add(*par) ;
00129 _initFloatParamList->addClone(*oldpar) ;
00130 _initConstParamList->remove(*oldpar) ;
00131 constStatChange=kTRUE ;
00132 _nDim++ ;
00133
00134 if (verbose) {
00135 oocoutI(_context,Minimization) << "RooMinimizerFcn::synchronize: parameter "
00136 << par->GetName() << " is now floating." << endl ;
00137 }
00138 }
00139
00140
00141 if (par->getVal()!= oldpar->getVal()) {
00142 constValChange=kTRUE ;
00143 if (verbose) {
00144 oocoutI(_context,Minimization) << "RooMinimizerFcn::synchronize: value of constant parameter "
00145 << par->GetName()
00146 << " changed from " << oldpar->getVal() << " to "
00147 << par->getVal() << endl ;
00148 }
00149 }
00150
00151 }
00152
00153
00154 *_initConstParamList = *_constParamList ;
00155
00156
00157
00158 for(index= 0; index < _floatParamList->getSize(); index++) {
00159 RooRealVar *par= dynamic_cast<RooRealVar*>(_floatParamList->at(index)) ;
00160 if (!par) continue ;
00161
00162 Double_t pstep(0) ;
00163 Double_t pmin(0) ;
00164 Double_t pmax(0) ;
00165
00166 if(!par->isConstant()) {
00167
00168
00169 if (!par->IsA()->InheritsFrom(RooRealVar::Class())) {
00170 oocoutW(_context,Minimization) << "RooMinimizerFcn::fit: Error, non-constant parameter "
00171 << par->GetName()
00172 << " is not of type RooRealVar, skipping" << endl ;
00173 _floatParamList->remove(*par);
00174 index--;
00175 _nDim--;
00176 continue ;
00177 }
00178
00179
00180 if (par->hasMin() && par->hasMax()) {
00181 pmin = par->getMin();
00182 pmax = par->getMax();
00183 }
00184
00185
00186 pstep = par->getError();
00187 if(pstep <= 0) {
00188
00189 if (par->hasMin() && par->hasMax()) {
00190 pstep= 0.1*(pmax-pmin);
00191
00192
00193 if (pmax - par->getVal() < 2*pstep) {
00194 pstep = (pmax - par->getVal())/2 ;
00195 } else if (par->getVal() - pmin < 2*pstep) {
00196 pstep = (par->getVal() - pmin )/2 ;
00197 }
00198
00199
00200 if (pstep==0) {
00201 pstep= 0.1*(pmax-pmin);
00202 }
00203
00204 } else {
00205 pstep=1 ;
00206 }
00207 if(verbose) {
00208 oocoutW(_context,Minimization) << "RooMinimizerFcn::synchronize: WARNING: no initial error estimate available for "
00209 << par->GetName() << ": using " << pstep << endl;
00210 }
00211 }
00212 } else {
00213 pmin = par->getVal() ;
00214 pmax = par->getVal() ;
00215 }
00216
00217
00218 if (index>=Int_t(parameters.size())) {
00219
00220 if (par->hasMin() && par->hasMax()) {
00221 parameters.push_back(ROOT::Fit::ParameterSettings(par->GetName(),
00222 par->getVal(),
00223 pstep,
00224 pmin,pmax));
00225 } else {
00226 parameters.push_back(ROOT::Fit::ParameterSettings(par->GetName(),
00227 par->getVal(),
00228 pstep));
00229 }
00230
00231 continue;
00232
00233 }
00234
00235 Bool_t oldFixed = parameters[index].IsFixed();
00236 Double_t oldVar = parameters[index].Value();
00237 Double_t oldVerr = parameters[index].StepSize();
00238 Double_t oldVlo = parameters[index].LowerLimit();
00239 Double_t oldVhi = parameters[index].UpperLimit();
00240
00241 if (par->isConstant() && !oldFixed) {
00242
00243
00244 if (oldVar!=par->getVal()) {
00245 parameters[index].SetValue(par->getVal());
00246 if (verbose) {
00247 oocoutI(_context,Minimization) << "RooMinimizerFcn::synchronize: value of parameter "
00248 << par->GetName() << " changed from " << oldVar
00249 << " to " << par->getVal() << endl ;
00250 }
00251 }
00252 parameters[index].Fix();
00253 constStatChange=kTRUE ;
00254 if (verbose) {
00255 oocoutI(_context,Minimization) << "RooMinimizerFcn::synchronize: parameter "
00256 << par->GetName() << " is now fixed." << endl ;
00257 }
00258
00259 } else if (par->isConstant() && oldFixed) {
00260
00261
00262 if (oldVar!=par->getVal()) {
00263 parameters[index].SetValue(par->getVal());
00264 constValChange=kTRUE ;
00265
00266 if (verbose) {
00267 oocoutI(_context,Minimization) << "RooMinimizerFcn::synchronize: value of fixed parameter "
00268 << par->GetName() << " changed from " << oldVar
00269 << " to " << par->getVal() << endl ;
00270 }
00271 }
00272
00273 } else {
00274
00275 if (!par->isConstant() && oldFixed) {
00276 parameters[index].Release();
00277 constStatChange=kTRUE ;
00278
00279 if (verbose) {
00280 oocoutI(_context,Minimization) << "RooMinimizerFcn::synchronize: parameter "
00281 << par->GetName() << " is now floating." << endl ;
00282 }
00283 }
00284
00285
00286 if (oldVar!=par->getVal() || oldVlo!=pmin || oldVhi != pmax || oldVerr!=pstep) {
00287 parameters[index].SetValue(par->getVal());
00288 parameters[index].SetStepSize(pstep);
00289 parameters[index].SetLimits(pmin,pmax);
00290 }
00291
00292
00293 if (verbose) {
00294
00295
00296 if (oldVar!=par->getVal()) {
00297 oocoutI(_context,Minimization) << "RooMinimizerFcn::synchronize: value of parameter "
00298 << par->GetName() << " changed from " << oldVar << " to "
00299 << par->getVal() << endl ;
00300 }
00301 if (oldVlo!=pmin || oldVhi!=pmax) {
00302 oocoutI(_context,Minimization) << "RooMinimizerFcn::synchronize: limits of parameter "
00303 << par->GetName() << " changed from [" << oldVlo << "," << oldVhi
00304 << "] to [" << pmin << "," << pmax << "]" << endl ;
00305 }
00306
00307
00308 if (oldVerr!=pstep && oldVerr!=0) {
00309 oocoutI(_context,Minimization) << "RooMinimizerFcn::synchronize: error/step size of parameter "
00310 << par->GetName() << " changed from " << oldVerr << " to " << pstep << endl ;
00311 }
00312 }
00313 }
00314 }
00315
00316 if (optConst) {
00317 if (constStatChange) {
00318
00319 RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::CollectErrors) ;
00320
00321 oocoutI(_context,Minimization) << "RooMinimizerFcn::synchronize: set of constant parameters changed, rerunning const optimizer" << endl ;
00322 _funct->constOptimizeTestStatistic(RooAbsArg::ConfigChange) ;
00323 } else if (constValChange) {
00324 oocoutI(_context,Minimization) << "RooMinimizerFcn::synchronize: constant parameter values changed, rerunning const optimizer" << endl ;
00325 _funct->constOptimizeTestStatistic(RooAbsArg::ValueChange) ;
00326 }
00327
00328 RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::PrintErrors) ;
00329
00330 }
00331
00332 return 0 ;
00333
00334 }
00335
00336 Double_t RooMinimizerFcn::GetPdfParamVal(Int_t index)
00337 {
00338
00339
00340 return ((RooRealVar*)_floatParamList->at(index))->getVal() ;
00341 }
00342
00343 Double_t RooMinimizerFcn::GetPdfParamErr(Int_t index)
00344 {
00345
00346 return ((RooRealVar*)_floatParamList->at(index))->getError() ;
00347 }
00348
00349
00350 void RooMinimizerFcn::SetPdfParamErr(Int_t index, Double_t value)
00351 {
00352
00353
00354 ((RooRealVar*)_floatParamList->at(index))->setError(value) ;
00355 }
00356
00357
00358
00359 void RooMinimizerFcn::ClearPdfParamAsymErr(Int_t index)
00360 {
00361
00362
00363 ((RooRealVar*)_floatParamList->at(index))->removeAsymError() ;
00364 }
00365
00366
00367 void RooMinimizerFcn::SetPdfParamErr(Int_t index, Double_t loVal, Double_t hiVal)
00368 {
00369
00370
00371 ((RooRealVar*)_floatParamList->at(index))->setAsymError(loVal,hiVal) ;
00372 }
00373
00374
00375 void RooMinimizerFcn::BackProp(const ROOT::Fit::FitResult &results)
00376 {
00377
00378
00379 for (Int_t index= 0; index < _nDim; index++) {
00380 Double_t value = results.Value(index);
00381 SetPdfParamVal(index, value);
00382
00383
00384 Double_t err = results.Error(index);
00385 SetPdfParamErr(index, err);
00386
00387 Double_t eminus = results.LowerError(index);
00388 Double_t eplus = results.UpperError(index);
00389
00390 if(eplus > 0 || eminus < 0) {
00391
00392 SetPdfParamErr(index, eminus,eplus);
00393 } else {
00394
00395 ClearPdfParamAsymErr(index) ;
00396 }
00397 }
00398
00399 }
00400
00401 Bool_t RooMinimizerFcn::SetLogFile(const char* inLogfile)
00402 {
00403
00404
00405
00406
00407 if (_logfile) {
00408 oocoutI(_context,Minimization) << "RooMinimizerFcn::setLogFile: closing previous log file" << endl ;
00409 _logfile->close() ;
00410 delete _logfile ;
00411 _logfile = 0 ;
00412 }
00413 _logfile = new ofstream(inLogfile) ;
00414 if (!_logfile->good()) {
00415 oocoutI(_context,Minimization) << "RooMinimizerFcn::setLogFile: cannot open file " << inLogfile << endl ;
00416 _logfile->close() ;
00417 delete _logfile ;
00418 _logfile= 0;
00419 }
00420
00421 return kFALSE ;
00422
00423 }
00424
00425
00426 void RooMinimizerFcn::ApplyCovarianceMatrix(TMatrixDSym& V)
00427 {
00428
00429
00430
00431
00432 for (Int_t i=0 ; i<_nDim ; i++) {
00433
00434 if (_floatParamList->at(i)->isConstant()) {
00435 continue ;
00436 }
00437 SetPdfParamErr(i, sqrt(V(i,i))) ;
00438 }
00439
00440 }
00441
00442
00443 Bool_t RooMinimizerFcn::SetPdfParamVal(const Int_t &index, const Double_t &value) const
00444 {
00445 RooRealVar* par = (RooRealVar*)_floatParamList->at(index);
00446 if (par->getVal()!=value) {
00447 if (_verbose) oocxcoutD(_context,Minimization) << par->GetName()
00448 << "=" << value << ", ";
00449 par->setVal(value);
00450 return kTRUE;
00451 }
00452
00453 return kFALSE;
00454 }
00455
00456
00457 double RooMinimizerFcn::DoEval(const double *x) const
00458 {
00459
00460
00461 for (int index = 0; index < _nDim; index++) {
00462 if (_logfile) (*_logfile) << x[index] << " " ;
00463 SetPdfParamVal(index,x[index]);
00464 }
00465
00466
00467 double fvalue = _funct->getVal();
00468 if (RooAbsPdf::evalError() || RooAbsReal::numEvalErrors()>0) {
00469
00470 if (_printEvalErrors>=0) {
00471
00472 if (_doEvalErrorWall) {
00473 oocoutW(_context,Minimization) << "RooMinimizerFcn: Minimized function has error status." << endl
00474 << "Returning maximum FCN so far (" << _maxFCN
00475 << ") to force MIGRAD to back out of this region. Error log follows" << endl ;
00476 } else {
00477 oocoutW(_context,Minimization) << "RooMinimizerFcn: Minimized function has error status but is ignored" << endl ;
00478 }
00479
00480 TIterator* iter = _floatParamList->createIterator() ;
00481 RooRealVar* var ;
00482 Bool_t first(kTRUE) ;
00483 ooccoutW(_context,Minimization) << "Parameter values: " ;
00484 while((var=(RooRealVar*)iter->Next())) {
00485 if (first) { first = kFALSE ; } else ooccoutW(_context,Minimization) << ", " ;
00486 ooccoutW(_context,Minimization) << var->GetName() << "=" << var->getVal() ;
00487 }
00488 delete iter ;
00489 ooccoutW(_context,Minimization) << endl ;
00490
00491 RooAbsReal::printEvalErrors(ooccoutW(_context,Minimization),_printEvalErrors) ;
00492 ooccoutW(_context,Minimization) << endl ;
00493 }
00494
00495 if (_doEvalErrorWall) {
00496 fvalue = _maxFCN ;
00497 }
00498
00499 RooAbsPdf::clearEvalError() ;
00500 RooAbsReal::clearEvalErrorLog() ;
00501 _numBadNLL++ ;
00502 } else if (fvalue>_maxFCN) {
00503 _maxFCN = fvalue ;
00504 }
00505
00506
00507 if (_logfile)
00508 (*_logfile) << setprecision(15) << fvalue << setprecision(4) << endl;
00509 if (_verbose) {
00510 cout << "\nprevFCN = " << setprecision(10)
00511 << fvalue << setprecision(4) << " " ;
00512 cout.flush() ;
00513 }
00514
00515 return fvalue;
00516 }
00517
00518 #endif
00519