cepgen is hosted by Hepforge, IPPP Durham
CepGen 1.2.5
Central exclusive processes event generator
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-2023 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 CepGenAddOns_ROOTWrapper_ROOTCanvas_h
20#define CepGenAddOns_ROOTWrapper_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 : 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
96 explicit inline ROOTCanvas(const std::string& name, const std::string& title = "", bool ratio = false)
97 : TCanvas(name.c_str(), "", 600, 600), ratio_(ratio) {
98 gStyle->SetOptStat(0);
99 gStyle->SetGridColor(17);
100 gStyle->SetEndErrorSize(0);
101 SetTopLabel(title);
102 Build();
103 }
104
106 inline void SetSize(double size = 600) { TCanvas::SetCanvasSize(size, 600); }
107
109 inline void Prettify(TH1* obj) {
110 if (auto* x = dynamic_cast<TAxis*>(obj->GetXaxis()); x) {
111 x->CenterTitle();
112 x->SetLabelFont(ROOTPaveText::fontType(3));
113 x->SetLabelSize(20);
114 x->SetTitleFont(ROOTPaveText::fontType(3));
115 x->SetTitleSize(29);
116 if (ratio_) {
117 x->SetTitleOffset(2.5);
118 x->SetLabelOffset(0.02);
119 }
120 x->SetTickLength(0.03);
121 }
122 if (auto* y = dynamic_cast<TAxis*>(obj->GetYaxis()); y) {
123 y->CenterTitle();
124 y->SetLabelFont(ROOTPaveText::fontType(3));
125 y->SetLabelSize(20);
126 y->SetTitleFont(ROOTPaveText::fontType(3));
127 y->SetTitleSize(29);
128 y->SetTitleOffset(1.3);
129 y->SetTickLength(0.03);
130 }
131 if (auto* z = dynamic_cast<TAxis*>(obj->GetZaxis()); z) {
132 z->CenterTitle();
133 z->SetLabelFont(ROOTPaveText::fontType(3));
134 z->SetLabelSize(16);
135 z->SetTitleFont(ROOTPaveText::fontType(3));
136 z->SetTitleSize(29);
137 }
138
139 // axis titles
140 TString ttle = obj->GetTitle();
141 if (ttle.Contains("\\")) {
142 TObjArray* tok = ttle.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 = ((TObjString*)tok->At(2))->String();
150 if (unit.Contains("?")) { // extract format specifier
151 TObjArray* tok2 = unit.Tokenize("?");
152 if (tok2->GetEntries() > 1) {
153 unit = dynamic_cast<TObjString*>(tok2->At(0))->String();
154 form_spec = dynamic_cast<TObjString*>(tok2->At(1))->String();
155 } else {
156 unit = "";
157 form_spec = dynamic_cast<TObjString*>(tok2->At(0))->String();
158 }
159 }
160 }
161 if (tok->GetEntries() > 3) {
162 distrib = ((TObjString*)tok->At(3))->String();
163 }
164 if (!unit.IsNull() or !form_spec.IsNull()) {
165 if (!unit.IsNull())
166 x_title = Form("%s (%s)", x_title.Data(), unit.Data());
167 if (!distrib.IsNull()) {
168 if (!form_spec.IsNull()) {
169 TString format = Form("%%s (%s / %%%s %%s)", distrib.Data(), form_spec.Data());
170 y_title = Form(format.Data(), y_title.Data(), GetBinning(obj), unit.Data());
171 } else
172 y_title = Form("%s (%s / %u %s)",
173 y_title.Data(),
174 distrib.Data(),
175 static_cast<unsigned int>(GetBinning(obj)),
176 unit.Data());
177 } else {
178 if (!form_spec.IsNull()) {
179 TString format = Form("%%s / %%%s %%s", form_spec.Data());
180 y_title = Form(format.Data(), y_title.Data(), GetBinning(obj), unit.Data());
181 } else
182 y_title = Form("%s / %u %s", y_title.Data(), static_cast<unsigned int>(GetBinning(obj)), unit.Data());
183 }
184 }
185 if (auto* x = dynamic_cast<TAxis*>(obj->GetXaxis()); x)
186 x->SetTitle(x_title);
187 if (auto* y = dynamic_cast<TAxis*>(obj->GetYaxis()); y)
188 y->SetTitle(y_title);
189 obj->SetTitle("");
190 }
191 //else obj->GetXaxis()->SetTitle(ttle);
192 }
193
194 inline void Prettify(THStack* hs) {
195 Prettify(hs->GetHistogram());
196 if (!ratio_)
197 return;
198 auto* objarr = hs->GetHists();
199 if (objarr->GetEntries() < 2)
200 return;
201 TH1* denom = nullptr;
202 std::vector<TH1*> numers{};
203 for (int i = 0; i < objarr->GetEntries(); ++i)
204 if (i == 0) { // reference is conventionally the first histogram
205 if (denom = dynamic_cast<TH1*>(objarr->At(i)->Clone()); denom)
206 denom->GetXaxis()->SetTitle(hs->GetHistogram()->GetXaxis()->GetTitle());
207 } else if (auto* numer = dynamic_cast<TH1*>(objarr->At(i)->Clone()); numer)
208 numers.emplace_back(numer);
209 RatioPlot(denom, numers);
210 }
211 inline void Prettify(TMultiGraph* mg) {
212 Prettify(mg->GetHistogram());
213 if (!ratio_)
214 return;
215 auto* list = mg->GetListOfGraphs();
216 if (list->GetEntries() < 2)
217 return;
218 TGraphErrors* denom = nullptr;
219 std::vector<TGraphErrors*> numers{};
220 double x_min{1.e10}, x_max{-1.e10};
221 for (int i = 0; i < list->GetEntries(); ++i) {
222 TGraphErrors* gre{nullptr};
223 if (strcmp(list->At(i)->ClassName(), "TGraph") == 0) {
224 if (auto* gr = dynamic_cast<TGraph*>(list->At(i)); gr) {
225 gre = new TGraphErrors(gr->GetN(), gr->GetX(), gr->GetY());
226 gre->SetLineColor(gr->GetLineColor());
227 gre->SetLineWidth(gr->GetLineWidth());
228 gre->SetLineStyle(gr->GetLineStyle());
229 gre->SetTitle(gr->GetTitle());
230 }
231 } else if (strcmp(list->At(i)->ClassName(), "TGraphErrors") == 0)
232 gre = dynamic_cast<TGraphErrors*>(list->At(i)->Clone());
233 if (gre) {
234 gre->GetXaxis()->SetTitle(mg->GetHistogram()->GetXaxis()->GetTitle());
235 x_min = TMath::Min(TMath::MinElement(gre->GetN(), gre->GetX()), x_min);
236 x_max = TMath::Max(TMath::MaxElement(gre->GetN(), gre->GetX()), x_max);
237 if (i == 0) { // reference is conventionally the first graph
238 denom = gre;
239 denom->GetXaxis()->SetTitle(mg->GetHistogram()->GetXaxis()->GetTitle());
240 } else
241 numers.emplace_back(gre);
242 }
243 }
244 RatioPlot(denom, numers, x_min, x_max);
245 mg->GetXaxis()->SetRangeUser(x_min, x_max);
246 }
247
248 inline std::vector<TH1*> RatioPlot(TH1* denom,
249 const std::vector<TH1*>& numers,
250 double xmin = -999.,
251 double xmax = -999.,
252 double ymin = -999.,
253 double ymax = -999.,
254 Option_t* draw_style = "hist") {
255 std::vector<TH1*> ratios{};
256 if (!ratio_)
257 return ratios;
258 TCanvas::cd(2);
259 auto* hs = Make<THStack>(); // garbage collected
260 for (const auto& numer : numers) {
261 if (auto* ratio = dynamic_cast<TH1*>(numer->Clone("ratio")); ratio) {
262 ratio->Divide(denom);
263 auto* ratio_shadow = dynamic_cast<TH1*>(ratio->Clone("ratio_shadow"));
264 ratio_shadow->SetFillColorAlpha(ratio->GetLineColor(), 0.25);
265 hs->Add(ratio_shadow, "e2");
266 hs->Add(ratio, draw_style);
267 ratios.emplace_back(ratio);
268 }
269 }
270 pads_.at(1)->SetLogy(false);
271 hs->Draw("nostack");
272 if (xmin == xmax) {
273 xmin = denom->GetXaxis()->GetXmin();
274 xmax = denom->GetXaxis()->GetXmax();
275 }
276 TLine l;
277 l.SetLineWidth(1);
278 l.SetLineColor(denom->GetLineColor());
279 l.SetLineStyle(denom->GetLineStyle());
280 l.DrawLine(xmin, 1., xmax, 1.);
281 auto* hst = hs->GetHistogram();
282 Prettify(hst);
283 hst->GetXaxis()->SetTitle(denom->GetXaxis()->GetTitle());
284 hst->GetXaxis()->SetTitleOffset(0.);
285 hst->GetXaxis()->SetTickSize(0.065);
286 hst->GetXaxis()->SetRangeUser(xmin, xmax);
287 hst->GetYaxis()->SetTitle("Ratio");
288 hst->GetYaxis()->SetLabelSize(15);
289 if (ymin != ymax)
290 hst->GetYaxis()->SetRangeUser(ymin, ymax);
291 else
292 hst->GetYaxis()->SetRangeUser(TMath::Max(-0.65, hst->GetYaxis()->GetXmin()),
293 TMath::Min(2.65, hst->GetYaxis()->GetXmax()));
294 denom->GetXaxis()->SetTitle("");
295 TCanvas::cd(1);
296 return ratios;
297 }
298
299 inline std::vector<TGraphErrors*> RatioPlot(TGraphErrors* denom,
300 const std::vector<TGraphErrors*>& numers,
301 double xmin = -999.,
302 double xmax = -999.,
303 double ymin = -999.,
304 double ymax = -999.) {
305 std::vector<TGraphErrors*> ratios{};
306 if (!ratio_)
307 return ratios;
308 auto* mg = Make<TMultiGraph>();
309 const auto *xd = denom->GetX(), *yd = denom->GetY(), *yde = denom->GetEY();
310 for (const auto& numer : numers) {
311 if (numer->GetN() != denom->GetN())
312 continue;
313 const auto *xn = numer->GetX(), *yn = numer->GetY(), *yne = numer->GetEY();
314 auto* ratio = new TGraphErrors();
315 ratio->SetTitle(denom->GetTitle());
316 for (int i = 0; i < denom->GetN(); i++) {
317 const auto xd_val = xd[i], yd_val = yd[i], yd_err = yde[i];
318 for (int j = 0; j < numer->GetN(); ++j) {
319 const auto xn_val = xn[j], yn_val = yn[j], yn_err = yne[j];
320 if ((xn_val == 0. && xd_val == 0.) || fabs(1. - xd_val / xn_val) * 2. * numer->GetN() < 1.) {
321 if (yd_val == 0. || yn_val == 0.)
322 break;
323 const auto y = yn_val / yd_val, err_y = std::hypot(yn_err / yn_val, yd_err / yd_val) * y;
324 const auto n = ratio->GetN();
325 ratio->SetPoint(n, xd_val, y);
326 ratio->SetPointError(n, 0., err_y);
327 break;
328 }
329 }
330 }
331 mg->Add(ratio);
332 ratio->SetLineColor(numer->GetLineColor());
333 ratio->SetLineWidth(numer->GetLineWidth());
334 ratio->SetLineStyle(numer->GetLineStyle());
335 ratios.emplace_back(ratio);
336 }
337 TCanvas::cd(2);
338 mg->Draw("al");
339 Prettify(mg->GetHistogram());
340 if (xmin == xmax) {
341 xmin = denom->GetXaxis()->GetXmin();
342 xmax = denom->GetXaxis()->GetXmax();
343 }
344 mg->GetXaxis()->SetRangeUser(xmin, xmax);
345 mg->GetXaxis()->SetTitle(denom->GetXaxis()->GetTitle());
346 mg->GetXaxis()->SetTitleOffset(0.);
347 mg->GetXaxis()->SetTickSize(0.065);
348 mg->GetYaxis()->SetTitle("Ratio");
349 mg->GetYaxis()->SetLabelSize(15);
350 if (ymin != ymax)
351 mg->GetYaxis()->SetRangeUser(ymin, ymax);
352 else
353 mg->GetYaxis()->SetRangeUser(TMath::Max(-0.65, mg->GetYaxis()->GetXmin()),
354 TMath::Min(2.65, mg->GetYaxis()->GetXmax()));
355 denom->GetXaxis()->SetTitle("");
356 TLine l;
357 l.SetLineWidth(1);
358 l.SetLineColor(denom->GetLineColor());
359 l.SetLineStyle(denom->GetLineStyle());
360 l.DrawLine(xmin, 1., xmax, 1.);
361 TCanvas::cd(1);
362 return ratios;
363 }
365 inline void SetTopLabel(const std::string& lab) {
366 TCanvas::cd();
367 std::string title = "CepGen v" + version::tag;
368 if (!lab.empty())
369 title += " - " + lab;
370 if (!top_label_)
371 BuildTopLabel();
372 else
373 top_label_->Clear();
374 top_label_->AddText(title.data());
375 //top_label_->Draw();
376 }
377 inline void SetGrid(int x = 1, int y = 1) {
378 if (pads_.empty())
379 TCanvas::SetGrid(x, y);
380 else
381 pads_.at(0)->SetGrid(x, y);
382 }
383 inline void SetLogx(int log = 1) {
384 if (pads_.empty())
385 TCanvas::SetLogx(log);
386 else
387 for (auto& pad : pads_)
388 pad->SetLogx(log);
389 }
390 inline void SetLogy(int log = 1) {
391 if (pads_.empty())
392 TCanvas::SetLogy(log);
393 else
394 pads_.at(0)->SetLogy(log);
395 }
396 inline void SetLogz(int log = 1) {
397 if (pads_.empty())
398 TCanvas::SetLogz(log);
399 else
400 pads_.at(0)->SetLogz(log);
401 }
402
404 inline void SetLegendMode(const std::string& mode) { leg_mode_ = mode; }
407 inline void SetLegendX1(double x) {
408 if (leg_)
409 perror("SetLegendX1");
410 leg_x1_ = x;
411 }
414 inline void SetLegendY1(double y) {
415 if (leg_)
416 perror("SetLegendY1");
417 leg_y1_ = y;
418 }
420 inline void AddLegendEntry(const TObject* obj, const std::string& title, Option_t* option = "lpf") {
421 if (!leg_)
422 BuildLeg();
423 leg_->AddEntry(obj, title.c_str(), option);
424 const unsigned int num_entries = leg_->GetNRows();
425 if (num_entries > 3)
426 leg_->SetY1(leg_->GetY1() - (num_entries - 3) * 0.01);
427 if (num_entries > 6) {
428 leg_->SetNColumns(1 + num_entries / 6);
429 leg_width_ = 0.55;
430 leg_->SetTextSize(0.035);
431 }
432 }
434 inline void Save(const std::string& ext, const std::string& out_dir = ".") {
435 const auto& extensions = utils::split(ext, ',');
436 if (extensions.empty())
437 return;
438 TCanvas::cd();
439 if (top_label_)
440 top_label_->Draw();
441 if (leg_) {
442 if (
443#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 28, 0)
444 TPad::PlaceBox(leg_.get(), leg_width_ * 1.15, leg_height_, leg_x1_, leg_y1_, leg_mode_.data())
445#elif ROOT_VERSION_CODE >= ROOT_VERSION(6, 10, 0)
446 TPad::PlaceBox(leg_.get(), leg_width_ * 1.15, leg_height_, leg_x1_, leg_y1_)
447#else
448 true
449#endif
450 ) {
451 leg_y1_ = std::min(leg_y1_, 0.9 - leg_height_);
452 leg_->SetX1(leg_x1_);
453 leg_->SetX2(leg_x1_ + leg_width_);
454 leg_->SetY1(leg_y1_);
455 leg_->SetY2(leg_y1_ + leg_height_);
456 }
457 leg_->Draw();
458 }
459 for (const auto& extension : extensions)
460 TCanvas::SaveAs(Form("%s/%s.%s", out_dir.c_str(), TCanvas::GetName(), extension.c_str()));
461 }
463 inline TLegend* GetLegend() { return leg_.get(); }
464 inline void Place(TLegend* leg, const Option_t* mode = "lt") {
465 if (!leg)
466 return;
467 double leg_x, leg_y;
468 const auto leg_width = leg->GetX2() - leg->GetX1(), leg_height = leg->GetY2() - leg->GetY1();
469 if (
470#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 28, 0)
471 TPad::PlaceBox(leg, leg_width_ * 1.15, leg_height_, leg_x, leg_y, mode)
472#elif ROOT_VERSION_CODE >= ROOT_VERSION(6, 10, 0)
473 TPad::PlaceBox(leg, leg_width_ * 1.15, leg_height_, leg_x, leg_y)
474#else
475 true
476#endif
477 ) {
478 leg->SetX1(leg_x);
479 leg->SetX2(leg_x + leg_width);
480 leg->SetY1(leg_y);
481 leg->SetY2(leg_y + leg_height);
482 }
483 leg->Draw();
484 }
486 template <typename T, typename... Args>
487 inline T* Make(Args&&... args) {
488 grb_obj_.emplace_back(new T(std::forward<Args>(args)...));
489 return dynamic_cast<T*>(grb_obj_.rbegin()->get());
490 }
491
492 private:
494 inline void Build() {
495 TCanvas::SetLeftMargin(0.14);
496 TCanvas::SetTopMargin(0.06);
497 TCanvas::SetRightMargin(0.1);
498 TCanvas::SetBottomMargin(0.12);
499 TCanvas::SetTicks(1, 1);
500 TCanvas::SetFillStyle(0);
501 TCanvas::Pad()->SetFillStyle(0);
502 if (ratio_)
503 DivideCanvas();
504 }
506 inline void DivideCanvas() {
507 TCanvas::Pad()->Divide(1, 2);
508 pads_.clear();
509 // main pad
510 if (auto* p1 = dynamic_cast<TPad*>(TCanvas::GetPad(1)); p1) {
511 p1->SetPad(0., 0.3, 1., 1.);
512 p1->SetFillStyle(0);
513 p1->SetLeftMargin(TCanvas::GetLeftMargin());
514 p1->SetRightMargin(TCanvas::GetRightMargin());
515 p1->SetTopMargin(TCanvas::GetTopMargin() + 0.025);
516 p1->SetBottomMargin(0.02);
517 p1->SetTicks(1, 1);
518 pads_.emplace_back(p1);
519 }
520 // ratio plot(s) pad
521 if (auto* p2 = dynamic_cast<TPad*>(TCanvas::GetPad(2)); p2) {
522 p2->SetPad(0., 0.0, 1., 0.3);
523 p2->SetFillStyle(0);
524 p2->SetLeftMargin(TCanvas::GetLeftMargin());
525 p2->SetRightMargin(TCanvas::GetRightMargin());
526 p2->SetTopMargin(0.02);
527 p2->SetBottomMargin(TCanvas::GetBottomMargin() + 0.25);
528 p2->SetTicks(1, 1);
529 p2->SetGrid(0, 1);
530 pads_.emplace_back(p2);
531 }
532 // roll back to main pad
533 TCanvas::cd(1);
534 }
536 inline void BuildTopLabel() {
537 TCanvas::cd();
538 top_label_.reset(new ROOTPaveText(0.5, 0.95, 0.915, 0.96));
539 top_label_->SetTextSize(0.04);
540 top_label_->SetTextAlign(kHAlignRight + kVAlignBottom);
541 }
543 inline void BuildLeg() {
544 if (leg_)
545 return;
546 if (ratio_)
547 TCanvas::cd(1);
548 leg_.reset(new TLegend);
549 leg_->SetLineColor(kWhite);
550 leg_->SetLineWidth(0);
551 leg_->SetFillStyle(0);
552 leg_->SetTextFont(ROOTPaveText::fontType(2));
553 leg_->SetTextSize(0.04);
554 }
556 inline double GetBinning(const TH1* hist) {
557 return (hist->GetXaxis()->GetXmax() - hist->GetXaxis()->GetXmin()) / hist->GetXaxis()->GetNbins();
558 }
559
560 const bool ratio_{false};
561 std::string leg_mode_{"rt"};
562 double leg_x1_{0.5}, leg_y1_{0.75};
563 double leg_width_{0.45}, leg_height_{0.15};
564 std::unique_ptr<TLegend> leg_{nullptr};
565 std::unique_ptr<ROOTPaveText> top_label_{nullptr};
566 std::vector<std::unique_ptr<TObject> > grb_obj_{};
567 std::vector<TPad*> pads_{};
568 };
569 const std::vector<int> ROOTCanvas::colours = {
570 kBlack, kRed + 1, kBlue - 2, kGreen + 1, kOrange + 1, kAzure + 1, kMagenta + 1, kCyan + 3, kPink + 5};
571} // namespace cepgen
572
573#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:407
void SetLogz(int log=1)
Definition ROOTCanvas.h:396
void Prettify(TMultiGraph *mg)
Definition ROOTCanvas.h:211
void Place(TLegend *leg, const Option_t *mode="lt")
Definition ROOTCanvas.h:464
void SetLegendMode(const std::string &mode)
Set the placement strategy for the legend.
Definition ROOTCanvas.h:404
T * Make(Args &&... args)
Garbage collector-like TObjects producer.
Definition ROOTCanvas.h:487
void Save(const std::string &ext, const std::string &out_dir=".")
Save the canvas in an external file.
Definition ROOTCanvas.h:434
void SetLegendY1(double y)
Set the vertical coordinate of the low-left part of the legend object.
Definition ROOTCanvas.h:414
ROOTCanvas(const std::string &name, const std::string &title="", bool ratio=false)
Build a canvas from its name, title, and attributes.
Definition ROOTCanvas.h:96
static const std::vector< int > colours
Definition ROOTCanvas.h:91
void SetSize(double size=600)
Set horizontal canvas width.
Definition ROOTCanvas.h:106
void SetGrid(int x=1, int y=1)
Definition ROOTCanvas.h:377
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
void Prettify(TH1 *obj)
Draw main plot attributes in a pretty manner.
Definition ROOTCanvas.h:109
std::vector< TH1 * > RatioPlot(TH1 *denom, const std::vector< TH1 * > &numers, double xmin=-999., double xmax=-999., double ymin=-999., double ymax=-999., Option_t *draw_style="hist")
Definition ROOTCanvas.h:248
void SetLogx(int log=1)
Definition ROOTCanvas.h:383
void SetLogy(int log=1)
Definition ROOTCanvas.h:390
std::vector< TGraphErrors * > RatioPlot(TGraphErrors *denom, const std::vector< TGraphErrors * > &numers, double xmin=-999., double xmax=-999., double ymin=-999., double ymax=-999.)
Definition ROOTCanvas.h:299
void SetTopLabel(const std::string &lab)
Specify the text to show on top of the canvas.
Definition ROOTCanvas.h:365
void Prettify(THStack *hs)
Definition ROOTCanvas.h:194
TLegend * GetLegend()
Retrieve the legend object (if produced)
Definition ROOTCanvas.h:463
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 &str, char delim, bool trim)
Split a string according to a separation character.
Definition String.cpp:233
Common namespace for this Monte Carlo generator.
T * AddUnderOverflowBins(const T *hist)
Definition ROOTCanvas.h:72
static const std::string tag
CepGen version.
Definition Version.h:28