CbmRoot
Loading...
Searching...
No Matches
CbmDrawHist.cxx
Go to the documentation of this file.
1/* Copyright (C) 2008-2020 GSI/JINR-LIT, Darmstadt/Dubna
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Andrey Lebedev [committer] */
4
10#include "CbmDrawHist.h"
11
12#include "CbmUtils.h" // for NumberToString
13
14#include <TAxis.h> // for TAxis
15#include <TF1.h> // for TF1
16#include <TGraph.h> // for TGraph
17#include <TGraph2D.h> // for TGraph2D
18#include <TH1.h> // for TH1, TH1D
19#include <TH2.h> // for TH2, TH2D
20#include <TH3.h> // for TH3
21#include <TLatex.h> // for TLatex
22#include <TLegend.h> // for TLegend
23#include <TStyle.h> // for TStyle, gStyle
24#include <TVirtualPad.h> // for TVirtualPad, gPad
25
26#include <algorithm> // for max, min
27#include <cassert> // for assert
28#include <iostream> // for string, operator<<, basic_ostream, strin...
29#include <limits> // for numeric_limits
30#include <string> // for operator+, allocator, basic_string, char...
31
32using std::string;
33using std::stringstream;
34using std::vector;
35
36/* Set default styles for histograms. */
38{
39 gStyle->SetOptStat("rm");
40 gStyle->SetOptFit(1);
41 gStyle->SetOptTitle(0);
42
43 gStyle->SetCanvasColor(kWhite);
44 gStyle->SetFrameFillColor(kWhite);
45 gStyle->SetFrameBorderMode(0);
46 gStyle->SetPadColor(kWhite);
47 gStyle->SetStatColor(kWhite);
48 gStyle->SetTitleFillColor(kWhite);
49 gStyle->SetPalette(55, 0);
50 // gStyle->SetPalette(1);
51}
52
53/* Draw TH1 histogram.*/
54void DrawH1(TH1* hist, HistScale logx, HistScale logy, const string& drawOpt, Int_t color, Int_t lineWidth,
55 Int_t lineStyle, Int_t markerSize, Int_t markerStyle)
56{
57 Double_t textSize = CbmDrawingOptions::TextSize();
58 hist->SetLineColor(color);
59 hist->SetLineWidth(lineWidth);
60 hist->SetLineStyle(lineStyle);
61 hist->SetMarkerColor(color);
62 hist->SetMarkerSize(markerSize);
63 hist->SetMarkerStyle(markerStyle);
64 if (logx == kLog) { gPad->SetLogx(); }
65 if (logy == kLog) { gPad->SetLogy(); }
66 hist->GetXaxis()->SetLabelSize(textSize);
67 hist->GetXaxis()->SetNdivisions(505, kTRUE);
68 hist->GetYaxis()->SetLabelSize(textSize);
69 hist->GetXaxis()->SetTitleSize(textSize);
70 hist->GetYaxis()->SetTitleSize(textSize);
71 hist->GetXaxis()->SetTitleOffset(1.0);
72 hist->GetYaxis()->SetTitleOffset(1.3);
73 gPad->SetLeftMargin(0.17);
74 gPad->SetBottomMargin(0.15);
75 gPad->SetTopMargin(0.12);
76 gPad->SetTicks(1, 1);
77 hist->Draw(drawOpt.c_str());
78 gPad->SetGrid(true, true);
79 hist->SetStats(false);
80}
81
82/* Draw TH2 histogram.*/
83void DrawH2(TH2* hist, HistScale logx, HistScale logy, HistScale logz, const string& drawOpt)
84{
85 Double_t textSize = CbmDrawingOptions::TextSize();
86 if (logx == kLog) { gPad->SetLogx(); }
87 if (logy == kLog) { gPad->SetLogy(); }
88 if (logz == kLog) { gPad->SetLogz(); }
89 hist->GetXaxis()->SetLabelSize(textSize);
90 hist->GetXaxis()->SetNdivisions(505, kTRUE);
91 hist->GetYaxis()->SetLabelSize(textSize);
92 hist->GetYaxis()->SetNdivisions(505, kTRUE);
93 hist->GetZaxis()->SetLabelSize(textSize);
94 // hist->GetZaxis()->SetNdivisions(505, kTRUE);
95 hist->GetXaxis()->SetTitleSize(textSize);
96 hist->GetYaxis()->SetTitleSize(textSize);
97 hist->GetZaxis()->SetTitleSize(textSize);
98 hist->GetXaxis()->SetTitleOffset(1.0);
99 hist->GetYaxis()->SetTitleOffset(1.3);
100 hist->GetZaxis()->SetTitleOffset(1.5);
101 gPad->SetLeftMargin(0.17);
102 gPad->SetRightMargin(0.30);
103 gPad->SetBottomMargin(0.15);
104 gPad->SetTicks(1, 1);
105 hist->Draw(drawOpt.c_str());
106 gPad->SetGrid(true, true);
107 hist->SetStats(false);
108}
109
110/* Draw several TH1 histograms. */
111void DrawH1(const vector<TH1*>& histos, const vector<string>& histLabels, HistScale logx, HistScale logy,
112 Bool_t drawLegend, Double_t x1, Double_t y1, Double_t x2, Double_t y2, const string& drawOpt)
113{
114 assert(histos.size() != 0 && histLabels.size() == histos.size());
115 Double_t max = std::numeric_limits<Double_t>::min();
116 UInt_t nofHistos = histos.size();
117 TLegend* legend = new TLegend(x1, y1, x2, y2);
118 legend->SetFillColor(kWhite);
119 for (UInt_t iHist = 0; iHist < nofHistos; iHist++) {
120 TH1* hist = histos[iHist];
121 string opt = (iHist == 0) ? drawOpt : (iHist == nofHistos - 1) ? "SAME" + drawOpt : "SAME" + drawOpt;
122 DrawH1(hist, logx, logy, opt, CbmDrawingOptions::Color(iHist), CbmDrawingOptions::LineWidth(),
124 max = std::max(max, hist->GetMaximum());
125 legend->AddEntry(hist, histLabels[iHist].c_str(), "lp");
126 }
127 histos[0]->SetMaximum(max * 1.17);
128 if (drawLegend) { legend->Draw(); }
129}
130
131void DrawGraph(TGraph* graph, HistScale logx, HistScale logy, const string& drawOpt, Int_t color, Int_t lineWidth,
132 Int_t lineStyle, Int_t markerSize, Int_t markerStyle)
133{
134 Double_t textSize = CbmDrawingOptions::TextSize();
135 graph->SetLineColor(color);
136 graph->SetLineWidth(lineWidth);
137 graph->SetLineStyle(lineStyle);
138 graph->SetMarkerColor(color);
139 graph->SetMarkerSize(markerSize);
140 graph->SetMarkerStyle(markerStyle);
141 if (drawOpt.find("A") != string::npos) {
142 if (logx == kLog) { gPad->SetLogx(); }
143 if (logy == kLog) { gPad->SetLogy(); }
144 graph->GetXaxis()->SetLabelSize(textSize);
145 graph->GetXaxis()->SetNdivisions(505, kTRUE);
146 graph->GetYaxis()->SetLabelSize(textSize);
147 graph->GetXaxis()->SetTitleSize(textSize);
148 graph->GetYaxis()->SetTitleSize(textSize);
149 graph->GetXaxis()->SetTitleOffset(1.0);
150 graph->GetYaxis()->SetTitleOffset(1.3);
151 }
152 gPad->SetLeftMargin(0.17);
153 gPad->SetBottomMargin(0.15);
154 graph->Draw(drawOpt.c_str());
155 gPad->SetGrid(true, true);
156}
157
158
159/* Draw several TGraphs. */
160void DrawGraph(const vector<TGraph*>& graphs, const vector<string>& graphLabels, HistScale logx, HistScale logy,
161 Bool_t drawLegend, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
162{
163 assert(graphs.size() != 0 && graphs.size() == graphLabels.size());
164
165 Double_t max = std::numeric_limits<Double_t>::min();
166 Double_t min = std::numeric_limits<Double_t>::max();
167 TLegend* legend = new TLegend(x1, y1, x2, y2);
168 legend->SetFillColor(kWhite);
169 UInt_t nofGraphs = graphs.size();
170 for (UInt_t iGraph = 0; iGraph < nofGraphs; iGraph++) {
171 TGraph* graph = graphs[iGraph];
172 string opt = (iGraph == 0) ? "ACP" : "CP";
173 DrawGraph(graph, logx, logy, opt, CbmDrawingOptions::Color(iGraph), CbmDrawingOptions::LineWidth(),
176 max = std::max(graph->GetYaxis()->GetXmax(), max);
177 min = std::min(graph->GetYaxis()->GetXmin(), min);
178 legend->AddEntry(graph, graphLabels[iGraph].c_str(), "lp");
179 }
180 graphs[0]->SetMaximum(max);
181 graphs[0]->SetMinimum(min);
182 if (drawLegend) { legend->Draw(); }
183}
184
185/* Draws 2D graph.*/
186void DrawGraph2D(TGraph2D* graph, HistScale logx, HistScale logy, HistScale logz, const string& drawOpt)
187{
188 Double_t textSize = CbmDrawingOptions::TextSize();
189 if (logx == kLog) { gPad->SetLogx(); }
190 if (logy == kLog) { gPad->SetLogy(); }
191 if (logz == kLog) { gPad->SetLogz(); }
192 graph->GetXaxis()->SetLabelSize(textSize);
193 graph->GetXaxis()->SetNdivisions(505, kTRUE);
194 graph->GetYaxis()->SetLabelSize(textSize);
195 graph->GetYaxis()->SetNdivisions(505, kTRUE);
196 graph->GetZaxis()->SetLabelSize(textSize);
197 // graph->GetZaxis()->SetNdivisions(505, kTRUE);
198 graph->GetXaxis()->SetTitleSize(textSize);
199 graph->GetYaxis()->SetTitleSize(textSize);
200 graph->GetZaxis()->SetTitleSize(textSize);
201 graph->GetXaxis()->SetTitleOffset(1.0);
202 graph->GetYaxis()->SetTitleOffset(1.3);
203 graph->GetZaxis()->SetTitleOffset(1.7);
204 gPad->SetLeftMargin(0.17);
205 gPad->SetRightMargin(0.2);
206 gPad->SetBottomMargin(0.15);
207 gPad->SetTicks(1, 1);
208 graph->Draw(drawOpt.c_str());
209 gPad->SetGrid(true, true);
210}
211
212void DrawTextOnPad(const string& text, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
213{
214 TLegend* leg = new TLegend(x1, y1, x2, y2);
215 leg->AddEntry(new TH2D(), text.c_str(), "");
216 leg->SetFillColor(kWhite);
217 leg->SetFillStyle(0);
218 leg->SetBorderSize(0);
219 leg->Draw();
220}
221
222void DrawH1andFitGauss(TH1* hist, Bool_t drawResults, Bool_t doScale, Double_t userRangeMin, Double_t userRangeMax)
223{
224 if (hist == nullptr) return;
225
226 hist->GetYaxis()->SetTitle("Yield (a.u.)");
227 DrawH1(hist, kLinear, kLinear, "hist");
228 if (doScale) hist->Scale(1. / hist->Integral());
229 if (!(userRangeMin == 0. && userRangeMax == 0.)) hist->GetXaxis()->SetRangeUser(userRangeMin, userRangeMax);
230 hist->Fit("gaus", "Q");
231 TF1* func = hist->GetFunction("gaus");
232 if (func == nullptr) return;
233 func->SetLineColor(kBlack);
234 func->Draw("same");
235
236 if (drawResults) {
237 double m = func->GetParameter(1);
238 double s = func->GetParameter(2);
239 string txt1 = Cbm::NumberToString<Double_t>(m, 2) + " / " + Cbm::NumberToString<Double_t>(s, 2);
240 TLatex text;
241 text.SetTextAlign(21);
242 text.SetTextSize(0.06);
243 text.DrawTextNDC(0.5, 0.92, txt1.c_str());
244 }
245}
246
247void DrawH2WithProfile(TH2* hist, Bool_t doGaussFit, Bool_t drawOnlyMean, const string& drawOpt2D, Int_t profileColor,
248 Int_t profileLineWidth)
249{
250 if (hist == nullptr) return;
251
252 // TProfile does not allow to fit individual slice with gauss
253 /* TProfile* profX = (TProfile*)hist->ProfileX("_pfx", 1, -1, "s")->Clone();
254 DrawH2(hist, kLinear, kLinear, kLinear, drawOpt);
255 if (!drawOnlyMean) {
256 DrawH1(profX, kLinear, kLinear, "same", profileColor, profileLineWidth, 1, 1, kOpenCircle);
257 } else {
258 DrawH1(profX, kLinear, kLinear, "same hist p", profileColor, profileLineWidth, 1, 1, kFullCircle);
259 }*/
260
261 TH1D* hMean = (TH1D*) hist->ProjectionX((string(hist->GetName()) + "_mean").c_str())->Clone();
262 string yTitle = (doGaussFit) ? "Mean and sigma. " : "Mean and RMS. ";
263 hMean->GetYaxis()->SetTitle((yTitle + string(hist->GetYaxis()->GetTitle())).c_str());
264 for (Int_t i = 1; i <= hist->GetXaxis()->GetNbins(); i++) {
265 stringstream ss;
266 ss << string(hist->GetName()) << "_py" << i;
267 TH1D* pr = hist->ProjectionY(ss.str().c_str(), i, i);
268 if (hMean == nullptr || pr == nullptr) continue;
269
270 Double_t m = 0., s = 0.;
271 if (doGaussFit) {
272 pr->Fit("gaus", "QO");
273 TF1* func = pr->GetFunction("gaus");
274 if (func != nullptr) {
275 m = func->GetParameter(1);
276 s = func->GetParameter(2);
277 }
278 }
279 else {
280 m = pr->GetMean();
281 s = pr->GetRMS();
282 }
283
284 hMean->SetBinContent(i, m);
285 if (!drawOnlyMean) { hMean->SetBinError(i, s); }
286 else {
287 hMean->SetBinError(i, 0.);
288 }
289 }
290 DrawH2(hist, kLinear, kLinear, kLinear, drawOpt2D);
291 if (!drawOnlyMean) { DrawH1(hMean, kLinear, kLinear, "same", profileColor, profileLineWidth, 1, 1, kOpenCircle); }
292 else {
293 DrawH1(hMean, kLinear, kLinear, "same hist p", profileColor, profileLineWidth, 1, 1, kFullCircle);
294 }
295}
296
297TH2D* DrawH3Profile(TH3* h, Bool_t drawMean, Bool_t doGaussFit, Double_t zMin, Double_t zMax)
298{
299 Int_t nBinsX = h->GetNbinsX();
300 Int_t nBinsY = h->GetNbinsY();
301 TH2D* h2 = (TH2D*) h->Project3D("yx")->Clone();
302
303 for (Int_t x = 1; x <= nBinsX; x++) {
304 for (Int_t y = 1; y <= nBinsY; y++) {
305 stringstream ss;
306 ss << h->GetName() << "_z_" << x << "_" << y;
307 TH1D* hz = h->ProjectionZ(ss.str().c_str(), x, x, y, y);
308 Double_t ms = 0.;
309 if (doGaussFit) {
310 hz->Fit("gaus", "QO");
311 TF1* func = hz->GetFunction("gaus");
312 if (func != nullptr) { ms = (drawMean) ? func->GetParameter(1) : func->GetParameter(2); }
313 }
314 else {
315 ms = (drawMean) ? hz->GetMean() : hz->GetRMS();
316 }
317 h2->SetBinContent(x, y, ms);
318 }
319 }
320
321 string zAxisTitle = string(h->GetZaxis()->GetTitle());
322 string sigmaRms = (doGaussFit) ? "Sigma." : "RMS.";
323 zAxisTitle = (drawMean) ? "Mean." + zAxisTitle : sigmaRms + zAxisTitle;
324
325 h2->GetZaxis()->SetTitle(zAxisTitle.c_str());
326 if (zMin < zMax) h2->GetZaxis()->SetRangeUser(zMin, zMax);
327 DrawH2(h2);
328
329 return h2;
330}
void DrawH1andFitGauss(TH1 *hist, Bool_t drawResults, Bool_t doScale, Double_t userRangeMin, Double_t userRangeMax)
void DrawH2WithProfile(TH2 *hist, Bool_t doGaussFit, Bool_t drawOnlyMean, const string &drawOpt2D, Int_t profileColor, Int_t profileLineWidth)
void DrawTextOnPad(const string &text, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
void SetDefaultDrawStyle()
void DrawH1(TH1 *hist, HistScale logx, HistScale logy, const string &drawOpt, Int_t color, Int_t lineWidth, Int_t lineStyle, Int_t markerSize, Int_t markerStyle)
void DrawH2(TH2 *hist, HistScale logx, HistScale logy, HistScale logz, const string &drawOpt)
TH2D * DrawH3Profile(TH3 *h, Bool_t drawMean, Bool_t doGaussFit, Double_t zMin, Double_t zMax)
void DrawGraph2D(TGraph2D *graph, HistScale logx, HistScale logy, HistScale logz, const string &drawOpt)
void DrawGraph(TGraph *graph, HistScale logx, HistScale logy, const string &drawOpt, Int_t color, Int_t lineWidth, Int_t lineStyle, Int_t markerSize, Int_t markerStyle)
Helper functions for drawing 1D and 2D histograms and graphs.
HistScale
Define linear or logarithmic scale for drawing.
Definition CbmDrawHist.h:67
@ kLinear
Definition CbmDrawHist.h:69
@ kLog
Definition CbmDrawHist.h:68
static Int_t MarkerSize()
Definition CbmDrawHist.h:49
static Int_t LineWidth()
Definition CbmDrawHist.h:45
static Double_t TextSize()
Definition CbmDrawHist.h:59
static Int_t LineStyle(Int_t lineStyleIndex)
Definition CbmDrawHist.h:47
static Int_t Color(Int_t colorIndex)
Definition CbmDrawHist.h:36
static Int_t MarkerStyle(Int_t markerIndex)
Definition CbmDrawHist.h:51
Data class with information on a STS local track.
std::string NumberToString(const T &value, int precision=1)
Definition CbmUtils.h:34