CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
List of all members | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes
Combine Class Reference

#include <Combine.h>

Public Member Functions

void applyOptions (const boost::program_options::variables_map &vm)
 
 Combine ()
 
boost::program_options::options_description & ioOptions ()
 
boost::program_options::options_description & miscOptions ()
 
void run (TString hlfFile, const std::string &dataset, double &limit, double &limitErr, int &iToy, TTree *tree, int nToys)
 
boost::program_options::options_description & statOptions ()
 

Static Public Member Functions

static void addBranch (const char *name, void *address, const char *leaflist)
 Add a branch to the output tree (for advanced use or debugging only) More...
 
static void commitPoint (bool expected, float quantile)
 Save a point into the output tree. Usually if expected = false, quantile should be set to -1 (except e.g. for saveGrid option of HybridNew) More...
 

Private Member Functions

bool mklimit (RooWorkspace *w, RooStats::ModelConfig *mc_s, RooStats::ModelConfig *mc_b, RooAbsData &data, double &limit, double &limitErr)
 

Private Attributes

bool compiledExpr_
 
float expectSignal_
 
bool generateBinnedWorkaround_
 
bool guessGenMode_
 
bool hintUsesStatOnly_
 
boost::program_options::options_description ioOptions_
 
bool makeTempDir_
 
float mass_
 
boost::program_options::options_description miscOptions_
 
std::string modelConfigName_
 
std::string modelConfigNameB_
 
bool newGen_
 
bool optSimPdf_
 
std::string prior_
 
bool rebuildSimPdf_
 
float rMax_
 
float rMin_
 
bool saveToys_
 
bool saveWorkspace_
 
boost::program_options::options_description statOptions_
 
bool toysFrequentist_
 
bool toysNoSystematics_
 
bool unbinned_
 
bool validateModel_
 
std::string workspaceName_
 

Static Private Attributes

static TTree * tree_ = 0
 

Detailed Description

Definition at line 24 of file Combine.h.

Constructor & Destructor Documentation

Combine::Combine ( )

Definition at line 75 of file Combine.cc.

References cl, expectSignal_, ioOptions_, makeTempDir_, miscOptions_, modelConfigName_, modelConfigNameB_, newGen_, optSimPdf_, prior_, rebuildSimPdf_, rMax_, rMin_, statOptions_, withSystematics, and workspaceName_.

75  :
76  statOptions_("Common statistics options"),
77  ioOptions_("Common input-output options"),
78  miscOptions_("Common miscellaneous options"),
79  rMin_(std::numeric_limits<float>::quiet_NaN()),
80  rMax_(std::numeric_limits<float>::quiet_NaN()) {
81  namespace po = boost::program_options;
82  statOptions_.add_options()
83  ("systematics,S", po::value<bool>(&withSystematics)->default_value(true), "Add systematic uncertainties")
84  ("cl,C", po::value<float>(&cl)->default_value(0.95), "Confidence Level")
85  ("rMin", po::value<float>(&rMin_), "Override minimum value for signal strength")
86  ("rMax", po::value<float>(&rMax_), "Override maximum value for signal strength")
87  ("prior", po::value<std::string>(&prior_)->default_value("flat"), "Prior to use, for methods that require it and if it's not already in the input file: 'flat' (default), '1/sqrt(r)'")
88  ("significance", "Compute significance instead of upper limit (works only for some methods)")
89  ("lowerLimit", "Compute the lower limit instead of the upper limit (works only for some methods)")
90  ("hintStatOnly", "Ignore systematics when computing the hint")
91  ("toysNoSystematics", "Generate all toys with the central value of the nuisance parameters, without fluctuating them")
92  ("toysFrequentist", "Generate all toys in the frequentist way. Note that this affects the toys generated by option '-t' that happen in the main loop, not the ones within the Hybrid(New) algorithm.")
93  ("expectSignal", po::value<float>(&expectSignal_)->default_value(0.), "If set to non-zero, generate *signal* toys instead of background ones, with the specified signal strength.")
94  ("unbinned,U", "Generate unbinned datasets instead of binned ones (works only for extended pdfs)")
95  ("generateBinnedWorkaround", "Make binned datasets generating unbinned ones and then binnning them. Workaround for a bug in RooFit.")
96  ;
97  ioOptions_.add_options()
98  ("saveWorkspace", "Save workspace to output root file")
99  ("workspaceName,w", po::value<std::string>(&workspaceName_)->default_value("w"), "Workspace name, when reading it from or writing it to a rootfile.")
100  ("modelConfigName", po::value<std::string>(&modelConfigName_)->default_value("ModelConfig"), "ModelConfig name, when reading it from or writing it to a rootfile.")
101  ("modelConfigNameB", po::value<std::string>(&modelConfigNameB_)->default_value("%s_bonly"), "Name of the ModelConfig for b-only hypothesis.\n"
102  "If not present, it will be made from the singal model taking zero signal strength.\n"
103  "A '%s' in the name will be replaced with the modelConfigName.")
104  ("validateModel,V", "Perform some sanity checks on the model and abort if they fail.")
105  ("saveToys", "Save results of toy MC in output file")
106  ;
107  miscOptions_.add_options()
108  ("newGenerator", po::value<bool>(&newGen_)->default_value(true), "Use new generator code for toys, fixes all issues with binned and mixed generation (equivalent of --newToyMC but affects the top-level toys from option '-t' instead of the ones within the HybridNew)")
109  ("optimizeSimPdf", po::value<bool>(&optSimPdf_)->default_value(true), "Turn on special optimizations of RooSimultaneous. On by default, you can turn it off if it doesn't work for your workspace.")
110  ("rebuildSimPdf", po::value<bool>(&rebuildSimPdf_)->default_value(false), "Rebuild simultaneous pdf from scratch to make sure constraints are correct (not needed in CMS workspaces)")
111  ("compile", "Compile expressions instead of interpreting them")
112  ("tempDir", po::value<bool>(&makeTempDir_)->default_value(false), "Run the program from a temporary directory (automatically on for text datacards or if 'compile' is activated)")
113  ("guessGenMode", "Guess if to generate binned or unbinned based on dataset");
114  ;
115 }
float expectSignal_
Definition: Combine.h:52
bool newGen_
Definition: Combine.h:46
boost::program_options::options_description statOptions_
Definition: Combine.h:43
bool withSystematics
Definition: Combine.cc:68
boost::program_options::options_description miscOptions_
Definition: Combine.h:43
bool optSimPdf_
Definition: Combine.h:66
boost::program_options::options_description ioOptions_
Definition: Combine.h:43
bool rebuildSimPdf_
Definition: Combine.h:65
std::string workspaceName_
Definition: Combine.h:56
float cl
Definition: Combine.cc:71
std::string prior_
Definition: Combine.h:48
std::string modelConfigNameB_
Definition: Combine.h:57
float rMax_
Definition: Combine.h:47
float rMin_
Definition: Combine.h:47
std::string modelConfigName_
Definition: Combine.h:57
bool makeTempDir_
Definition: Combine.h:64

