1 #include "../interface/ChannelCompatibilityCheck.h"
3 #include <RooRealVar.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"
18 #include <Math/MinimizerOptions.h>
20 using namespace RooStats;
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)")
42 fixedMu_ = !vm[
"fixedSignalStrength"].defaulted();
48 RooRealVar *
r =
dynamic_cast<RooRealVar *
>(mc_s->GetParametersOfInterest()->first());
49 if (
fixedMu_) { r->setVal(
mu_); r->setConstant(
true); }
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");
55 RooAbsCategoryLValue *cat = (RooAbsCategoryLValue *) sim->indexCat().Clone();
56 int nbins = cat->numBins((
const char *)0);
57 TString satname = TString::Format(
"%s_freeform", sim->GetName());
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) {
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()));
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));
77 const RooCmdArg &constCmdArg =
withSystematics ? RooFit::Constrain(*mc_s->GetNuisanceParameters()) : RooFit::NumCPU(1);
78 std::auto_ptr<RooFitResult> result_nominal (
doFit( *sim, data, minosOneVar, constCmdArg,
runMinos_));
79 std::auto_ptr<RooFitResult> result_freeform(
doFit(*newsim, data, minosVars, constCmdArg,
runMinos_));
82 if (result_nominal.get() == 0)
return false;
83 if (result_freeform.get() == 0)
return false;
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);
90 std::cout <<
"\n --- ChannelCompatibilityCheck --- " << std::endl;
93 printf(
"Nominal fit: %s fixed at %7.4f\n", r->GetName(), r->getVal());
95 RooRealVar *rNominal = (RooRealVar*) result_nominal->floatParsFinal().find(r->GetName());
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());
100 printf(
"Nominal fit : %s = %7.4f %+6.4f/%+6.4f\n", r->GetName(), rNominal->getVal(), rNominal->getAsymErrorLo(), rNominal->getAsymErrorHi());
102 printf(
"Nominal fit : %s = %7.4f +/- %6.4f\n", r->GetName(), rNominal->getVal(), rNominal->getError());
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());
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());
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());
113 printf(
"Alternate fit: %s = %7.4f +/- %6.4f in channel %s\n", r->GetName(), ri->getVal(), ri->getError(), it->first.c_str());
117 std::cout <<
"Chi2-like compatibility variable: " << limit << std::endl;
120 writeToysHere->GetFile()->WriteTObject(result_nominal.release(),
"fit_nominal" );
121 writeToysHere->GetFile()->WriteTObject(result_freeform.release(),
"fit_alternate");
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; }
void applyOptionsBase(const boost::program_options::variables_map &vm)
virtual void applyOptions(const boost::program_options::variables_map &vm)
ChannelCompatibilityCheck()
TDirectory * writeToysHere
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]
static bool saveFitResult_
std::string nameForLabel(const char *label)
boost::program_options::options_description options_