2 #include "boost/program_options.hpp" 
    3 #include "boost/format.hpp" 
   11 namespace po = boost::program_options;
 
   16   std::vector<float> contents(h.GetNbinsX());
 
   17   std::vector<float> errors(h.GetNbinsX());
 
   18   for (
int i = 0; i < h.GetNbinsX(); ++i) {
 
   19     contents[i] = h.GetBinContent(i + 1);
 
   20     errors[i] = h.GetBinError(i + 1);
 
   22   for (
int i = 0; i < h.GetNbinsX(); ++i) {
 
   23     h.SetBinContent(h.GetNbinsX() - i, contents[i]);
 
   24     h.SetBinError(h.GetNbinsX() - i, errors[i]);
 
   29 int main(
int argc, 
char* argv[]) {
 
   31   gSystem->Load(
"libHiggsAnalysisCombinedLimit");
 
   34   string workspace  = 
"";
 
   35   string fitresult  = 
"";
 
   38   bool sampling     = 
false;
 
   39   bool no_sampling  = 
false;
 
   42   unsigned samples  = 500;
 
   43   std::string freeze_arg = 
"";
 
   44   bool covariance   = 
false;
 
   45   string data       = 
"data_obs";
 
   46   bool skip_prefit  = 
false;
 
   47   bool skip_proc_errs = 
false;
 
   48   bool total_shapes = 
false;
 
   49   std::vector<std::string> reverse_bins_;
 
   51   po::options_description help_config(
"Help");
 
   52   help_config.add_options()
 
   53     (
"help,h", 
"produce help message");
 
   55   po::options_description config(
"Configuration");
 
   58       po::value<string>(&workspace)->required(),
 
   59       "The input workspace-containing file [REQUIRED]")
 
   61       po::value<string>(&data)->default_value(data),
 
   62       "The input dataset name")
 
   64       po::value<string>(&datacard),
 
   65       "The input datacard, only used for rebinning")
 
   67       po::value<string>(&output)->required(),
 
   68       "Name of the output root file to create [REQUIRED]")
 
   70       po::value<string>(&fitresult)->default_value(fitresult),
 
   71       "Path to a RooFitResult, only needed for postfit")
 
   73       po::value<string>(&mass)->default_value(
""),
 
   74       "Signal mass point of the input datacard")
 
   76       po::value<bool>(&postfit)
 
   77       ->default_value(postfit)->implicit_value(
true),
 
   78       "Create post-fit histograms in addition to pre-fit")
 
   80       po::value<bool>(&sampling)->default_value(sampling)->implicit_value(
true),
 
   81       "Use the cov. matrix sampling method for the post-fit uncertainty (deprecated, this is the default)")
 
   83       po::value<bool>(&no_sampling)->default_value(no_sampling)->implicit_value(
true),
 
   84       "Do not use the cov. matrix sampling method for the post-fit uncertainty")
 
   86       po::value<unsigned>(&samples)->default_value(samples),
 
   87       "Number of samples to make in each evaluate call")
 
   89       po::value<bool>(&factors)->default_value(factors)->implicit_value(
true),
 
   90       "Print tables of background shifts and relative uncertainties")
 
   92       po::value<string>(&freeze_arg)->default_value(freeze_arg),
 
   93       "Format PARAM1,PARAM2=X,PARAM3=Y where the values X and Y are optional")
 
   95       po::value<bool>(&covariance)->default_value(covariance)->implicit_value(
true),
 
   96       "Save the covariance and correlation matrices of the process yields")
 
   98       po::value<bool>(&skip_prefit)->default_value(skip_prefit)->implicit_value(
true),
 
   99       "Skip the pre-fit evaluation")
 
  101       po::value<bool>(&skip_proc_errs)->default_value(skip_proc_errs)->implicit_value(
true),
 
  102       "Skip evaluation of errors on individual processes")
 
  104       po::value<bool>(&total_shapes)->default_value(total_shapes)->implicit_value(
true),
 
  105       "Save signal- and background shapes added for all channels/categories")
 
  106     (
"reverse-bins", po::value<vector<string>>(&reverse_bins_)->multitoken(), 
"List of bins to reverse the order for");
 
  109   po::variables_map vm;
 
  113   po::store(po::command_line_parser(argc, argv)
 
  114     .options(help_config).allow_unregistered().run(), vm);
 
  116   if (vm.count(
"help")) {
 
  117     cout << config << 
"\nExample usage:\n";
 
  118     cout << 
"PostFitShapesFromWorkspace.root -d htt_mt_125.txt -w htt_mt_125.root -o htt_mt_125_shapes.root -m 125 " 
  119             "-f mlfit.root:fit_s --postfit --print\n";
 
  124   po::store(po::command_line_parser(argc, argv).options(config).run(), vm);
 
  128     std::cout<<
"WARNING: the default behaviour of PostFitShapesFromWorkspace is to use the covariance matrix sampling method for the post-fit uncertainty. The option --sampling is deprecated and will be removed in future versions of CombineHarvester"<<std::endl;
 
  131   TFile infile(workspace.c_str());
 
  133   RooWorkspace *ws = 
dynamic_cast<RooWorkspace*
>(gDirectory->Get(
"w"));
 
  136     throw std::runtime_error(
 
  137         FNERROR(
"Could not locate workspace in input file"));
 
  142   cmb.
SetFlag(
"workspaces-use-clone", 
true);
 
  146   if(! freeze_arg.empty())
 
  148     vector<string> freeze_vec;
 
  149     boost::split(freeze_vec, freeze_arg, boost::is_any_of(
","));
 
  150     for (
auto const& item : freeze_vec) {
 
  151       vector<string> parts;
 
  152       boost::split(parts, item, boost::is_any_of(
"="));
 
  153       if (parts.size() == 1) {
 
  156         else throw std::runtime_error(
 
  157           FNERROR(
"Requested variable to freeze does not exist in workspace"));
 
  159         if (parts.size() == 2) {
 
  162             par->
set_val(boost::lexical_cast<double>(parts[1]));
 
  165           else throw std::runtime_error(
 
  166             FNERROR(
"Requested variable to freeze does not exist in workspace"));
 
  174   cmb_card.
SetFlag(
"workspaces-use-clone",
true);
 
  175   if (datacard != 
"") {
 
  181     bool no_shape = !proc->
shape() && !proc->
data() && !proc->
pdf();
 
  183       cout << 
"Filtering process with no shape:\n";
 
  191   TFile outfile(output.c_str(), 
"RECREATE");
 
  192   TH1::AddDirectory(
false);
 
  196   map<string, map<string, TH1F>> pre_shapes;
 
  201   map<string, TH1F> pre_shapes_tot;
 
  209       std::cout << 
">> Doing prefit: TotalBkg" << std::endl;
 
  210       pre_shapes_tot[
"TotalBkg"] =
 
  212       std::cout << 
">> Doing prefit: TotalSig" << std::endl;
 
  213       pre_shapes_tot[
"TotalSig"] =
 
  215       std::cout << 
">> Doing prefit: TotalProcs" << std::endl;
 
  216       pre_shapes_tot[
"TotalProcs"] =
 
  219       if (datacard != 
"") {
 
  221         for (
auto & it : pre_shapes_tot) {
 
  228       for (
auto& iter : pre_shapes_tot) {
 
  232     for (
auto bin : bins) {
 
  242         std::cout << 
">> Doing prefit: " << bin << 
"," << proc << std::endl;
 
  243         if (skip_proc_errs) {
 
  244           pre_shapes[bin][proc] =
 
  247           pre_shapes[bin][proc] =
 
  248               cmb_bin.
cp().
process({proc}).GetShapeWithUncertainty();
 
  253       std::cout << 
">> Doing prefit: " << bin << 
"," << 
"TotalBkg" << std::endl;
 
  254       pre_shapes[bin][
"TotalBkg"] =
 
  256       std::cout << 
">> Doing prefit: " << bin << 
"," << 
"TotalSig" << std::endl;
 
  257       pre_shapes[bin][
"TotalSig"] =
 
  259       std::cout << 
">> Doing prefit: " << bin << 
"," << 
"TotalProcs" << std::endl;
 
  260       pre_shapes[bin][
"TotalProcs"] =
 
  264       if (datacard != 
"") {
 
  265         TH1F ref = cmb_card.
cp().
bin({bin}).GetObservedShape();
 
  266         for (
auto & it : pre_shapes[bin]) {
 
  271       for (
auto const& rbin : reverse_bins_) {
 
  272         if (rbin != bin) 
continue;
 
  273         auto & hists = pre_shapes[bin];
 
  274         for (
auto it = hists.begin(); it != hists.end(); ++it) {
 
  280       for (
auto& iter : pre_shapes[bin]) {
 
  287       cout << boost::format(
"%-25s %-32s\n") % 
"Bin" %
 
  288                   "Total relative bkg uncert. (prefit)";
 
  289       cout << string(58, 
'-') << 
"\n";
 
  290       for (
auto bin : bins) {
 
  294         cout << boost::format(
"%-25s %-10.5f") % bin %
 
  295                     (rate > 0. ? (err / rate) : 0.) << std::endl;
 
  304     RooFitResult res = ch::OpenFromTFile<RooFitResult>(fitresult);
 
  309     map<string, map<string, TH1F>> post_shapes;
 
  310     map<string, TH2F> post_yield_cov;
 
  311     map<string, TH2F> post_yield_cor;
 
  313     map<string, TH1F> post_shapes_tot;
 
  320       std::cout << 
">> Doing postfit: TotalBkg" << std::endl;
 
  321       post_shapes_tot[
"TotalBkg"] =
 
  323                    : cmb_bkgs.GetShapeWithUncertainty(res, samples);
 
  324       std::cout << 
">> Doing postfit: TotalSig" << std::endl;
 
  325       post_shapes_tot[
"TotalSig"] =
 
  326           no_sampling ? cmb_sigs.GetShapeWithUncertainty()
 
  327                    : cmb_sigs.GetShapeWithUncertainty(res, samples);
 
  328       std::cout << 
">> Doing postfit: TotalProcs" << std::endl;
 
  329       post_shapes_tot[
"TotalProcs"] =
 
  333       if (datacard != 
"") {
 
  335         for (
auto & it : post_shapes_tot) {
 
  342       for (
auto & iter : post_shapes_tot) {
 
  344                          "postfit/" + iter.first);
 
  349     for (
auto bin : bins) {
 
  353         auto cmb_proc = cmb_bin.
cp().
process({proc});
 
  356         std::cout << 
">> Doing postfit: " << bin << 
"," << proc << std::endl;
 
  357         if (skip_proc_errs) {
 
  358           post_shapes[bin][proc] = cmb_proc.GetShape();
 
  360           post_shapes[bin][proc] =
 
  361               no_sampling ? cmb_proc.GetShapeWithUncertainty()
 
  362                        : cmb_proc.GetShapeWithUncertainty(res, samples);
 
  365       if (!no_sampling && covariance) {
 
  372       std::cout << 
">> Doing postfit: " << bin << 
"," << 
"TotalBkg" << std::endl;
 
  373       post_shapes[bin][
"TotalBkg"] =
 
  375                    : cmb_bkgs.GetShapeWithUncertainty(res, samples);
 
  376       std::cout << 
">> Doing postfit: " << bin << 
"," << 
"TotalSig" << std::endl;
 
  377       post_shapes[bin][
"TotalSig"] =
 
  378           no_sampling ? cmb_sigs.GetShapeWithUncertainty()
 
  379                    : cmb_sigs.GetShapeWithUncertainty(res, samples);
 
  380       std::cout << 
">> Doing postfit: " << bin << 
"," << 
"TotalProcs" << std::endl;
 
  381       post_shapes[bin][
"TotalProcs"] =
 
  385       if (datacard != 
"") {
 
  386         TH1F ref = cmb_card.
cp().
bin({bin}).GetObservedShape();
 
  387         for (
auto & it : post_shapes[bin]) {
 
  395       for (
auto const& rbin : reverse_bins_) {
 
  396         if (rbin != bin) 
continue;
 
  397         std::cout << 
">> reversing hists in bin " << bin << 
"\n";
 
  398         auto & hists = post_shapes[bin];
 
  399         for (
auto it = hists.begin(); it != hists.end(); ++it) {
 
  404       for (
auto & iter : post_shapes[bin]) {
 
  406                          bin + 
"_postfit/" + iter.first);
 
  408       for (
auto & iter : post_yield_cov) {
 
  412       for (
auto & iter : post_yield_cor) {
 
  420       cout << boost::format(
"\n%-25s %-32s\n") % 
"Bin" %
 
  421                   "Total relative bkg uncert. (postfit)";
 
  422       cout << string(58, 
'-') << 
"\n";
 
  423       for (
auto bin : bins) {
 
  425         double rate = cmb_bkgs.
GetRate();
 
  428         cout << boost::format(
"%-25s %-10.5f") % bin %
 
  429                     (rate > 0. ? (err / rate) : 0.) << std::endl;
 
  435     if (factors && postfit) {
 
  436       cout << boost::format(
"\n%-25s %-20s %-10s\n") % 
"Bin" % 
"Process" %
 
  438       cout << string(58, 
'-') << 
"\n";
 
  439       for (
auto bin : bins) {
 
  444           TH1 
const& pre = pre_shapes[bin][proc];
 
  445           TH1 
const& post = post_shapes[bin][proc];
 
  446           cout << boost::format(
"%-25s %-20s %-10.5f\n") % bin % proc %
 
  447                       (pre.Integral() > 0. ? (post.Integral() / pre.Integral())
 
int main(int argc, char *argv[])
 
void ReverseBins(TH1F &h)
 
TH2F GetRateCovariance(RooFitResult const &fit, unsigned n_samples)
 
CombineHarvester & backgrounds()
 
CombineHarvester & signals()
 
TH2F GetRateCorrelation(RooFitResult const &fit, unsigned n_samples)
 
CombineHarvester & process(std::vector< std::string > const &vec, bool cond=true)
 
void SetFlag(std::string const &flag, bool const &value)
Set a named flag value.
 
std::set< std::string > process_set()
 
TH1F GetShapeWithUncertainty()
 
CombineHarvester & bin(std::vector< std::string > const &vec, bool cond=true)
 
void UpdateParameters(std::vector< ch::Parameter > const ¶ms)
 
std::set< std::string > bin_set()
 
int ParseDatacard(std::string const &filename, std::string const &analysis, std::string const &era, std::string const &channel, int bin_id, std::string const &mass)
 
CombineHarvester & FilterProcs(Function func)
 
CombineHarvester cp()
Creates and returns a shallow copy of the CombineHarvester instance.
 
ch::Parameter const  * GetParameter(std::string const &name) const
 
void set_frozen(bool const &frozen)
 
void set_val(double const &val)
 
RooAbsReal const  * pdf() const
 
RooAbsData const  * data() const
 
static std::ostream & PrintHeader(std::ostream &out)
 
TH1 const  * shape() const
 
void WriteToTFile(T *ptr, TFile *file, std::string const &path)
 
TH1F RestoreBinning(TH1F const &src, TH1F const &ref)
 
void ParseCombineWorkspace(CombineHarvester &cb, RooWorkspace &ws, std::string const &modelcfg, std::string const &data, bool verbose=false)