Member Function Documentation

void Combine::addBranch ( const char *  name,
void *  address,
const char *  leaflist 
)
static

Add a branch to the output tree (for advanced use or debugging only)

Definition at line 564 of file Combine.cc.

References tree_.

Referenced by MultiDimFit::initOnce(), and FitterAlgoBase::run().

564  {
565  tree_->Branch(name,address,leaflist);
566 }
char * address
Definition: mlp_lapack.h:14
static TTree * tree_
Definition: Combine.h:68
void Combine::applyOptions ( const boost::program_options::variables_map &  vm)

Definition at line 117 of file Combine.cc.

References compiledExpr_, gather_cfg::cout, doSignificance_, generateBinnedWorkaround_, guessGenMode_, hintUsesStatOnly_, lowerLimit_, makeTempDir_, mass_, modelConfigName_, modelConfigNameB_, saveToys_, saveWorkspace_, toysFrequentist_, toysNoSystematics_, unbinned_, validateModel_, and withSystematics.

117  {
118  if(withSystematics) {
119  std::cout << ">>> including systematics" << std::endl;
120  } else {
121  std::cout << ">>> no systematics included" << std::endl;
122  }
123  unbinned_ = vm.count("unbinned");
124  generateBinnedWorkaround_ = vm.count("generateBinnedWorkaround");
125  if (unbinned_ && generateBinnedWorkaround_) throw std::logic_error("You can't set generateBinnedWorkaround and unbinned options at the same time");
126  guessGenMode_ = vm.count("guessGenMode");
127  compiledExpr_ = vm.count("compile"); if (compiledExpr_) makeTempDir_ = true;
128  doSignificance_ = vm.count("significance");
129  lowerLimit_ = vm.count("lowerLimit");
130  hintUsesStatOnly_ = vm.count("hintStatOnly");
131  saveWorkspace_ = vm.count("saveWorkspace");
132  toysNoSystematics_ = vm.count("toysNoSystematics");
133  toysFrequentist_ = vm.count("toysFrequentist");
134  if (toysNoSystematics_ && toysFrequentist_) throw std::logic_error("You can't set toysNoSystematics and toysFrequentist options at the same time");
135  if (modelConfigNameB_.find("%s") != std::string::npos) {
136  char modelBName[1024];
137  sprintf(modelBName, modelConfigNameB_.c_str(), modelConfigName_.c_str());
138  modelConfigNameB_ = modelBName;
139  }
140  mass_ = vm["mass"].as<float>();
141  saveToys_ = vm.count("saveToys");
142  validateModel_ = vm.count("validateModel");
143 }
bool doSignificance_
Definition: Combine.cc:69
bool lowerLimit_
Definition: Combine.cc:70
bool withSystematics
Definition: Combine.cc:68
bool validateModel_
Definition: Combine.h:58
float mass_
Definition: Combine.h:60
bool saveToys_
Definition: Combine.h:59
bool unbinned_
Definition: Combine.h:46
bool generateBinnedWorkaround_
Definition: Combine.h:46
bool guessGenMode_
Definition: Combine.h:46
bool toysNoSystematics_
Definition: Combine.h:50
bool compiledExpr_
Definition: Combine.h:63
bool hintUsesStatOnly_
Definition: Combine.h:49
std::string modelConfigNameB_
Definition: Combine.h:57
std::string modelConfigName_
Definition: Combine.h:57
bool toysFrequentist_
Definition: Combine.h:51
bool saveWorkspace_
Definition: Combine.h:55
tuple cout
Definition: gather_cfg.py:121
bool makeTempDir_
Definition: Combine.h:64
void Combine::commitPoint ( bool  expected,
float  quantile 
)
static

Save a point into the output tree. Usually if expected = false, quantile should be set to -1 (except e.g. for saveGrid option of HybridNew)

Definition at line 557 of file Combine.cc.

References g_quantileExpected_, and tree_.

Referenced by MultiDimFit::doBox(), MultiDimFit::doContour2D(), MultiDimFit::doGrid(), MultiDimFit::doRandomPoints(), MultiDimFit::doSingles(), Asymptotic::getCLs(), AsymptoticNew::runLimit(), HybridNew::runLimit(), Asymptotic::runLimitExpected(), MultiDimFit::runSpecific(), and MaxLikelihoodFit::runSpecific().

557  {
558  Float_t saveQuantile = g_quantileExpected_;
559  g_quantileExpected_ = quantile;
560  tree_->Fill();
561  g_quantileExpected_ = saveQuantile;
562 }
Float_t g_quantileExpected_
Definition: Combine.cc:63
static TTree * tree_
Definition: Combine.h:68
boost::program_options::options_description& Combine::ioOptions ( )
inline

