CombineHarvester
ParseCombineWorkspace.cc
Go to the documentation of this file.
2 #include "HiggsAnalysis/CombinedLimit/interface/CMSHistErrorPropagator.h"
3 #include <iostream>
4 #include <string>
5 #include <vector>
6 #include "RooWorkspace.h"
7 #include "RooSimultaneous.h"
8 #include "RooCategory.h"
9 #include "RooAddPdf.h"
10 #include "RooProdPdf.h"
11 #include "RooRealSumPdf.h"
12 #include "RooStats/ModelConfig.h"
14 
15 namespace ch {
16 void ParseCombineWorkspacePy(CombineHarvester& cb, RooWorkspace const& ws,
17  std::string const& modelcfg,
18  std::string const& data, bool verbose) {
19  ParseCombineWorkspace(cb, const_cast<RooWorkspace&>(ws), modelcfg, data, verbose);
20 }
21 
22 void ParseCombineWorkspace(CombineHarvester& cb, RooWorkspace& ws,
23  std::string const& modelcfg_name,
24  std::string const& data_name, bool verbose) {
25  bool v = verbose;
26 
27  RooStats::ModelConfig* cfg =
28  dynamic_cast<RooStats::ModelConfig*>(ws.genobj(modelcfg_name.c_str()));
29  if (!cfg) {
30  throw std::runtime_error(
31  FNERROR("Could not get ModelConfig from workspace"));
32  }
33  RooSimultaneous* pdf = dynamic_cast<RooSimultaneous*>(cfg->GetPdf());
34  if (!pdf) {
35  throw std::runtime_error(FNERROR("PDF is not a RooSimultaneous"));
36  }
37 
38  std::vector<std::string> cats;
39 
40  struct ProcInfo {
41  std::string bin;
42  std::string proc;
43  std::string pdf;
44  std::string norm;
45  };
46  std::map<std::string, std::vector<ProcInfo>> proc_infos;
47 
48  RooAbsData *data = ws.data(data_name.c_str());
49  // Hard-coded the category as "CMS_channel". Could deduce instead...
50  std::unique_ptr<TList> split(data->split(RooCategory("CMS_channel", "")));
51  for (int i = 0; i < split->GetSize(); ++i) {
52  RooAbsData *idat = dynamic_cast<RooAbsData*>(split->At(i));
53  cats.push_back(idat->GetName());
54  FNLOGC(std::cout, v) << "Found data for category: " << cats.back() << "\n";
55 
56  ch::Observation obs;
57  obs.set_bin(cats.back());
58  cb.InsertObservation(obs);
59 
60  bool delete_pdfs = false;
61 
62  RooAbsReal *ipdf = FindAddPdf(pdf->getPdf(cats.back().c_str()));
63  if (ipdf) {
64  std::unique_ptr<RooArgSet> pdf_obs(ipdf->getObservables(data->get()));
65  idat = idat->reduce(*pdf_obs);
66  ws.import(*idat);
67  RooAddPdf *ipdf_add = dynamic_cast<RooAddPdf*>(ipdf);
68  RooRealSumPdf *ipdf_sum = dynamic_cast<RooRealSumPdf*>(ipdf);
69  RooArgList const* coeffs = nullptr;
70  RooArgList const* pdfs = nullptr;
71  if (ipdf_add) {
72  FNLOGC(std::cout, v) << "Found RooAddPdf: " << ipdf_add->GetName() << "\n";
73  coeffs = &(ipdf_add->coefList());
74  pdfs = &(ipdf_add->pdfList());
75  if (coeffs->getSize() != pdfs->getSize()) {
76  throw std::runtime_error(FNERROR("This RooAddPdf is not extended!"));
77  }
78  }
79  if (ipdf_sum) {
80  FNLOGC(std::cout, v) << "Found RooRealSumPdf: " << ipdf_sum->GetName() << "\n";
81  coeffs = &(ipdf_sum->coefList());
82  pdfs = &(ipdf_sum->funcList());
83  if (coeffs->getSize() != pdfs->getSize()) {
84  throw std::runtime_error(FNERROR("This RooRealSumPdf is not extended!"));
85  }
86  if (pdfs->getSize() == 1) {
87  CMSHistErrorPropagator *err = dynamic_cast<CMSHistErrorPropagator*>(pdfs->at(0));
88  if (err) {
89  coeffs = &(err->coefList());
90  pdfs = new RooArgList(err->wrapperList());
91  delete_pdfs = true;
92  }
93  }
94  }
95  for (int j = 0; j < coeffs->getSize(); ++j) {
96  RooAbsReal *jcoeff = dynamic_cast<RooAbsReal*>(coeffs->at(j));
97  RooAbsReal *jpdf = dynamic_cast<RooAbsReal*>(pdfs->at(j));
98  FNLOGC(std::cout, v) << "Component " << j << "\t" << jcoeff->GetName()
99  << "\t" << jpdf->GetName() << "\n";
100  ch::Process proc;
101  proc.set_bin(cats.back());
102  // Get the process name & signal flag from the pdf attributes that are
103  // set by text2workspace. Should really check they exist first...
104  proc.set_process(jpdf->getStringAttribute("combine.process"));
105  proc.set_rate(1.);
106  proc.set_signal(jcoeff->getAttribute("combine.signal"));
107  proc_infos[proc.bin()].push_back(
108  {proc.bin(), proc.process(), jpdf->GetName(), jcoeff->GetName()});
109  cb.InsertProcess(proc);
110  }
111  if (delete_pdfs) delete pdfs;
112  }
113  }
114  cb.AddWorkspace(ws);
115  cb.ExtractData(ws.GetName(), "$BIN");
116  // This loop is slow if we have have a lot of procs
117  // Better way would be to filter to each bin, then do all the procs for that
118  // bin
119  for (auto b : cb.bin_set()) {
120  auto cb_bin = cb.cp().bin({b});
121  for (auto const& pinfo: proc_infos[b]) {
122  cb_bin.cp().process({pinfo.proc}).ExtractPdfs(
123  cb, ws.GetName(), pinfo.pdf, pinfo.norm);
124  }
125  }
126 }
127 
128 RooAbsReal* FindAddPdf(RooAbsReal* input) {
129  RooAddPdf *as_add = dynamic_cast<RooAddPdf*>(input);
130  RooRealSumPdf *as_sum = dynamic_cast<RooRealSumPdf*>(input);
131  if (as_add) return as_add;
132  if (as_sum) return as_sum;
133  RooProdPdf *as_prod = dynamic_cast<RooProdPdf*>(input);
134  if (as_prod) {
135  RooArgList const& comps = as_prod->pdfList();
136  for (int i = 0; i < comps.getSize(); ++i) {
137  RooAbsReal* try_add = FindAddPdf(dynamic_cast<RooAbsReal*>(comps.at(i)));
138  if (try_add) return try_add;
139  }
140  }
141  return nullptr;
142 }
143 }
#define FNLOGC(x, y)
Definition: Logging.h:14
#define FNERROR(x)
Definition: Logging.h:9
void AddWorkspace(RooWorkspace const &ws, bool can_rename=false)
CombineHarvester & process(std::vector< std::string > const &vec, bool cond=true)
CombineHarvester & bin(std::vector< std::string > const &vec, bool cond=true)
std::set< std::string > bin_set()
void InsertProcess(ch::Process const &proc)
void ExtractData(std::string const &ws_name, std::string const &rule)
void InsertObservation(ch::Observation const &obs)
CombineHarvester cp()
Creates and returns a shallow copy of the CombineHarvester instance.
virtual void set_process(std::string const &process)
Definition: Object.h:19
virtual std::string const & process() const
Definition: Object.h:20
virtual void set_bin(std::string const &bin)
Definition: Object.h:16
virtual std::string const & bin() const
Definition: Object.h:17
void set_signal(bool const &signal)
Definition: Object.h:22
void set_rate(double const &rate)
Definition: Process.h:24
Definition: Algorithm.h:10
RooAbsReal * FindAddPdf(RooAbsReal *input)
void ParseCombineWorkspace(CombineHarvester &cb, RooWorkspace &ws, std::string const &modelcfg, std::string const &data, bool verbose=false)
void ParseCombineWorkspacePy(CombineHarvester &cb, RooWorkspace const &ws, std::string const &modelcfg, std::string const &data, bool verbose=false)