CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_9_patch3/src/HiggsAnalysis/CombinedLimit/src/ChannelCompatibilityCheck.cc

Go to the documentation of this file.
00001 #include "../interface/ChannelCompatibilityCheck.h"
00002 #include <TFile.h>
00003 #include <RooRealVar.h>
00004 #include <RooArgSet.h>
00005 #include <RooRandom.h>
00006 #include <RooDataSet.h>
00007 #include <RooFitResult.h>
00008 #include <RooCustomizer.h>
00009 #include <RooSimultaneous.h>
00010 #include <RooStats/ModelConfig.h>
00011 #include "../interface/Combine.h"
00012 #include "../interface/ProfileLikelihood.h"
00013 #include "../interface/CloseCoutSentry.h"
00014 #include "../interface/RooSimultaneousOpt.h"
00015 #include "../interface/utils.h"
00016 
00017 
00018 #include <Math/MinimizerOptions.h>
00019 
00020 using namespace RooStats;
00021 
00022 float ChannelCompatibilityCheck::mu_ = 0.0;
00023 bool  ChannelCompatibilityCheck::fixedMu_ = false;
00024 bool  ChannelCompatibilityCheck::saveFitResult_ = true;
00025 bool  ChannelCompatibilityCheck::runMinos_ = true;
00026 std::vector<std::string> ChannelCompatibilityCheck::groups_;
00027 
00028 ChannelCompatibilityCheck::ChannelCompatibilityCheck() :
00029     FitterAlgoBase("ChannelCompatibilityCheck specific options")
00030 {
00031     options_.add_options()
00032         ("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")
00033         ("saveFitResult",       "Save fit results in output file")
00034         ("group,g",             boost::program_options::value<std::vector<std::string> >(&groups_), "Group together channels that contain a given name. Can be used multiple times.")
00035         ("runMinos", boost::program_options::value<bool>(&runMinos_)->default_value(runMinos_), "Compute also uncertainties using profile likeilhood (MINOS or robust variants of it)")
00036     ;
00037 }
00038 
00039 void ChannelCompatibilityCheck::applyOptions(const boost::program_options::variables_map &vm) 
00040 {
00041     applyOptionsBase(vm);
00042     fixedMu_ = !vm["fixedSignalStrength"].defaulted();
00043     saveFitResult_ = vm.count("saveFitResult");
00044 }
00045 
00046 bool ChannelCompatibilityCheck::runSpecific(RooWorkspace *w, RooStats::ModelConfig *mc_s, RooStats::ModelConfig *mc_b, RooAbsData &data, double &limit, double &limitErr, const double *hint) { 
00047 
00048   RooRealVar *r = dynamic_cast<RooRealVar *>(mc_s->GetParametersOfInterest()->first());
00049   if (fixedMu_) { r->setVal(mu_); r->setConstant(true); }
00050   else          { r->setVal(preFitValue_); r->setConstant(false); }
00051 
00052   RooSimultaneous *sim = dynamic_cast<RooSimultaneous *>(mc_s->GetPdf());
00053   if (sim == 0) throw std::logic_error("Cannot use ChannelCompatibilityCheck if the pdf is not a RooSimultaneous");
00054 
00055   RooAbsCategoryLValue *cat = (RooAbsCategoryLValue *) sim->indexCat().Clone();
00056   int nbins = cat->numBins((const char *)0);
00057   TString satname = TString::Format("%s_freeform", sim->GetName());
00058   std::auto_ptr<RooSimultaneous> newsim((typeid(*sim) == typeid(RooSimultaneousOpt)) ? new RooSimultaneousOpt(satname, "", *cat) : new RooSimultaneous(satname, "", *cat)); 
00059   std::map<std::string,std::string> rs;
00060   RooArgList minosVars, minosOneVar; if (runMinos_) minosOneVar.add(*r);
00061   for (int ic = 0, nc = nbins; ic < nc; ++ic) {
00062       cat->setBin(ic);
00063       RooAbsPdf *pdfi = sim->getPdf(cat->getLabel());
00064       if (pdfi == 0) continue;
00065       RooCustomizer customizer(*pdfi, "freeform");
00066       TString riName = TString::Format("_ChannelCompatibilityCheck_%s_%s", r->GetName(), nameForLabel(cat->getLabel()).c_str());
00067       rs.insert(std::pair<std::string,std::string>(nameForLabel(cat->getLabel()), riName.Data()));
00068       if (w->var(riName) == 0) {
00069         w->factory(TString::Format("%s[%g,%g]", riName.Data(), r->getMin(), r->getMax()));
00070       }
00071       customizer.replaceArg(*r, *w->var(riName));
00072       newsim->addPdf((RooAbsPdf&)*customizer.build(), cat->getLabel());
00073       if (runMinos_ && !minosVars.find(riName)) minosVars.add(*w->var(riName));
00074   }
00075 
00076   CloseCoutSentry sentry(verbose < 2);
00077   const RooCmdArg &constCmdArg = withSystematics  ? RooFit::Constrain(*mc_s->GetNuisanceParameters()) : RooFit::NumCPU(1); // use something dummy 
00078   std::auto_ptr<RooFitResult> result_nominal (doFit(   *sim, data, minosOneVar, constCmdArg, runMinos_)); // let's run Hesse if we want to run Minos
00079   std::auto_ptr<RooFitResult> result_freeform(doFit(*newsim, data, minosVars,   constCmdArg, runMinos_));
00080   sentry.clear();
00081 
00082   if (result_nominal.get()  == 0) return false;
00083   if (result_freeform.get() == 0) return false;
00084 
00085   double nll_nominal   = result_nominal->minNll();
00086   double nll_freeform = result_freeform->minNll();
00087   if (fabs(nll_nominal) > 1e10 || fabs(nll_freeform) > 1e10) return false;
00088   limit = 2*(nll_nominal-nll_freeform);
00089   
00090   std::cout << "\n --- ChannelCompatibilityCheck --- " << std::endl;
00091   if (verbose) {
00092     if (fixedMu_) { 
00093         printf("Nominal fit: %s fixed at %7.4f\n", r->GetName(), r->getVal());
00094     } else {
00095         RooRealVar *rNominal = (RooRealVar*) result_nominal->floatParsFinal().find(r->GetName());
00096         if (runMinos_ && do95_) {
00097             printf("Nominal fit  : %s = %7.4f  %+6.4f/%+6.4f (68%% CL)\n", r->GetName(), rNominal->getVal(), rNominal->getAsymErrorLo(), rNominal->getAsymErrorHi());
00098             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());
00099         } else if (runMinos_) {
00100             printf("Nominal fit  : %s = %7.4f  %+6.4f/%+6.4f\n", r->GetName(), rNominal->getVal(), rNominal->getAsymErrorLo(), rNominal->getAsymErrorHi());
00101         } else {
00102             printf("Nominal fit  : %s = %7.4f  +/- %6.4f\n", r->GetName(), rNominal->getVal(), rNominal->getError());
00103         }
00104     }
00105     for (std::map<std::string,std::string>::const_iterator it = rs.begin(), ed = rs.end(); it != ed; ++it) {
00106         RooRealVar *ri = (RooRealVar*) result_freeform->floatParsFinal().find(it->second.c_str());
00107         if (runMinos_ && do95_) {
00108             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());
00109             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());
00110         } else if (runMinos_) {
00111             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());
00112         } else {
00113             printf("Alternate fit: %s = %7.4f  +/- %6.4f   in channel %s\n", r->GetName(), ri->getVal(), ri->getError(), it->first.c_str());
00114         }
00115     }
00116   }
00117   std::cout << "Chi2-like compatibility variable: " << limit << std::endl;
00118 
00119   if (saveFitResult_) {
00120       writeToysHere->GetFile()->WriteTObject(result_nominal.release(),  "fit_nominal"  );
00121       writeToysHere->GetFile()->WriteTObject(result_freeform.release(), "fit_alternate");
00122   }
00123   return true;
00124 }
00125 
00126 std::string ChannelCompatibilityCheck::nameForLabel(const char *label)
00127 {
00128     std::string ret(label);
00129     for (std::vector<std::string>::const_iterator it = groups_.begin(), ed = groups_.end(); it != ed; ++it) {
00130         if (ret.find(*it) != std::string::npos) { ret = *it; break; }
00131     }
00132     return ret;
00133 }
00134