Definition at line 29 of file Combine.h.

References ioOptions_.

29 { return ioOptions_; }
boost::program_options::options_description ioOptions_
Definition: Combine.h:43
boost::program_options::options_description& Combine::miscOptions ( )
inline

Definition at line 30 of file Combine.h.

References miscOptions_.

30 { return miscOptions_; }
boost::program_options::options_description miscOptions_
Definition: Combine.h:43
bool Combine::mklimit ( RooWorkspace *  w,
RooStats::ModelConfig *  mc_s,
RooStats::ModelConfig *  mc_b,
RooAbsData &  data,
double &  limit,
double &  limitErr 
)
private

Definition at line 145 of file Combine.cc.

References algo, dtNoiseDBValidation_cfg::cerr, cppFunctionSkipper::exception, hintAlgo, hintUsesStatOnly_, run_regression::ret, LimitAlgo::run(), t_cpu_, t_real_, and withSystematics.

Referenced by run().

145  {
146  TStopwatch timer;
147  bool ret = false;
148  try {
149  double hint = 0, hintErr = 0; bool hashint = false;
150  if (hintAlgo) {
152  withSystematics = false;
153  hashint = hintAlgo->run(w, mc_s, mc_b, data, hint, hintErr, 0);
154  withSystematics = true;
155  } else {
156  hashint = hintAlgo->run(w, mc_s, mc_b, data, hint, hintErr, 0);
157  }
158  }
159  limitErr = 0; // start with 0, as some algorithms don't compute it
160  ret = algo->run(w, mc_s, mc_b, data, limit, limitErr, (hashint ? &hint : 0));
161  } catch (std::exception &ex) {
162  std::cerr << "Caught exception " << ex.what() << std::endl;
163  return false;
164  }
165  /* if ((ret == false) && (verbose > 3)) {
166  std::cout << "Failed for method " << algo->name() << "\n";
167  std::cout << " --- DATA ---\n";
168  utils::printRAD(&data);
169  std::cout << " --- MODEL ---\n";
170  w->Print("V");
171  } */
172  timer.Stop(); t_cpu_ = timer.CpuTime()/60.; t_real_ = timer.RealTime()/60.;
173  printf("Done in %.2f min (cpu), %.2f min (real)\n", t_cpu_, t_real_);
174  return ret;
175 }
Float_t t_cpu_
Definition: Combine.cc:62
bool withSystematics
Definition: Combine.cc:68
Float_t t_real_
Definition: Combine.cc:62
LimitAlgo * hintAlgo
Definition: Combine.cc:60
bool hintUsesStatOnly_
Definition: Combine.h:49
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
LimitAlgo * algo
Definition: Combine.cc:60
virtual bool run(RooWorkspace *w, RooStats::ModelConfig *mc_s, RooStats::ModelConfig *mc_b, RooAbsData &data, double &limit, double &limitErr, const double *hint)=0
T w() const
void Combine::run ( TString  hlfFile,
const std::string &  dataset,
double &  limit,
double &  limitErr,
int &  iToy,
TTree *  tree,
int  nToys 
)

Definition at line 190 of file Combine.cc.

References algo, asimovutils::asimovDatasetWithFit(), dtNoiseDBValidation_cfg::cerr, utils::checkModel(), cl, compiledExpr_, gather_cfg::cout, dqm::qstatus::ERROR, expectSignal_, toymcoptutils::SimPdfGenInfo::generate(), toymcoptutils::SimPdfGenInfo::generateAsimov(), generateBinnedWorkaround_, utils::guessChannelMode(), guessGenMode_, instance, officialUncalib2006Production_0_4_0_cfg::isBinary, edm::detail::isnan(), MessageLogger_cff::limit, utils::makeNuisancePdf(), makeTempDir_, mass_, mklimit(), modelConfigName_, modelConfigNameB_, newGen_, AlCaHLTBitMon_ParallelJobs::options, optSimPdf_, download_sqlite_cfg::outputFile, funct::pow(), utils::printPdf(), utils::printRAD(), bookConverter::prior, prior_, alignCSCRings::pwd, readToysFromHere, utils::rebuildSimPdf(), rebuildSimPdf_, rMax_, rMin_, plotscripts::rms(), saveToys_, saveWorkspace_, utils::setAllConstant(), LimitAlgo::setNToys(), LimitAlgo::setToyNumber(), python.multivaluedict::sort(), mathSSE::sqrt(), ntuplemaker::status, toysFrequentist_, toysNoSystematics_, diffTreeTool::tree, tree_, unbinned_, validateModel_, w(), dqm::qstatus::WARNING, withSystematics, workspaceName_, and writeToysHere.

