cepgen
is hosted by
Hepforge
,
IPPP Durham
CepGen
N/A
Central exclusive processes event generator
Toggle main menu visibility
Main Page
Related Pages
Packages
Package List
Package Members
All
a
b
c
d
e
f
g
h
i
k
l
m
n
o
p
q
r
s
t
u
x
y
Functions
a
b
c
d
e
f
g
h
i
k
l
m
n
o
p
q
r
s
t
u
x
y
Variables
Typedefs
Enumerations
Classes
Class List
Class Index
Class Hierarchy
Class Members
All
a
b
c
d
e
f
g
h
i
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
~
Functions
a
b
c
d
e
f
g
h
i
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
~
Variables
a
b
c
d
e
f
g
h
i
k
l
m
n
p
q
r
s
t
u
v
w
x
y
z
Typedefs
Enumerations
Enumerator
b
c
d
e
g
h
i
l
m
n
p
r
t
u
w
x
y
z
Related Symbols
d
g
h
o
u
v
Files
File List
File Members
All
_
a
b
c
d
e
h
o
p
r
s
Functions
Variables
Macros
_
b
c
d
e
p
r
s
▼
CepGen
Reference manual
Bibliography
►
Packages
►
Classes
▼
Files
▼
File List
▼
include
►
CepGen
►
CepGenBoost
►
CepGenHepMC2
►
CepGenHepMC3
►
CepGenHerwig6
►
CepGenMadGraph
►
CepGenPythia6
►
CepGenPythia8
►
CepGenPython
▼
CepGenRoot
►
ROOTCanvas.h
►
ROOTTreeInfo.h
►
File Members
•
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Pages
Loading...
Searching...
No Matches
ROOTCanvas.h
Go to the documentation of this file.
1
/*
2
* CepGen: a central exclusive processes event generator
3
* Copyright (C) 2013-2025 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
#ifndef CepGenRoot_ROOTCanvas_h
20
#define CepGenRoot_ROOTCanvas_h
21
22
#include <TCanvas.h>
23
#include <TGraphErrors.h>
24
#include <TH1.h>
25
#include <THStack.h>
26
#include <TLegend.h>
27
#include <TLine.h>
28
#include <TMath.h>
29
#include <TMultiGraph.h>
30
#include <TObjArray.h>
31
#include <TObjString.h>
32
#include <TPaveText.h>
33
#include <TStyle.h>
34
35
#include <cstring>
36
#include <vector>
37
38
#include "
CepGen/Utils/String.h
"
39
#include "
CepGen/Version.h
"
40
41
namespace
cepgen
{
43
class
ROOTPaveText
final :
public
TPaveText {
44
public
:
45
inline
explicit
ROOTPaveText
(
double
x1,
double
y1,
double
x2,
double
y2,
const
std::string& text =
""
)
46
: TPaveText(x1, y1, x2, y2,
"NB NDC"
) {
47
TPaveText::SetTextAlign(kHAlignLeft + kVAlignTop);
48
if
(!text.empty()) {
49
TString txt = text;
50
if
(txt.Contains(
"\\"
)) {
51
TObjArray* tok = txt.Tokenize(
"\\"
);
52
for
(
int
i = 0; i < tok->GetEntries(); ++i)
53
if
(
auto
* str =
dynamic_cast<
TObjString*
>
(tok->At(i)); str)
54
TPaveText::AddText(str->String());
55
}
else
56
TPaveText::AddText(txt);
57
}
58
TPaveText::SetFillColor(0);
59
TPaveText::SetFillStyle(0);
60
TPaveText::SetLineColor(0);
61
TPaveText::SetLineWidth(0);
62
TPaveText::SetShadowColor(0);
63
TPaveText::SetTextFont(
fontType
(2));
64
TPaveText::SetTextSize(0.058);
65
}
45
inline
explicit
ROOTPaveText
(
double
x1,
double
y1,
double
x2,
double
y2,
const
std::string& text =
""
) {
…
}
66
68
inline
static
int
fontType
(
int
mode) {
return
130 + mode; }
69
};
43
class
ROOTPaveText
final :
public
TPaveText {
…
};
70
71
template
<
typename
T>
72
T*
AddUnderOverflowBins
(
const
T* hist) {
73
std::vector<double> bins;
74
if
(hist->GetXaxis()->IsVariableBinSize()) {
75
const
auto
* arr_bins = hist->GetXaxis()->GetXbins();
76
bins = std::vector<double>(arr_bins->GetArray(), arr_bins->GetArray() + hist->GetNbinsX());
77
}
else
78
for
(
int
i = 0; i <= hist->GetNbinsX(); ++i)
79
bins.emplace_back(hist->GetXaxis()->GetBinUpEdge(i));
80
bins.insert(bins.begin(), bins.at(0) - (bins.at(1) - bins.at(0)));
81
bins.insert(bins.end(), bins.at(bins.size() - 1) + (bins.at(bins.size() - 1) - bins.at(bins.size() - 2)));
82
auto
* hist_new =
new
T(TString(hist->GetName()) +
"_uo"
, hist->GetTitle(), bins.size() - 1, bins.data());
83
for
(
int
i = 0; i <= hist->GetNbinsX() + 1; ++i)
84
hist_new->SetBinContent(i + 1, hist->GetBinContent(i));
85
return
hist_new;
86
}
72
T*
AddUnderOverflowBins
(
const
T* hist) {
…
}
87
89
class
ROOTCanvas
:
public
TCanvas {
90
public
:
91
static
const
std::vector<int>
colours
;
92
97
explicit
ROOTCanvas
(
const
std::string& name,
const
std::string& title =
""
,
bool
ratio =
false
)
98
: TCanvas(name.c_str(),
""
, 600, 600), ratio_(ratio) {
99
gStyle->SetOptStat(0);
100
gStyle->SetGridColor(17);
101
gStyle->SetEndErrorSize(0);
102
SetTopLabel
(title);
103
Build();
104
}
97
explicit
ROOTCanvas
(
const
std::string& name,
const
std::string& title =
""
,
bool
ratio =
false
) {
…
}
105
107
inline
void
SetSize
(
double
size = 600) { TCanvas::SetCanvasSize(size, 600); }
108
110
inline
void
Prettify
(TH1* obj)
const
{
111
if
(
auto
* x = obj->GetXaxis(); x) {
112
x->CenterTitle();
113
x->SetLabelFont(
ROOTPaveText::fontType
(3));
114
x->SetLabelSize(20);
115
x->SetTitleFont(
ROOTPaveText::fontType
(3));
116
x->SetTitleSize(29);
117
if
(ratio_) {
118
x->SetTitleOffset(2.5);
119
x->SetLabelOffset(0.02);
120
}
121
x->SetTickLength(0.03);
122
}
123
if
(
auto
* y = obj->GetYaxis(); y) {
124
y->CenterTitle();
125
y->SetLabelFont(
ROOTPaveText::fontType
(3));
126
y->SetLabelSize(20);
127
y->SetTitleFont(
ROOTPaveText::fontType
(3));
128
y->SetTitleSize(29);
129
y->SetTitleOffset(1.3);
130
y->SetTickLength(0.03);
131
}
132
if
(
auto
* z = obj->GetZaxis(); z) {
133
z->CenterTitle();
134
z->SetLabelFont(
ROOTPaveText::fontType
(3));
135
z->SetLabelSize(16);
136
z->SetTitleFont(
ROOTPaveText::fontType
(3));
137
z->SetTitleSize(29);
138
}
139
140
// axis titles
141
if
(TString axis_title = obj->GetTitle(); axis_title.Contains(
"\\"
)) {
142
TObjArray* tok = axis_title.Tokenize(
"\\"
);
143
TString x_title =
""
, y_title =
""
, unit =
""
, form_spec =
""
, distrib =
""
;
144
if
(tok->GetEntries() > 0)
145
x_title =
dynamic_cast<
TObjString*
>
(tok->At(0))->String();
146
if
(tok->GetEntries() > 1)
147
y_title =
dynamic_cast<
TObjString*
>
(tok->At(1))->String();
148
if
(tok->GetEntries() > 2) {
149
unit =
dynamic_cast<
TObjString*
>
(tok->At(2))->String();
150
if
(unit.Contains(
"?"
)) {
// extract format specifier
151
if
(
const
TObjArray* tok2 = unit.Tokenize(
"?"
); tok2->GetEntries() > 1) {
152
unit =
dynamic_cast<
TObjString*
>
(tok2->At(0))->String();
153
form_spec =
dynamic_cast<
TObjString*
>
(tok2->At(1))->String();
154
}
else
{
155
unit =
""
;
156
form_spec =
dynamic_cast<
TObjString*
>
(tok2->At(0))->String();
157
}
158
}
159
}
160
if
(tok->GetEntries() > 3)
161
distrib =
dynamic_cast<
TObjString*
>
(tok->At(3))->String();
162
if
(!unit.IsNull() or !form_spec.IsNull()) {
163
if
(!unit.IsNull())
164
x_title = Form(
"%s (%s)"
, x_title.Data(), unit.Data());
165
if
(!distrib.IsNull()) {
166
if
(!form_spec.IsNull()) {
167
TString format = Form(
"%%s (%s / %%%s %%s)"
, distrib.Data(), form_spec.Data());
168
y_title = Form(format.Data(), y_title.Data(), GetBinning(obj), unit.Data());
169
}
else
170
y_title = Form(
"%s (%s / %u %s)"
,
171
y_title.Data(),
172
distrib.Data(),
173
static_cast<
unsigned
int
>
(GetBinning(obj)),
174
unit.Data());
175
}
else
{
176
if
(!form_spec.IsNull()) {
177
TString format = Form(
"%%s / %%%s %%s"
, form_spec.Data());
178
y_title = Form(format.Data(), y_title.Data(), GetBinning(obj), unit.Data());
179
}
else
180
y_title = Form(
"%s / %u %s"
, y_title.Data(),
static_cast<
unsigned
int
>
(GetBinning(obj)), unit.Data());
181
}
182
}
183
if
(
auto
* x = obj->GetXaxis(); x)
184
x->SetTitle(x_title);
185
if
(
auto
* y = obj->GetYaxis(); y)
186
y->SetTitle(y_title);
187
obj->SetTitle(
""
);
188
}
189
//else obj->GetXaxis()->SetTitle(axis_title);
190
}
110
inline
void
Prettify
(TH1* obj)
const
{
…
}
191
192
inline
void
Prettify
(
const
THStack* stack) {
193
Prettify
(stack->GetHistogram());
194
if
(!ratio_)
195
return
;
196
if
(
const
auto
* histograms_array = stack->GetHists(); histograms_array->GetEntries() >= 2) {
197
TH1* denominator =
nullptr
;
198
std::vector<TH1*> numerators{};
199
for
(
int
i = 0; i < histograms_array->GetEntries(); ++i)
200
if
(i == 0) {
// reference is conventionally the first histogram
201
if
(denominator =
dynamic_cast<
TH1*
>
(histograms_array->At(i)->Clone()); denominator)
202
denominator->GetXaxis()->SetTitle(stack->GetHistogram()->GetXaxis()->GetTitle());
203
}
else
if
(
auto
* numer =
dynamic_cast<
TH1*
>
(histograms_array->At(i)->Clone()); numer)
204
numerators.emplace_back(numer);
205
RatioPlot
(denominator, numerators);
206
}
207
}
192
inline
void
Prettify
(
const
THStack* stack) {
…
}
208
inline
void
Prettify
(TMultiGraph* mg) {
209
Prettify
(mg->GetHistogram());
210
if
(!ratio_)
211
return
;
212
auto
* list = mg->GetListOfGraphs();
213
if
(list->GetEntries() < 2)
214
return
;
215
TGraphErrors* denominator =
nullptr
;
216
std::vector<TGraphErrors*> numerators{};
217
double
x_min{1.e10}, x_max{-1.e10};
218
for
(
int
i = 0; i < list->GetEntries(); ++i) {
219
TGraphErrors* gre{
nullptr
};
220
if
(strcmp(list->At(i)->ClassName(),
"TGraph"
) == 0) {
221
if
(
auto
* gr =
dynamic_cast<
TGraph*
>
(list->At(i)); gr) {
222
gre =
new
TGraphErrors(gr->GetN(), gr->GetX(), gr->GetY());
223
gre->SetLineColor(gr->GetLineColor());
224
gre->SetLineWidth(gr->GetLineWidth());
225
gre->SetLineStyle(gr->GetLineStyle());
226
gre->SetTitle(gr->GetTitle());
227
}
228
}
else
if
(strcmp(list->At(i)->ClassName(),
"TGraphErrors"
) == 0)
229
gre =
dynamic_cast<
TGraphErrors*
>
(list->At(i)->Clone());
230
if
(gre) {
231
gre->GetXaxis()->SetTitle(mg->GetHistogram()->GetXaxis()->GetTitle());
232
x_min = TMath::Min(TMath::MinElement(gre->GetN(), gre->GetX()), x_min);
233
x_max = TMath::Max(TMath::MaxElement(gre->GetN(), gre->GetX()), x_max);
234
if
(i == 0) {
// reference is conventionally the first graph
235
denominator = gre;
236
denominator->GetXaxis()->SetTitle(mg->GetHistogram()->GetXaxis()->GetTitle());
237
}
else
238
numerators.emplace_back(gre);
239
}
240
}
241
RatioPlot
(denominator, numerators, x_min, x_max);
242
mg->GetXaxis()->SetRangeUser(x_min, x_max);
243
}
208
inline
void
Prettify
(TMultiGraph* mg) {
…
}
244
245
inline
std::vector<TH1*>
RatioPlot
(TH1* denominator,
246
const
std::vector<TH1*>& numerators,
247
double
x_min = -999.,
248
double
x_max = -999.,
249
double
y_min = -999.,
250
double
y_max = -999.,
251
Option_t* draw_style =
"hist"
) {
252
std::vector<TH1*> ratios{};
253
if
(!ratio_)
254
return
ratios;
255
TCanvas::cd(2);
256
auto
* hs = Make<THStack>();
// garbage collected
257
for
(
const
auto
& numer : numerators) {
258
if
(
auto
* ratio =
dynamic_cast<
TH1*
>
(numer->Clone(
"ratio"
)); ratio) {
259
ratio->Divide(denominator);
260
auto
* ratio_shadow =
dynamic_cast<
TH1*
>
(ratio->Clone(
"ratio_shadow"
));
261
ratio_shadow->SetFillColorAlpha(ratio->GetLineColor(), 0.25);
262
hs->Add(ratio_shadow,
"e2"
);
263
hs->Add(ratio, draw_style);
264
ratios.emplace_back(ratio);
265
}
266
}
267
pads_.at(1)->SetLogy(
false
);
268
hs->Draw(
"nostack"
);
269
if
(x_min == x_max) {
270
x_min = denominator->GetXaxis()->GetXmin();
271
x_max = denominator->GetXaxis()->GetXmax();
272
}
273
TLine l;
274
l.SetLineWidth(1);
275
l.SetLineColor(denominator->GetLineColor());
276
l.SetLineStyle(denominator->GetLineStyle());
277
l.DrawLine(x_min, 1., x_max, 1.);
278
auto
* hst = hs->GetHistogram();
279
Prettify
(hst);
280
hst->GetXaxis()->SetTitle(denominator->GetXaxis()->GetTitle());
281
hst->GetXaxis()->SetTitleOffset(0.);
282
hst->GetXaxis()->SetTickSize(0.065);
283
hst->GetXaxis()->SetRangeUser(x_min, x_max);
284
hst->GetYaxis()->SetTitle(
"Ratio"
);
285
hst->GetYaxis()->SetLabelSize(15);
286
if
(y_min != y_max)
287
hst->GetYaxis()->SetRangeUser(y_min, y_max);
288
else
289
hst->GetYaxis()->SetRangeUser(TMath::Max(-0.65, hst->GetYaxis()->GetXmin()),
290
TMath::Min(2.65, hst->GetYaxis()->GetXmax()));
291
denominator->GetXaxis()->SetTitle(
""
);
292
TCanvas::cd(1);
293
return
ratios;
294
}
245
inline
std::vector<TH1*>
RatioPlot
(TH1* denominator, {
…
}
295
296
inline
std::vector<TGraphErrors*>
RatioPlot
(
const
TGraphErrors* denominator,
297
const
std::vector<TGraphErrors*>& numerators,
298
double
x_min = -999.,
299
double
x_max = -999.,
300
double
y_min = -999.,
301
double
y_max = -999.) {
302
std::vector<TGraphErrors*> ratios{};
303
if
(!ratio_)
304
return
ratios;
305
auto
* mg = Make<TMultiGraph>();
306
const
auto
*xd = denominator->GetX(), *yd = denominator->GetY(), *yde = denominator->GetEY();
307
for
(
const
auto
& numer : numerators) {
308
if
(numer->GetN() != denominator->GetN())
309
continue
;
310
const
auto
*xn = numer->GetX(), *yn = numer->GetY(), *yne = numer->GetEY();
311
auto
* ratio =
new
TGraphErrors();
312
ratio->SetTitle(denominator->GetTitle());
313
for
(
int
i = 0; i < denominator->GetN(); i++) {
314
const
auto
xd_val = xd[i], yd_val = yd[i], yd_err = yde[i];
315
for
(
int
j = 0; j < numer->GetN(); ++j) {
316
const
auto
xn_val = xn[j], yn_val = yn[j], yn_err = yne[j];
317
if
((xn_val == 0. && xd_val == 0.) || fabs(1. - xd_val / xn_val) * 2. * numer->GetN() < 1.) {
318
if
(yd_val == 0. || yn_val == 0.)
319
break
;
320
const
auto
y = yn_val / yd_val, err_y = std::hypot(yn_err / yn_val, yd_err / yd_val) * y;
321
const
auto
n = ratio->GetN();
322
ratio->SetPoint(n, xd_val, y);
323
ratio->SetPointError(n, 0., err_y);
324
break
;
325
}
326
}
327
}
328
mg->Add(ratio);
329
ratio->SetLineColor(numer->GetLineColor());
330
ratio->SetLineWidth(numer->GetLineWidth());
331
ratio->SetLineStyle(numer->GetLineStyle());
332
ratios.emplace_back(ratio);
333
}
334
TCanvas::cd(2);
335
mg->Draw(
"al"
);
336
Prettify
(mg->GetHistogram());
337
if
(x_min == x_max) {
338
x_min = denominator->GetXaxis()->GetXmin();
339
x_max = denominator->GetXaxis()->GetXmax();
340
}
341
mg->GetXaxis()->SetRangeUser(x_min, x_max);
342
mg->GetXaxis()->SetTitle(denominator->GetXaxis()->GetTitle());
343
mg->GetXaxis()->SetTitleOffset(0.);
344
mg->GetXaxis()->SetTickSize(0.065);
345
mg->GetYaxis()->SetTitle(
"Ratio"
);
346
mg->GetYaxis()->SetLabelSize(15);
347
if
(y_min != y_max)
348
mg->GetYaxis()->SetRangeUser(y_min, y_max);
349
else
350
mg->GetYaxis()->SetRangeUser(TMath::Max(-0.65, mg->GetYaxis()->GetXmin()),
351
TMath::Min(2.65, mg->GetYaxis()->GetXmax()));
352
denominator->GetXaxis()->SetTitle(
""
);
353
TLine l;
354
l.SetLineWidth(1);
355
l.SetLineColor(denominator->GetLineColor());
356
l.SetLineStyle(denominator->GetLineStyle());
357
l.DrawLine(x_min, 1., x_max, 1.);
358
TCanvas::cd(1);
359
return
ratios;
360
}
296
inline
std::vector<TGraphErrors*>
RatioPlot
(
const
TGraphErrors* denominator, {
…
}
362
inline
void
SetTopLabel
(
const
std::string& lab) {
363
TCanvas::cd();
364
std::string title =
"CepGen v"
+
version::tag
;
365
if
(!lab.empty())
366
title +=
" - "
+ lab;
367
if
(!top_label_)
368
BuildTopLabel();
369
else
370
top_label_->Clear();
371
top_label_->AddText(title.data());
372
//top_label_->Draw();
373
}
362
inline
void
SetTopLabel
(
const
std::string& lab) {
…
}
374
inline
void
SetGrid
(
int
x = 1,
int
y = 1)
override
{
375
if
(pads_.empty())
376
TCanvas::SetGrid(x, y);
377
else
378
pads_.at(0)->SetGrid(x, y);
379
}
374
inline
void
SetGrid
(
int
x = 1,
int
y = 1)
override
{
…
}
380
inline
void
SetLogx
(
int
log = 1)
override
{
381
if
(pads_.empty())
382
TCanvas::SetLogx(log);
383
else
384
for
(
auto
& pad : pads_)
385
pad->SetLogx(log);
386
}
380
inline
void
SetLogx
(
int
log = 1)
override
{
…
}
387
inline
void
SetLogy
(
int
log = 1)
override
{
388
if
(pads_.empty())
389
TCanvas::SetLogy(log);
390
else
391
pads_.at(0)->SetLogy(log);
392
}
387
inline
void
SetLogy
(
int
log = 1)
override
{
…
}
393
inline
void
SetLogz
(
int
log = 1)
override
{
394
if
(pads_.empty())
395
TCanvas::SetLogz(log);
396
else
397
pads_.at(0)->SetLogz(log);
398
}
393
inline
void
SetLogz
(
int
log = 1)
override
{
…
}
399
401
inline
void
SetLegendMode
(
const
std::string& mode) { leg_mode_ = mode; }
404
inline
void
SetLegendX1
(
double
x) {
405
if
(leg_)
406
perror(
"SetLegendX1"
);
407
leg_x1_ = x;
408
}
404
inline
void
SetLegendX1
(
double
x) {
…
}
411
inline
void
SetLegendY1
(
double
y) {
412
if
(leg_)
413
perror(
"SetLegendY1"
);
414
leg_y1_ = y;
415
}
411
inline
void
SetLegendY1
(
double
y) {
…
}
417
inline
void
AddLegendEntry
(
const
TObject* obj,
const
std::string& title, Option_t* option =
"lpf"
) {
418
if
(!leg_)
419
BuildLeg();
420
leg_->AddEntry(obj, title.c_str(), option);
421
const
unsigned
int
num_entries = leg_->GetNRows();
422
if
(num_entries > 3)
423
leg_->SetY1(leg_->GetY1() - (num_entries - 3) * 0.01);
424
if
(num_entries > 6) {
425
leg_->SetNColumns(1 + num_entries / 6);
426
leg_width_ = 0.55;
427
leg_->SetTextSize(0.035);
428
}
429
}
417
inline
void
AddLegendEntry
(
const
TObject* obj,
const
std::string& title, Option_t* option =
"lpf"
) {
…
}
431
inline
void
Save
(
const
std::string& ext,
const
std::string& out_dir =
"."
) {
432
const
auto
& extensions =
utils::split
(ext,
','
);
433
if
(extensions.empty())
434
return
;
435
TCanvas::cd();
436
if
(top_label_)
437
top_label_->Draw();
438
if
(leg_) {
439
if
(
440
#
if
ROOT_VERSION_CODE >= ROOT_VERSION(6, 28, 0)
441
TPad::PlaceBox(leg_.get(), leg_width_ * 1.15, leg_height_, leg_x1_, leg_y1_, leg_mode_.data())
442
#elif ROOT_VERSION_CODE >= ROOT_VERSION(6, 10, 0)
443
TPad::PlaceBox(leg_.get(), leg_width_ * 1.15, leg_height_, leg_x1_, leg_y1_)
444
#
else
445
true
446
#endif
447
) {
448
leg_y1_ = std::min(leg_y1_, 0.9 - leg_height_);
449
leg_->SetX1(leg_x1_);
450
leg_->SetX2(leg_x1_ + leg_width_);
451
leg_->SetY1(leg_y1_);
452
leg_->SetY2(leg_y1_ + leg_height_);
453
}
454
leg_->Draw();
455
}
456
for
(
const
auto
& extension : extensions)
457
TCanvas::SaveAs(Form(
"%s/%s.%s"
, out_dir.c_str(), TCanvas::GetName(), extension.c_str()));
458
}
431
inline
void
Save
(
const
std::string& ext,
const
std::string& out_dir =
"."
) {
…
}
460
inline
TLegend*
GetLegend
()
const
{
return
leg_.get(); }
461
inline
void
Place
(TLegend* leg,
const
Option_t* mode =
"lt"
) {
462
if
(!leg)
463
return
;
464
double
leg_x, leg_y;
465
const
auto
leg_width = leg->GetX2() - leg->GetX1(), leg_height = leg->GetY2() - leg->GetY1();
466
if
(
467
#
if
ROOT_VERSION_CODE >= ROOT_VERSION(6, 28, 0)
468
TPad::PlaceBox(leg, leg_width_ * 1.15, leg_height_, leg_x, leg_y, mode)
469
#elif ROOT_VERSION_CODE >= ROOT_VERSION(6, 10, 0)
470
TPad::PlaceBox(leg, leg_width_ * 1.15, leg_height_, leg_x, leg_y)
471
#
else
472
true
473
#endif
474
) {
475
leg->SetX1(leg_x);
476
leg->SetX2(leg_x + leg_width);
477
leg->SetY1(leg_y);
478
leg->SetY2(leg_y + leg_height);
479
}
480
leg->Draw();
481
}
461
inline
void
Place
(TLegend* leg,
const
Option_t* mode =
"lt"
) {
…
}
483
template
<
typename
T,
typename
... Args>
484
inline
T*
Make
(Args&&... args) {
485
grb_obj_.emplace_back(
new
T(std::forward<Args>(args)...));
486
return
dynamic_cast<
T*
>
(grb_obj_.rbegin()->get());
487
}
484
inline
T*
Make
(Args&&... args) {
…
}
488
489
private
:
491
inline
void
Build() {
492
TCanvas::SetLeftMargin(0.14);
493
TCanvas::SetTopMargin(0.06);
494
TCanvas::SetRightMargin(0.1);
495
TCanvas::SetBottomMargin(0.12);
496
TCanvas::SetTicks(1, 1);
497
TCanvas::SetFillStyle(0);
498
TCanvas::Pad()->SetFillStyle(0);
499
if
(ratio_)
500
DivideCanvas();
501
}
503
inline
void
DivideCanvas() {
504
TCanvas::Pad()->Divide(1, 2);
505
pads_.clear();
506
// main pad
507
if
(
auto
* p1 =
dynamic_cast<
TPad*
>
(TCanvas::GetPad(1)); p1) {
508
p1->SetPad(0., 0.3, 1., 1.);
509
p1->SetFillStyle(0);
510
p1->SetLeftMargin(TCanvas::GetLeftMargin());
511
p1->SetRightMargin(TCanvas::GetRightMargin());
512
p1->SetTopMargin(TCanvas::GetTopMargin() + 0.025);
513
p1->SetBottomMargin(0.02);
514
p1->SetTicks(1, 1);
515
pads_.emplace_back(p1);
516
}
517
// ratio plot(s) pad
518
if
(
auto
* p2 =
dynamic_cast<
TPad*
>
(TCanvas::GetPad(2)); p2) {
519
p2->SetPad(0., 0.0, 1., 0.3);
520
p2->SetFillStyle(0);
521
p2->SetLeftMargin(TCanvas::GetLeftMargin());
522
p2->SetRightMargin(TCanvas::GetRightMargin());
523
p2->SetTopMargin(0.02);
524
p2->SetBottomMargin(TCanvas::GetBottomMargin() + 0.25);
525
p2->SetTicks(1, 1);
526
p2->SetGrid(0, 1);
527
pads_.emplace_back(p2);
528
}
529
TCanvas::cd(1);
// roll back to the main pad
530
}
532
inline
void
BuildTopLabel() {
533
TCanvas::cd();
534
top_label_.reset(
new
ROOTPaveText(0.5, 0.95, 0.915, 0.96));
535
top_label_->SetTextSize(0.04);
536
top_label_->SetTextAlign(kHAlignRight + kVAlignBottom);
537
}
539
inline
void
BuildLeg() {
540
if
(leg_)
541
return
;
542
if
(ratio_)
543
TCanvas::cd(1);
544
leg_.reset(
new
TLegend(leg_x1_, leg_y1_, leg_x1_ + leg_width_, leg_y1_ + leg_height_));
545
leg_->SetLineColor(kWhite);
546
leg_->SetLineWidth(0);
547
leg_->SetFillStyle(0);
548
leg_->SetTextFont(
ROOTPaveText::fontType
(2));
549
leg_->SetTextSize(0.04);
550
}
552
static
double
GetBinning(
const
TH1* hist) {
553
return
(hist->GetXaxis()->GetXmax() - hist->GetXaxis()->GetXmin()) / hist->GetXaxis()->GetNbins();
554
}
555
556
const
bool
ratio_{
false
};
557
std::string leg_mode_{
"rt"
};
558
double
leg_x1_{0.15}, leg_y1_{0.75};
559
double
leg_width_{0.45}, leg_height_{0.15};
560
std::unique_ptr<TLegend> leg_{
nullptr
};
561
std::unique_ptr<ROOTPaveText> top_label_{
nullptr
};
562
std::vector<std::unique_ptr<TObject> > grb_obj_{};
563
std::vector<TPad*> pads_{};
564
};
89
class
ROOTCanvas
:
public
TCanvas {
…
};
565
const
std::vector<int>
ROOTCanvas::colours
= {
566
kBlack, kRed + 1, kBlue - 2, kGreen + 1, kOrange + 1, kAzure + 1, kMagenta + 1, kCyan + 3, kPink + 5};
567
}
// namespace cepgen
568
569
#endif
String.h
Version.h
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:404
cepgen::ROOTCanvas::Prettify
void Prettify(TMultiGraph *mg)
Definition
ROOTCanvas.h:208
cepgen::ROOTCanvas::GetLegend
TLegend * GetLegend() const
Retrieve the legend object (if produced)
Definition
ROOTCanvas.h:460
cepgen::ROOTCanvas::Place
void Place(TLegend *leg, const Option_t *mode="lt")
Definition
ROOTCanvas.h:461
cepgen::ROOTCanvas::SetLegendMode
void SetLegendMode(const std::string &mode)
Set the placement strategy for the legend.
Definition
ROOTCanvas.h:401
cepgen::ROOTCanvas::Make
T * Make(Args &&... args)
Garbage collector-like TObjects producer.
Definition
ROOTCanvas.h:484
cepgen::ROOTCanvas::SetLogz
void SetLogz(int log=1) override
Definition
ROOTCanvas.h:393
cepgen::ROOTCanvas::Save
void Save(const std::string &ext, const std::string &out_dir=".")
Save the canvas in an external file.
Definition
ROOTCanvas.h:431
cepgen::ROOTCanvas::SetLegendY1
void SetLegendY1(double y)
Set the vertical coordinate of the low-left part of the legend object.
Definition
ROOTCanvas.h:411
cepgen::ROOTCanvas::ROOTCanvas
ROOTCanvas(const std::string &name, const std::string &title="", bool ratio=false)
Build a canvas from its name, title, and attributes.
Definition
ROOTCanvas.h:97
cepgen::ROOTCanvas::colours
static const std::vector< int > colours
Definition
ROOTCanvas.h:91
cepgen::ROOTCanvas::Prettify
void Prettify(TH1 *obj) const
Draw main plot attributes in a pretty manner.
Definition
ROOTCanvas.h:110
cepgen::ROOTCanvas::RatioPlot
std::vector< TGraphErrors * > RatioPlot(const TGraphErrors *denominator, const std::vector< TGraphErrors * > &numerators, double x_min=-999., double x_max=-999., double y_min=-999., double y_max=-999.)
Definition
ROOTCanvas.h:296
cepgen::ROOTCanvas::RatioPlot
std::vector< TH1 * > RatioPlot(TH1 *denominator, const std::vector< TH1 * > &numerators, double x_min=-999., double x_max=-999., double y_min=-999., double y_max=-999., Option_t *draw_style="hist")
Definition
ROOTCanvas.h:245
cepgen::ROOTCanvas::SetLogx
void SetLogx(int log=1) override
Definition
ROOTCanvas.h:380
cepgen::ROOTCanvas::SetSize
void SetSize(double size=600)
Set horizontal canvas width.
Definition
ROOTCanvas.h:107
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:417
cepgen::ROOTCanvas::SetGrid
void SetGrid(int x=1, int y=1) override
Definition
ROOTCanvas.h:374
cepgen::ROOTCanvas::SetTopLabel
void SetTopLabel(const std::string &lab)
Specify the text to show on top of the canvas.
Definition
ROOTCanvas.h:362
cepgen::ROOTCanvas::SetLogy
void SetLogy(int log=1) override
Definition
ROOTCanvas.h:387
cepgen::ROOTCanvas::Prettify
void Prettify(const THStack *stack)
Definition
ROOTCanvas.h:192
cepgen::ROOTPaveText
A "prettified" text box object.
Definition
ROOTCanvas.h:43
cepgen::ROOTPaveText::fontType
static int fontType(int mode)
Force font to be Times New Roman-style.
Definition
ROOTCanvas.h:68
cepgen::ROOTPaveText::ROOTPaveText
ROOTPaveText(double x1, double y1, double x2, double y2, const std::string &text="")
Definition
ROOTCanvas.h:45
cepgen::utils::split
std::vector< std::string > split(const std::string &, char, bool trim_parts=false)
Split a string according to a separation character.
cepgen
Common namespace for this Monte Carlo generator.
Definition
Handler.h:26
cepgen::AddUnderOverflowBins
T * AddUnderOverflowBins(const T *hist)
Definition
ROOTCanvas.h:72
cepgen::version::tag
static const std::string tag
CepGen version.
Definition
Version.h:27
include
CepGenRoot
ROOTCanvas.h
Generated on Tue Apr 22 2025 for CepGen by
1.10.0