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