190  {
191  ToCleanUp garbageCollect; // use this to close and delete temporary files
192 
193  TString tmpDir = "", tmpFile = "", pwd(gSystem->pwd());
194  if (makeTempDir_) {
195  tmpDir = "roostats-XXXXXX"; tmpFile = "model";
196  mkdtemp(const_cast<char *>(tmpDir.Data()));
197  gSystem->cd(tmpDir.Data());
198  garbageCollect.path = tmpDir.Data(); // request that we delete this dir when done
199  } else if (!hlfFile.EndsWith(".hlf") && !hlfFile.EndsWith(".root")) {
200  tmpFile = "roostats-XXXXXX";
201  mktemp(const_cast<char *>(tmpFile.Data())); // somewhat unsafe, but I want to get a proper extension in the output file
202  }
203 
204  bool isTextDatacard = false, isBinary = false;
205  TString fileToLoad = (hlfFile[0] == '/' ? hlfFile : pwd+"/"+hlfFile);
206  if (!boost::filesystem::exists(fileToLoad.Data())) throw std::invalid_argument(("File "+fileToLoad+" does not exist").Data());
207  if (hlfFile.EndsWith(".hlf") ) {
208  // nothing to do
209  } else if (hlfFile.EndsWith(".root")) {
210  isBinary = true;
211  } else {
212  TString txtFile = fileToLoad.Data();
213  TString options = TString::Format(" -m %f -D %s", mass_, dataset.c_str());
214  if (!withSystematics) options += " --stat ";
215  if (compiledExpr_) options += " --compiled ";
216  if (verbose > 1) options += TString::Format(" --verbose %d", verbose-1);
217  //-- Text mode: old default
218  //int status = gSystem->Exec("text2workspace.py "+options+" '"+txtFile+"' -o "+tmpFile+".hlf");
219  //isTextDatacard = true; fileToLoad = tmpFile+".hlf";
220  //-- Binary mode: new default
221  int status = gSystem->Exec("text2workspace.py "+options+" '"+txtFile+"' -b -o "+tmpFile+".root");
222  isBinary = true; fileToLoad = tmpFile+".root";
223  if (status != 0 || !boost::filesystem::exists(fileToLoad.Data())) {
224  throw std::invalid_argument("Failed to convert the input datacard from LandS to RooStats format. The lines above probably contain more information about the error.");
225  }
226  garbageCollect.file = fileToLoad;
227  }
228 
229  if (getenv("CMSSW_BASE")) {
230  gSystem->AddIncludePath(TString::Format(" -I%s/src ", getenv("CMSSW_BASE")));
231  if (verbose > 3) std::cout << "Adding " << getenv("CMSSW_BASE") << "/src to include path" << std::endl;
232  }
233  if (getenv("ROOFITSYS")) {
234  gSystem->AddIncludePath(TString::Format(" -I%s/include ", getenv("ROOFITSYS")));
235  if (verbose > 3) std::cout << "Adding " << getenv("ROOFITSYS") << "/include to include path" << std::endl;
236  }
237 
238  if (verbose <= 2) RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR);
239  // Load the model, but going in a temporary directory to avoid polluting the current one with garbage from 'cexpr'
240  RooWorkspace *w = 0; RooStats::ModelConfig *mc = 0, *mc_bonly = 0;
241  std::auto_ptr<RooStats::HLFactory> hlf(0);
242  if (isBinary) {
243  TFile *fIn = TFile::Open(fileToLoad);
244  garbageCollect.tfile = fIn; // request that we close this file when done
245 
246  w = dynamic_cast<RooWorkspace *>(fIn->Get(workspaceName_.c_str()));
247  if (w == 0) {
248  std::cerr << "Could not find workspace '" << workspaceName_ << "' in file " << fileToLoad << std::endl; fIn->ls();
249  throw std::invalid_argument("Missing Workspace");
250  }
251  if (verbose > 3) { std::cout << "Input workspace '" << workspaceName_ << "': \n"; w->Print("V"); }
252  RooRealVar *MH = w->var("MH");
253  if (MH!=0) {
254  if (verbose > 2) std::cerr << "Setting variable 'MH' in workspace to the higgs mass " << mass_ << std::endl;
255  MH->setVal(mass_);
256  }
257  mc = dynamic_cast<RooStats::ModelConfig *>(w->genobj(modelConfigName_.c_str()));
258  mc_bonly = dynamic_cast<RooStats::ModelConfig *>(w->genobj(modelConfigNameB_.c_str()));
259  if (mc == 0) {
260  std::cerr << "Could not find ModelConfig '" << modelConfigName_ << "' in workspace '" << workspaceName_ << "' in file " << fileToLoad << std::endl;
261  throw std::invalid_argument("Missing ModelConfig");
262  } else if (verbose > 3) { std::cout << "Workspace has a ModelConfig for signal called '" << modelConfigName_ << "', with contents:\n"; mc->Print("V"); }
263  if (verbose > 3) { std::cout << "Input ModelConfig '" << modelConfigName_ << "': \n"; mc->Print("V"); }
264  const RooArgSet *POI = mc->GetParametersOfInterest();
265  if (POI == 0 || POI->getSize() == 0) throw std::invalid_argument("ModelConfig '"+modelConfigName_+"' does not define parameters of interest.");
266  if (POI->getSize() > 1) std::cerr << "ModelConfig '" << modelConfigName_ << "' defines more than one parameter of interest. This is not supported in some statistical methods." << std::endl;
267  if (mc->GetObservables() == 0) throw std::invalid_argument("ModelConfig '"+modelConfigName_+"' does not define observables.");
268  if (mc->GetPdf() == 0) throw std::invalid_argument("ModelConfig '"+modelConfigName_+"' does not define a pdf.");
269  if (rebuildSimPdf_ && typeid(*mc->GetPdf()) == typeid(RooSimultaneous)) {
270  RooSimultaneous *newpdf = utils::rebuildSimPdf(*mc->GetObservables(), dynamic_cast<RooSimultaneous*>(mc->GetPdf()));
271  w->import(*newpdf);
272  mc->SetPdf(*newpdf);
273  }
274  if (optSimPdf_ && typeid(*mc->GetPdf()) == typeid(RooSimultaneous)) {
275  RooSimultaneousOpt *optpdf = new RooSimultaneousOpt(static_cast<RooSimultaneous&>(*mc->GetPdf()), TString(mc->GetPdf()->GetName())+"_opt");
276  w->import(*optpdf);
277  mc->SetPdf(*optpdf);
278  }
279  if (mc_bonly == 0) {
280  std::cerr << "Missing background ModelConfig '" << modelConfigNameB_ << "' in workspace '" << workspaceName_ << "' in file " << fileToLoad << std::endl;
281  std::cerr << "Will make one from the signal ModelConfig '" << modelConfigName_ << "' setting signal strenth '" << POI->first()->GetName() << "' to zero" << std::endl;
282  w->factory("_zero_[0]");
283  RooCustomizer make_model_s(*mc->GetPdf(),"_model_bonly_");
284  make_model_s.replaceArg(*POI->first(), *w->var("_zero_"));
285  RooAbsPdf *model_b = dynamic_cast<RooAbsPdf *>(make_model_s.build());
286  model_b->SetName("_model_bonly_");
287  w->import(*model_b);
288  mc_bonly = new RooStats::ModelConfig(*mc);
289  mc_bonly->SetPdf(*model_b);
290  }
291  } else {
292  hlf.reset(new RooStats::HLFactory("factory", fileToLoad));
293  w = hlf->GetWs();
294  if (w == 0) {
295  std::cerr << "Could not read HLF from file " << (hlfFile[0] == '/' ? hlfFile : pwd+"/"+hlfFile) << std::endl;
296  return;
297  }
298  RooRealVar *MH = w->var("MH");
299  if (MH==0) {
300  std::cerr << "Could not find MH var in workspace '" << workspaceName_ << "' in file " << fileToLoad << std::endl;
301  throw std::invalid_argument("Missing MH");
302  }
303  MH->setVal(mass_);
304  if (w->set("observables") == 0) throw std::invalid_argument("The model must define a RooArgSet 'observables'");
305  if (w->set("POI") == 0) throw std::invalid_argument("The model must define a RooArgSet 'POI' for the parameters of interest");
306  if (w->pdf("model_b") == 0) throw std::invalid_argument("The model must define a RooAbsPdf 'model_b'");
307  if (w->pdf("model_s") == 0) throw std::invalid_argument("The model must define a RooAbsPdf 'model_s'");
308 
309  // create ModelConfig
310  mc = new RooStats::ModelConfig(modelConfigName_.c_str(),"signal",w);
311  mc->SetPdf(*w->pdf("model_s"));
312  mc->SetObservables(*w->set("observables"));
313  mc->SetParametersOfInterest(*w->set("POI"));
314  if (w->set("nuisances")) mc->SetNuisanceParameters(*w->set("nuisances"));
315  if (w->set("globalObservables")) mc->SetGlobalObservables(*w->set("globalObservables"));
316  if (w->pdf("prior")) mc->SetNuisanceParameters(*w->pdf("prior"));
317  w->import(*mc, modelConfigName_.c_str());
318 
319  mc_bonly = new RooStats::ModelConfig(modelConfigNameB_.c_str(),"background",w);
320  mc_bonly->SetPdf(*w->pdf("model_b"));
321  mc_bonly->SetObservables(*w->set("observables"));
322  mc_bonly->SetParametersOfInterest(*w->set("POI"));
323  if (w->set("nuisances")) mc_bonly->SetNuisanceParameters(*w->set("nuisances"));
324  if (w->set("globalObservables")) mc_bonly->SetGlobalObservables(*w->set("globalObservables"));
325  if (w->pdf("prior")) mc_bonly->SetNuisanceParameters(*w->pdf("prior"));
326  w->import(*mc_bonly, modelConfigNameB_.c_str());
327  }
328  gSystem->cd(pwd);
329 
330  if (verbose <= 2) RooMsgService::instance().setGlobalKillBelow(RooFit::WARNING);
331 
332  const RooArgSet * observables = mc->GetObservables(); // not null
333  const RooArgSet * POI = mc->GetParametersOfInterest(); // not null
334  const RooArgSet * nuisances = mc->GetNuisanceParameters(); // note: may be null
335  if (dynamic_cast<RooRealVar*>(POI->first()) == 0) throw std::invalid_argument("First parameter of interest is not a RooRealVar");
336 
337  if (w->data(dataset.c_str()) == 0) {
338  if (isTextDatacard) { // that's ok: the observables are pre-set to the observed values
339  RooDataSet *data_obs = new RooDataSet(dataset.c_str(), dataset.c_str(), *observables);
340  data_obs->add(*observables);
341  w->import(*data_obs);
342  } else {
343  std::cout << "Dataset " << dataset.c_str() << " not found." << std::endl;
344  }
345  }
346 
347  if (verbose < -1) {
348  RooMsgService::instance().setStreamStatus(0,kFALSE);
349  RooMsgService::instance().setStreamStatus(1,kFALSE);
350  RooMsgService::instance().setGlobalKillBelow(RooFit::FATAL);
351  }
352 
353 
354  if (!isnan(rMin_)) ((RooRealVar*)POI->first())->setMin(rMin_);
355  if (!isnan(rMax_)) ((RooRealVar*)POI->first())->setMax(rMax_);
356 
357  if (mc->GetPriorPdf() == 0) {
358  if (prior_ == "flat") {
359  RooAbsPdf *prior = new RooUniform("prior","prior",*POI);
360  w->import(*prior);
361  mc->SetPriorPdf(*prior);
362  } else if (prior_ == "1/sqrt(r)") {
363  w->factory(TString::Format("EXPR::prior(\\\"1/sqrt(@0)\\\",%s)", POI->first()->GetName()));
364  mc->SetPriorPdf(*w->pdf("prior"));
365  } else if (!prior_.empty() && w->pdf(prior_.c_str()) != 0) {
366  std::cout << "Will use prior '" << prior_ << "' in from the input workspace" << std::endl;
367  mc->SetPriorPdf(*w->pdf(prior_.c_str()));
368  } else {
369  std::cerr << "Unknown prior '" << prior_ << "'. It's not 'flat' '1/sqrt(r)' or the name of a pdf in the model.\n" << std::endl;
370  throw std::invalid_argument("Bad prior");
371  }
372  }
373 
374  if (withSystematics && nuisances == 0) {
375  std::cout << "The signal model has no nuisance parameters. Please run the limit tool with no systematics (option -S 0)." << std::endl;
376  std::cout << "To make things easier, I will assume you have done it." << std::endl;
377  withSystematics = false;
378  } else if (!withSystematics && nuisances != 0) {
379  std::cout << "Will set nuisance parameters to constants: " ;
380  utils::setAllConstant(*nuisances, true);
381  }
382 
383  bool validModel = validateModel_ ? utils::checkModel(*mc, false) : true;
384  if (validateModel_ && verbose) std::cout << "Sanity checks on the model: " << (validModel ? "OK" : "FAIL") << std::endl;
385 
386  // make sure these things are set consistently with what we expect
387  if (mc->GetNuisanceParameters() && withSystematics) utils::setAllConstant(*mc->GetNuisanceParameters(), false);
388  if (mc->GetGlobalObservables()) utils::setAllConstant(*mc->GetGlobalObservables(), true);
389  if (mc_bonly->GetNuisanceParameters() && withSystematics) utils::setAllConstant(*mc_bonly->GetNuisanceParameters(), false);
390  if (mc_bonly->GetGlobalObservables()) utils::setAllConstant(*mc_bonly->GetGlobalObservables(), true);
391 
392 
393  w->saveSnapshot("clean", w->allVars());
394 
395  if (saveWorkspace_) {
396  w->SetName(workspaceName_.c_str());
397  outputFile->WriteTObject(w,workspaceName_.c_str());
398  }
399 
400  tree_ = tree;
401 
402  bool isExtended = mc_bonly->GetPdf()->canBeExtended();
403  RooAbsData *dobs = w->data(dataset.c_str());
404  RooAbsPdf *genPdf = expectSignal_ > 0 ? mc->GetPdf() : mc_bonly->GetPdf();
405  toymcoptutils::SimPdfGenInfo newToyMC(*genPdf, *observables, !unbinned_); RooRealVar *weightVar_ = 0;
406 
407  if (guessGenMode_ && genPdf->InheritsFrom("RooSimultaneous") && (dobs != 0)) {
408  utils::guessChannelMode(dynamic_cast<RooSimultaneous&>(*mc->GetPdf()), *dobs, verbose);
409  utils::guessChannelMode(dynamic_cast<RooSimultaneous&>(*mc_bonly->GetPdf()), *dobs, 0);
410  }
411  if (expectSignal_ > 0) {
412  ((RooRealVar*)POI->first())->setVal(expectSignal_);
413  }
414  if (nToys <= 0) { // observed or asimov
415  iToy = nToys;
416  if (iToy == -1) {
417  if (newGen_) {
418  if (toysFrequentist_) {
419  w->saveSnapshot("reallyClean", w->allVars());
420  if (dobs == 0) throw std::invalid_argument("Frequentist Asimov datasets can't be generated without a real dataset to fit");
421  RooArgSet gobsAsimov;
422  dobs = asimovutils::asimovDatasetWithFit(mc, *dobs, gobsAsimov, expectSignal_, verbose);
423  if (mc->GetGlobalObservables()) {
424  RooArgSet gobs(*mc->GetGlobalObservables());
425  gobs = gobsAsimov;
426  utils::setAllConstant(*mc->GetParametersOfInterest(), false);
427  w->saveSnapshot("clean", w->allVars());
428  }
429  } else {
430  dobs = newToyMC.generateAsimov(weightVar_); // as simple as that
431  }
432  } else if (isExtended) {
433  if (unbinned_) {
434  throw std::invalid_argument("Asimov datasets can only be generated binned");
435  } else {
436  dobs = genPdf->generateBinned(*observables,RooFit::Extended(),RooFit::Asimov());
437  }
438  } else {
439  dobs = genPdf->generate(*observables,1,RooFit::Asimov());
440  }
441  } else if (dobs == 0) {
442  std::cerr << "No observed data '" << dataset << "' in the workspace. Cannot compute limit.\n" << std::endl;
443  return;
444  }
445  if (saveToys_) {
446  writeToysHere->WriteTObject(dobs, TString::Format("toy_asimov%g", expectSignal_));
447  }
448  std::cout << "Computing limit starting from " << (iToy == 0 ? "observation" : "expected outcome") << std::endl;
449  if (verbose > (isExtended ? 3 : 2)) utils::printRAD(dobs);
450  if (mklimit(w,mc,mc_bonly,*dobs,limit,limitErr)) tree->Fill();
451  }
452 
453 
454  std::vector<double> limitHistory;
455  std::auto_ptr<RooAbsPdf> nuisancePdf;
456  if (nToys > 0) {
457  double expLimit = 0;
458  unsigned int nLimits = 0;
459  w->loadSnapshot("clean");
460  RooDataSet *systDs = 0;
462  if (nuisances == 0) throw std::logic_error("Running with systematics enabled, but nuisances not defined.");
463  nuisancePdf.reset(utils::makeNuisancePdf(expectSignal_ ? *mc : *mc_bonly));
464  if (toysFrequentist_) {
465  if (mc->GetGlobalObservables() == 0) throw std::logic_error("Cannot use toysFrequentist with no global observables");
466  w->saveSnapshot("reallyClean", w->allVars());
467  {
468  if (dobs == 0) throw std::logic_error("Cannot use toysFrequentist with no input dataset");
469  CloseCoutSentry sentry(verbose < 3);
470  genPdf->fitTo(*dobs, RooFit::Save(1), RooFit::Minimizer("Minuit2","minimize"), RooFit::Strategy(0), RooFit::Hesse(0), RooFit::Constrain(*(expectSignal_ ?mc:mc_bonly)->GetNuisanceParameters()));
471  }
472  w->saveSnapshot("clean", w->allVars());
473  systDs = nuisancePdf->generate(*mc->GetGlobalObservables(), nToys);
474  } else {
475  systDs = nuisancePdf->generate(*nuisances, nToys);
476  }
477  }
478  std::auto_ptr<RooArgSet> vars(genPdf->getVariables());
479  algo->setNToys(nToys);
480  for (iToy = 1; iToy <= nToys; ++iToy) {
481  algo->setToyNumber(iToy-1);
482  RooAbsData *absdata_toy = 0;
483  if (readToysFromHere == 0) {
484  w->loadSnapshot("clean");
485  if (verbose > 3) utils::printPdf(*mc_bonly);
487  *vars = *systDs->get(iToy-1);
488  if (toysFrequentist_) w->saveSnapshot("clean", w->allVars());
489  if (verbose > 3) utils::printPdf(*mc_bonly);
490  }
491  if (expectSignal_) ((RooRealVar*)POI->first())->setVal(expectSignal_);
492  std::cout << "Generate toy " << iToy << "/" << nToys << std::endl;
493  if (isExtended) {
494  if (newGen_) {
495  absdata_toy = newToyMC.generate(weightVar_); // as simple as that
496  } else if (unbinned_) {
497  absdata_toy = genPdf->generate(*observables,RooFit::Extended());
498  } else if (generateBinnedWorkaround_) {
499  std::auto_ptr<RooDataSet> unbinn(genPdf->generate(*observables,RooFit::Extended()));
500  absdata_toy = new RooDataHist("toy","binned toy", *observables, *unbinn);
501  } else {
502  absdata_toy = genPdf->generateBinned(*observables,RooFit::Extended());
503  }
504  } else {
505  RooDataSet *data_toy = genPdf->generate(*observables,1);
506  absdata_toy = data_toy;
507  }
508  } else {
509  absdata_toy = dynamic_cast<RooAbsData *>(readToysFromHere->Get(TString::Format("toys/toy_%d",iToy)));
510  if (absdata_toy == 0) {
511  std::cerr << "Toy toy_"<<iToy<<" not found in " << readToysFromHere->GetName() << ". List follows:\n";
512  readToysFromHere->ls();
513  return;
514  }
515  }
516  if (verbose > (isExtended ? 3 : 2)) utils::printRAD(absdata_toy);
517  w->loadSnapshot("clean");
518  //if (verbose > 1) utils::printPdf(w, "model_b");
519  if (mklimit(w,mc,mc_bonly,*absdata_toy,limit,limitErr)) {
520  tree->Fill();
521  ++nLimits;
522  expLimit += limit;
523  limitHistory.push_back(limit);
524  }
525  if (saveToys_) {
526  writeToysHere->WriteTObject(absdata_toy, TString::Format("toy_%d", iToy));
527  }
528  delete absdata_toy;
529  }
530  if (weightVar_) delete weightVar_;
531  expLimit /= nLimits;
532  double rms = 0;
533  for (std::vector<double>::const_iterator itl = limitHistory.begin(); itl != limitHistory.end(); ++itl) {
534  rms += pow(*itl-expLimit, 2);
535  }
536  if (nLimits > 1) {
537  rms = sqrt(rms/(nLimits-1)/nLimits);
538  cout << "mean expected limit: r < " << expLimit << " +/- " << rms << " @ " << cl*100 << "%CL (" <<nLimits << " toyMC)" << endl;
539  } else {
540  cout << "mean expected limit: r < " << expLimit << " @ " << cl*100 << "%CL (" <<nLimits << " toyMC)" << endl;
541  }
542  sort(limitHistory.begin(), limitHistory.end());
543  if (nLimits > 0) {
544  double medianLimit = (nLimits % 2 == 0 ? 0.5*(limitHistory[nLimits/2-1]+limitHistory[nLimits/2]) : limitHistory[nLimits/2]);
545  cout << "median expected limit: r < " << medianLimit << " @ " << cl*100 << "%CL (" <<nLimits << " toyMC)" << endl;
546  double hi68 = limitHistory[min<int>(nLimits-1, ceil(0.84 * nLimits))];
547  double lo68 = limitHistory[min<int>(nLimits-1, floor(0.16 * nLimits))];
548  double hi95 = limitHistory[min<int>(nLimits-1, ceil(0.975 * nLimits))];
549  double lo95 = limitHistory[min<int>(nLimits-1, floor(0.025 * nLimits))];
550  cout << " 68% expected band : " << lo68 << " < r < " << hi68 << endl;
551  cout << " 95% expected band : " << lo95 << " < r < " << hi95 << endl;
552  }
553  }
554 
555 }
TDirectory * readToysFromHere
Definition: Combine.cc:66
float expectSignal_
Definition: Combine.h:52
bool newGen_
Definition: Combine.h:46
bool setAllConstant(const RooAbsCollection &coll, bool constant=true)
set all RooRealVars to constants. return true if at least one changed status
Definition: utils.cc:248
static PFTauRenderPlugin instance
void guessChannelMode(RooSimultaneous &simPdf, RooAbsData &simData, bool verbose=false)
Definition: utils.cc:376
static const int WARNING
bool withSystematics
Definition: Combine.cc:68
virtual void setNToys(const int)
Definition: LimitAlgo.h:24
RooAbsPdf * makeNuisancePdf(RooStats::ModelConfig &model, const char *name="nuisancePdf")
Definition: utils.cc:200
RooAbsData * asimovDatasetWithFit(RooStats::ModelConfig *mc, RooAbsData &realdata, RooAbsCollection &snapshot, double poiValue=0.0, int verbose=0)
Generate asimov dataset from best fit value of nuisance parameters, and fill in snapshot of correspon...
Definition: AsimovUtils.cc:26
TDirectory * writeToysHere
Definition: Combine.cc:65
bool validateModel_
Definition: Combine.h:58
bool optSimPdf_
Definition: Combine.h:66
RooSimultaneous * rebuildSimPdf(const RooArgSet &observables, RooSimultaneous *pdf)
Definition: utils.cc:327
void printPdf(RooAbsPdf *pdf)
Definition: utils.cc:61
bool isnan(float x)
Definition: math.h:13
T sqrt(T t)
Definition: SSEVec.h:46
float mass_
Definition: Combine.h:60
bool saveToys_
Definition: Combine.h:59
bool unbinned_
Definition: Combine.h:46
bool generateBinnedWorkaround_
Definition: Combine.h:46
bool guessGenMode_
Definition: Combine.h:46
bool rebuildSimPdf_
Definition: Combine.h:65
bool toysNoSystematics_
Definition: Combine.h:50
bool compiledExpr_
Definition: Combine.h:63
std::string workspaceName_
Definition: Combine.h:56
float cl
Definition: Combine.cc:71
bool checkModel(const RooStats::ModelConfig &model, bool throwOnFail=false)
Definition: utils.cc:261
std::string prior_
Definition: Combine.h:48
std::string modelConfigNameB_
Definition: Combine.h:57
tuple dataset
Definition: dataset.py:393
float rMax_
Definition: Combine.h:47
float rMin_
Definition: Combine.h:47
bool mklimit(RooWorkspace *w, RooStats::ModelConfig *mc_s, RooStats::ModelConfig *mc_b, RooAbsData &data, double &limit, double &limitErr)
Definition: Combine.cc:145
dictionary prior
std::string modelConfigName_
Definition: Combine.h:57
void printRAD(const RooAbsData *d)
Definition: utils.cc:56
bool toysFrequentist_
Definition: Combine.h:51
bool saveWorkspace_
Definition: Combine.h:55
tuple cout
Definition: gather_cfg.py:121
virtual void setToyNumber(const int)
Definition: LimitAlgo.h:23
LimitAlgo * algo
Definition: Combine.cc:60
tuple status
Definition: ntuplemaker.py:245
bool makeTempDir_
Definition: Combine.h:64
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
static const int ERROR
T w() const
static TTree * tree_
Definition: Combine.h:68
boost::program_options::options_description& Combine::statOptions ( )
inline

