CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CascadeMinimizer.cc
Go to the documentation of this file.
1 #include "../interface/CascadeMinimizer.h"
2 #include "../interface/ProfiledLikelihoodRatioTestStatExt.h"
3 #include "../interface/ProfileLikelihood.h"
4 #include "../interface/CloseCoutSentry.h"
5 #include "../interface/utils.h"
6 
7 #include <Math/MinimizerOptions.h>
8 #include <RooCategory.h>
9 #include <RooNumIntConfig.h>
10 
11 
12 boost::program_options::options_description CascadeMinimizer::options_("Cascade Minimizer options");
13 std::vector<CascadeMinimizer::Algo> CascadeMinimizer::fallbacks_;
19 
20 CascadeMinimizer::CascadeMinimizer(RooAbsReal &nll, Mode mode, RooRealVar *poi, int initialStrategy) :
21  nll_(nll),
22  minimizer_(nll_),
23  mode_(mode),
24  strategy_(initialStrategy),
25  poi_(poi)
26 {
27 }
28 
29 bool CascadeMinimizer::improve(int verbose, bool cascade)
30 {
31  minimizer_.setPrintLevel(verbose-2);
32  minimizer_.setStrategy(strategy_);
33  bool outcome = improveOnce(verbose-2);
34  if (cascade && !outcome && !fallbacks_.empty()) {
35  std::string nominalType(ROOT::Math::MinimizerOptions::DefaultMinimizerType());
36  std::string nominalAlgo(ROOT::Math::MinimizerOptions::DefaultMinimizerAlgo());
37  float nominalTol(ROOT::Math::MinimizerOptions::DefaultTolerance());
38  int nominalStrat(strategy_);
39  if (verbose > 0) std::cerr << "Failed minimization with " << nominalType << "," << nominalAlgo << " and tolerance " << nominalTol << std::endl;
40  for (std::vector<Algo>::const_iterator it = fallbacks_.begin(), ed = fallbacks_.end(); it != ed; ++it) {
41  ProfileLikelihood::MinimizerSentry minimizerConfig(it->algo, it->tolerance != Algo::default_tolerance() ? it->tolerance : nominalTol);
42  int myStrategy = it->strategy; if (myStrategy == Algo::default_strategy()) myStrategy = nominalStrat;
43  if (nominalType != ROOT::Math::MinimizerOptions::DefaultMinimizerType() ||
44  nominalAlgo != ROOT::Math::MinimizerOptions::DefaultMinimizerAlgo() ||
45  nominalTol != ROOT::Math::MinimizerOptions::DefaultTolerance() ||
46  myStrategy != nominalStrat) {
47  if (verbose > 0) std::cerr << "Will fallback to minimization using " << it->algo << ", strategy " << myStrategy << " and tolerance " << it->tolerance << std::endl;
48  minimizer_.setStrategy(myStrategy);
49  outcome = improveOnce(verbose-2);
50  if (outcome) break;
51  }
52  }
53  }
54  if (setZeroPoint_) {
55  cacheutils::CachingSimNLL *simnll = dynamic_cast<cacheutils::CachingSimNLL *>(&nll_);
56  if (simnll) simnll->clearZeroPoint();
57  }
58  return outcome;
59 }
60 
62 {
63  std::string myType(ROOT::Math::MinimizerOptions::DefaultMinimizerType());
64  std::string myAlgo(ROOT::Math::MinimizerOptions::DefaultMinimizerAlgo());
65  if (setZeroPoint_) {
66  cacheutils::CachingSimNLL *simnll = dynamic_cast<cacheutils::CachingSimNLL *>(&nll_);
67  if (simnll) {
68  simnll->setZeroPoint();
69  }
70  }
71  bool outcome = false;
72  if (oldFallback_){
73  outcome = nllutils::robustMinimize(nll_, minimizer_, verbose);
74  } else {
75  int status = minimizer_.minimize(myType.c_str(), myAlgo.c_str());
76  outcome = (status == 0);
77  }
78  if (setZeroPoint_) {
79  cacheutils::CachingSimNLL *simnll = dynamic_cast<cacheutils::CachingSimNLL *>(&nll_);
80  if (simnll) simnll->clearZeroPoint();
81  }
82  return outcome;
83 }
84 
85 bool CascadeMinimizer::minimize(int verbose, bool cascade)
86 {
87  minimizer_.setPrintLevel(verbose-2);
88  minimizer_.setStrategy(strategy_);
89  if (preScan_) minimizer_.minimize("Minuit2","Scan");
90  // FIXME can be made smarter than this
91  if (mode_ == Unconstrained && poiOnlyFit_) {
92  trivialMinimize(nll_, *poi_, 200);
93  }
94  return improve(verbose, cascade);
95 }
96 
97 
99 {
100  options_.add_options()
101  ("cminPoiOnlyFit", "Do first a fit floating only the parameter of interest")
102  ("cminPreScan", "Do a scan before first minimization")
103  ("cminSingleNuisFit", "Do first a minimization of each nuisance parameter individually")
104  ("cminFallbackAlgo", boost::program_options::value<std::vector<std::string> >(), "Fallback algorithms if the default minimizer fails (can use multiple ones). Syntax is algo[,subalgo][,strategy][:tolerance]")
105  ("cminSetZeroPoint", boost::program_options::value<bool>(&setZeroPoint_)->default_value(setZeroPoint_), "Change the reference point of the NLL to be zero during minimization")
106  ("cminOldRobustMinimize", boost::program_options::value<bool>(&oldFallback_)->default_value(oldFallback_), "Use the old 'robustMinimize' logic in addition to the cascade")
107  //("cminDefaultIntegratorEpsAbs", boost::program_options::value<double>(), "RooAbsReal::defaultIntegratorConfig()->setEpsAbs(x)")
108  //("cminDefaultIntegratorEpsRel", boost::program_options::value<double>(), "RooAbsReal::defaultIntegratorConfig()->setEpsRel(x)")
109  //("cminDefaultIntegrator1D", boost::program_options::value<std::string>(), "RooAbsReal::defaultIntegratorConfig()->method1D().setLabel(x)")
110  //("cminDefaultIntegrator1DOpen", boost::program_options::value<std::string>(), "RooAbsReal::defaultIntegratorConfig()->method1DOpen().setLabel(x)")
111  //("cminDefaultIntegrator2D", boost::program_options::value<std::string>(), "RooAbsReal::defaultIntegratorConfig()->method2D().setLabel(x)")
112  //("cminDefaultIntegrator2DOpen", boost::program_options::value<std::string>(), "RooAbsReal::defaultIntegratorConfig()->method2DOpen().setLabel(x)")
113  //("cminDefaultIntegratorND", boost::program_options::value<std::string>(), "RooAbsReal::defaultIntegratorConfig()->methodND().setLabel(x)")
114  //("cminDefaultIntegratorNDOpen", boost::program_options::value<std::string>(), "RooAbsReal::defaultIntegratorConfig()->methodNDOpen().setLabel(x)")
115  ;
116 }
117 
118 void CascadeMinimizer::applyOptions(const boost::program_options::variables_map &vm)
119 {
120  using namespace std;
121 
122  preScan_ = vm.count("cminPreScan");
123  poiOnlyFit_ = vm.count("cminPoiOnlyFit");
124  singleNuisFit_ = vm.count("cminSingleNuisFit");
125  setZeroPoint_ = vm.count("cminSetZeroPoint");
126  if (vm.count("cminFallbackAlgo")) {
127  vector<string> falls(vm["cminFallbackAlgo"].as<vector<string> >());
128  for (vector<string>::const_iterator it = falls.begin(), ed = falls.end(); it != ed; ++it) {
129  std::string algo = *it;
130  float tolerance = Algo::default_tolerance();
131  int strategy = Algo::default_strategy();
132  string::size_type idx = std::min(algo.find(";"), algo.find(":"));
133  if (idx != string::npos && idx < algo.length()) {
134  tolerance = atof(algo.substr(idx+1).c_str());
135  algo = algo.substr(0,idx); // DON'T SWAP THESE TWO LINES
136  }
137  idx = algo.find(",");
138  if (idx != string::npos && idx < algo.length()) {
139  // if after the comma there's a number, then it's a strategy
140  if ( '0' <= algo[idx+1] && algo[idx+1] <= '9' ) {
141  strategy = atoi(algo.substr(idx+1).c_str());
142  algo = algo.substr(0,idx); // DON'T SWAP THESE TWO LINES
143  } else {
144  // otherwise, it could be Name,subname,strategy
145  idx = algo.find(",",idx+1);
146  if (idx != string::npos && idx < algo.length()) {
147  strategy = atoi(algo.substr(idx+1).c_str());
148  algo = algo.substr(0,idx); // DON'T SWAP THESE TWO LINES
149  }
150  }
151  }
152  fallbacks_.push_back(Algo(algo, tolerance, strategy));
153  std::cout << "Configured fallback algorithm " << fallbacks_.back().algo <<
154  ", strategy " << fallbacks_.back().strategy <<
155  ", tolerance " << fallbacks_.back().tolerance << std::endl;
156  }
157  }
158  //if (vm.count("cminDefaultIntegratorEpsAbs")) RooAbsReal::defaultIntegratorConfig()->setEpsAbs(vm["cminDefaultIntegratorEpsAbs"].as<double>());
159  //if (vm.count("cminDefaultIntegratorEpsRel")) RooAbsReal::defaultIntegratorConfig()->setEpsRel(vm["cminDefaultIntegratorEpsRel"].as<double>());
160  //if (vm.count("cminDefaultIntegrator1D")) setDefaultIntegrator(RooAbsReal::defaultIntegratorConfig()->method1D(), vm["cminDefaultIntegrator1D"].as<std::string>());
161  //if (vm.count("cminDefaultIntegrator1DOpen")) setDefaultIntegrator(RooAbsReal::defaultIntegratorConfig()->method1DOpen(), vm["cminDefaultIntegrator1DOpen"].as<std::string>());
162  //if (vm.count("cminDefaultIntegrator2D")) setDefaultIntegrator(RooAbsReal::defaultIntegratorConfig()->method2D(), vm["cminDefaultIntegrator2D"].as<std::string>());
163  //if (vm.count("cminDefaultIntegrator2DOpen")) setDefaultIntegrator(RooAbsReal::defaultIntegratorConfig()->method2DOpen(), vm["cminDefaultIntegrator2DOpen"].as<std::string>());
164  //if (vm.count("cminDefaultIntegratorND")) setDefaultIntegrator(RooAbsReal::defaultIntegratorConfig()->methodND(), vm["cminDefaultIntegratorND"].as<std::string>());
165  //if (vm.count("cminDefaultIntegratorNDOpen")) setDefaultIntegrator(RooAbsReal::defaultIntegratorConfig()->methodNDOpen(), vm["cminDefaultIntegratorNDOpen"].as<std::string>());
166 }
167 
168 //void CascadeMinimizer::setDefaultIntegrator(RooCategory &cat, const std::string & val) {
169 // if (val == "list") {
170 // std::cout << "States for " << cat.GetName() << std::endl;
171 // int i0 = cat.getBin();
172 // for (int i = 0, n = cat.numBins((const char *)0); i < n; ++i) {
173 // cat.setBin(i); std::cout << " - " << cat.getLabel() << ( i == i0 ? " (current default)" : "") << std::endl;
174 // }
175 // std::cout << std::endl;
176 // cat.setBin(i0);
177 // } else {
178 // cat.setLabel(val.c_str());
179 // }
180 //}
181 
182 
183 void CascadeMinimizer::trivialMinimize(const RooAbsReal &nll, RooRealVar &r, int points) const {
184  double rMin = r.getMin(), rMax = r.getMax(), rStep = (rMax-rMin)/(points-1);
185  int iMin = -1; double minnll = 0;
186  for (int i = 0; i < points; ++i) {
187  double x = rMin + (i+0.5)*rStep;
188  r.setVal(x);
189  double y = nll.getVal();
190  if (iMin == -1 || y < minnll) { minnll = y; iMin = i; }
191  }
192  r.setVal( rMin + (iMin+0.5)*rStep );
193 }
static bool poiOnlyFit_
do first a fit of only the POI
bool improveOnce(int verbose)
int i
Definition: DBlmapReader.cc:9
static bool preScan_
do a pre-scan
bool robustMinimize(RooAbsReal &nll, RooMinimizerOpt &minimizer, int verbosity=0)
bool minimize(int verbose=0, bool cascade=true)
static float default_tolerance()
static void applyOptions(const boost::program_options::variables_map &vm)
static int default_strategy()
#define min(a, b)
Definition: mlp_lapack.h:161
bool improve(int verbose=0, bool cascade=true)
uint16_t size_type
CascadeMinimizer(RooAbsReal &nll, Mode mode, RooRealVar *poi=0, int initialStrategy=0)
compact information about an algorithm
static bool singleNuisFit_
do first a minimization of each nuisance individually
static bool oldFallback_
don&#39;t do old fallback using robustMinimize
static bool setZeroPoint_
do first a fit of only the POI
static boost::program_options::options_description options_
options configured from command line
RooMinimizerOpt minimizer_
static void initOptions()
Setup Minimizer configuration on creation, reset the previous one on destruction. ...
RooAbsReal & nll_
static std::vector< Algo > fallbacks_
list of algorithms to run if the default one fails
void trivialMinimize(const RooAbsReal &nll, RooRealVar &r, int points=100) const
tuple cout
Definition: gather_cfg.py:121
LimitAlgo * algo
Definition: Combine.cc:60
tuple status
Definition: ntuplemaker.py:245
x
Definition: VDTMath.h:216
RooRealVar * poi_