CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ChannelCompatibilityCheck.cc
Go to the documentation of this file.
1 #include "../interface/ChannelCompatibilityCheck.h"
2 #include <TFile.h>
3 #include <RooRealVar.h>
4 #include <RooArgSet.h>
5 #include <RooRandom.h>
6 #include <RooDataSet.h>
7 #include <RooFitResult.h>
8 #include <RooCustomizer.h>
9 #include <RooSimultaneous.h>
10 #include <RooStats/ModelConfig.h>
11 #include "../interface/Combine.h"
12 #include "../interface/ProfileLikelihood.h"
13 #include "../interface/CloseCoutSentry.h"
14 #include "../interface/RooSimultaneousOpt.h"
15 #include "../interface/utils.h"
16 
17 
18 #include <Math/MinimizerOptions.h>
19 
20 using namespace RooStats;
21 
26 std::vector<std::string> ChannelCompatibilityCheck::groups_;
27 
29  FitterAlgoBase("ChannelCompatibilityCheck specific options")
30 {
31  options_.add_options()
32  ("fixedSignalStrength", boost::program_options::value<float>(&mu_)->default_value(mu_), "Compute the compatibility for a fixed signal strength. If not specified, it's left floating")
33  ("saveFitResult", "Save fit results in output file")
34  ("group,g", boost::program_options::value<std::vector<std::string> >(&groups_), "Group together channels that contain a given name. Can be used multiple times.")
35  ("runMinos", boost::program_options::value<bool>(&runMinos_)->default_value(runMinos_), "Compute also uncertainties using profile likeilhood (MINOS or robust variants of it)")
36  ;
37 }
38 
39 void ChannelCompatibilityCheck::applyOptions(const boost::program_options::variables_map &vm)
40 {
41  applyOptionsBase(vm);
42  fixedMu_ = !vm["fixedSignalStrength"].defaulted();
43  saveFitResult_ = vm.count("saveFitResult");
44 }
45 
46 bool ChannelCompatibilityCheck::runSpecific(RooWorkspace *w, RooStats::ModelConfig *mc_s, RooStats::ModelConfig *mc_b, RooAbsData &data, double &limit, double &limitErr, const double *hint) {
47 
48  RooRealVar *r = dynamic_cast<RooRealVar *>(mc_s->GetParametersOfInterest()->first());
49  if (fixedMu_) { r->setVal(mu_); r->setConstant(true); }
50  else { r->setVal(preFitValue_); r->setConstant(false); }
51 
52  RooSimultaneous *sim = dynamic_cast<RooSimultaneous *>(mc_s->GetPdf());
53  if (sim == 0) throw std::logic_error("Cannot use ChannelCompatibilityCheck if the pdf is not a RooSimultaneous");
54 
55  RooAbsCategoryLValue *cat = (RooAbsCategoryLValue *) sim->indexCat().Clone();
56  int nbins = cat->numBins((const char *)0);
57  TString satname = TString::Format("%s_freeform", sim->GetName());
58  std::auto_ptr<RooSimultaneous> newsim((typeid(*sim) == typeid(RooSimultaneousOpt)) ? new RooSimultaneousOpt(satname, "", *cat) : new RooSimultaneous(satname, "", *cat));
59  std::map<std::string,std::string> rs;
60  RooArgList minosVars, minosOneVar; if (runMinos_) minosOneVar.add(*r);
61  for (int ic = 0, nc = nbins; ic < nc; ++ic) {
62  cat->setBin(ic);
63  RooAbsPdf *pdfi = sim->getPdf(cat->getLabel());
64  if (pdfi == 0) continue;
65  RooCustomizer customizer(*pdfi, "freeform");
66  TString riName = TString::Format("_ChannelCompatibilityCheck_%s_%s", r->GetName(), nameForLabel(cat->getLabel()).c_str());
67  rs.insert(std::pair<std::string,std::string>(nameForLabel(cat->getLabel()), riName.Data()));
68  if (w->var(riName) == 0) {
69  w->factory(TString::Format("%s[%g,%g]", riName.Data(), r->getMin(), r->getMax()));
70  }
71  customizer.replaceArg(*r, *w->var(riName));
72  newsim->addPdf((RooAbsPdf&)*customizer.build(), cat->getLabel());
73  if (runMinos_ && !minosVars.find(riName)) minosVars.add(*w->var(riName));
74  }
75 
76  CloseCoutSentry sentry(verbose < 2);
77  const RooCmdArg &constCmdArg = withSystematics ? RooFit::Constrain(*mc_s->GetNuisanceParameters()) : RooFit::NumCPU(1); // use something dummy
78  std::auto_ptr<RooFitResult> result_nominal (doFit( *sim, data, minosOneVar, constCmdArg, runMinos_)); // let's run Hesse if we want to run Minos
79  std::auto_ptr<RooFitResult> result_freeform(doFit(*newsim, data, minosVars, constCmdArg, runMinos_));
80  sentry.clear();
81 
82  if (result_nominal.get() == 0) return false;
83  if (result_freeform.get() == 0) return false;
84 
85  double nll_nominal = result_nominal->minNll();
86  double nll_freeform = result_freeform->minNll();
87  if (fabs(nll_nominal) > 1e10 || fabs(nll_freeform) > 1e10) return false;
88  limit = 2*(nll_nominal-nll_freeform);
89 
90  std::cout << "\n --- ChannelCompatibilityCheck --- " << std::endl;
91  if (verbose) {
92  if (fixedMu_) {
93  printf("Nominal fit: %s fixed at %7.4f\n", r->GetName(), r->getVal());
94  } else {
95  RooRealVar *rNominal = (RooRealVar*) result_nominal->floatParsFinal().find(r->GetName());
96  if (runMinos_ && do95_) {
97  printf("Nominal fit : %s = %7.4f %+6.4f/%+6.4f (68%% CL)\n", r->GetName(), rNominal->getVal(), rNominal->getAsymErrorLo(), rNominal->getAsymErrorHi());
98  printf(" %s = %7.4f %+6.4f/%+6.4f (95%% CL)\n", r->GetName(), rNominal->getVal(), rNominal->getMin("err95")-rNominal->getVal(), rNominal->getMax("err95")-rNominal->getVal());
99  } else if (runMinos_) {
100  printf("Nominal fit : %s = %7.4f %+6.4f/%+6.4f\n", r->GetName(), rNominal->getVal(), rNominal->getAsymErrorLo(), rNominal->getAsymErrorHi());
101  } else {
102  printf("Nominal fit : %s = %7.4f +/- %6.4f\n", r->GetName(), rNominal->getVal(), rNominal->getError());
103  }
104  }
105  for (std::map<std::string,std::string>::const_iterator it = rs.begin(), ed = rs.end(); it != ed; ++it) {
106  RooRealVar *ri = (RooRealVar*) result_freeform->floatParsFinal().find(it->second.c_str());
107  if (runMinos_ && do95_) {
108  printf("Alternate fit: %s = %7.4f %+6.4f/%+6.4f (68%% CL) in channel %s\n", r->GetName(), ri->getVal(), ri->getAsymErrorLo(), ri->getAsymErrorHi(), it->first.c_str());
109  printf(" %s = %7.4f %+6.4f/%+6.4f (95%% CL) in channel %s\n", r->GetName(), ri->getVal(), ri->getMin("err95")-ri->getVal(), ri->getMax("err95")-ri->getVal(), it->first.c_str());
110  } else if (runMinos_) {
111  printf("Alternate fit: %s = %7.4f %+6.4f/%+6.4f in channel %s\n", r->GetName(), ri->getVal(), ri->getAsymErrorLo(), ri->getAsymErrorHi(), it->first.c_str());
112  } else {
113  printf("Alternate fit: %s = %7.4f +/- %6.4f in channel %s\n", r->GetName(), ri->getVal(), ri->getError(), it->first.c_str());
114  }
115  }
116  }
117  std::cout << "Chi2-like compatibility variable: " << limit << std::endl;
118 
119  if (saveFitResult_) {
120  writeToysHere->GetFile()->WriteTObject(result_nominal.release(), "fit_nominal" );
121  writeToysHere->GetFile()->WriteTObject(result_freeform.release(), "fit_alternate");
122  }
123  return true;
124 }
125 
127 {
128  std::string ret(label);
129  for (std::vector<std::string>::const_iterator it = groups_.begin(), ed = groups_.end(); it != ed; ++it) {
130  if (ret.find(*it) != std::string::npos) { ret = *it; break; }
131  }
132  return ret;
133 }
134 
void applyOptionsBase(const boost::program_options::variables_map &vm)
virtual void applyOptions(const boost::program_options::variables_map &vm)
bool withSystematics
Definition: Combine.cc:68
static bool do95_
Definition: sim.h:19
TDirectory * writeToysHere
Definition: Combine.cc:65
RooFitResult * doFit(RooAbsPdf &pdf, RooAbsData &data, RooRealVar &r, const RooCmdArg &constrain, bool doHesse=true, int ndim=1, bool reuseNLL=false)
static std::vector< std::string > groups_
static float preFitValue_
virtual bool runSpecific(RooWorkspace *w, RooStats::ModelConfig *mc_s, RooStats::ModelConfig *mc_b, RooAbsData &data, double &limit, double &limitErr, const double *hint)
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
tuple cout
Definition: gather_cfg.py:121
std::string nameForLabel(const char *label)
boost::program_options::options_description options_
Definition: LimitAlgo.h:32
T w() const