CombineHarvester
Observation.cc
Go to the documentation of this file.
2 #include <iostream>
3 #include "boost/format.hpp"
5 
6 namespace {
7 auto format_obs(const ch::Observation& val) {
8  return boost::format("%-6s %-9s %-6s %-8s %-28s %-3i %-21s %-10.5g %-5i")
9  % val.mass()
10  % val.analysis()
11  % val.era()
12  % val.channel()
13  % val.bin()
14  % val.bin_id()
15  % "data_obs"
16  % val.rate()
17  % (bool(val.shape()) || bool(val.data()));
18 }
19 }
20 
21 namespace ch {
22 
24  : Object(),
25  rate_(0.0),
26  shape_(),
27  data_(nullptr) {
28  this->set_process("data_obs");
29  }
30 
32 
33 void swap(Observation& first, Observation& second) {
34  using std::swap;
35  swap(static_cast<Object&>(first), static_cast<Object&>(second));
36  swap(first.rate_, second.rate_);
37  swap(first.shape_, second.shape_);
38  swap(first.data_, second.data_);
39 }
40 
42  : Object(other),
43  rate_(other.rate_),
44  data_(other.data_) {
45  TH1* h = nullptr;
46  if (other.shape_) {
47  h = dynamic_cast<TH1*>(other.shape_->Clone());
48  h->SetDirectory(0);
49  }
50  shape_ = std::unique_ptr<TH1>(h);
51 }
52 
54  : Object(),
55  rate_(0.0),
56  shape_(),
57  data_(nullptr) {
58  swap(*this, other);
59 }
60 
62  swap(*this, other);
63  return (*this);
64 }
65 
66 void Observation::set_shape(std::unique_ptr<TH1> shape, bool set_rate) {
67  // We were given a nullptr - this is fine, and so we're done
68  if (!shape) {
69  // This will safely release any existing TH1 held by shape_
70  shape_ = nullptr;
71  return;
72  }
73  // Otherwise we validate this new hist. First is to check that all bins have
74  // +ve values, otherwise the interpretation as a pdf is tricky
75  // for (int i = 1; i <= shape->GetNbinsX(); ++i) {
76  // if (shape->GetBinContent(i) < 0.) {
77  // throw std::runtime_error(FNERROR("TH1 has a bin with content < 0"));
78  // }
79  // }
80  // At this point we can safely move the shape in and take ownership
81  shape_ = std::move(shape);
82  // Ensure that root will not try and clean this up
83  shape_->SetDirectory(0);
84  if (set_rate) {
85  this->set_rate(shape_->Integral());
86  }
87  if (shape_->Integral() > 0.) shape_->Scale(1. / shape_->Integral());
88 }
89 
90 void Observation::set_shape(TH1 const& shape, bool set_rate) {
91  set_shape(std::unique_ptr<TH1>(static_cast<TH1*>(shape.Clone())), set_rate);
92 }
93 
94 std::unique_ptr<TH1> Observation::ClonedShape() const {
95  if (!shape_) return std::unique_ptr<TH1>();
96  std::unique_ptr<TH1> res(static_cast<TH1 *>(shape_->Clone()));
97  res->SetDirectory(0);
98  return res;
99 }
100 
101 std::unique_ptr<TH1> Observation::ClonedScaledShape() const {
102  if (!shape_) return std::unique_ptr<TH1>();
103  std::unique_ptr<TH1> res(ClonedShape());
104  res->Scale(this->rate());
105  return res;
106 }
107 
109  if (!shape_) {
110  throw std::runtime_error(
111  FNERROR("Observation object does not contain a shape"));
112  }
113  TH1F res;
114  // Need to get the shape as a concrete type (TH1F or TH1D)
115  // A nice way to do this is just to use TH1D::Copy into a fresh TH1F
116  TH1F const* test_f = dynamic_cast<TH1F const*>(this->shape());
117  TH1D const* test_d = dynamic_cast<TH1D const*>(this->shape());
118  if (test_f) {
119  test_f->Copy(res);
120  } else if (test_d) {
121  test_d->Copy(res);
122  } else {
123  throw std::runtime_error(FNERROR("TH1 shape is not a TH1F or a TH1D"));
124  }
125  return res;
126 }
127 
128 std::ostream& Observation::PrintHeader(std::ostream &out) {
129  std::string line =
130  (boost::format("%-6s %-9s %-6s %-8s %-28s %-3i %-21s %-10.5g %-5i")
131  % "mass" % "analysis" % "era" % "channel" % "bin" % "id" % "process" %
132  "rate" % "shape").str();
133  std::string div(line.length(), '-');
134  out << div << std::endl;
135  out << line << std::endl;
136  out << div << std::endl;
137  return out;
138 }
139 
140 std::string Observation::to_string() const {
141  return ::format_obs(*this).str();
142 }
143 
144 std::ostream& operator<< (std::ostream &out, Observation const& val) {
145  out << ::format_obs(val);
146  return out;
147 }
148 }
#define FNERROR(x)
Definition: Logging.h:9
virtual void set_process(std::string const &process)
Definition: Object.h:19
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
virtual std::string const & channel() const
Definition: Object.h:32
void set_rate(double const &rate)
Definition: Observation.h:20
TH1F ShapeAsTH1F() const
Definition: Observation.cc:108
TH1 const * shape() const
Definition: Observation.h:27
std::unique_ptr< TH1 > ClonedScaledShape() const
Definition: Observation.cc:101
static std::ostream & PrintHeader(std::ostream &out)
Definition: Observation.cc:128
Observation & operator=(Observation other)
Definition: Observation.cc:61
void set_shape(std::unique_ptr< TH1 > shape, bool set_rate)
Definition: Observation.cc:66
RooAbsData const * data() const
Definition: Observation.h:35
std::string to_string() const
Definition: Observation.cc:140
std::unique_ptr< TH1 > ClonedShape() const
Definition: Observation.cc:94
friend void swap(Observation &first, Observation &second)
Definition: Observation.cc:33
double rate() const
Definition: Observation.h:21
Definition: Algorithm.h:10
std::ostream & operator<<(std::ostream &out, HistMapping const &val)
Definition: HistMapping.cc:70
void swap(Observation &first, Observation &second)
Definition: Observation.cc:33
void swap(CombineHarvester &first, CombineHarvester &second)