ppfx_plot_utils.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "TH1.h"
4 #include "TH2.h"
5 #include "TLegend.h"
6 #include "TLine.h"
7 #include "TText.h"
8 #include "TLatex.h"
9 #include "TLegend.h"
10 #include "TPad.h"
11 
12 #include <fstream>
13 #include <iostream>
14 #include <cmath>
15 #include <algorithm>
16 
17 void set_labels_1D(std::vector<std::string> labels, TH1D* hist)
18 {
19  int nlabels = labels.size();
20 
21  double left = gPad->GetLeftMargin();
22  double right = 1-gPad->GetRightMargin();
23  double top = 1-gPad->GetTopMargin();
24  double bottom = gPad->GetBottomMargin();
25 
26  TLatex *tLabel = new TLatex();
27  if(nlabels == 8)
28  tLabel->SetTextSize(0.05);
29  if(nlabels == 16)
30  tLabel->SetTextSize(0.0125);
31 
32  tLabel->SetNDC();
33 
34  double start = 0;
35  int nbins = hist->GetNbinsX();
36 
37  double hxmin = hist->GetXaxis()->GetBinLowEdge(1);
38  double hxmax = hist->GetXaxis()->GetBinLowEdge(nbins+1);
39  start = left + 0.25*(right-left)*nbins/(nlabels*(hxmax-hxmin));
40 
41  std::for_each(labels.begin(), labels.end(),
42  [&](std::string label){
43  tLabel->DrawLatex(start, 0.25*bottom, label.c_str());
44  start += (right-left)*nbins/(nlabels*(hxmax-hxmin));
45  });
46 
47  gPad->Update();
48 }
49 
50 void set_labels_2D(std::vector<std::string> labels_x, std::vector<std::string> labels_y, TH2D* hist)
51 {
52  int nlabels_x = labels_x.size();
53  int nlabels_y = labels_y.size();
54 
55  double left = gPad->GetLeftMargin();
56  double right = 1-gPad->GetRightMargin();
57  double top = 1-gPad->GetTopMargin();
58  double bottom = gPad->GetBottomMargin();
59 
60  TLatex *tLabelX = new TLatex();
61  if(nlabels_x == 8)
62  tLabelX->SetTextSize(0.02);
63  if(nlabels_x == 16)
64  tLabelX->SetTextSize(0.0125);
65  tLabelX->SetNDC();
66 
67  TLatex *tLabelY = new TLatex();
68  if(nlabels_y == 8)
69  tLabelY->SetTextSize(0.0125);
70  if(nlabels_y == 16)
71  tLabelY->SetTextSize(0.01);
72 
73  tLabelY->SetNDC();
74  tLabelY->SetTextAngle(90);
75 
76  double start_x = 0;
77  double start_y = 0;
78  int nbins_x = hist->GetNbinsX();
79  int nbins_y = hist->GetNbinsY();
80 
81  double hxmin = hist->GetXaxis()->GetBinLowEdge(1);
82  double hxmax = hist->GetXaxis()->GetBinLowEdge(nbins_x+1);
83 
84  double hymin = hist->GetYaxis()->GetBinLowEdge(1);
85  double hymax = hist->GetYaxis()->GetBinLowEdge(nbins_y+1);
86 
87  start_x = left + 0.25*(right-left)*nbins_x/(nlabels_y*(hxmax-hxmin));
88  start_y = bottom + 0.25*(top-bottom)*nbins_y/(nlabels_y*(hymax-hymin));
89 
90  std::for_each(labels_x.begin(), labels_x.end(),
91  [&](std::string label){
92  tLabelX->DrawLatex(start_x, 0.25*bottom, label.c_str());
93  start_x += (right-left)*nbins_x/(nlabels_x*(hxmax-hxmin));
94  });
95 
96  std::for_each(labels_y.begin(), labels_y.end(),
97  [&](std::string label){
98  tLabelY->DrawLatex(0.25*left, start_y, label.c_str());
99  start_y += (top-bottom)*nbins_y/(nlabels_y*(hymax-hymin));
100  });
101 
102  gPad->Update();
103 }
104 
105 void draw_vlines(int n, double xmax, double y0, double y1, Color_t color = kBlack)
106 {
107  TLine *line = new TLine();
108  line->SetLineWidth(2);
109  line->SetLineColor(color);
110  double x = 0;
111  for(int i = 0; i < n; i++) {
112  line->DrawLine(x, y0, x, y1);
113  x += (double)xmax/n;
114  }
115  gPad->Update();
116 }
117 
118 struct plot_h
119 {
120  TH1* hist;
121  Option_t* drawOption;
122  Color_t color;
125  Option_t* legendOption;
126 };
127 
128 TLegend* auto_legend(std::vector <TH1*> hists, double dx, double dy, double hymin, double hymax)
129 {
130  //get pad coordinates first
131  double left = gPad->GetLeftMargin();
132  double right = 1-gPad->GetRightMargin();
133  double top = 1-gPad->GetTopMargin();
134  double bottom = gPad->GetBottomMargin();
135 
136  // start at centre
137  double x = 0.5*(right + left) - 0.5*dx;
138  double y = 0.5*(top + bottom) - 0.5*dy;
139 
140  for(int i = 0; i < 1000; i++){
141  double overlap = 0.;
142  double doverlap_x = 0.;
143  double doverlap_y = 0.;
144 
145  for(int histIdx = 0; histIdx < (int)hists.size(); histIdx++){
146  double hxmin = hists[histIdx]->GetXaxis()->GetBinLowEdge(1);
147  double hxmax = hists[histIdx]->GetXaxis()->GetBinLowEdge(hists[histIdx]->GetNbinsX()+1);
148 
149  for(int binIdx = 1; binIdx < hists[histIdx]->GetNbinsX()+1; ++binIdx){
150 
151  // convert histogram coordinates to pad coordinates
152  double bx = (hists[histIdx]->GetXaxis()->GetBinWidth(binIdx))*(right - left)/(hxmax - hxmin);
153  double hx = ((hists[histIdx]->GetXaxis()->GetBinLowEdge(binIdx) - hxmin)*(right - left)/(hxmax - hxmin)) + left;
154  double hy = (hists[histIdx]->GetBinContent(binIdx) - hymin)*(top - bottom)/(hymax - hymin) + bottom;
155  double hy_prev = (hists[histIdx]->GetBinContent(binIdx-1))*(top - bottom)/(hymax - hymin) + bottom;
156  double by = std::abs(hy - hy_prev);
157  double low_hy = hy;
158 
159  // calculate overlap
160  double overlap_x = (dx + bx) - (std::max(x+dx, hx+bx) - std::min(x, hx));
161  double overlap_y = 0.;
162  if (hy > hy_prev){
163  overlap_y = (dy + by) - (std::max(y+dy, hy) - std::min(y, hy_prev));
164  low_hy = hy_prev;
165  }
166  else {
167  overlap_y = (dy + by) - (std::max(y+dy, hy_prev) - std::min(y, hy));
168  }
169 
170  // negative overlap is as good as 0
171  if (overlap_x < 0.) overlap_x = 0.;
172  if (overlap_y < 0.) overlap_y = 0.;
173 
174  // gradient
175  if(overlap_x == bx || overlap_x == dx || overlap_x == 0.)
176  doverlap_x += 0.;
177  else if(x+dx >= hx + bx)
178  doverlap_x += -1.*overlap_y;
179  else
180  doverlap_x += overlap_y;
181 
182  if(overlap_y == by || overlap_y == dy || overlap_y == 0.)
183  doverlap_y += 0.;
184  else if(y+dy >= low_hy + by)
185  doverlap_y += -1.*overlap_x;
186  else
187  doverlap_y += overlap_x;
188 
189  overlap += overlap_x*overlap_y;
190  }
191  }
192 
193  // descend along gradient
194  double xprev = x;
195  double yprev = y;
196  x -= 0.02*doverlap_x;
197  y -= 0.02*doverlap_y;
198 
199  // if it hits an edge, throw it to the other end with offset to prevent bouncing back
200  if(x+dx >= right){
201  x = right - x + 0.1;
202  continue;
203  }
204  if(x <= left) {
205  x = right - x - dx - 0.1;
206  continue;
207  }
208  if(y+dy >= top) {
209  y = top - y + 0.1;
210  continue;
211  }
212  if(y <= bottom) {
213  y = top - y - dy - 0.1;
214  continue;
215  }
216  // if it has found a space or converges
217  if(overlap == 0. || (std::abs(x - xprev) < 0.00005 && std::abs(y - yprev) < 0.00005)) break;
218 
219  }
220  return new TLegend(x, y, x+dx, y+dy);
221 
222 }
223 
224 void plot_hists(std::vector <plot_h> hists, std::string title="",
225  bool turnOnlegend = true, bool turnOnMaxRange = true,
226  double leg_w = 0.2, double leg_h = 0.3,
227  double offset = 1.5)
228 {
229 
230  double yMax = 0;
231  std::vector <TH1*> h_leg;
232 
233  for(int histIdx = 0; histIdx<(int)hists.size(); ++histIdx){
234 
235  hists[histIdx].hist->SetLineColor(hists[histIdx].color);
236  double tmp = hists[histIdx].hist->GetBinContent(hists[histIdx].hist->GetMaximumBin())
237  + std::sqrt(hists[histIdx].hist->GetBinContent(hists[histIdx].hist->GetMaximumBin()));
238  tmp *= offset;
239  if(yMax < tmp) yMax = tmp;
240 
241  h_leg.push_back(hists[histIdx].hist);
242  }
243 
244  hists[0].hist->SetTitle(title.c_str());
245 
246  if(turnOnMaxRange)
247  hists[0].hist->GetYaxis()->SetRangeUser(0, yMax);
248 
249 
250  for(int histIdx = 0; histIdx<(int)hists.size(); ++histIdx)
251  hists[histIdx].hist->Draw(hists[histIdx].drawOption);
252 
253  if(turnOnlegend) {
254  TLegend* legnd = auto_legend(h_leg, leg_w, leg_h, 0., yMax);
255  for(int histIdx = 0; histIdx<(int)hists.size(); ++histIdx){
256  if(hists[histIdx].drawLegend)
257  legnd->AddEntry(hists[histIdx].hist,hists[histIdx].legendLabel.c_str(),hists[histIdx].legendOption);
258  }
259  legnd->Draw();
260  }
261 
262  gPad->Update();
263 
264 }
265 
266 TH1* plot_ratios(std::vector <std::pair<plot_h, TH1*>> hists, std::string title = "",
267  bool turnOnlegend = false, double low_y = -1, double high_y = -1)
268 {
269  TH1* ret = 0;
270  bool turnOnMaxRange = false;
271  std::vector <plot_h> ratios;
272  if(low_y == high_y) turnOnMaxRange = true;
273  for(int histIdx = 0; histIdx < (int) hists.size(); histIdx++){
274 
275  TH1F* hRatio = (TH1F*)hists[histIdx].first.hist->Clone("");
276  hRatio->Sumw2();
277  hRatio->Divide(hists[histIdx].second);
278  hRatio->GetYaxis()->SetTitle("Ratio");
279  if(!turnOnMaxRange) hRatio->GetYaxis()->SetRangeUser(low_y, high_y);
280 
281  ratios.push_back({hRatio, hists[histIdx].first.drawOption, hists[histIdx].first.color,
282  hists[histIdx].first.drawLegend, hists[histIdx].first.legendLabel, hists[histIdx].first.legendOption});
283 
284  }
285 
286  plot_hists(ratios, title, turnOnlegend, turnOnMaxRange);
287 
288  // return histogram object to make modifications later
289  ret = ratios[0].hist;
290  return ret;
291 }
292 
293 void plot_label(double x, double y, std::string label)
294 {
295  TLatex *tLabel = new TLatex(x, y, label.c_str());
296  tLabel->SetTextSize(0.035);
297  tLabel->SetNDC();
298  tLabel->Draw();
299 
300  gPad->Update();
301 }
302 
303 void draw_h_line(double x0, double x1, double y, Color_t color)
304 {
305  TLine *line1 = new TLine(x0,y,x1, y);
306  line1->SetLineWidth(2);
307  line1->SetLineStyle(kDashed);
308  line1->SetLineColor(color);
309  line1->Draw("same");
310 
311  gPad->Update();
312 }
313 
314 void draw_v_line(double x, double y0, double y1, Color_t color)
315 {
316  TLine *line1 = new TLine(x,y0,x, y1);
317  line1->SetLineWidth(2);
318  line1->SetLineStyle(kDashed);
319  line1->SetLineColor(color);
320  line1->Draw("same");
321 
322  gPad->Update();
323 }
T max(const caf::Proxy< T > &a, T b)
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:112
std::map< std::string, double > xmax
Float_t y1[n_points_granero]
Definition: compare.C:5
Float_t x1[n_points_granero]
Definition: compare.C:5
T sqrt(T number)
Definition: d0nt_math.hpp:156
std::string legendLabel
Color_t color
Float_t tmp
Definition: plot.C:36
TString hists[nhists]
Definition: bdt_com.C:3
void set_labels_2D(std::vector< std::string > labels_x, std::vector< std::string > labels_y, TH2D *hist)
float abs(float number)
Definition: d0nt_math.hpp:39
void draw_v_line(double x, double y0, double y1, Color_t color)
const char * label
const int nbins
Definition: cellShifts.C:15
double dy[NP][NC]
double dx[NP][NC]
Option_t * drawOption
void plot_hists(std::vector< plot_h > hists, std::string title="", bool turnOnlegend=true, bool turnOnMaxRange=true, double leg_w=0.2, double leg_h=0.3, double offset=1.5)
Option_t * legendOption
void draw_h_line(double x0, double x1, double y, Color_t color)
TLegend * auto_legend(std::vector< TH1 * > hists, double dx, double dy, double hymin, double hymax)
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:104
::xsd::cxx::tree::string< char, simple_type > string
Definition: Database.h:154
TH1 * plot_ratios(std::vector< std::pair< plot_h, TH1 * >> hists, std::string title="", bool turnOnlegend=false, double low_y=-1, double high_y=-1)
TH1 * hist
void set_labels_1D(std::vector< std::string > labels, TH1D *hist)
void draw_vlines(int n, double xmax, double y0, double y1, Color_t color=kBlack)
bool drawLegend
T min(const caf::Proxy< T > &a, T b)
TGeoVolume * top
Definition: make_fe_box.C:9
void plot_label(double x, double y, std::string label)