00001 #include "../interface/ProfiledLikelihoodRatioTestStatExt.h"
00002 #include "../interface/CascadeMinimizer.h"
00003 #include "../interface/CloseCoutSentry.h"
00004 #include "../interface/utils.h"
00005 #include <stdexcept>
00006 #include <RooRealVar.h>
00007 #include <RooMinimizer.h>
00008 #include <RooFitResult.h>
00009 #include <RooSimultaneous.h>
00010 #include <RooCategory.h>
00011 #include <RooRandom.h>
00012 #include <Math/MinimizerOptions.h>
00013 #include <RooStats/RooStatsUtils.h>
00014 #include "../interface/ProfilingTools.h"
00015
00016
00017
00018 #ifdef DEBUG_FIT_STATUS
00019 #define COUNT_ONE(x) PerfCounter::add(x);
00020 #else
00021 #define COUNT_ONE(X)
00022 #endif
00023
00024
00025 #if 0
00026 #define DBG(X,Z) if (X) { Z; }
00027 #define DBGV(X,Z) if (X>1) { Z; }
00028 #define DBG_TestStat_params 0 // ProfiledLikelihoodRatioTestStatOpt::Evaluate; 1 = dump nlls; 2 = dump params at each eval
00029 #define DBG_TestStat_NOFIT 0 // FIXME HACK: if set, don't profile the likelihood, just evaluate it
00030 #define DBG_PLTestStat_ctor 2 // dump parameters in c-tor
00031 #define DBG_PLTestStat_pars 2 // dump parameters in eval
00032 #define DBG_PLTestStat_fit 2 // dump fit result
00033 #define DBG_PLTestStat_main 2 // limited debugging (final NLLs, failed fits)
00034 #else
00035 #define DBG(X,Z)
00036 #define DBGV(X,Z)
00037 #endif
00038
00039
00040 ProfiledLikelihoodRatioTestStatOpt::ProfiledLikelihoodRatioTestStatOpt(
00041 const RooArgSet & observables,
00042 RooAbsPdf &pdfNull, RooAbsPdf &pdfAlt,
00043 const RooArgSet *nuisances,
00044 const RooArgSet & paramsNull, const RooArgSet & paramsAlt,
00045 int verbosity)
00046 :
00047 pdfNull_(&pdfNull), pdfAlt_(&pdfAlt),
00048 paramsNull_(pdfNull_->getVariables()),
00049 paramsAlt_(pdfAlt_->getVariables()),
00050 verbosity_(verbosity)
00051 {
00052 snapNull_.addClone(paramsNull);
00053 snapAlt_.addClone(paramsAlt);
00054 DBG(DBG_TestStat_params, (std::cout << "Null snapshot" << pdfNull_->GetName())) DBG(DBG_TestStat_params, (snapNull_.Print("V")))
00055 DBG(DBG_TestStat_params, (std::cout << "Alt snapshot" << pdfAlt_->GetName())) DBG(DBG_TestStat_params, (snapAlt_.Print("V")))
00056 if (nuisances) nuisances_.addClone(*nuisances);
00057 }
00058
00059 Double_t ProfiledLikelihoodRatioTestStatOpt::Evaluate(RooAbsData& data, RooArgSet& nullPOI)
00060 {
00061 *paramsNull_ = nuisances_;
00062 *paramsNull_ = snapNull_;
00063 *paramsNull_ = nullPOI;
00064
00065 DBGV(DBG_TestStat_params, (std::cout << "Parameters of null pdf (pre fit)" << pdfNull_->GetName()))
00066 DBGV(DBG_TestStat_params, (paramsNull_->Print("V")))
00067
00068 bool canKeepNullNLL = createNLL(*pdfNull_, data, nllNull_);
00069 double nullNLL = minNLL(nllNull_);
00070 if (!canKeepNullNLL) nllNull_.reset();
00071
00072 *paramsAlt_ = nuisances_;
00073 *paramsAlt_ = snapAlt_;
00074
00075 DBGV(DBG_TestStat_params, (std::cout << "Parameters of alt pdf " << pdfAlt_->GetName()))
00076 DBGV(DBG_TestStat_params, (paramsAlt_->Print("V")))
00077 bool canKeepAltNLL = createNLL(*pdfAlt_, data, nllAlt_);
00078 double altNLL = minNLL(nllAlt_);
00079 if (!canKeepAltNLL) nllAlt_.reset();
00080
00081 DBG(DBG_TestStat_params, (printf("Pln: null = %+8.4f, alt = %+8.4f\n", nullNLL, altNLL)))
00082 return nullNLL-altNLL;
00083 }
00084
00085 bool ProfiledLikelihoodRatioTestStatOpt::createNLL(RooAbsPdf &pdf, RooAbsData &data, std::auto_ptr<RooAbsReal> &nll_)
00086 {
00087 if (typeid(pdf) == typeid(RooSimultaneousOpt)) {
00088 if (nll_.get() == 0) nll_.reset(pdf.createNLL(data, RooFit::Constrain(nuisances_)));
00089 else ((cacheutils::CachingSimNLL&)(*nll_)).setData(data);
00090 return true;
00091 } else {
00092 nll_.reset(pdf.createNLL(data, RooFit::Constrain(nuisances_)));
00093 return false;
00094 }
00095 }
00096
00097
00098 double ProfiledLikelihoodRatioTestStatOpt::minNLL(std::auto_ptr<RooAbsReal> &nll_)
00099 {
00100 #if defined(DBG_TestStat_NOFIT) && (DBG_TestStat_NOFIT > 0)
00101 if (verbosity_ > 0) std::cout << "Profiling likelihood for pdf " << pdf.GetName() << std::endl;
00102 std::auto_ptr<RooAbsReal> nll_(pdf.createNLL(data, RooFit::Constrain(nuisances_)));
00103 return nll_->getVal();
00104 #endif
00105 RooMinimizer minim(*nll_);
00106 minim.setStrategy(0);
00107 minim.setPrintLevel(verbosity_-2);
00108 minim.minimize(ROOT::Math::MinimizerOptions::DefaultMinimizerType().c_str(), ROOT::Math::MinimizerOptions::DefaultMinimizerAlgo().c_str());
00109 if (verbosity_ > 1) {
00110 std::auto_ptr<RooFitResult> res(minim.save());
00111 res->Print("V");
00112 }
00113 return nll_->getVal();
00114 }
00115
00116
00117 ProfiledLikelihoodTestStatOpt::ProfiledLikelihoodTestStatOpt(
00118 const RooArgSet & observables,
00119 RooAbsPdf &pdf,
00120 const RooArgSet *nuisances,
00121 const RooArgSet & params,
00122 const RooArgSet & poi,
00123 const RooArgList &gobsParams,
00124 const RooArgList &gobs,
00125 int verbosity,
00126 OneSidedness oneSided)
00127 :
00128 pdf_(&pdf),
00129 gobsParams_(gobsParams),
00130 gobs_(gobs),
00131 verbosity_(verbosity),
00132 oneSided_(oneSided)
00133 {
00134 DBG(DBG_PLTestStat_main, (std::cout << "Created for " << pdf.GetName() << "." << std::endl))
00135
00136 params.snapshot(snap_,false);
00137 ((RooRealVar*)snap_.find(params.first()->GetName()))->setConstant(false);
00138 if (nuisances) { nuisances_.add(*nuisances); snap_.addClone(*nuisances, true); }
00139 params_.reset(pdf_->getParameters(observables));
00140 DBG(DBG_PLTestStat_ctor, (std::cout << "Observables: " << std::endl)) DBG(DBG_PLTestStat_ctor, (observables.Print("V")))
00141 DBG(DBG_PLTestStat_ctor, (std::cout << "All params: " << std::endl)) DBG(DBG_PLTestStat_ctor, (params_->Print("V")))
00142 DBG(DBG_PLTestStat_ctor, (std::cout << "Snapshot: " << std::endl)) DBG(DBG_PLTestStat_ctor, (snap_.Print("V")))
00143 DBG(DBG_PLTestStat_ctor, (std::cout << "POI: " << std::endl)) DBG(DBG_PLTestStat_ctor, (poi_.Print("V")))
00144 RooLinkedListIter it = poi.iterator();
00145 for (RooAbsArg *a = (RooAbsArg*) it.Next(); a != 0; a = (RooAbsArg*) it.Next()) {
00146
00147 RooAbsArg *ps = snap_.find(a->GetName());
00148 RooAbsArg *pp = params_->find(a->GetName());
00149 if (pp == 0) { std::cerr << "WARNING: NLL does not depend on POI " << a->GetName() << ", cannot profile" << std::endl; continue; }
00150 if (ps == 0) { std::cerr << "WARNING: no snapshot for POI " << a->GetName() << ", cannot profile" << std::endl; continue; }
00151 poi_.add(*ps);
00152 poiParams_.add(*pp);
00153 }
00154 }
00155
00156
00157 Double_t ProfiledLikelihoodTestStatOpt::Evaluate(RooAbsData& data, RooArgSet& )
00158 {
00159 bool do_debug = runtimedef::get("DEBUG_PLTSO");
00160
00161 DBG(DBG_PLTestStat_main, (std::cout << "Being evaluated on " << data.GetName() << std::endl))
00162
00163
00164 RooArgSet initialState; params_->snapshot(initialState);
00165
00166 DBG(DBG_PLTestStat_pars, std::cout << "Being evaluated on " << data.GetName() << ": params before snapshot are " << std::endl)
00167 DBG(DBG_PLTestStat_pars, params_->Print("V"))
00168
00169 *params_ = snap_;
00170
00171
00172 for (int i=0; i<gobsParams_.getSize(); ++i) {
00173 RooRealVar *nuis = (RooRealVar*)gobsParams_.at(i);
00174 RooRealVar *gobs = (RooRealVar*)gobs_.at(i);
00175 nuis->setVal(gobs->getVal());
00176 nuis->setConstant();
00177 }
00178
00179 DBG(DBG_PLTestStat_pars, std::cout << "Being evaluated on " << data.GetName() << ": params after snapshot are " << std::endl)
00180 DBG(DBG_PLTestStat_pars, params_->Print("V"))
00181
00182 RooRealVar *rIn = (RooRealVar *) poi_.first();
00183 RooRealVar *r = (RooRealVar *) params_->find(rIn->GetName());
00184 bool canKeepNLL = createNLL(*pdf_, data);
00185
00186 double initialR = rIn->getVal();
00187
00188
00189 if (poi_.getSize() == 1) {
00190 r->setMin(0); if (initialR == 0 || (oneSided_ != oneSidedDef)) r->removeMax(); else r->setMax(1.1*initialR);
00191 r->setVal(initialR == 0 ? 0.5 : 0.5*initialR);
00192 r->setConstant(false);
00193 } else {
00194 utils::setAllConstant(poiParams_,false);
00195 }
00196 DBG(DBG_PLTestStat_pars, (std::cout << "r In: ")) DBG(DBG_PLTestStat_pars, (rIn->Print(""))) DBG(DBG_PLTestStat_pars, std::cout << std::endl)
00197 DBG(DBG_PLTestStat_pars, std::cout << "r before the fit: ") DBG(DBG_PLTestStat_pars, r->Print("")) DBG(DBG_PLTestStat_pars, std::cout << std::endl)
00198
00199
00200 double nullNLL = minNLL(false, r);
00201 double bestFitR = r->getVal();
00202
00203 DBG(DBG_PLTestStat_pars, (std::cout << "r after the fit: ")) DBG(DBG_PLTestStat_pars, (r->Print(""))) DBG(DBG_PLTestStat_pars, std::cout << std::endl)
00204 DBG(DBG_PLTestStat_pars, std::cout << "Was evaluated on " << data.GetName() << ": params before snapshot are " << std::endl)
00205 DBG(DBG_PLTestStat_pars, params_->Print("V"))
00206
00207
00208 if (poi_.getSize() == 1) {
00209 r->setVal(initialR);
00210 r->setConstant(true);
00211 } else {
00212 poiParams_.assignValueOnly(poi_);
00213 utils::setAllConstant(poiParams_,true);
00214 }
00215 double thisNLL = nullNLL;
00216 if (initialR == 0 || oneSided_ != oneSidedDef || bestFitR < initialR) {
00217
00218
00219 thisNLL = (nuisances_.getSize() > 0 ? minNLL(true, r) : nll_->getVal());
00220 if (thisNLL - nullNLL < -0.02) {
00221 DBG(DBG_PLTestStat_main, (printf(" --> constrained fit is better... will repeat unconstrained fit\n")))
00222 utils::setAllConstant(poiParams_,false);
00223 nullNLL = minNLL(false, r);
00224 bestFitR = r->getVal();
00225 if (bestFitR > initialR && oneSided_ == oneSidedDef) {
00226 DBG(DBG_PLTestStat_main, (printf(" after re-fit, signal %7.4f > %7.4f, test statistics will be zero.\n", bestFitR, initialR)))
00227 thisNLL = nullNLL;
00228 }
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 if (bestFitR > initialR && oneSided_ == signFlipDef) {
00244 DBG(DBG_PLTestStat_main, (printf(" fitted signal %7.4f > %7.4f, test statistics will be negative.\n", bestFitR, initialR)))
00245 std::swap(thisNLL, nullNLL);
00246 }
00247 } else {
00248 DBG(DBG_PLTestStat_main, (printf(" signal fit %7.4f > %7.4f: don't need to compute numerator\n", bestFitR, initialR)))
00249 }
00250
00251
00252 *params_ = initialState;
00253
00254 if (!canKeepNLL) nll_.reset();
00255
00256 DBG(DBG_PLTestStat_main, (printf("\nNLLs: num % 10.4f, den % 10.4f (signal %7.4f), test stat % 10.4f\n", thisNLL, nullNLL, bestFitR, thisNLL-nullNLL)))
00257 if (do_debug) printf("\nNLLs: num % 10.4f, den % 10.4f (signal %7.4f), test stat % 10.4f\n", thisNLL, nullNLL, bestFitR, thisNLL-nullNLL);
00258
00259 return thisNLL-nullNLL;
00260 }
00261
00262 std::vector<Double_t> ProfiledLikelihoodTestStatOpt::Evaluate(RooAbsData& data, RooArgSet& , const std::vector<Double_t> &rVals)
00263 {
00264 static bool do_debug = runtimedef::get("DEBUG_PLTSO");
00265 std::vector<Double_t> ret(rVals.size(), 0);
00266
00267 DBG(DBG_PLTestStat_main, (std::cout << "Being evaluated on " << data.GetName() << std::endl))
00268
00269
00270 RooArgSet initialState; params_->snapshot(initialState);
00271
00272 DBG(DBG_PLTestStat_pars, std::cout << "Being evaluated on " << data.GetName() << ": params before snapshot are " << std::endl)
00273 DBG(DBG_PLTestStat_pars, params_->Print("V"))
00274
00275 *params_ = snap_;
00276
00277
00278 for (int i=0; i<gobsParams_.getSize(); ++i) {
00279 RooRealVar *nuis = (RooRealVar*)gobsParams_.at(i);
00280 RooRealVar *gobs = (RooRealVar*)gobs_.at(i);
00281 nuis->setVal(gobs->getVal());
00282 nuis->setConstant();
00283 }
00284
00285 DBG(DBG_PLTestStat_pars, std::cout << "Being evaluated on " << data.GetName() << ": params after snapshot are " << std::endl)
00286 DBG(DBG_PLTestStat_pars, params_->Print("V"))
00287
00288 RooRealVar *rIn = (RooRealVar *) poi_.first();
00289 RooRealVar *r = (RooRealVar *) params_->find(rIn->GetName());
00290 bool canKeepNLL = createNLL(*pdf_, data);
00291
00292 double initialR = rVals.back();
00293
00294
00295 r->setMin(0); if (initialR == 0 || (oneSided_ != oneSidedDef)) r->removeMax(); else r->setMax(1.1*initialR);
00296 r->setVal(initialR == 0 ? 0.5 : 0.5*initialR);
00297 r->setConstant(false);
00298 DBG(DBG_PLTestStat_pars, (std::cout << "r In: ")) DBG(DBG_PLTestStat_pars, (rIn->Print(""))) DBG(DBG_PLTestStat_pars, std::cout << std::endl)
00299 DBG(DBG_PLTestStat_pars, std::cout << "r before the fit: ") DBG(DBG_PLTestStat_pars, r->Print("")) DBG(DBG_PLTestStat_pars, std::cout << std::endl)
00300
00301 if (do_debug) std::cout << "PERFORMING UNCONSTRAINED FIT " << r->GetName() << " [ " << r->getMin() << " - " << r->getVal() << " - " << r->getMax() << " ] "<< std::endl;
00302 double nullNLL = minNLL(false, r);
00303 double bestFitR = r->getVal();
00304
00305 RooArgSet bestFitState; params_->snapshot(bestFitState);
00306
00307
00308 DBG(DBG_PLTestStat_pars, (std::cout << "r after the fit: ")) DBG(DBG_PLTestStat_pars, (r->Print(""))) DBG(DBG_PLTestStat_pars, std::cout << std::endl)
00309 DBG(DBG_PLTestStat_pars, std::cout << "Was evaluated on " << data.GetName() << ": params before snapshot are " << std::endl)
00310 DBG(DBG_PLTestStat_pars, params_->Print("V"))
00311
00312 double EPS = 0.25*ROOT::Math::MinimizerOptions::DefaultTolerance();
00313 for (int iR = 0, nR = rVals.size(); iR < nR; ++iR) {
00314 if (fabs(ret[iR]) > 10*EPS) continue;
00315 *params_ = bestFitState;
00316 initialR = rVals[iR];
00317
00318 r->setVal(initialR);
00319 r->setConstant(true);
00320 double thisNLL = nullNLL, sign = +1.0;
00321 if (initialR == 0 || oneSided_ != oneSidedDef || bestFitR < initialR) {
00322
00323
00324 thisNLL = (nuisances_.getSize() > 0 ? minNLL(true, r) : nll_->getVal());
00325 if (thisNLL - nullNLL < 0 && thisNLL - nullNLL >= -EPS) {
00326 thisNLL = nullNLL;
00327 } else if (thisNLL - nullNLL < 0) {
00328 DBG(DBG_PLTestStat_main, (printf(" --> constrained fit is better... will repeat unconstrained fit\n")))
00329 r->setConstant(false);
00330 r->setVal(bestFitR);
00331 double oldNullNLL = nullNLL;
00332 nullNLL = minNLL(false, r);
00333 bestFitR = r->getVal();
00334 bestFitState.removeAll(); params_->snapshot(bestFitState);
00335 for (int iR2 = 0; iR2 < iR; ++iR2) {
00336 ret[iR2] -= (nullNLL - oldNullNLL);
00337 }
00338 iR = -1; continue;
00339 }
00340 if (bestFitR > initialR && oneSided_ == signFlipDef) {
00341 DBG(DBG_PLTestStat_main, (printf(" fitted signal %7.4f > %7.4f, test statistics will be negative.\n", bestFitR, initialR)))
00342 sign = -1.0;
00343 }
00344 } else {
00345 DBG(DBG_PLTestStat_main, (printf(" signal fit %7.4f > %7.4f: don't need to compute numerator\n", bestFitR, initialR)))
00346 }
00347
00348 ret[iR] = sign * (thisNLL-nullNLL);
00349 DBG(DBG_PLTestStat_main, (printf("\nNLLs for %7.4f: num % 10.4f, den % 10.4f (signal %7.4f), test stat % 10.4f\n", initialR, thisNLL, nullNLL, bestFitR, ret[iR])))
00350 if (do_debug) {
00351 printf(" Q(%.4f) = %.4f (best fit signal %.4f), from num %.4f, den %.4f\n", rVals[iR], ret[iR], bestFitR, thisNLL, nullNLL); fflush(stdout);
00352 }
00353 }
00354
00355 *params_ = initialState;
00356
00357 if (!canKeepNLL) nll_.reset();
00358
00359
00360 return ret;
00361 }
00362 bool ProfiledLikelihoodTestStatOpt::createNLL(RooAbsPdf &pdf, RooAbsData &data)
00363 {
00364 if (typeid(pdf) == typeid(RooSimultaneousOpt)) {
00365 if (nll_.get() == 0) nll_.reset(pdf.createNLL(data, RooFit::Constrain(nuisances_)));
00366 else ((cacheutils::CachingSimNLL&)(*nll_)).setData(data);
00367 return true;
00368 } else {
00369 nll_.reset(pdf.createNLL(data, RooFit::Constrain(nuisances_)));
00370 return false;
00371 }
00372 }
00373
00374 double ProfiledLikelihoodTestStatOpt::minNLL(bool constrained, RooRealVar *r)
00375 {
00376 CascadeMinimizer::Mode mode(constrained ? CascadeMinimizer::Constrained : CascadeMinimizer::Unconstrained);
00377 CascadeMinimizer minim(*nll_, mode, r);
00378 minim.minimize(verbosity_-2);
00379 return nll_->getVal();
00380 }
00381
00382
00383 bool nllutils::robustMinimize(RooAbsReal &nll, RooMinimizerOpt &minim, int verbosity)
00384 {
00385 static bool do_debug = (runtimedef::get("DEBUG_MINIM") || runtimedef::get("DEBUG_PLTSO") > 1);
00386 double initialNll = nll.getVal();
00387 std::auto_ptr<RooArgSet> pars;
00388 bool ret = false;
00389 for (int tries = 0, maxtries = 4; tries <= maxtries; ++tries) {
00390 int status = minim.minimize(ROOT::Math::MinimizerOptions::DefaultMinimizerType().c_str(), ROOT::Math::MinimizerOptions::DefaultMinimizerAlgo().c_str());
00391
00392 if (status == 0 && nll.getVal() > initialNll + 0.02) {
00393 std::auto_ptr<RooFitResult> res(minim.save());
00394
00395 DBG(DBG_PLTestStat_main, (printf("\n --> false minimum, status %d, cov. quality %d, edm %10.7f, nll initial % 10.4f, nll final % 10.4f, change %10.5f\n", status, res->covQual(), res->edm(), initialNll, nll.getVal(), initialNll - nll.getVal())))
00396 if (pars.get() == 0) pars.reset(nll.getParameters((const RooArgSet*)0));
00397 *pars = res->floatParsInit();
00398 if (tries == 0) {
00399 COUNT_ONE("nllutils::robustMinimize: false minimum (first try)")
00400 DBG(DBG_PLTestStat_main, (printf(" ----> Doing a re-scan and re-trying\n")))
00401 minim.minimize("Minuit2","Scan");
00402 } else if (tries == 1) {
00403 COUNT_ONE("nllutils::robustMinimize: false minimum (second try)")
00404 DBG(DBG_PLTestStat_main, (printf(" ----> Re-trying with strategy = 1\n")))
00405 minim.setStrategy(1);
00406 } else if (tries == 2) {
00407 COUNT_ONE("nllutils::robustMinimize: false minimum (third try)")
00408 DBG(DBG_PLTestStat_main, (printf(" ----> Re-trying with strategy = 2\n")))
00409 minim.setStrategy(2);
00410 } else {
00411 COUNT_ONE("nllutils::robustMinimize: false minimum (third try)")
00412 DBG(DBG_PLTestStat_main, (printf(" ----> Last attempt: simplex method \n")))
00413 status = minim.minimize("Minuit2","Simplex");
00414 if (nll.getVal() < initialNll + 0.02) {
00415 DBG(DBG_PLTestStat_main, (printf("\n --> success: status %d, nll initial % 10.4f, nll final % 10.4f, change %10.5f\n", status, initialNll, nll.getVal(), initialNll - nll.getVal())))
00416 if (do_debug) printf("\n --> success: status %d, nll initial % 10.4f, nll final % 10.4f, change %10.5f\n", status, initialNll, nll.getVal(), initialNll - nll.getVal());
00417 COUNT_ONE("nllutils::robustMinimize: final success")
00418 ret = true;
00419 break;
00420 } else {
00421 COUNT_ONE("nllutils::robustMinimize: final fail")
00422 DBG(DBG_PLTestStat_main, (printf("\n --> final fail: status %d, nll initial % 10.4f, nll final % 10.4f, change %10.5f\n", status, initialNll, nll.getVal(), initialNll - nll.getVal())))
00423 if (do_debug) printf("\n --> final fail: status %d, nll initial % 10.4f, nll final % 10.4f, change %10.5f\n", status, initialNll, nll.getVal(), initialNll - nll.getVal());
00424 return false;
00425 }
00426 }
00427 } else if (status == 0) {
00428 DBG(DBG_PLTestStat_main, (printf("\n --> success: status %d, nll initial % 10.4f, nll final % 10.4f, change %10.5f\n", status, initialNll, nll.getVal(), initialNll - nll.getVal())))
00429 if (do_debug) printf("\n --> success: status %d, nll initial % 10.4f, nll final % 10.4f, change %10.5f\n", status, initialNll, nll.getVal(), initialNll - nll.getVal());
00430 COUNT_ONE("nllutils::robustMinimize: final success")
00431 ret = true;
00432 break;
00433 } else if (tries != maxtries) {
00434 std::auto_ptr<RooFitResult> res(do_debug ? minim.save() : 0);
00435
00436 if (tries > 0 && minim.edm() < 0.05*ROOT::Math::MinimizerOptions::DefaultTolerance()) {
00437 DBG(DBG_PLTestStat_main, (printf("\n --> acceptable: status %d, edm %10.7f, nll initial % 10.4f, nll final % 10.4f, change %10.5f\n", status, res->edm(), initialNll, nll.getVal(), initialNll - nll.getVal())))
00438 if (do_debug) printf("\n --> acceptable: status %d, edm %10.7f, nll initial % 10.4f, nll final % 10.4f, change %10.5f\n", status, res->edm(), initialNll, nll.getVal(), initialNll - nll.getVal());
00439 COUNT_ONE("nllutils::robustMinimize: accepting fit with bad status but good EDM")
00440 COUNT_ONE("nllutils::robustMinimize: final success")
00441 ret = true;
00442 break;
00443 }
00444 DBG(DBG_PLTestStat_main, (printf("\n --> partial fail: status %d, cov. quality %d, edm %10.7f, nll initial % 10.4f, nll final % 10.4f, change %10.5f\n", status, res->covQual(), res->edm(), initialNll, nll.getVal(), initialNll - nll.getVal())))
00445 if (tries == 1) {
00446 COUNT_ONE("nllutils::robustMinimize: failed first attempt")
00447 DBG(DBG_PLTestStat_main, (printf(" ----> Doing a re-scan first, and switching to strategy 1\n")))
00448 minim.minimize("Minuit2","Scan");
00449 minim.setStrategy(1);
00450 }
00451 if (tries == 2) {
00452 COUNT_ONE("nllutils::robustMinimize: failed second attempt")
00453 DBG(DBG_PLTestStat_main, (printf(" ----> trying with strategy = 2\n")))
00454 minim.minimize("Minuit2","Scan");
00455 minim.setStrategy(2);
00456 }
00457 } else {
00458 std::auto_ptr<RooFitResult> res(do_debug ? minim.save() : 0);
00459 DBG(DBG_PLTestStat_main, (printf("\n --> final fail: status %d, cov. quality %d, edm %10.7f, nll initial % 10.4f, nll final % 10.4f, change %10.5f\n", status, res->covQual(), res->edm(), initialNll, nll.getVal(), initialNll - nll.getVal())))
00460 if (do_debug) printf("\n --> final fail: status %d, cov. quality %d, edm %10.7f, nll initial % 10.4f, nll final % 10.4f, change %10.5f\n", status, res->covQual(), res->edm(), initialNll, nll.getVal(), initialNll - nll.getVal());
00461 COUNT_ONE("nllutils::robustMinimize: final fail")
00462 }
00463 }
00464 return ret;
00465 }
00466