LDMX Software
HistogramPool.cxx
1
2#include "Framework/HistogramPool.h"
3
4//----------------//
5// C++ StdLib //
6//----------------//
7#include <stdexcept>
8
9//----------//
10// ROOT //
11//----------//
12#include "TH1.h"
13#include "TStyle.h"
14
15namespace framework {
16
17TH1* HistogramPool::get(const std::string& name) {
18 auto histo = histograms_.find(name);
19 if (histo == histograms_.end()) {
20 EXCEPTION_RAISE(
21 "InvalidArg",
22 "Histogram " + name +
23 " not found in pool."
24 "\nMake sure to `histograms_.create` in onProcessStart for any "
25 "histogram you want to `histograms_.fill`.");
26 }
27
28 return histograms_[name];
29}
30
31void HistogramPool::insert(const std::string& name,
32 std::function<TH1*()> factory, bool weighted) {
33 if (histograms_.find(name) != histograms_.end()) {
34 EXCEPTION_RAISE(
35 "RepeatName",
36 "Histogram " + name +
37 " already exists in histogram pool."
38 "\nMake sure to use distinct names for your different histograms!"
39 "\nYou can use `histograms_.get` to retrieve a pointer to a "
40 "specific histogram "
41 "if you want to do some other customizations besides filling.");
42 }
43
44 get_directory_()->cd();
45
52 auto hist = factory();
53 if (weighted) hist->Sumw2();
54 histograms_[name] = hist;
55}
56
57std::tuple<std::size_t, double, double> categoryBins(
58 const std::vector<std::string>& categories, int offset = 0) {
59 std::size_t n_categories = categories.size();
60 double min = offset - 0.5;
61 double max = offset + n_categories + 0.5;
62 return std::make_tuple(n_categories, min, max);
63}
64
65void labelAxis(TAxis* axis, const std::vector<std::string>& categories) {
66 for (std::size_t ibin{1}; ibin <= categories.size(); ibin++) {
67 axis->SetBinLabel(ibin, categories[ibin - 1].c_str());
68 }
69}
70
72 auto name{p.get<std::string>("name")};
73 auto x_label{p.get<std::string>("xlabel")};
74 auto y_label{p.get<std::string>("ylabel")};
75 auto weighted{p.get<bool>("weighted")};
76 auto numeric_xbins{p.get<std::vector<double>>("xbins")};
77 auto category_xbins{p.get<std::vector<std::string>>("xcategories", {})};
78 auto numeric_ybins{p.get<std::vector<double>>("ybins", {})};
79 auto category_ybins{p.get<std::vector<std::string>>("ycategories", {})};
80
81 bool one_dim = (numeric_ybins.empty() and category_ybins.empty());
82 bool x_is_category = (not category_xbins.empty());
83 bool y_is_category = (not category_ybins.empty());
84 if (one_dim) {
85 // assume 1D histogram
86 if (x_is_category) {
87 create(name, x_label, category_xbins, weighted);
88 } else {
89 create(name, x_label, numeric_xbins, weighted);
90 }
91 } else {
92 if (x_is_category and y_is_category) {
93 create(name, x_label, category_xbins, y_label, category_ybins, weighted);
94 } else if (x_is_category and not y_is_category) {
95 create(name, x_label, category_xbins, y_label, numeric_ybins, weighted);
96 } else if (not x_is_category and y_is_category) {
97 create(name, x_label, numeric_xbins, y_label, category_ybins, weighted);
98 } else /* not x_is_category and not y_is_category */ {
99 create(name, x_label, numeric_xbins, y_label, numeric_ybins, weighted);
100 }
101 }
102}
103
104void HistogramPool::create(const std::string& name, const std::string& x_label,
105 const std::vector<std::string>& categories,
106 bool weighted) {
107 insert(
108 name,
109 [&]() {
110 auto [nbins, xmin, xmax] = categoryBins(categories);
111 auto hist = new TH1F(name.c_str(), "", nbins, xmin, xmax);
112 hist->GetXaxis()->SetTitle(x_label.c_str());
113 labelAxis(hist->GetXaxis(), categories);
114 return hist;
115 },
116 weighted);
117}
118
119void HistogramPool::create(const std::string& name, const std::string& x_label,
120 const int& bins, const double& xmin,
121 const double& xmax, bool weighted) {
122 insert(
123 name,
124 [&]() {
125 auto hist = new TH1F(name.c_str(), "", bins, xmin, xmax);
126 hist->GetXaxis()->SetTitle(x_label.c_str());
127 return hist;
128 },
129 weighted);
130}
131
132void HistogramPool::create(const std::string& name, const std::string& x_label,
133 const std::vector<double>& bins, bool weighted) {
134 insert(
135 name,
136 [&]() {
137 auto hist = new TH1F(name.c_str(), "", bins.size() - 1, bins.data());
138 hist->GetXaxis()->SetTitle(x_label.c_str());
139 return hist;
140 },
141 weighted);
142}
143
144void HistogramPool::create(const std::string& name, const std::string& x_label,
145 const int& xbins, const double& xmin,
146 const double& xmax, const std::string& y_label,
147 const int& ybins, const double& ymin,
148 const double& ymax, bool weighted) {
149 insert(
150 name,
151 [&]() {
152 auto hist =
153 new TH2F(name.c_str(), "", xbins, xmin, xmax, ybins, ymin, ymax);
154 hist->GetXaxis()->SetTitle(x_label.c_str());
155 hist->GetYaxis()->SetTitle(y_label.c_str());
156 return hist;
157 },
158 weighted);
159}
160
161void HistogramPool::create(const std::string& name, const std::string& x_label,
162 const std::vector<double>& xbins,
163 const std::string& y_label, const int& ybins,
164 const double& ymin, const double& ymax,
165 bool weighted) {
166 insert(
167 name,
168 [&]() {
169 auto hist = new TH2F(name.c_str(), "", xbins.size() - 1, xbins.data(),
170 ybins, ymin, ymax);
171 hist->GetXaxis()->SetTitle(x_label.c_str());
172 hist->GetYaxis()->SetTitle(y_label.c_str());
173 return hist;
174 },
175 weighted);
176}
177
178void HistogramPool::create(const std::string& name, const std::string& x_label,
179 const std::vector<std::string>& xcategories,
180 const std::string& y_label, const int& ybins,
181 const double& ymin, const double& ymax,
182 bool weighted) {
183 insert(
184 name,
185 [&]() {
186 auto [nxbins, xmin, xmax] = categoryBins(xcategories);
187 auto hist =
188 new TH2F(name.c_str(), "", nxbins, xmin, xmax, ybins, ymin, ymax);
189 labelAxis(hist->GetXaxis(), xcategories);
190 hist->GetXaxis()->SetTitle(x_label.c_str());
191 hist->GetYaxis()->SetTitle(y_label.c_str());
192 return hist;
193 },
194 weighted);
195}
196
197void HistogramPool::create(const std::string& name, const std::string& x_label,
198 const int& xbins, const double& xmin,
199 const double& xmax, const std::string& y_label,
200 const std::vector<double>& ybins, bool weighted) {
201 insert(
202 name,
203 [&]() {
204 auto hist = new TH2F(name.c_str(), "", xbins, xmin, xmax,
205 ybins.size() - 1, ybins.data());
206 hist->GetXaxis()->SetTitle(x_label.c_str());
207 hist->GetYaxis()->SetTitle(y_label.c_str());
208 return hist;
209 },
210 weighted);
211}
212
213void HistogramPool::create(const std::string& name, const std::string& x_label,
214 const int& xbins, const double& xmin,
215 const double& xmax, const std::string& y_label,
216 const std::vector<std::string>& ycategories,
217 bool weighted) {
218 insert(
219 name,
220 [&]() {
221 auto [nybins, ymin, ymax] = categoryBins(ycategories);
222 auto hist =
223 new TH2F(name.c_str(), "", xbins, xmin, xmax, nybins, ymin, ymax);
224 labelAxis(hist->GetYaxis(), ycategories);
225 hist->GetXaxis()->SetTitle(x_label.c_str());
226 hist->GetYaxis()->SetTitle(y_label.c_str());
227 return hist;
228 },
229 weighted);
230}
231
232void HistogramPool::create(const std::string& name, const std::string& x_label,
233 const std::vector<double>& xbins,
234 const std::string& y_label,
235 const std::vector<double>& ybins, bool weighted) {
236 insert(
237 name,
238 [&]() {
239 auto hist = new TH2F(name.c_str(), "", xbins.size() - 1, xbins.data(),
240 ybins.size() - 1, ybins.data());
241 hist->GetXaxis()->SetTitle(x_label.c_str());
242 hist->GetYaxis()->SetTitle(y_label.c_str());
243 return hist;
244 },
245 weighted);
246}
247
248void HistogramPool::create(const std::string& name, const std::string& x_label,
249 const std::vector<double>& xbins,
250 const std::string& y_label,
251 const std::vector<std::string>& ycategories,
252 bool weighted) {
253 insert(
254 name,
255 [&]() {
256 auto [nybins, ymin, ymax] = categoryBins(ycategories);
257 auto hist = new TH2F(name.c_str(), "", xbins.size() - 1, xbins.data(),
258 nybins, ymin, ymax);
259 labelAxis(hist->GetYaxis(), ycategories);
260 hist->GetXaxis()->SetTitle(x_label.c_str());
261 hist->GetYaxis()->SetTitle(y_label.c_str());
262 return hist;
263 },
264 weighted);
265}
266
267void HistogramPool::create(const std::string& name, const std::string& x_label,
268 const std::vector<std::string>& xcategories,
269 const std::string& y_label,
270 const std::vector<double>& ybins, bool weighted) {
271 insert(
272 name,
273 [&]() {
274 auto [nxbins, xmin, xmax] = categoryBins(xcategories);
275 auto hist = new TH2F(name.c_str(), "", nxbins, xmin, xmax,
276 ybins.size() - 1, ybins.data());
277 labelAxis(hist->GetXaxis(), xcategories);
278 hist->GetXaxis()->SetTitle(x_label.c_str());
279 hist->GetYaxis()->SetTitle(y_label.c_str());
280 return hist;
281 },
282 weighted);
283}
284
285void HistogramPool::create(const std::string& name, const std::string& x_label,
286 const std::vector<std::string>& xcategories,
287 const std::string& y_label,
288 const std::vector<std::string>& ycategories,
289 bool weighted) {
290 insert(
291 name,
292 [&]() {
293 auto [nybins, ymin, ymax] = categoryBins(ycategories);
294 auto [nxbins, xmin, xmax] = categoryBins(xcategories);
295 auto hist =
296 new TH2F(name.c_str(), "", nxbins, xmin, xmax, nybins, ymin, ymax);
297 labelAxis(hist->GetYaxis(), ycategories);
298 labelAxis(hist->GetXaxis(), xcategories);
299 hist->GetXaxis()->SetTitle(x_label.c_str());
300 hist->GetYaxis()->SetTitle(y_label.c_str());
301 return hist;
302 },
303 weighted);
304}
305
306} // namespace framework
void insert(const std::string &name, std::function< TH1 *()> factory, bool weighted)
insert a histogram into this pool by name
std::function< TDirectory *()> get_directory_
the callback to get the directory these histograms should go in
void create(const config::Parameters &p)
Create a histogram from the input configuration parameters.
TH1 * get(const std::string &name)
get a histogram from this pool by name
std::unordered_map< std::string, TH1 * > histograms_
the pool of histogram pointers
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:29
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:78
All classes in the ldmx-sw project use this namespace.