Definition at line 28 of file Combine.h.

References statOptions_.

28 { return statOptions_; }
boost::program_options::options_description statOptions_
Definition: Combine.h:43

Member Data Documentation

bool Combine::compiledExpr_
private

Definition at line 63 of file Combine.h.

Referenced by applyOptions(), and run().

float Combine::expectSignal_
private

Definition at line 52 of file Combine.h.

Referenced by Combine(), and run().

bool Combine::generateBinnedWorkaround_
private

Definition at line 46 of file Combine.h.

Referenced by applyOptions(), and run().

bool Combine::guessGenMode_
private

Definition at line 46 of file Combine.h.

Referenced by applyOptions(), and run().

bool Combine::hintUsesStatOnly_
private

Definition at line 49 of file Combine.h.

Referenced by applyOptions(), and mklimit().

boost::program_options::options_description Combine::ioOptions_
private

Definition at line 43 of file Combine.h.

Referenced by Combine(), and ioOptions().

bool Combine::makeTempDir_
private

Definition at line 64 of file Combine.h.

Referenced by applyOptions(), Combine(), and run().

float Combine::mass_
private

Definition at line 60 of file Combine.h.

Referenced by applyOptions(), and run().

boost::program_options::options_description Combine::miscOptions_
private

Definition at line 43 of file Combine.h.

