00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "RooFit.h"
00043 #include "Riostream.h"
00044
00045 #include "TClass.h"
00046
00047 #include <fstream>
00048 #include <iomanip>
00049 #include "TH1.h"
00050 #include "TH2.h"
00051 #include "TMarker.h"
00052 #include "TGraph.h"
00053 #include "TStopwatch.h"
00054 #include "TFitter.h"
00055 #include "TMinuit.h"
00056 #include "TDirectory.h"
00057 #include "TMatrixDSym.h"
00058 #include "RooMinuit.h"
00059 #include "RooArgSet.h"
00060 #include "RooArgList.h"
00061 #include "RooAbsReal.h"
00062 #include "RooAbsRealLValue.h"
00063 #include "RooRealVar.h"
00064 #include "RooFitResult.h"
00065 #include "RooAbsPdf.h"
00066 #include "RooSentinel.h"
00067 #include "RooMsgService.h"
00068 #include "RooPlot.h"
00069
00070
00071
00072 #if (__GNUC__==3&&__GNUC_MINOR__==2&&__GNUC_PATCHLEVEL__==3)
00073 char* operator+( streampos&, char* );
00074 #endif
00075
00076 ClassImp(RooMinuit)
00077 ;
00078
00079 TVirtualFitter *RooMinuit::_theFitter = 0 ;
00080
00081
00082
00083
00084 void RooMinuit::cleanup()
00085 {
00086
00087
00088 if (_theFitter) {
00089 delete _theFitter ;
00090 _theFitter =0 ;
00091 }
00092 }
00093
00094
00095
00096
00097 RooMinuit::RooMinuit(RooAbsReal& function)
00098 {
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 RooSentinel::activate() ;
00111
00112
00113 _extV = 0 ;
00114 _func = &function ;
00115 _logfile = 0 ;
00116 _optConst = kFALSE ;
00117 _verbose = kFALSE ;
00118 _profile = kFALSE ;
00119 _handleLocalErrors = kTRUE ;
00120 _printLevel = 1 ;
00121 _printEvalErrors = 10 ;
00122 _warnLevel = -999 ;
00123 _doEvalErrorWall = kTRUE ;
00124
00125
00126 RooArgSet* paramSet = function.getParameters(RooArgSet()) ;
00127 RooArgList paramList(*paramSet) ;
00128 delete paramSet ;
00129
00130 _floatParamList = (RooArgList*) paramList.selectByAttrib("Constant",kFALSE) ;
00131 if (_floatParamList->getSize()>1) {
00132 _floatParamList->sort() ;
00133 }
00134 _floatParamList->setName("floatParamList") ;
00135
00136 _constParamList = (RooArgList*) paramList.selectByAttrib("Constant",kTRUE) ;
00137 if (_constParamList->getSize()>1) {
00138 _constParamList->sort() ;
00139 }
00140 _constParamList->setName("constParamList") ;
00141
00142
00143 TIterator* pIter = _floatParamList->createIterator() ;
00144 RooAbsArg* arg ;
00145 while((arg=(RooAbsArg*)pIter->Next())) {
00146 if (!arg->IsA()->InheritsFrom(RooAbsRealLValue::Class())) {
00147 coutW(Minimization) << "RooMinuit::RooMinuit: removing parameter " << arg->GetName()
00148 << " from list because it is not of type RooRealVar" << endl ;
00149 _floatParamList->remove(*arg) ;
00150 }
00151 }
00152 _nPar = _floatParamList->getSize() ;
00153 delete pIter ;
00154
00155
00156 _initFloatParamList = (RooArgList*) _floatParamList->snapshot(kFALSE) ;
00157 _initConstParamList = (RooArgList*) _constParamList->snapshot(kFALSE) ;
00158
00159
00160 Int_t nPar= _floatParamList->getSize();
00161 if (_theFitter) delete _theFitter ;
00162 _theFitter = new TFitter(nPar*2+1) ;
00163 _theFitter->SetObjectFit(this) ;
00164
00165
00166 setPrintLevel(-1) ;
00167 _theFitter->Clear();
00168
00169
00170 _theFitter->SetFCN(RooMinuitGlue);
00171
00172
00173 setErrorLevel(function.defaultErrorLevel()) ;
00174
00175
00176 synchronize(kFALSE) ;
00177
00178
00179 _maxFCN= -1e30 ;
00180 _numBadNLL = 0 ;
00181
00182
00183 if (RooMsgService::instance().silentMode()) {
00184 setWarnLevel(-1) ;
00185 setPrintLevel(-1) ;
00186 } else {
00187 setWarnLevel(1) ;
00188 setPrintLevel(1) ;
00189 }
00190 }
00191
00192
00193
00194
00195 RooMinuit::~RooMinuit()
00196 {
00197
00198
00199 delete _floatParamList ;
00200 delete _initFloatParamList ;
00201 delete _constParamList ;
00202 delete _initConstParamList ;
00203 if (_extV) {
00204 delete _extV ;
00205 }
00206 }
00207
00208
00209
00210
00211 void RooMinuit::setStrategy(Int_t istrat)
00212 {
00213
00214
00215
00216
00217
00218 Double_t stratArg(istrat) ;
00219 _theFitter->ExecuteCommand("SET STR",&stratArg,1) ;
00220 }
00221
00222
00223
00224
00225 void RooMinuit::setErrorLevel(Double_t level)
00226 {
00227
00228
00229
00230
00231 _theFitter->ExecuteCommand("SET ERR",&level,1);
00232 }
00233
00234
00235
00236
00237 void RooMinuit::setEps(Double_t eps)
00238 {
00239
00240 _theFitter->ExecuteCommand("SET EPS",&eps,1) ;
00241 }
00242
00243
00244
00245
00246 RooFitResult* RooMinuit::fit(const char* options)
00247 {
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 if (_floatParamList->getSize()==0) {
00260 return 0 ;
00261 }
00262
00263 _theFitter->SetObjectFit(this) ;
00264
00265 TString opts(options) ;
00266 opts.ToLower() ;
00267
00268
00269 if (opts.Contains("v")) setVerbose(1) ;
00270 if (opts.Contains("t")) setProfile(1) ;
00271 if (opts.Contains("l")) setLogFile(Form("%s.log",_func->GetName())) ;
00272 if (opts.Contains("c")) optimizeConst(1) ;
00273
00274
00275 if (opts.Contains("s")) hesse() ;
00276 if (opts.Contains("0")) setStrategy(0) ;
00277 migrad() ;
00278 if (opts.Contains("0")) setStrategy(1) ;
00279 if (opts.Contains("h")||!opts.Contains("m")) hesse() ;
00280 if (!opts.Contains("m")) minos() ;
00281
00282 return (opts.Contains("r")) ? save() : 0 ;
00283 }
00284
00285
00286
00287
00288 Int_t RooMinuit::migrad()
00289 {
00290
00291
00292
00293
00294
00295 if (_floatParamList->getSize()==0) {
00296 return -1 ;
00297 }
00298
00299 _theFitter->SetObjectFit(this) ;
00300
00301 Double_t arglist[2];
00302 arglist[0]= 500*_nPar;
00303 arglist[1]= 1.0;
00304
00305 synchronize(_verbose) ;
00306 profileStart() ;
00307 RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::CollectErrors) ;
00308 RooAbsReal::clearEvalErrorLog() ;
00309 _status= _theFitter->ExecuteCommand("MIGRAD",arglist,2);
00310 RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::PrintErrors) ;
00311 profileStop() ;
00312 backProp() ;
00313 return _status ;
00314 }
00315
00316
00317
00318
00319 Int_t RooMinuit::hesse()
00320 {
00321
00322
00323
00324
00325
00326 if (_floatParamList->getSize()==0) {
00327 return -1 ;
00328 }
00329
00330 _theFitter->SetObjectFit(this) ;
00331
00332 Double_t arglist[2];
00333 arglist[0]= 500*_nPar;
00334
00335 synchronize(_verbose) ;
00336 profileStart() ;
00337 RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::CollectErrors) ;
00338 RooAbsReal::clearEvalErrorLog() ;
00339 _status= _theFitter->ExecuteCommand("HESSE",arglist,1);
00340 RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::PrintErrors) ;
00341 profileStop() ;
00342 backProp() ;
00343 return _status ;
00344 }
00345
00346
00347
00348
00349 Int_t RooMinuit::minos()
00350 {
00351
00352
00353
00354
00355
00356 if (_floatParamList->getSize()==0) {
00357 return -1 ;
00358 }
00359
00360 _theFitter->SetObjectFit(this) ;
00361
00362 Double_t arglist[2];
00363 arglist[0]= 500*_nPar;
00364
00365 synchronize(_verbose) ;
00366 profileStart() ;
00367 RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::CollectErrors) ;
00368 RooAbsReal::clearEvalErrorLog() ;
00369 _status= _theFitter->ExecuteCommand("MINOS",arglist,1);
00370 RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::PrintErrors) ;
00371 profileStop() ;
00372 backProp() ;
00373 return _status ;
00374 }
00375
00376
00377
00378
00379
00380 Int_t RooMinuit::minos(const RooArgSet& minosParamList)
00381 {
00382
00383
00384
00385
00386
00387 if (_floatParamList->getSize()==0) {
00388 return -1 ;
00389 }
00390
00391 _theFitter->SetObjectFit(this) ;
00392
00393 Int_t nMinosPar(0) ;
00394 Double_t* arglist = new Double_t[_nPar+1];
00395
00396 if (minosParamList.getSize()>0) {
00397 TIterator* aIter = minosParamList.createIterator() ;
00398 RooAbsArg* arg ;
00399 while((arg=(RooAbsArg*)aIter->Next())) {
00400 RooAbsArg* par = _floatParamList->find(arg->GetName());
00401 if (par && !par->isConstant()) {
00402 Int_t index = _floatParamList->index(par);
00403 nMinosPar++;
00404 arglist[nMinosPar]=index+1;
00405 }
00406 }
00407 delete aIter ;
00408 }
00409 arglist[0]= 500*_nPar;
00410
00411 synchronize(_verbose) ;
00412 profileStart() ;
00413 RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::CollectErrors) ;
00414 RooAbsReal::clearEvalErrorLog() ;
00415 _status= _theFitter->ExecuteCommand("MINOS",arglist,1+nMinosPar);
00416 RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::PrintErrors) ;
00417 profileStop() ;
00418 backProp() ;
00419
00420 delete[] arglist ;
00421 return _status ;
00422 }
00423
00424
00425
00426
00427 Int_t RooMinuit::seek()
00428 {
00429
00430
00431
00432
00433
00434 if (_floatParamList->getSize()==0) {
00435 return -1 ;
00436 }
00437
00438 _theFitter->SetObjectFit(this) ;
00439
00440 Double_t arglist[2];
00441 arglist[0]= 500*_nPar;
00442
00443 synchronize(_verbose) ;
00444 profileStart() ;
00445 RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::CollectErrors) ;
00446 RooAbsReal::clearEvalErrorLog() ;
00447 _status= _theFitter->ExecuteCommand("SEEK",arglist,1);
00448 RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::PrintErrors) ;
00449 profileStop() ;
00450 backProp() ;
00451 return _status ;
00452 }
00453
00454
00455
00456
00457 Int_t RooMinuit::simplex()
00458 {
00459
00460
00461
00462
00463
00464 if (_floatParamList->getSize()==0) {
00465 return -1 ;
00466 }
00467
00468 _theFitter->SetObjectFit(this) ;
00469
00470 Double_t arglist[2];
00471 arglist[0]= 500*_nPar;
00472 arglist[1]= 1.0;
00473
00474 synchronize(_verbose) ;
00475 profileStart() ;
00476 RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::CollectErrors) ;
00477 RooAbsReal::clearEvalErrorLog() ;
00478 _status= _theFitter->ExecuteCommand("SIMPLEX",arglist,2);
00479 RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::PrintErrors) ;
00480 profileStop() ;
00481 backProp() ;
00482 return _status ;
00483 }
00484
00485
00486
00487
00488 Int_t RooMinuit::improve()
00489 {
00490
00491
00492
00493
00494
00495 if (_floatParamList->getSize()==0) {
00496 return -1 ;
00497 }
00498
00499 _theFitter->SetObjectFit(this) ;
00500
00501 Double_t arglist[2];
00502 arglist[0]= 500*_nPar;
00503
00504 synchronize(_verbose) ;
00505 profileStart() ;
00506 RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::CollectErrors) ;
00507 RooAbsReal::clearEvalErrorLog() ;
00508 _status= _theFitter->ExecuteCommand("IMPROVE",arglist,1);
00509 RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::PrintErrors) ;
00510 profileStop() ;
00511 backProp() ;
00512 return _status ;
00513 }
00514
00515
00516
00517
00518 Int_t RooMinuit::setPrintLevel(Int_t newLevel)
00519 {
00520
00521 Int_t ret = _printLevel ;
00522 Double_t arg(newLevel) ;
00523 _theFitter->ExecuteCommand("SET PRINT",&arg,1);
00524 _printLevel = newLevel ;
00525 return ret ;
00526 }
00527
00528
00529
00530
00531 void RooMinuit::setNoWarn()
00532 {
00533
00534
00535 Double_t arg(0) ;
00536 _theFitter->ExecuteCommand("SET NOWARNINGS",&arg,1);
00537 _warnLevel = -1 ;
00538 }
00539
00540
00541
00542
00543 Int_t RooMinuit::setWarnLevel(Int_t newLevel)
00544 {
00545
00546
00547 if (newLevel==_warnLevel) {
00548 return _warnLevel ;
00549 }
00550
00551 Int_t ret = _warnLevel ;
00552 Double_t arg(newLevel) ;
00553
00554 if (newLevel>=0) {
00555 _theFitter->ExecuteCommand("SET WARNINGS",&arg,1);
00556 } else {
00557 Double_t arg2(0) ;
00558 _theFitter->ExecuteCommand("SET NOWARNINGS",&arg2,1);
00559 }
00560 _warnLevel = newLevel ;
00561
00562 return ret ;
00563 }
00564
00565
00566
00567
00568 Bool_t RooMinuit::synchronize(Bool_t verbose)
00569 {
00570
00571
00572
00573 Int_t oldPrint = setPrintLevel(-1) ;
00574 gMinuit->fNwrmes[0] = 0;
00575 Int_t oldWarn = setWarnLevel(-1) ;
00576
00577 Bool_t constValChange(kFALSE) ;
00578 Bool_t constStatChange(kFALSE) ;
00579
00580 Int_t index(0) ;
00581
00582
00583 for(index= 0; index < _constParamList->getSize() ; index++) {
00584 RooRealVar *par= dynamic_cast<RooRealVar*>(_constParamList->at(index)) ;
00585 if (!par) continue ;
00586
00587 RooRealVar *oldpar= dynamic_cast<RooRealVar*>(_initConstParamList->at(index)) ;
00588 if (!oldpar) continue ;
00589
00590
00591 if (!par->isConstant()) {
00592
00593
00594 _constParamList->remove(*par) ;
00595 _floatParamList->add(*par) ;
00596 _initFloatParamList->addClone(*oldpar) ;
00597 _initConstParamList->remove(*oldpar) ;
00598 constStatChange=kTRUE ;
00599 _nPar++ ;
00600
00601 if (verbose) {
00602 coutI(Minimization) << "RooMinuit::synchronize: parameter " << par->GetName() << " is now floating." << endl ;
00603 }
00604 }
00605
00606
00607 if (par->getVal()!= oldpar->getVal()) {
00608 constValChange=kTRUE ;
00609 if (verbose) {
00610 coutI(Minimization) << "RooMinuit::synchronize: value of constant parameter " << par->GetName()
00611 << " changed from " << oldpar->getVal() << " to " << par->getVal() << endl ;
00612 }
00613 }
00614
00615 }
00616
00617
00618 *_initConstParamList = *_constParamList ;
00619
00620
00621
00622 for(index= 0; index < _nPar; index++) {
00623 RooRealVar *par= dynamic_cast<RooRealVar*>(_floatParamList->at(index)) ;
00624 if (!par) continue ;
00625
00626 Double_t pstep(0) ;
00627 Double_t pmin(0) ;
00628 Double_t pmax(0) ;
00629
00630 if(!par->isConstant()) {
00631
00632
00633 if (!par->IsA()->InheritsFrom(RooRealVar::Class())) {
00634 coutW(Minimization) << "RooMinuit::fit: Error, non-constant parameter " << par->GetName()
00635 << " is not of type RooRealVar, skipping" << endl ;
00636 continue ;
00637 }
00638
00639
00640 if (par->hasMin() && par->hasMax()) {
00641 pmin = par->getMin();
00642 pmax = par->getMax();
00643 }
00644
00645
00646 pstep= par->getError();
00647 if(pstep <= 0) {
00648
00649 if (par->hasMin() && par->hasMax()) {
00650 pstep= 0.1*(pmax-pmin);
00651
00652
00653 if (pmax - par->getVal() < 2*pstep) {
00654 pstep = (pmax - par->getVal())/2 ;
00655 } else if (par->getVal() - pmin < 2*pstep) {
00656 pstep = (par->getVal() - pmin )/2 ;
00657 }
00658
00659
00660 if (pstep==0) {
00661 pstep= 0.1*(pmax-pmin);
00662 }
00663
00664 } else {
00665 pstep=1 ;
00666 }
00667 if(_verbose) {
00668 coutW(Minimization) << "RooMinuit::synchronize: WARNING: no initial error estimate available for "
00669 << par->GetName() << ": using " << pstep << endl;
00670 }
00671 }
00672 } else {
00673 pmin = par->getVal() ;
00674 pmax = par->getVal() ;
00675 }
00676
00677
00678 Double_t oldVar,oldVerr,oldVlo,oldVhi ;
00679 char oldParname[100] ;
00680 Int_t ierr = _theFitter->GetParameter(index,oldParname,oldVar,oldVerr,oldVlo,oldVhi) ;
00681
00682
00683
00684 Int_t ix ;
00685 Bool_t oldFixed(kFALSE) ;
00686 if (ierr>=0) {
00687 for (ix = 1; ix <= gMinuit->fNpfix; ++ix) {
00688 if (gMinuit->fIpfix[ix-1] == index+1) oldFixed=kTRUE ;
00689 }
00690 }
00691
00692 if (par->isConstant() && !oldFixed) {
00693
00694
00695 if (oldVar!=par->getVal()) {
00696 Double_t arglist[2] ;
00697 arglist[0] = index+1 ;
00698 arglist[1] = par->getVal() ;
00699 _theFitter->ExecuteCommand("SET PAR",arglist,2) ;
00700 if (verbose) {
00701 coutI(Minimization) << "RooMinuit::synchronize: value of parameter " << par->GetName() << " changed from " << oldVar << " to " << par->getVal() << endl ;
00702 }
00703 }
00704
00705 _theFitter->FixParameter(index) ;
00706 constStatChange=kTRUE ;
00707 if (verbose) {
00708 coutI(Minimization) << "RooMinuit::synchronize: parameter " << par->GetName() << " is now fixed." << endl ;
00709 }
00710
00711 } else if (par->isConstant() && oldFixed) {
00712
00713
00714 if (oldVar!=par->getVal()) {
00715 Double_t arglist[2] ;
00716 arglist[0] = index+1 ;
00717 arglist[1] = par->getVal() ;
00718 _theFitter->ExecuteCommand("SET PAR",arglist,2) ;
00719 constValChange=kTRUE ;
00720
00721 if (verbose) {
00722 coutI(Minimization) << "RooMinuit::synchronize: value of fixed parameter " << par->GetName() << " changed from " << oldVar << " to " << par->getVal() << endl ;
00723 }
00724 }
00725
00726 } else {
00727
00728 if (!par->isConstant() && oldFixed) {
00729 _theFitter->ReleaseParameter(index) ;
00730 constStatChange=kTRUE ;
00731
00732 if (verbose) {
00733 coutI(Minimization) << "RooMinuit::synchronize: parameter " << par->GetName() << " is now floating." << endl ;
00734 }
00735 }
00736
00737
00738 if (oldVar!=par->getVal() || oldVlo!=pmin || oldVhi != pmax || oldVerr!=pstep) {
00739 _theFitter->SetParameter(index, par->GetName(), par->getVal(), pstep, pmin, pmax);
00740 }
00741
00742
00743 if (verbose && ierr>=0) {
00744
00745
00746 if (oldVar!=par->getVal()) {
00747 coutI(Minimization) << "RooMinuit::synchronize: value of parameter " << par->GetName() << " changed from " << oldVar << " to " << par->getVal() << endl ;
00748 }
00749 if (oldVlo!=pmin || oldVhi!=pmax) {
00750 coutI(Minimization) << "RooMinuit::synchronize: limits of parameter " << par->GetName() << " changed from [" << oldVlo << "," << oldVhi
00751 << "] to [" << pmin << "," << pmax << "]" << endl ;
00752 }
00753
00754
00755 if (oldVerr!=pstep && oldVerr!=0) {
00756 coutI(Minimization) << "RooMinuit::synchronize: error/step size of parameter " << par->GetName() << " changed from " << oldVerr << " to " << pstep << endl ;
00757 }
00758 }
00759 }
00760 }
00761
00762
00763 gMinuit->fNwrmes[0] = 0;
00764 oldWarn = setWarnLevel(oldWarn) ;
00765 oldPrint = setPrintLevel(oldPrint) ;
00766
00767 if (_optConst) {
00768 if (constStatChange) {
00769
00770 RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::CollectErrors) ;
00771
00772 coutI(Minimization) << "RooMinuit::synchronize: set of constant parameters changed, rerunning const optimizer" << endl ;
00773 _func->constOptimizeTestStatistic(RooAbsArg::ConfigChange) ;
00774 } else if (constValChange) {
00775 coutI(Minimization) << "RooMinuit::synchronize: constant parameter values changed, rerunning const optimizer" << endl ;
00776 _func->constOptimizeTestStatistic(RooAbsArg::ValueChange) ;
00777 }
00778
00779 RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::PrintErrors) ;
00780
00781 }
00782
00783 return 0 ;
00784 }
00785
00786
00787
00788
00789
00790 void RooMinuit::optimizeConst(Bool_t flag)
00791 {
00792
00793
00794
00795 RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::CollectErrors) ;
00796
00797 if (_optConst && !flag){
00798 if (_printLevel>-1) coutI(Minimization) << "RooMinuit::optimizeConst: deactivating const optimization" << endl ;
00799 _func->constOptimizeTestStatistic(RooAbsArg::DeActivate) ;
00800 _optConst = flag ;
00801 } else if (!_optConst && flag) {
00802 if (_printLevel>-1) coutI(Minimization) << "RooMinuit::optimizeConst: activating const optimization" << endl ;
00803 _func->constOptimizeTestStatistic(RooAbsArg::Activate) ;
00804 _optConst = flag ;
00805 } else if (_optConst && flag) {
00806 if (_printLevel>-1) coutI(Minimization) << "RooMinuit::optimizeConst: const optimization already active" << endl ;
00807 } else {
00808 if (_printLevel>-1) coutI(Minimization) << "RooMinuit::optimizeConst: const optimization wasn't active" << endl ;
00809 }
00810
00811 RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::PrintErrors) ;
00812
00813 }
00814
00815
00816
00817
00818 RooFitResult* RooMinuit::save(const char* userName, const char* userTitle)
00819 {
00820
00821
00822
00823
00824
00825
00826
00827 TString name,title ;
00828 name = userName ? userName : Form("%s", _func->GetName()) ;
00829 title = userTitle ? userTitle : Form("%s", _func->GetTitle()) ;
00830
00831 if (_floatParamList->getSize()==0) {
00832 RooFitResult* fitRes = new RooFitResult(name,title) ;
00833 fitRes->setConstParList(*_constParamList) ;
00834 fitRes->setInitParList(RooArgList()) ;
00835 fitRes->setFinalParList(RooArgList()) ;
00836 fitRes->setStatus(-999) ;
00837 fitRes->setCovQual(-999) ;
00838 fitRes->setMinNLL(_func->getVal()) ;
00839 fitRes->setNumInvalidNLL(0) ;
00840 fitRes->setEDM(-999) ;
00841 return fitRes ;
00842 }
00843
00844 RooFitResult* fitRes = new RooFitResult(name,title) ;
00845
00846
00847 Int_t i ;
00848 RooArgList saveConstList(*_constParamList) ;
00849 RooArgList saveFloatInitList(*_initFloatParamList) ;
00850 RooArgList saveFloatFinalList(*_floatParamList) ;
00851 for (i=0 ; i<_floatParamList->getSize() ; i++) {
00852 RooAbsArg* par = _floatParamList->at(i) ;
00853 if (par->isConstant()) {
00854 saveFloatInitList.remove(*saveFloatInitList.find(par->GetName()),kTRUE) ;
00855 saveFloatFinalList.remove(*par) ;
00856 saveConstList.add(*par) ;
00857 }
00858 }
00859 saveConstList.sort() ;
00860
00861 fitRes->setConstParList(saveConstList) ;
00862 fitRes->setInitParList(saveFloatInitList) ;
00863
00864 Double_t edm, errdef, minVal;
00865 Int_t nvpar, nparx;
00866 Int_t icode = _theFitter->GetStats(minVal, edm, errdef, nvpar, nparx);
00867 fitRes->setStatus(_status) ;
00868 fitRes->setCovQual(icode) ;
00869 fitRes->setMinNLL(minVal) ;
00870 fitRes->setNumInvalidNLL(_numBadNLL) ;
00871 fitRes->setEDM(edm) ;
00872 fitRes->setFinalParList(saveFloatFinalList) ;
00873 if (!_extV) {
00874 fitRes->fillCorrMatrix() ;
00875 } else {
00876 fitRes->setCovarianceMatrix(*_extV) ;
00877 }
00878
00879 return fitRes ;
00880 }
00881
00882
00883
00884
00885
00886 RooPlot* RooMinuit::contour(RooRealVar& var1, RooRealVar& var2, Double_t n1, Double_t n2, Double_t n3, Double_t n4, Double_t n5, Double_t n6)
00887 {
00888
00889
00890
00891
00892 _theFitter->SetObjectFit(this) ;
00893
00894 RooArgList* paramSave = (RooArgList*) _floatParamList->snapshot() ;
00895
00896
00897 Int_t index1= _floatParamList->index(&var1);
00898 if(index1 < 0) {
00899 coutE(Minimization) << "RooMinuit::contour(" << GetName()
00900 << ") ERROR: " << var1.GetName() << " is not a floating parameter of " << _func->GetName() << endl ;
00901 return 0;
00902 }
00903
00904 Int_t index2= _floatParamList->index(&var2);
00905 if(index2 < 0) {
00906 coutE(Minimization) << "RooMinuit::contour(" << GetName()
00907 << ") ERROR: " << var2.GetName() << " is not a floating parameter of PDF " << _func->GetName() << endl ;
00908 return 0;
00909 }
00910
00911
00912 RooPlot* frame = new RooPlot(var1,var2) ;
00913
00914
00915 TMarker *point= new TMarker(var1.getVal(), var2.getVal(), 8);
00916 frame->addObject(point) ;
00917
00918
00919 Double_t errdef= gMinuit->fUp;
00920
00921 Double_t n[6] ;
00922 n[0] = n1 ; n[1] = n2 ; n[2] = n3 ; n[3] = n4 ; n[4] = n5 ; n[5] = n6 ;
00923
00924
00925 for (Int_t ic = 0 ; ic<6 ; ic++) {
00926 if(n[ic] > 0) {
00927
00928 gMinuit->SetErrorDef(n[ic]*n[ic]*errdef);
00929
00930 TGraph* graph= (TGraph*)gMinuit->Contour(50, index1, index2);
00931 if (!graph) {
00932 coutE(Minimization) << "RooMinuit::contour(" << GetName() << ") ERROR: MINUIT did not return a contour graph for n=" << n[ic] << endl ;
00933 } else {
00934 graph->SetName(Form("contour_%s_n%f",_func->GetName(),n[ic])) ;
00935 graph->SetLineStyle(ic+1) ;
00936 graph->SetLineWidth(2) ;
00937 graph->SetLineColor(kBlue) ;
00938 frame->addObject(graph,"L") ;
00939 }
00940 }
00941 }
00942
00943
00944 gMinuit->SetErrorDef(errdef);
00945
00946
00947 *_floatParamList = *paramSave ;
00948 delete paramSave ;
00949
00950
00951 return frame ;
00952 }
00953
00954
00955
00956
00957 Bool_t RooMinuit::setLogFile(const char* inLogfile)
00958 {
00959
00960
00961
00962
00963 if (_logfile) {
00964 coutI(Minimization) << "RooMinuit::setLogFile: closing previous log file" << endl ;
00965 _logfile->close() ;
00966 delete _logfile ;
00967 _logfile = 0 ;
00968 }
00969 _logfile = new ofstream(inLogfile) ;
00970 if (!_logfile->good()) {
00971 coutI(Minimization) << "RooMinuit::setLogFile: cannot open file " << inLogfile << endl ;
00972 _logfile->close() ;
00973 delete _logfile ;
00974 _logfile= 0;
00975 }
00976 return kFALSE ;
00977 }
00978
00979
00980
00981
00982 Double_t RooMinuit::getPdfParamVal(Int_t index)
00983 {
00984
00985
00986 return ((RooRealVar*)_floatParamList->at(index))->getVal() ;
00987 }
00988
00989
00990
00991
00992 Double_t RooMinuit::getPdfParamErr(Int_t index)
00993 {
00994
00995
00996 return ((RooRealVar*)_floatParamList->at(index))->getError() ;
00997 }
00998
00999
01000
01001
01002 Bool_t RooMinuit::setPdfParamVal(Int_t index, Double_t value, Bool_t verbose)
01003 {
01004
01005
01006 RooRealVar* par = (RooRealVar*)_floatParamList->at(index) ;
01007
01008 if (par->getVal()!=value) {
01009 if (verbose) cout << par->GetName() << "=" << value << ", " ;
01010 par->setVal(value) ;
01011 return kTRUE ;
01012 }
01013
01014 return kFALSE ;
01015 }
01016
01017
01018
01019
01020 void RooMinuit::setPdfParamErr(Int_t index, Double_t value)
01021 {
01022
01023
01024 ((RooRealVar*)_floatParamList->at(index))->setError(value) ;
01025 }
01026
01027
01028
01029
01030 void RooMinuit::clearPdfParamAsymErr(Int_t index)
01031 {
01032
01033
01034 ((RooRealVar*)_floatParamList->at(index))->removeAsymError() ;
01035 }
01036
01037
01038
01039 void RooMinuit::setPdfParamErr(Int_t index, Double_t loVal, Double_t hiVal)
01040 {
01041
01042
01043 ((RooRealVar*)_floatParamList->at(index))->setAsymError(loVal,hiVal) ;
01044 }
01045
01046
01047
01048
01049 void RooMinuit::profileStart()
01050 {
01051
01052 if (_profile) {
01053 _timer.Start() ;
01054 _cumulTimer.Start(kFALSE) ;
01055 }
01056 }
01057
01058
01059
01060
01061
01062 void RooMinuit::profileStop()
01063 {
01064
01065 if (_profile) {
01066 _timer.Stop() ;
01067 _cumulTimer.Stop() ;
01068 coutI(Minimization) << "Command timer: " ; _timer.Print() ;
01069 coutI(Minimization) << "Session timer: " ; _cumulTimer.Print() ;
01070 }
01071 }
01072
01073
01074
01075
01076
01077
01078 void RooMinuit::backProp()
01079 {
01080
01081
01082 Double_t val,err,vlo,vhi, eplus, eminus, eparab, globcc;
01083 char buffer[10240];
01084 Int_t index ;
01085 for(index= 0; index < _nPar; index++) {
01086 _theFitter->GetParameter(index, buffer, val, err, vlo, vhi);
01087 setPdfParamVal(index, val);
01088 _theFitter->GetErrors(index, eplus, eminus, eparab, globcc);
01089
01090
01091 setPdfParamErr(index, err);
01092
01093 if(eplus > 0 || eminus < 0) {
01094
01095 setPdfParamErr(index, eminus,eplus);
01096 } else {
01097
01098 clearPdfParamAsymErr(index) ;
01099 }
01100 }
01101 }
01102
01103
01104
01105
01106
01107 void RooMinuit::applyCovarianceMatrix(TMatrixDSym& V)
01108 {
01109
01110
01111
01112
01113 _extV = (TMatrixDSym*) V.Clone() ;
01114
01115 for (Int_t i=0 ; i<getNPar() ; i++) {
01116
01117 if (_floatParamList->at(i)->isConstant()) {
01118 continue ;
01119 }
01120 setPdfParamErr(i, sqrt((*_extV)(i,i))) ;
01121 }
01122
01123 }
01124
01125
01126
01127
01128 void RooMinuitGlue(Int_t& , Double_t* ,
01129 Double_t &f, Double_t *par, Int_t )
01130 {
01131
01132
01133
01134 RooMinuit* context = (RooMinuit*) RooMinuit::_theFitter->GetObjectFit() ;
01135 ofstream* logf = context->logfile() ;
01136 Double_t& maxFCN = context->maxFCN() ;
01137 Bool_t verbose = context->_verbose ;
01138
01139
01140 Int_t nPar= context->getNPar();
01141 for(Int_t index= 0; index < nPar; index++) {
01142 if (logf) (*logf) << par[index] << " " ;
01143 context->setPdfParamVal(index, par[index],verbose);
01144 }
01145
01146
01147 f= context->_func->getVal() ;
01148 if ( RooAbsPdf::evalError() || RooAbsReal::numEvalErrors()>0 ) {
01149
01150 if (context->_printEvalErrors>=0) {
01151
01152 if (context->_doEvalErrorWall) {
01153 oocoutW(context,Minimization) << "RooFitGlue: Minimized function has error status." << endl
01154 << "Returning maximum FCN so far (" << maxFCN
01155 << ") to force MIGRAD to back out of this region. Error log follows" << endl ;
01156 } else {
01157 oocoutW(context,Minimization) << "RooFitGlue: Minimized function has error status but is ignored" << endl ;
01158 }
01159
01160 TIterator* iter = context->_floatParamList->createIterator() ;
01161 RooRealVar* var ;
01162 Bool_t first(kTRUE) ;
01163 ooccoutW(context,Minimization) << "Parameter values: " ;
01164 while((var=(RooRealVar*)iter->Next())) {
01165 if (first) { first = kFALSE ; } else ooccoutW(context,Minimization) << ", " ;
01166 ooccoutW(context,Minimization) << var->GetName() << "=" << var->getVal() ;
01167 }
01168 delete iter ;
01169 ooccoutW(context,Minimization) << endl ;
01170
01171 RooAbsReal::printEvalErrors(ooccoutW(context,Minimization),context->_printEvalErrors) ;
01172 ooccoutW(context,Minimization) << endl ;
01173 }
01174
01175 if (context->_doEvalErrorWall) {
01176 f = maxFCN ;
01177 }
01178
01179 RooAbsPdf::clearEvalError() ;
01180 RooAbsReal::clearEvalErrorLog() ;
01181 context->_numBadNLL++ ;
01182 } else if (f>maxFCN) {
01183 maxFCN = f ;
01184 }
01185
01186
01187 if (logf) (*logf) << setprecision(15) << f << setprecision(4) << endl;
01188 if (verbose) {
01189 cout << "\nprevFCN = " << setprecision(10) << f << setprecision(4) << " " ;
01190 cout.flush() ;
01191 }
01192 }