cepgen is hosted by Hepforge, IPPP Durham
CepGen 1.2.5
Central exclusive processes event generator
Loading...
Searching...
No Matches
ROOTHistsHandler.cpp
Go to the documentation of this file.
1/*
2 * CepGen: a central exclusive processes event generator
3 * Copyright (C) 2019-2024 Laurent Forthomme
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <TFile.h>
20#include <TH1.h>
21#include <TH2.h>
22#include <TH3.h>
23#include <TProfile.h>
24#include <TProfile2D.h>
25
27#include "CepGen/Event/Event.h"
31#include "CepGen/Utils/Limits.h"
32#include "CepGen/Utils/String.h"
33#include "CepGen/Utils/Value.h"
34
35namespace cepgen {
39 class ROOTHistsHandler final : public EventExporter {
40 public:
41 explicit ROOTHistsHandler(const ParametersList&);
43
45 auto desc = EventExporter::description();
46 desc.setDescription("ROOT histograming/profiling module");
47 desc.add<std::string>("filename", "output.root").setDescription("Output filename");
48 auto var_desc = ParametersDescription();
49 var_desc.add<std::string>("title", "").setDescription("Variable description");
50 var_desc.add<int>("nbins", -1);
51 var_desc.add<int>("nbinsX", 10).setDescription("Bins multiplicity for x-axis");
52 var_desc.add<Limits>("xrange", Limits{0., 1.}).setDescription("Minimum-maximum range for x-axis");
53 var_desc.add<int>("nbinsY", 10).setDescription("Bins multiplicity for y-axis");
54 var_desc.add<Limits>("yrange", Limits{0., 1.}).setDescription("Minimum-maximum range for y-axis");
55 var_desc.add<int>("nbinsZ", 10).setDescription("Bins multiplicity for z-axis");
56 var_desc.add<Limits>("zrange", Limits{0., 1.}).setDescription("Minimum-maximum range for z-axis");
57 var_desc.add<bool>("profile", false);
58 desc.addParametersDescriptionVector("variables", var_desc);
59 return desc;
60 }
61
62 void setCrossSection(const Value& cross_section) override { cross_section_ = cross_section; }
63 bool operator<<(const Event&) override;
64
65 private:
66 void initialise() override {}
67
68 const std::unique_ptr<TFile> file_;
69 std::vector<std::pair<std::string, TH1*> > hists1d_;
70 std::vector<std::pair<std::vector<std::string>, TH2*> > hists2d_;
71 std::vector<std::pair<std::vector<std::string>, TH3*> > hists3d_;
72 std::vector<std::pair<std::vector<std::string>, TProfile*> > profiles1d_;
73 std::vector<std::pair<std::vector<std::string>, TProfile2D*> > profiles2d_;
74
75 const ParametersList variables_;
76
77 Value cross_section_{1., 0.};
78 const utils::EventBrowser browser_;
79 };
80
82 : EventExporter(params),
83 file_(TFile::Open(steer<std::string>("filename").c_str(), "recreate")),
84 variables_(steer<ParametersList>("variables")) {
85 //--- extract list of variables/correlations to be plotted in histograms
86 for (const auto& key : variables_.keys()) {
87 const auto& vars = utils::split(key, ':');
88 if (vars.size() < 1 || vars.size() > 3)
89 throw CG_FATAL("ROOTHistsHandler") << "Invalid number of variables to correlate for '" << key << "'!";
90
91 const auto& hvars = variables_.get<ParametersList>(key);
92 int nbins_x = hvars.get<int>("nbinsX");
93 if (hvars.get<int>("nbins") > 0)
94 nbins_x = hvars.get<int>("nbins");
95 const auto& xrange = hvars.get<Limits>("xrange");
96 const bool profile = hvars.get<bool>("profile");
97 if (vars.size() == 1) { // 1D histogram
98 auto title = hvars.get<std::string>("title");
99 if (title.empty())
100 title = utils::format("%s;%s;d#sigma/d(%s) (pb/bin)", key.c_str(), key.c_str(), key.c_str());
101 hists1d_.emplace_back(
102 std::make_pair(key, new TH1D(key.c_str(), title.c_str(), nbins_x, xrange.min(), xrange.max())));
103 CG_INFO("ROOTHistsHandler") << "Booking a 1D histogram with " << utils::s("bin", nbins_x) << " in range "
104 << xrange << " for \"" << key << "\".";
105 continue;
106 }
107 const int nbins_y = hvars.get<int>("nbinsY");
108 const auto& yrange = hvars.get<Limits>("yrange");
109 if (vars.size() == 2) { // 2D histogram / 1D profile
110 auto title = hvars.get<std::string>("title");
111 if (title.empty())
112 title = utils::format("(%s / %s) correlation;%s;%s;d^{2}#sigma/d(%s)/d(%s) (pb/bin)",
113 vars[0].c_str(),
114 vars[1].c_str(),
115 vars[0].c_str(),
116 vars[1].c_str(),
117 vars[0].c_str(),
118 vars[1].c_str());
119 if (profile) {
120 profiles1d_.emplace_back(
121 std::make_pair(vars, new TProfile(key.c_str(), title.c_str(), nbins_x, xrange.min(), xrange.max())));
122 CG_INFO("ROOTHistsHandler") << "Booking a 1D profile with " << utils::s("bin", nbins_x, true) << " in range "
123 << xrange << " for \"" << utils::merge(vars, " / ") << "\".";
124 } else {
125 hists2d_.emplace_back(std::make_pair(
126 vars,
127 new TH2D(
128 key.c_str(), title.c_str(), nbins_x, xrange.min(), xrange.max(), nbins_y, yrange.min(), yrange.max())));
129 CG_INFO("ROOTHistsHandler") << "Booking a 2D correlation plot with "
130 << utils::s("bin", nbins_x + nbins_y, true) << " in range x=" << xrange
131 << " and y=" << yrange << " for \"" << utils::merge(vars, " / ") << "\".";
132 }
133 continue;
134 }
135 const int nbins_z = hvars.get<int>("nbinsZ");
136 const auto& zrange = hvars.get<Limits>("zrange");
137 if (vars.size() == 3) { // 3D histogram
138 auto title = hvars.get<std::string>("title");
139 if (title.empty())
140 title = utils::format("(%s / %s / %s) correlation;%s;%s;%s;d^{3}#sigma/d(%s)/d(%s)/d(%s) (pb/bin)",
141 vars[0].c_str(),
142 vars[1].c_str(),
143 vars[2].c_str(),
144 vars[0].c_str(),
145 vars[1].c_str(),
146 vars[2].c_str(),
147 vars[0].c_str(),
148 vars[1].c_str(),
149 vars[2].c_str());
150 if (profile) {
151 profiles2d_.emplace_back(std::make_pair(
152 vars,
153 new TProfile2D(
154 key.c_str(), title.c_str(), nbins_x, xrange.min(), xrange.max(), nbins_y, yrange.min(), yrange.max())));
155 CG_INFO("ROOTHistsHandler") << "Booking a 2D profile with " << utils::s("bin", nbins_x + nbins_y, true)
156 << " in range x=" << xrange << " and y=" << yrange << " for \""
157 << utils::merge(vars, " / ") << "\".";
158 } else {
159 hists3d_.emplace_back(std::make_pair(vars,
160 new TH3D(key.c_str(),
161 title.c_str(),
162 nbins_x,
163 xrange.min(),
164 xrange.max(),
165 nbins_y,
166 yrange.min(),
167 yrange.max(),
168 nbins_z,
169 zrange.min(),
170 zrange.max())));
171 CG_INFO("ROOTHistsHandler") << "Booking a 3D correlation plot with "
172 << utils::s("bin", nbins_x + nbins_y + nbins_z, true) << " in range x=" << xrange
173 << ", y=" << yrange << ", and z=" << zrange << " for \""
174 << utils::merge(vars, " / ") << "\".";
175 }
176 continue;
177 }
178 }
179 }
180
182 // finalisation of the output file
183 for (const auto& hist : hists1d_)
184 hist.second->Write(hist.first.c_str());
185 for (const auto& hist : hists2d_)
186 hist.second->Write(utils::merge(hist.first, "_vs_").c_str());
187 for (const auto& hist : hists3d_)
188 hist.second->Write(utils::merge(hist.first, "_vs_").c_str());
189 for (const auto& hist : profiles1d_)
190 hist.second->Write(utils::merge(hist.first, "_vs_").c_str());
191 for (const auto& hist : profiles2d_)
192 hist.second->Write(utils::merge(hist.first, "_vs_").c_str());
193 file_->Close(); // ROOT and its sumptuous memory management disallows the "delete" here
194 }
195
197 // increment the corresponding histograms
198 for (const auto& h_var : hists1d_)
199 h_var.second->Fill(browser_.get(ev, h_var.first), cross_section_);
200 for (const auto& h_var : hists2d_)
201 h_var.second->Fill(browser_.get(ev, h_var.first[0]), browser_.get(ev, h_var.first[1]), cross_section_);
202 for (const auto& h_var : hists3d_)
203 h_var.second->Fill(browser_.get(ev, h_var.first[0]),
204 browser_.get(ev, h_var.first[1]),
205 browser_.get(ev, h_var.first[2]),
206 cross_section_);
207 for (const auto& h_var : profiles1d_)
208 h_var.second->Fill(browser_.get(ev, h_var.first[0]), browser_.get(ev, h_var.first[1]), cross_section_);
209 for (const auto& h_var : profiles2d_)
210 h_var.second->Fill(browser_.get(ev, h_var.first[0]),
211 browser_.get(ev, h_var.first[1]),
212 browser_.get(ev, h_var.first[2]),
213 cross_section_);
214 return true;
215 }
216} // namespace cepgen
217REGISTER_EXPORTER("root_hist", ROOTHistsHandler);
#define REGISTER_EXPORTER(name, obj)
Add a generic export module definition to the factory.
#define CG_FATAL(mod)
Definition Exception.h:61
#define CG_INFO(mod)
Definition Message.h:216
Output format handler for events export.
Container for the information on the in- and outgoing particles' kinematics.
Definition Event.h:28
Validity interval for a variable.
Definition Limits.h:28
A description object for parameters collection.
std::vector< std::string > keys(bool name_key=true) const
T get(const std::string &key, const T &def=default_arg< T >::get()) const
Get a parameter value.
Handler for the generic ROOT file output.
bool operator<<(const Event &) override
Writer operator.
ROOTHistsHandler(const ParametersList &)
static ParametersDescription description()
void setCrossSection(const Value &cross_section) override
Specify the cross section value, in pb.
static ParametersDescription description()
Description of all object parameters.
Definition Steerable.cpp:42
A scalar value with its uncertainty.
Definition Value.h:26
double get(const Event &ev, const std::string &var) const
Get/compute a variable value.
std::string format(const std::string &fmt, Args... args)
Format a string using a printf style format descriptor.
Definition String.h:61
std::string s(const std::string &word, float num, bool show_number)
Add a trailing "s" when needed.
Definition String.cpp:228
std::string merge(const std::vector< T > &vec, const std::string &delim)
Merge a collection of a printable type in a single string.
Definition String.cpp:248
std::vector< std::string > split(const std::string &str, char delim, bool trim)
Split a string according to a separation character.
Definition String.cpp:233
Common namespace for this Monte Carlo generator.