cepgen is hosted by Hepforge, IPPP Durham
CepGen N/A
Central exclusive processes event generator
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
41namespace 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 }
66
68 inline static int fontType(int mode) { return 130 + mode; }
69 };
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
411 inline void SetLegendY1(double y) {
412 if (leg_)
413 perror("SetLegendY1");
414 leg_y1_ = y;
415 }
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 }
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 }
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 }
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 }
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 };
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
A "prettified" generic figure canvas.
Definition ROOTCanvas.h:89
void SetLegendX1(double x)
Set the horizontal coordinate of the low-left part of the legend object.
Definition ROOTCanvas.h:404
void Prettify(TMultiGraph *mg)
Definition ROOTCanvas.h:208
TLegend * GetLegend() const
Retrieve the legend object (if produced)
Definition ROOTCanvas.h:460
void Place(TLegend *leg, const Option_t *mode="lt")
Definition ROOTCanvas.h:461
void SetLegendMode(const std::string &mode)
Set the placement strategy for the legend.
Definition ROOTCanvas.h:401
T * Make(Args &&... args)
Garbage collector-like TObjects producer.
Definition ROOTCanvas.h:484
void SetLogz(int log=1) override
Definition ROOTCanvas.h:393
void Save(const std::string &ext, const std::string &out_dir=".")
Save the canvas in an external file.
Definition ROOTCanvas.h:431
void SetLegendY1(double y)
Set the vertical coordinate of the low-left part of the legend object.
Definition ROOTCanvas.h:411
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
static const std::vector< int > colours
Definition ROOTCanvas.h:91
void Prettify(TH1 *obj) const
Draw main plot attributes in a pretty manner.
Definition ROOTCanvas.h:110
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
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
void SetLogx(int log=1) override
Definition ROOTCanvas.h:380
void SetSize(double size=600)
Set horizontal canvas width.
Definition ROOTCanvas.h:107
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
void SetGrid(int x=1, int y=1) override
Definition ROOTCanvas.h:374
void SetTopLabel(const std::string &lab)
Specify the text to show on top of the canvas.
Definition ROOTCanvas.h:362
void SetLogy(int log=1) override
Definition ROOTCanvas.h:387
void Prettify(const THStack *stack)
Definition ROOTCanvas.h:192
A "prettified" text box object.
Definition ROOTCanvas.h:43
static int fontType(int mode)
Force font to be Times New Roman-style.
Definition ROOTCanvas.h:68
ROOTPaveText(double x1, double y1, double x2, double y2, const std::string &text="")
Definition ROOTCanvas.h:45
std::vector< std::string > split(const std::string &, char, bool trim_parts=false)
Split a string according to a separation character.
Common namespace for this Monte Carlo generator.
Definition Handler.h:26
T * AddUnderOverflowBins(const T *hist)
Definition ROOTCanvas.h:72
static const std::string tag
CepGen version.
Definition Version.h:27