5 #include "boost/format.hpp"
6 #include "boost/lexical_cast.hpp"
7 #include "Math/QuantFunc.h"
12 : pattern_(
"CMS_$ANALYSIS_$CHANNEL_$BIN_$ERA_$PROCESS_bin_$#"),
17 poisson_errors_(false),
18 merge_zero_bins_(true),
19 merge_saturated_bins_(true) {}
29 for (
auto const& bin : bins) {
30 unsigned bbb_added = 0;
31 unsigned bbb_removed = 0;
33 std::vector<Process *> procs;
35 if (p->
shape()->GetSumw2N() == 0) {
36 std::cout <<
"Process " << p->process()
37 <<
" does not continue the weights information needed for "
38 "valid errors, skipping\n";
43 if (procs.size() == 0)
continue;
45 std::vector<std::unique_ptr<TH1>> h_copies(procs.size());
46 for (
unsigned i = 0; i < h_copies.size(); ++i) {
47 h_copies[i] = procs[i]->ClonedScaledShape();
50 for (
int i = 1; i <= h_copies[0]->GetNbinsX(); ++i) {
51 double tot_bbb_added = 0.0;
52 std::vector<std::tuple<double, TH1 *, bool>> result;
53 for (
unsigned j = 0; j < h_copies.size(); ++j) {
54 double val = h_copies[j]->GetBinContent(i);
55 double err = h_copies[j]->GetBinError(i);
58 if (val == 0.0 && err == 0.0)
continue;
66 bool can_expand =
true;
70 tot_bbb_added += (err * err);
72 result.push_back(std::make_tuple(err*err, h_copies[j].get(), can_expand));
75 if (tot_bbb_added == 0.0)
continue;
76 std::sort(result.begin(), result.end());
78 for (
unsigned r = 0; r < result.size(); ++r) {
79 if ((std::get<0>(result[r]) + removed) < (merge_threshold * tot_bbb_added) &&
80 r < (result.size() - 1) && std::get<2>(result[r])) {
82 removed += std::get<0>(result[r]);
83 std::get<1>(result[r])->SetBinError(i, 0.0);
86 double expand = std::sqrt(1. / (1. - (removed / tot_bbb_added)));
87 for (
unsigned r = 0; r < result.size(); ++r) {
88 if (!std::get<2>(result[r]))
continue;
89 std::get<1>(result[r])->SetBinError(
90 i, std::get<1>(result[r])->GetBinError(i) * expand);
93 for (
unsigned i = 0; i < h_copies.size(); ++i) {
94 procs[i]->set_shape(std::move(h_copies[i]),
false);
97 std::cout <<
"BIN: " << bin << std::endl;
98 std::cout <<
"Total bbb added: " << bbb_added <<
"\n";
99 std::cout <<
"Total bbb removed: " << bbb_removed <<
"\n";
100 std::cout <<
"Total bbb =======>: " << bbb_added-bbb_removed <<
"\n";
106 unsigned bbb_added = 0;
107 std::vector<Process *> procs;
111 for (
unsigned i = 0; i < procs.size(); ++i) {
112 if (!procs[i]->shape())
continue;
113 TH1
const* h = procs[i]->shape();
114 if (h->GetSumw2N() == 0) {
115 std::cout <<
"Process " << procs[i]->process()
116 <<
" does not continue the weights information needed for "
117 "valid errors, skipping\n";
120 unsigned n_pop_bins = 0;
121 for (
int j = 1; j <= h->GetNbinsX(); ++j) {
122 if (h->GetBinContent(j) > 0.0) ++n_pop_bins;
126 std::cout <<
"Requested fixed_norm but template has <= 1 populated "
132 for (
int j = 1; j <= h->GetNbinsX(); ++j) {
134 double val = h->GetBinContent(j);
135 double err = h->GetBinError(j);
138 if (val == 0. && err > 0.) do_bbb =
true;
149 double n_evt_float = (val*val) / (err*err);
150 unsigned n_evt = std::floor(0.5 + n_evt_float);
151 if (n_evt == 0) n_evt = 1;
155 err_hi = ROOT::Math::gamma_quantile((1.-((1.-cl)/2.)), n_evt+1, 1) - n_evt;
156 err_lo = n_evt - ROOT::Math::gamma_quantile(((1.-cl)/2.), n_evt, 1);
161 err_hi = (err_hi/n_evt_float) * val;
162 err_lo = (err_lo/n_evt_float) * val;
170 boost::replace_all(name,
"$ANALYSIS", sys.
analysis());
171 boost::replace_all(name,
"$CHANNEL", sys.
channel());
172 boost::replace_all(name,
"$BIN", sys.
bin());
173 boost::replace_all(name,
"$BINID", boost::lexical_cast<std::string>(sys.
bin_id()));
174 boost::replace_all(name,
"$ERA", sys.
era());
175 boost::replace_all(name,
"$PROCESS", sys.
process());
176 boost::replace_all(name,
"$MASS", sys.
mass());
177 boost::replace_all(name,
"$#", boost::lexical_cast<std::string>(j));
180 std::unique_ptr<TH1> h_d(
static_cast<TH1 *
>(h->Clone()));
181 std::unique_ptr<TH1> h_u(
static_cast<TH1 *
>(h->Clone()));
182 h_d->SetBinContent(j, val - err_lo);
183 if (h_d->GetBinContent(j) < 0.) h_d->SetBinContent(j, 0.);
184 if (!(h_d->Integral() > 0.)) h_d->SetBinContent(j,0.00001*h->Integral());
185 h_u->SetBinContent(j, val + err_hi);
193 sys.
set_shapes(std::move(h_u), std::move(h_d),
nullptr);
unsigned GetVerbosity()
Getter functions for class attributes.
void MergeBinErrors(CombineHarvester &cb)
Merges histogram bin errors between processes.
void MergeAndAdd(CombineHarvester &src, CombineHarvester &dest)
A convenience function which calls MergeBinErrors and AddBinByBin in turn.
void AddBinByBin(CombineHarvester &src, CombineHarvester &dest)
Create bin-by-bin shape uncertainties for every process in src, and add these to dest
bool GetMergeSaturatedBins()
double GetMergeThreshold()
void CreateParameterIfEmpty(std::string const &name)
void ForEachProc(Function func)
CombineHarvester & bin(std::vector< std::string > const &vec, bool cond=true)
std::set< std::string > bin_set()
CombineHarvester & histograms()
void InsertSystematic(ch::Systematic const &sys)
CombineHarvester cp()
Creates and returns a shallow copy of the CombineHarvester instance.
virtual std::string const & process() const
virtual std::string const & bin() const
virtual int bin_id() const
virtual std::string const & analysis() const
virtual std::string const & era() const
virtual std::string const & mass() const
virtual std::string const & channel() const
static std::ostream & PrintHeader(std::ostream &out)
TH1 const * shape() const
void set_shapes(std::unique_ptr< TH1 > shape_u, std::unique_ptr< TH1 > shape_d, TH1 const *nominal)
void set_value_d(double const &value_d)
void set_name(std::string const &name)
void set_value_u(double const &value_u)
std::string const & name() const
void set_asymm(bool const &asymm)
void set_type(std::string const &type)
void SetProperties(T *first, U const *second)