CombineHarvester
Systematic.cc
Go to the documentation of this file.
2 #include <iostream>
3 #include "boost/format.hpp"
5 #include <regex>
6 
7 namespace {
8 auto format_syst(const ch::Systematic& val) {
9  std::string value_fmt;
10  if (val.asymm()) {
11  value_fmt = (boost::format("%.4g/%.4g")
12  % val.value_d() % val.value_u()).str();
13  } else {
14  value_fmt = (boost::format("%.4g") % val.value_u()).str();
15  }
16  return boost::format("%-6s %-9s %-6s %-8s %-28s %-3i"
17  " %-16s %-4i %-45s %-8s %-13s %-4i %-4i")
18  % val.mass()
19  % val.analysis()
20  % val.era()
21  % val.channel()
22  % val.bin()
23  % val.bin_id()
24  % val.process()
25  % val.signal()
26  % val.name()
27  % val.type()
28  % value_fmt
29  % (bool(val.shape_d()) || bool(val.data_d()) || bool(val.pdf_d()))
30  % (bool(val.shape_u()) || bool(val.data_u()) || bool(val.pdf_u()));
31 }
32 }
33 
34 namespace ch {
35 
37  : Object(),
38  name_(""),
39  type_(""),
40  value_u_(0.0),
41  value_d_(0.0),
42  scale_(1.0),
43  asymm_(false),
44  shape_u_(),
45  shape_d_(),
46  pdf_u_(nullptr),
47  pdf_d_(nullptr),
48  data_u_(nullptr),
49  data_d_(nullptr) {
50  }
51 
53 
54 void Systematic::set_name(std::string const& name) {
55 //test = std::regex_replace(test, std::regex("def"), "klm");
56  if (data_u_) data_u_->SetName(std::regex_replace(data_u_->GetName(),std::regex(name_),name).c_str());
57  if (data_d_) data_d_->SetName(std::regex_replace(data_d_->GetName(),std::regex(name_),name).c_str());
58  if (pdf_u_) pdf_u_->SetName(std::regex_replace(pdf_u_->GetName(),std::regex(name_),name).c_str());
59  if (pdf_d_) pdf_d_->SetName(std::regex_replace(pdf_d_->GetName(),std::regex(name_),name).c_str());
60  name_ = name;
61 }
62 
63 void swap(Systematic& first, Systematic& second) {
64  using std::swap;
65  swap(static_cast<Object&>(first), static_cast<Object&>(second));
66  swap(first.name_, second.name_);
67  swap(first.type_, second.type_);
68  swap(first.value_u_, second.value_u_);
69  swap(first.value_d_, second.value_d_);
70  swap(first.scale_, second.scale_);
71  swap(first.asymm_, second.asymm_);
72  swap(first.shape_u_, second.shape_u_);
73  swap(first.shape_d_, second.shape_d_);
74  swap(first.pdf_u_, second.pdf_u_);
75  swap(first.pdf_d_, second.pdf_d_);
76  swap(first.data_u_, second.data_u_);
77  swap(first.data_d_, second.data_d_);
78 }
79 
81  : Object(other),
82  name_(other.name_),
83  type_(other.type_),
84  value_u_(other.value_u_),
85  value_d_(other.value_d_),
86  scale_(other.scale_),
87  asymm_(other.asymm_),
88  pdf_u_(other.pdf_u_),
89  pdf_d_(other.pdf_d_),
90  data_u_(other.data_u_),
91  data_d_(other.data_d_) {
92  TH1 *h_u = nullptr;
93  if (other.shape_u_) {
94  h_u = dynamic_cast<TH1*>(other.shape_u_->Clone());
95  h_u->SetDirectory(0);
96  }
97  shape_u_ = std::unique_ptr<TH1>(h_u);
98  TH1 *h_d = nullptr;
99  if (other.shape_d_) {
100  h_d = dynamic_cast<TH1*>(other.shape_d_->Clone());
101  h_d->SetDirectory(0);
102  }
103  shape_d_ = std::unique_ptr<TH1>(h_d);
104 }
105 
107  : Object(),
108  name_(""),
109  type_(""),
110  value_u_(0.0),
111  value_d_(0.0),
112  scale_(1.0),
113  asymm_(false),
114  shape_u_(),
115  shape_d_(),
116  pdf_u_(nullptr),
117  pdf_d_(nullptr),
118  data_u_(nullptr),
119  data_d_(nullptr) {
120  swap(*this, other);
121 }
122 
124  swap(*this, other);
125  return (*this);
126 }
127 
128 void Systematic::set_shapes(std::unique_ptr<TH1> shape_u,
129  std::unique_ptr<TH1> shape_d, TH1 const* nominal) {
130  // Check that the inputs make sense
131  if (bool(shape_u) != bool(shape_d)) {
132  throw std::runtime_error(
133  "shape_u and shape_d must be either both valid or both null");
134  }
135  if (!shape_u && !shape_d) {
136  shape_u_ = nullptr;
137  shape_d_ = nullptr;
138  return;
139  }
140 
141  // for (int i = 1; i <= shape_u->GetNbinsX(); ++i) {
142  // if (shape_u->GetBinContent(i) < 0.) {
143  // throw std::runtime_error(
144  // FNERROR("shape_u TH1 has a bin with content < 0"));
145  // }
146  // }
147  // for (int i = 1; i <= shape_d->GetNbinsX(); ++i) {
148  // if (shape_d->GetBinContent(i) < 0.) {
149  // throw std::runtime_error(
150  // FNERROR("shape_d TH1 has a bin with content < 0"));
151  // }
152  // }
153 
154  // if (nominal) {
155  // for (int i = 1; i <= nominal->GetNbinsX(); ++i) {
156  // if (nominal->GetBinContent(i) < 0.) {
157  // throw std::runtime_error(
158  // FNERROR("nominal TH1 has a bin with content < 0"));
159  // }
160  // }
161  // }
162 
163  shape_u_ = std::move(shape_u);
164  shape_d_ = std::move(shape_d);
165  shape_u_->SetDirectory(0);
166  shape_d_->SetDirectory(0);
167 
168  if (nominal && nominal->Integral() > 0.) {
169  this->set_value_u(shape_u_->Integral() / nominal->Integral());
170  this->set_value_d(shape_d_->Integral() / nominal->Integral());
171  }
172 
173  if (shape_u_->Integral() > 0.) shape_u_->Scale(1. / shape_u_->Integral());
174  if (shape_d_->Integral() > 0.) shape_d_->Scale(1. / shape_d_->Integral());
175 }
176 
177 void Systematic::set_shapes(TH1 const& shape_u, TH1 const& shape_d,
178  TH1 const& nominal) {
179  set_shapes(std::unique_ptr<TH1>(static_cast<TH1*>(shape_u.Clone())),
180  std::unique_ptr<TH1>(static_cast<TH1*>(shape_d.Clone())),
181  &nominal);
182 }
183 
184 void Systematic::set_data(RooDataHist* data_u, RooDataHist* data_d,
185  RooDataHist const* nominal) {
186  if (nominal && nominal->sumEntries() > 0.) {
187  this->set_value_u(data_u->sumEntries() / nominal->sumEntries());
188  this->set_value_d(data_d->sumEntries() / nominal->sumEntries());
189  }
190  data_u_ = data_u;
191  data_d_ = data_d;
192 }
193 
194 void Systematic::set_pdf(RooAbsReal* pdf_u, RooAbsReal* pdf_d,
195  RooAbsReal const* nominal) {
196  pdf_u_ = pdf_u;
197  pdf_d_ = pdf_d;
198 }
199 
200 std::unique_ptr<TH1> Systematic::ClonedShapeU() const {
201  if (!shape_u_) return std::unique_ptr<TH1>();
202  std::unique_ptr<TH1> res(static_cast<TH1 *>(shape_u_->Clone()));
203  res->SetDirectory(0);
204  return res;
205 }
206 
207 std::unique_ptr<TH1> Systematic::ClonedShapeD() const {
208  if (!shape_d_) return std::unique_ptr<TH1>();
209  std::unique_ptr<TH1> res(static_cast<TH1 *>(shape_d_->Clone()));
210  res->SetDirectory(0);
211  return res;
212 }
213 
215  TH1F res;
216  if (this->shape_u()) {
217  // Need to get the shape as a concrete type (TH1F or TH1D)
218  // A nice way to do this is just to use TH1D::Copy into a fresh TH1F
219  TH1F const* test_f = dynamic_cast<TH1F const*>(this->shape_u());
220  TH1D const* test_d = dynamic_cast<TH1D const*>(this->shape_u());
221  if (test_f) {
222  test_f->Copy(res);
223  } else if (test_d) {
224  test_d->Copy(res);
225  } else {
226  throw std::runtime_error(FNERROR("TH1 shape is not a TH1F or a TH1D"));
227  }
228  }
229  return res;
230 }
231 
233  TH1F res;
234  if (this->shape_d()) {
235  // Need to get the shape as a concrete type (TH1F or TH1D)
236  // A nice way to do this is just to use TH1D::Copy into a fresh TH1F
237  TH1F const* test_f = dynamic_cast<TH1F const*>(this->shape_d());
238  TH1D const* test_d = dynamic_cast<TH1D const*>(this->shape_d());
239  if (test_f) {
240  test_f->Copy(res);
241  } else if (test_d) {
242  test_d->Copy(res);
243  } else {
244  throw std::runtime_error(FNERROR("TH1 shape is not a TH1F or a TH1D"));
245  }
246  }
247  return res;
248 }
249 
250 
251 std::ostream& Systematic::PrintHeader(std::ostream &out) {
252  std::string line =
253  (boost::format("%-6s %-9s %-6s %-8s %-28s %-3i"
254  " %-16s %-4i %-45s %-8s %-13s %-4i %-4i")
255  % "mass" % "analysis" % "era" % "channel" % "bin" % "id" % "process" % "sig"
256  % "nuisance" % "type" % "value" % "sh_d" % "sh_u").str();
257  std::string div(line.length(), '-');
258  out << div << "\n";
259  out << line << "\n";
260  out << div << "\n";
261  return out;
262 }
263 
264 std::string Systematic::to_string() const {
265  return ::format_syst(*this).str();
266 }
267 
268 std::ostream& operator<< (std::ostream &out, Systematic const& val) {
269  out << ::format_syst(val);
270  return out;
271 }
272 
274  if (not asymm())
275  value_u_=1./value_u_;
276  else{
277  double tmp = value_u_;
278  value_u_ = value_d_;
279  value_d_ = tmp;
280  }
281  shape_u_.swap(shape_d_);
282 }
283 }
#define FNERROR(x)
Definition: Logging.h:9
virtual std::string const & process() const
Definition: Object.h:20
virtual std::string const & bin() const
Definition: Object.h:17
virtual int bin_id() const
Definition: Object.h:35
virtual std::string const & analysis() const
Definition: Object.h:26
virtual std::string const & era() const
Definition: Object.h:29
virtual std::string const & mass() const
Definition: Object.h:38
bool signal() const
Definition: Object.h:23
virtual std::string const & channel() const
Definition: Object.h:32
Systematic & operator=(Systematic other)
Definition: Systematic.cc:123
void set_pdf(RooAbsReal *pdf_u, RooAbsReal *pdf_d, RooAbsReal const *nominal)
Definition: Systematic.cc:194
double value_u() const
Definition: Systematic.h:28
RooDataHist const * data_d() const
Definition: Systematic.h:51
std::unique_ptr< TH1 > ClonedShapeU() const
Definition: Systematic.cc:200
std::string const & type() const
Definition: Systematic.h:25
std::unique_ptr< TH1 > ClonedShapeD() const
Definition: Systematic.cc:207
void set_shapes(std::unique_ptr< TH1 > shape_u, std::unique_ptr< TH1 > shape_d, TH1 const *nominal)
Definition: Systematic.cc:128
void set_value_d(double const &value_d)
Definition: Systematic.h:30
bool asymm() const
Definition: Systematic.h:37
TH1 const * shape_d() const
Definition: Systematic.h:47
void set_name(std::string const &name)
Definition: Systematic.cc:54
void set_data(RooDataHist *data_u, RooDataHist *data_d, RooDataHist const *nominal)
Definition: Systematic.cc:184
void set_value_u(double const &value_u)
Definition: Systematic.h:27
TH1 const * shape_u() const
Definition: Systematic.h:39
void SwapUpAndDown()
Definition: Systematic.cc:273
std::string const & name() const
Definition: Systematic.h:22
std::string to_string() const
Definition: Systematic.cc:264
RooAbsReal const * pdf_d() const
Definition: Systematic.h:55
RooAbsReal const * pdf_u() const
Definition: Systematic.h:53
RooDataHist const * data_u() const
Definition: Systematic.h:49
double value_d() const
Definition: Systematic.h:31
TH1F ShapeUAsTH1F() const
Definition: Systematic.cc:214
TH1F ShapeDAsTH1F() const
Definition: Systematic.cc:232
friend void swap(Systematic &first, Systematic &second)
Definition: Systematic.cc:63
static std::ostream & PrintHeader(std::ostream &out)
Definition: Systematic.cc:251
Definition: Algorithm.h:10
std::ostream & operator<<(std::ostream &out, HistMapping const &val)
Definition: HistMapping.cc:70
void swap(Systematic &first, Systematic &second)
Definition: Systematic.cc:63
void swap(CombineHarvester &first, CombineHarvester &second)