cepgen
is hosted by
Hepforge
,
IPPP Durham
CepGen
1.2.5
Central exclusive processes event generator
Loading...
Searching...
No Matches
Drawer.cpp
Go to the documentation of this file.
1
/*
2
* CepGen: a central exclusive processes event generator
3
* Copyright (C) 2022-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 <TGraph2DErrors.h>
20
#include <TH2D.h>
21
#include <TMultiGraph.h>
22
23
#include "
CepGen/Modules/DrawerFactory.h
"
24
#include "
CepGen/Utils/Drawer.h
"
25
#include "
CepGen/Utils/Graph.h
"
26
#include "
CepGen/Utils/Histogram.h
"
27
#include "
CepGen/Utils/Message.h
"
28
#include "
CepGen/Utils/String.h
"
29
#include "
CepGenAddOns/ROOTWrapper/ROOTCanvas.h
"
30
31
using namespace
std::string_literals;
32
33
namespace
cepgen
{
34
namespace
root
{
35
class
Drawer
:
public
cepgen::utils::Drawer
{
36
public
:
37
explicit
Drawer
(
const
ParametersList
& params)
38
:
cepgen
::utils::
Drawer
(params),
39
def_filename_(
steer
<std::string>(
"filename"
)),
40
def_extension_(
steer
<std::string>(
"format"
)) {
41
gStyle->SetPalette(steer<int>(
"palette"
));
42
}
43
44
inline
static
ParametersDescription
description
() {
45
auto
desc =
cepgen::utils::Drawer::description
();
46
desc.add(
"filename"
,
"canvas"
s).setDescription(
"default filename for the output"
);
47
desc.add(
"format"
,
"pdf"
s).setDescription(
"default extension for the output"
);
48
desc.add<
int
>(
"palette"
, kLightTemperature).setDescription(
"ROOT colour palette to use"
);
49
return
desc;
50
}
51
52
inline
const
Drawer
&
draw
(
const
utils::Graph1D
& graph,
const
Mode
& mode)
const override
{
53
auto
gr = convert(graph);
54
ROOTCanvas
canv(graph.
name
().empty() ? def_filename_ : graph.
name
(), gr.GetTitle(), mode & Mode::ratio);
55
setMode(canv, mode);
56
gr.Draw(
"al"
);
57
gr.GetHistogram()->SetTitle(delatexify(
";"
+ graph.
xAxis
().
label
() +
";"
+ graph.
yAxis
().
label
()));
58
canv.Prettify(gr.GetHistogram());
59
postDraw(gr.GetHistogram(), graph);
60
canv.Save(def_extension_);
61
return
*
this
;
62
}
63
inline
const
Drawer
&
draw
(
const
utils::Graph2D
& graph,
const
Mode
& mode)
const override
{
64
auto
gr = convert(graph);
65
ROOTCanvas
canv(graph.
name
().empty() ? def_filename_ : graph.
name
(), gr.GetTitle(), mode & Mode::ratio);
66
setMode(canv, mode);
67
if
(mode & Mode::col)
68
gr.Draw(
"colz"
);
69
else
if
(mode & Mode::cont)
70
gr.Draw(
"cont"
);
71
else
72
gr.Draw(
"surf3"
);
73
gr.GetHistogram()->SetTitle(
74
delatexify(
";"
+ graph.
xAxis
().
label
() +
";"
+ graph.
yAxis
().
label
() +
";"
+ graph.
zAxis
().
label
()));
75
canv.Prettify(gr.GetHistogram());
76
postDraw(gr.GetHistogram(), graph);
77
canv.Save(def_extension_);
78
return
*
this
;
79
}
80
inline
const
Drawer
&
draw
(
const
utils::Hist1D
& hist,
const
Mode
& mode)
const override
{
81
auto
h = convert(hist);
82
ROOTCanvas
canv(hist.
name
().empty() ? def_filename_ : hist.
name
(), h.GetTitle(), mode & Mode::ratio);
83
setMode(canv, mode);
84
h.Draw();
85
canv.Prettify(&h);
86
postDraw(&h, hist);
87
canv.Save(def_extension_);
88
return
*
this
;
89
}
90
inline
const
Drawer
&
draw
(
const
utils::Hist2D
& hist,
const
Mode
& mode)
const override
{
91
auto
h = convert(hist);
92
ROOTCanvas
canv(hist.
name
().empty() ? def_filename_ : hist.
name
(), h.GetTitle(), mode & Mode::ratio);
93
setMode(canv, mode);
94
h.Draw(
"colz"
);
95
canv.Prettify(&h);
96
postDraw(&h, hist);
97
canv.Save(def_extension_);
98
return
*
this
;
99
}
100
101
const
Drawer
&
draw
(
const
utils::DrawableColl
&,
102
const
std::string&
name
=
""
,
103
const
std::string& title =
""
,
104
const
Mode& mode = Mode::none)
const override
;
105
106
private
:
107
inline
static
void
setMode(
ROOTCanvas
& canv,
const
Mode& mode) {
108
canv.
SetLegendX1
(0.175);
109
if
(mode & Mode::logx)
110
canv.
SetLogx
();
111
if
(mode & Mode::logy)
112
canv.
SetLogy
();
113
if
(mode & Mode::logz)
114
canv.
SetLogz
();
115
if
(mode & Mode::grid)
116
canv.
SetGrid
();
117
}
118
119
inline
static
void
postDraw(TH1* obj,
const
utils::Drawable
& dr) {
120
const
auto
&xrng = dr.
xAxis
().
range
(), &yrng = dr.
yAxis
().
range
();
121
obj->GetXaxis()->SetTitle(delatexify(dr.
xAxis
().
label
()));
122
obj->GetYaxis()->SetTitle(delatexify(dr.
yAxis
().
label
()));
123
obj->SetLineWidth(std::max((
short
)3, obj->GetLineWidth()));
124
if
(xrng.valid())
125
obj->GetXaxis()->SetLimits(xrng.min(), xrng.max());
126
if
(yrng.valid()) {
127
if
(yrng.hasMin())
128
obj->SetMinimum(yrng.min());
129
if
(yrng.hasMax())
130
obj->SetMaximum(yrng.max());
131
}
132
}
133
inline
static
TString delatexify(
const
std::string& tok) {
134
auto
out =
utils::replaceAll
(tok, {{
"$"
,
""
}, {
"\\"
,
"#"
}});
135
return
TString(out);
136
}
137
static
TGraphErrors convert(
const
utils::Graph1D&);
138
static
TGraph2DErrors convert(
const
utils::Graph2D&);
139
static
TH1D convert(
const
utils::Hist1D&);
140
static
TH2D convert(
const
utils::Hist2D&);
141
142
const
std::string def_filename_;
143
const
std::string def_extension_;
144
};
145
146
const
Drawer
&
Drawer::draw
(
const
utils::DrawableColl
& objs,
147
const
std::string& name,
148
const
std::string& title,
149
const
Mode
& mode)
const
{
150
ROOTCanvas
canv(
name
.empty() ? def_filename_ :
name
, delatexify(title).Data(), mode & Mode::ratio);
151
auto
* mg = canv.
Make
<TMultiGraph>();
152
auto
* hs = canv.
Make
<THStack>();
153
setMode(canv, mode);
154
utils::Drawable
* first =
nullptr
;
155
utils::DrawableColl
plots_2d;
156
for
(
size_t
i = 0; i < objs.size(); ++i) {
157
const
auto
* obj = objs.at(i);
158
auto
colour =
ROOTCanvas::colours
.at(i %
ROOTCanvas::colours
.size());
159
auto
style = i + 1;
160
if
(obj->isHist1D()) {
161
if
(
auto
* hist =
new
TH1D(convert(*
dynamic_cast<
const
utils::Hist1D
*
>
(obj))); hist) {
162
hist->SetLineColor(colour);
163
hist->SetLineStyle(style);
164
hs->Add(hist);
165
canv.
AddLegendEntry
(hist, hist->GetTitle(),
"l"
);
166
}
167
}
else
if
(obj->isGraph1D()) {
168
if
(
auto
* gr =
new
TGraphErrors(convert(*
dynamic_cast<
const
utils::Graph1D
*
>
(obj))); gr) {
169
gr->SetLineColor(colour);
170
gr->SetLineStyle(style);
171
mg->Add(gr);
172
canv.
AddLegendEntry
(gr, gr->GetTitle(),
"l"
);
173
}
174
}
else
{
175
plots_2d.emplace_back(obj);
176
CG_DEBUG
(
"root:Drawer:draw"
) <<
"Adding a 2-dimensional drawable '"
<< obj->name() <<
"' to the stack."
;
177
continue
;
178
}
179
if
(!first)
180
first =
const_cast<
utils::Drawable
*
>
(obj);
181
}
182
const
bool
has_hists = hs->GetHists() && !hs->GetHists()->IsEmpty();
183
const
bool
has_graphs = mg->GetListOfGraphs() && !mg->GetListOfGraphs()->IsEmpty();
184
if
(has_hists || has_graphs) {
185
if
(has_hists)
186
hs->Draw(((mode & Mode::bar ?
"hist"
s :
""
s) + (mode & Mode::nostack ?
"nostack"
s :
""
s)).data());
187
if
(has_graphs)
188
mg->Draw((
"l"
s + (!has_hists ?
"a"
:
""
)).c_str());
189
if
(has_hists) {
190
postDraw(hs->GetHistogram(), *first);
191
canv.
Prettify
(hs);
192
}
else
if
(has_graphs) {
193
postDraw(mg->GetHistogram(), *first);
194
canv.
Prettify
(mg);
195
}
196
canv.
Save
(def_extension_);
197
}
198
for
(
size_t
i = 0; i < plots_2d.size(); ++i) {
199
const
auto
* obj = plots_2d.at(i);
200
const
std::string postfix = i == 0 ?
"("
: i == plots_2d.size() - 1 ?
")"
:
""
;
201
if
(obj->isHist2D()) {
202
if
(
const
auto
* hist =
dynamic_cast<
const
utils::Hist2D
*
>
(obj); hist) {
203
auto
* h =
new
TH2D(convert(*hist));
204
setMode(canv, mode);
205
h->Draw(
"colz"
);
206
canv.
Prettify
(h);
207
postDraw(h, *hist);
208
}
209
}
else
if
(obj->isGraph2D()) {
210
if
(
const
auto
* graph =
dynamic_cast<
const
utils::Graph2D
*
>
(obj); graph) {
211
auto
* gr =
new
TGraph2D(convert(*graph));
212
setMode(canv, mode);
213
if
(mode & Mode::col)
214
gr->Draw(
"colz"
);
215
else
if
(mode & Mode::cont)
216
gr->Draw(
"cont"
);
217
else
218
gr->Draw(
"surf3"
);
219
gr->GetHistogram()->SetTitle(
220
delatexify(
";"
+ graph->xAxis().label() +
";"
+ graph->yAxis().label() +
";"
+ graph->zAxis().label()));
221
canv.
Prettify
(gr->GetHistogram());
222
postDraw(gr->GetHistogram(), *graph);
223
}
224
}
225
canv.Print(
utils::format
(
"%s_multi.%s%s"
, canv.GetName(), def_extension_.data(), postfix.data()).data());
226
}
227
return
*
this
;
228
}
229
230
TGraphErrors Drawer::convert(
const
utils::Graph1D
& graph) {
231
TGraphErrors gr;
232
gr.SetTitle(delatexify(graph.
title
()));
233
int
i = 0;
234
for
(
const
auto
& it : graph.points()) {
235
const
auto
& val = it.second;
236
gr.SetPoint(i, it.first.value, val);
237
gr.SetPointError(i, it.first.value_unc, val.uncertainty());
238
++i;
239
}
240
gr.SetLineWidth(3);
241
return
gr;
242
}
243
244
TGraph2DErrors Drawer::convert(
const
utils::Graph2D& graph) {
245
TGraph2DErrors gr;
246
gr.SetTitle(delatexify(graph.title()));
247
int
i = 0;
248
for
(
const
auto
& it_x : graph.points()) {
249
const
auto
& ax_x = it_x.first.value;
250
for
(
const
auto
& it_y : it_x.second) {
251
const
auto
& ax_y = it_y.first.value;
252
const
auto
& val = it_y.second;
253
gr.SetPoint(i, ax_x, ax_y, val);
254
gr.SetPointError(i, 0., 0., val.uncertainty());
255
++i;
256
}
257
}
258
return
gr;
259
}
260
261
TH1D Drawer::convert(
const
utils::Hist1D& hist) {
262
const
auto
bins = hist.bins(
utils::Histogram::BinMode::both
);
263
TH1D h(hist.name().c_str(), delatexify(hist.title()), bins.size() - 1, bins.data());
264
h.SetBinContent(0, hist.underflow());
265
for
(
size_t
i = 0; i < hist.nbins(); ++i) {
266
const
auto
val = hist.value(i);
267
h.SetBinContent(i + 1, val);
268
h.SetBinError(i + 1, val.uncertainty());
269
}
270
h.SetBinContent(hist.nbins() + 1, hist.overflow());
271
h.GetXaxis()->SetTitle(delatexify(hist.xAxis().label()));
272
h.GetYaxis()->SetTitle(delatexify(hist.yAxis().label()));
273
h.SetLineWidth(3);
274
return
h;
275
}
276
277
TH2D Drawer::convert(
const
utils::Hist2D& hist) {
278
const
auto
bins_x = hist.binsX(
utils::Histogram::BinMode::both
),
279
bins_y = hist.binsY(
utils::Histogram::BinMode::both
);
280
TH2D h(hist.name().c_str(),
281
delatexify(hist.title()),
282
bins_x.size() - 1,
283
bins_x.data(),
284
bins_y.size() - 1,
285
bins_y.data());
286
for
(
size_t
ix = 0; ix < hist.nbinsX(); ++ix)
287
for
(
size_t
iy = 0; iy < hist.nbinsY(); ++iy) {
288
const
auto
val = hist.value(ix, iy);
289
h.SetBinContent(ix + 1, iy + 1, val);
290
h.SetBinError(ix + 1, iy + 1, val.uncertainty());
291
}
292
h.SetBinContent(0, 0, hist.outOfRange().at(
utils::Hist2D::contents_t::LT_LT
));
293
h.SetBinContent(0, 1, hist.outOfRange().at(
utils::Hist2D::contents_t::LT_IN
));
294
h.SetBinContent(0, hist.nbinsY() + 1, hist.outOfRange().at(
utils::Hist2D::contents_t::LT_GT
));
295
h.SetBinContent(1, 0, hist.outOfRange().at(
utils::Hist2D::contents_t::IN_LT
));
296
h.SetBinContent(1, hist.nbinsY() + 1, hist.outOfRange().at(
utils::Hist2D::contents_t::IN_GT
));
297
h.SetBinContent(hist.nbinsX() + 1, 0, hist.outOfRange().at(
utils::Hist2D::contents_t::GT_LT
));
298
h.SetBinContent(hist.nbinsX() + 1, 1, hist.outOfRange().at(
utils::Hist2D::contents_t::GT_IN
));
299
h.SetBinContent(hist.nbinsX() + 1, hist.nbinsY() + 1, hist.outOfRange().at(
utils::Hist2D::contents_t::GT_GT
));
300
h.GetXaxis()->SetTitle(delatexify(hist.xAxis().label()));
301
h.GetYaxis()->SetTitle(delatexify(hist.yAxis().label()));
302
h.GetZaxis()->SetTitle(delatexify(hist.zAxis().label()));
303
return
h;
304
}
305
}
// namespace root
306
}
// namespace cepgen
307
using
cepgen::root::Drawer
;
308
REGISTER_DRAWER
(
"root"
,
Drawer
);
DrawerFactory.h
REGISTER_DRAWER
#define REGISTER_DRAWER(name, obj)
Add a drawing utilitary.
Definition
DrawerFactory.h:25
Drawer.h
Graph.h
Histogram.h
Message.h
CG_DEBUG
#define CG_DEBUG(mod)
Definition
Message.h:220
ROOTCanvas.h
String.h
cepgen::NamedModule< Drawer >::name
const std::string & name() const
Module unique indexing name.
Definition
NamedModule.h:42
cepgen::ParametersDescription
A description object for parameters collection.
Definition
ParametersDescription.h:26
cepgen::ParametersList
Definition
ParametersList.h:52
cepgen::ROOTCanvas
A "prettified" generic figure canvas.
Definition
ROOTCanvas.h:89
cepgen::ROOTCanvas::SetLegendX1
void SetLegendX1(double x)
Set the horizontal coordinate of the low-left part of the legend object.
Definition
ROOTCanvas.h:407
cepgen::ROOTCanvas::SetLogz
void SetLogz(int log=1)
Definition
ROOTCanvas.h:396
cepgen::ROOTCanvas::Make
T * Make(Args &&... args)
Garbage collector-like TObjects producer.
Definition
ROOTCanvas.h:487
cepgen::ROOTCanvas::Save
void Save(const std::string &ext, const std::string &out_dir=".")
Save the canvas in an external file.
Definition
ROOTCanvas.h:434
cepgen::ROOTCanvas::colours
static const std::vector< int > colours
Definition
ROOTCanvas.h:91
cepgen::ROOTCanvas::SetGrid
void SetGrid(int x=1, int y=1)
Definition
ROOTCanvas.h:377
cepgen::ROOTCanvas::AddLegendEntry
void AddLegendEntry(const TObject *obj, const std::string &title, Option_t *option="lpf")
Add one new entry to the legend object.
Definition
ROOTCanvas.h:420
cepgen::ROOTCanvas::Prettify
void Prettify(TH1 *obj)
Draw main plot attributes in a pretty manner.
Definition
ROOTCanvas.h:109
cepgen::ROOTCanvas::SetLogx
void SetLogx(int log=1)
Definition
ROOTCanvas.h:383
cepgen::ROOTCanvas::SetLogy
void SetLogy(int log=1)
Definition
ROOTCanvas.h:390
cepgen::Steerable::description
static ParametersDescription description()
Description of all object parameters.
Definition
Steerable.cpp:42
cepgen::Steerable::steer
T steer(const std::string &key) const
Retrieve a parameters as previously steered.
Definition
Steerable.h:39
cepgen::root::Drawer
Definition
Drawer.cpp:35
cepgen::root::Drawer::draw
const Drawer & draw(const utils::Hist2D &hist, const Mode &mode) const override
Draw a two-dimensional histogram.
Definition
Drawer.cpp:90
cepgen::root::Drawer::draw
const Drawer & draw(const utils::Graph2D &graph, const Mode &mode) const override
Draw a two-dimensional graph.
Definition
Drawer.cpp:63
cepgen::root::Drawer::Drawer
Drawer(const ParametersList ¶ms)
Definition
Drawer.cpp:37
cepgen::root::Drawer::description
static ParametersDescription description()
Definition
Drawer.cpp:44
cepgen::root::Drawer::draw
const Drawer & draw(const utils::Hist1D &hist, const Mode &mode) const override
Draw a one-dimensional histogram.
Definition
Drawer.cpp:80
cepgen::root::Drawer::draw
const Drawer & draw(const utils::Graph1D &graph, const Mode &mode) const override
Draw a one-dimensional graph.
Definition
Drawer.cpp:52
cepgen::utils::Drawable::AxisInfo::label
const std::string & label() const
Axis title.
Definition
Drawable.h:55
cepgen::utils::Drawable::AxisInfo::range
const Limits & range() const
Axis range.
Definition
Drawable.h:72
cepgen::utils::Drawable
A generic object which can be drawn in the standard output.
Definition
Drawable.h:31
cepgen::utils::Drawable::name
const std::string & name() const
Drawable name.
Definition
Drawable.h:37
cepgen::utils::Drawable::yAxis
AxisInfo & yAxis()
Definition
Drawable.h:81
cepgen::utils::Drawable::zAxis
AxisInfo & zAxis()
Definition
Drawable.h:83
cepgen::utils::Drawable::title
const std::string & title() const
Drawable name.
Definition
Drawable.h:42
cepgen::utils::Drawable::xAxis
AxisInfo & xAxis()
Definition
Drawable.h:79
cepgen::utils::Drawer::Mode
Definition
Drawer.h:41
cepgen::utils::Drawer
A generic drawing utility.
Definition
Drawer.h:36
cepgen::utils::Graph1D
A one-dimensional graph object.
Definition
Graph.h:29
cepgen::utils::Graph2D
A two-dimensional graph object.
Definition
Graph.h:58
cepgen::utils::Hist1D
1D histogram container
Definition
Histogram.h:72
cepgen::utils::Hist2D
2D histogram container
Definition
Histogram.h:146
cepgen::utils::Histogram::both
@ both
Definition
Histogram.h:46
cepgen::utils::format
std::string format(const std::string &fmt, Args... args)
Format a string using a printf style format descriptor.
Definition
String.h:61
cepgen::utils::DrawableColl
std::vector< const Drawable * > DrawableColl
A collection of drawable objects.
Definition
Drawer.h:34
cepgen::utils::replaceAll
size_t replaceAll(std::string &str, const std::string &from, const std::string &to)
Replace all occurrences of a text by another.
Definition
String.cpp:118
cepgen
Common namespace for this Monte Carlo generator.
Definition
CommandLineHandler.cpp:36
python_modules.Integrators.root_cfi.root
root
Definition
root_cfi.py:3
cepgen::utils::Hist2D::contents_t::LT_LT
@ LT_LT
Definition
Histogram.h:223
cepgen::utils::Hist2D::contents_t::IN_GT
@ IN_GT
Definition
Histogram.h:219
cepgen::utils::Hist2D::contents_t::IN_LT
@ IN_LT
Definition
Histogram.h:224
cepgen::utils::Hist2D::contents_t::LT_IN
@ LT_IN
Definition
Histogram.h:221
cepgen::utils::Hist2D::contents_t::LT_GT
@ LT_GT
Definition
Histogram.h:218
cepgen::utils::Hist2D::contents_t::GT_LT
@ GT_LT
Definition
Histogram.h:225
cepgen::utils::Hist2D::contents_t::GT_GT
@ GT_GT
Definition
Histogram.h:220
cepgen::utils::Hist2D::contents_t::GT_IN
@ GT_IN
Definition
Histogram.h:222
CepGenAddOns
ROOTWrapper
Drawer.cpp
Generated on Mon Jul 29 2024 for CepGen by
1.9.7