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