Referenced by Combine(), and miscOptions().

std::string Combine::modelConfigName_
private

Definition at line 57 of file Combine.h.

Referenced by applyOptions(), Combine(), and run().

std::string Combine::modelConfigNameB_
private

Definition at line 57 of file Combine.h.

Referenced by applyOptions(), Combine(), and run().

bool Combine::newGen_
private

Definition at line 46 of file Combine.h.

Referenced by Combine(), and run().

bool Combine::optSimPdf_
private

Definition at line 66 of file Combine.h.

Referenced by Combine(), and run().

std::string Combine::prior_
private

Definition at line 48 of file Combine.h.

Referenced by Combine(), and run().

bool Combine::rebuildSimPdf_
private

Definition at line 65 of file Combine.h.

Referenced by Combine(), and run().

float Combine::rMax_
private

Definition at line 47 of file Combine.h.

Referenced by Combine(), and run().

float Combine::rMin_
private

Definition at line 47 of file Combine.h.

Referenced by Combine(), and run().

bool Combine::saveToys_
private

Definition at line 59 of file Combine.h.

Referenced by applyOptions(), and run().

bool Combine::saveWorkspace_
private

Definition at line 55 of file Combine.h.

Referenced by applyOptions(), and run().

boost::program_options::options_description Combine::statOptions_
private

Definition at line 43 of file Combine.h.

Referenced by Combine(), and statOptions().

bool Combine::toysFrequentist_
private

Definition at line 51 of file Combine.h.

Referenced by applyOptions(), and run().

bool Combine::toysNoSystematics_
private

Definition at line 50 of file Combine.h.

Referenced by applyOptions(), and run().

TTree * Combine::tree_ = 0
staticprivate

Definition at line 68 of file Combine.h.

Referenced by addBranch(), commitPoint(), and run().

bool Combine::unbinned_
private

Definition at line 46 of file Combine.h.

Referenced by applyOptions(), and run().

bool Combine::validateModel_
private

Definition at line 58 of file Combine.h.

Referenced by applyOptions(), and run().

std::string Combine::workspaceName_
private

Definition at line 56 of file Combine.h.

Referenced by Combine(), and run().