Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
TRatioPlot.cxx
Go to the documentation of this file.
1// @(#)root/gpad:$Id$
2// Author: Paul Gessinger 25/08/2016
3
4/*************************************************************************
5 * Copyright (C) 1995-2024, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include "TRatioPlot.h"
13#include "TColor.h"
14#include "TROOT.h"
15#include "TBrowser.h"
16#include "TH1.h"
17#include "TF1.h"
18#include "TPad.h"
19#include "TString.h"
20#include "TMath.h"
21#include "TGraphAsymmErrors.h"
22#include "TGraphErrors.h"
23#include "TGaxis.h"
24#include "TLine.h"
25#include "TVirtualFitter.h"
26#include "TFitResult.h"
27#include "THStack.h"
28#include "TStyle.h"
29
30/** \class TRatioPlot
31 \ingroup gpad
32Class for displaying ratios, differences and fit residuals.
33
34RatioPlot is a helper class designed to draw ratios; it is not meant to be a persistent
35object on its own. Therefore, saving a TRatioPlot in a ROOT file (or exporting it directly
36as a PDF or PNG) does not make sense, because it is not a self-contained entity like a TH1
37or a TGraph. TRatioPlot is specifically designed to arrange pads, which becomes evident
38when inspecting the pad contents (using gPad->ls()): multiple pads and axes are created.
39To save its visual output, you should print the entire canvas in formats such as PDF, SVG, or PNG.
40
41TRatioPlot has two constructors, one which accepts two histograms, and is responsible
42for setting up the calculation of ratios and differences. This calculation is in part
43delegated to `TEfficiency`. A single option can be given as a parameter, that is
44used to determine which procedure is chosen. The remaining option string is then
45passed through to the calculation, if applicable. The other constructor uses a
46fitted histogram to calculate the fit residual and plot it with the histogram
47and the fit function.
48
49## Ratios and differences
50The simplest case is passing two histograms without specifying any options. This defaults to using
51`TGraphAsymmErrors::Divide`. The `option` variable is passed through, as are the parameters
52`c1` and `c2`, that you can set via `TRatioPlot::SetC1` and `TRatioPlot::SetC1`. If you set the
53`option` to `divsym` the method `TH1::Divide` will be used instead, also receiving all the parameters.
54
55Using the `option` `diff` or `diffsig`, both histograms will be subtracted, and in the case of diffsig,
56the difference will be divided by the uncertainty. `c1` and `c2` will only be used to
57scale the histograms using `TH1::Scale` prior to subtraction.
58
59Available options are for `option`:
60| Option | Description |
61| ---------- | ------------------------------------------------------------ |
62| divsym | uses the histogram `TH1::Divide` method, yields symmetric errors |
63| diff | subtracts the histograms |
64| diffsig | subtracts the histograms and divides by the uncertainty |
65
66Begin_Macro(source)
67../../../tutorials/hist/hist029_TRatioPlot_simple.C
68End_Macro
69
70## Fit residuals
71A second constructor only accepts a single histogram, but expects it to have a fitted
72function. The function is used to calculate the residual between the fit and the
73histogram. Here, it is expected that h1 has a fit function in it's list of functions. The class calculates the
74difference between the histogram and the fit function at each point and divides it by the uncertainty. There
75are a few option to steer which error is used (as is the case for `diffsig`). The default is to use
76the statistical uncertainty from h1 using `TH1::GetBinError`. If the `option` string contains `errasym`, asymmetric
77errors will be used. The type of error can be steered by `TH1::SetBinErrorOption`. The corresponding error will be used,
78depending on if the function is below or above the bin content. The third option `errfunc` uses the square root of
79the function value as the error.
80
81
82Begin_Macro(source)
83../../../tutorials/hist/hist030_TRatioPlot_residual.C
84End_Macro
85
86## Error options for difference divided by uncertainty and fit residual
87The uncertainty that is used in the calculation can be steered by providing
88options to the `option` argument.
89
90| Option | Description |
91| ---------- | ------------------------------------------------------------ |
92| errasym | Uses calculated asymmetric errors from `TH1::GetBinErrorUp`/`TH1::GetBinErrorLow`. Note that you need to
93set `TH1::SetBinErrorOption` first | | errfunc | Uses \f$ \sqrt{f(x)} \f$ as the error |
94
95The asymmetric error case uses the upper or lower error depending on the relative size
96of the bin contents, or the bin content and the function value.
97
98## Access to internal parts
99You can access the internal objects that are used to construct the plot via a series of
100methods. `TRatioPlot::GetUpperPad` and `TRatioPlot::GetLowerPad` can be used to draw additional
101elements on top of the existing ones.
102`TRatioPlot::GetLowerRefGraph` returns a reference to the lower pad's graph that
103is responsible for the range, which enables you to modify the range.
104
105\image html gpad_ratioplot.png
106*/
107
108////////////////////////////////////////////////////////////////////////////////
109/// TRatioPlot default constructor
110
111TRatioPlot::TRatioPlot() : fLeftMargin(gStyle->GetPadLeftMargin()), fRightMargin(gStyle->GetPadRightMargin()) {}
112
113////////////////////////////////////////////////////////////////////////////////
114/// Destructor
115
117{
118 delete fSharedXAxis;
119 delete fUpYaxis;
120 delete fLowYaxis;
121
125 }
126
127 // special case when fH1 created from the stack but not drawn - need to delete it
129 delete fH1;
130}
131
132////////////////////////////////////////////////////////////////////////////////
133/// Internal method that shares constructor logic
134
135void TRatioPlot::Init(TH1* h1, TH1* h2, Option_t *option)
136{
137
138 fH1 = h1;
139 fH2 = h2;
140
141 SetupPads();
142
143 TString optionString = option;
144
145 if (optionString.Contains("divsym")) {
146 optionString.ReplaceAll("divsym", "");
148 } else if (optionString.Contains("diffsig")) {
149 optionString.ReplaceAll("diffsig", "");
151
152 // determine which error style
153 if (optionString.Contains("errasym")) {
155 optionString.ReplaceAll("errasym", "");
156 }
157
158 if (optionString.Contains("errfunc")) {
160 optionString.ReplaceAll("errfunc", "");
161 }
162 } else if (optionString.Contains("diff")) {
163 optionString.ReplaceAll("diff", "");
165 } else {
166 fMode = CalculationMode::kDivideGraph; // <- default
167 }
168
169 fOption = optionString;
170
171
172 fH1DrawOpt = "hist";
173 fH2DrawOpt = "E";
174 fGraphDrawOpt = "AP";
175
176
177 // build ratio, everything is ready
178 if (!BuildLowerPlot()) return;
179
180 // taking x axis information from h1 by cloning it x axis
181 fSharedXAxis = static_cast<TAxis *>(fH1->GetXaxis()->Clone());
182 fUpYaxis = static_cast<TAxis *>(fH1->GetYaxis()->Clone());
183 fLowYaxis = static_cast<TAxis *>(fRatioGraph->GetYaxis()->Clone());
184}
185
186////////////////////////////////////////////////////////////////////////////////
187/// Constructor for two histograms
188///
189/// \param h1 First histogram
190/// \param h2 Second histogram
191/// \param option Steers the error calculation, as well as ratio / difference
192
194{
195 if (!h1 || !h2) {
196 Warning("TRatioPlot", "Need two histograms.");
197 return;
198 }
199
200 Bool_t h1IsTH1 = h1->InheritsFrom(TH1::Class());
201 Bool_t h2IsTH1 = h2->InheritsFrom(TH1::Class());
202
203 if (!h1IsTH1 && !h2IsTH1) {
204 Warning("TRatioPlot", "Need two histograms deriving from TH2 or TH3.");
205 return;
206 }
207
208 fHistDrawProxy = h1;
209
210 Init(h1, h2, option);
211
212}
213
214////////////////////////////////////////////////////////////////////////////////
215/// Constructor which accepts a `THStack` and a histogram. Converts the
216/// stack to a regular sum of its containing histograms for processing.
217///
218/// \param st The THStack object
219/// \param h2 The other histogram
220/// \param option Steers the calculation of the lower plot
221
223{
224 if (!st || !h2) {
225 Warning("TRatioPlot", "Need a histogram and a stack");
226 return;
227 }
228
229 TList *stackHists = st->GetHists();
230
231 if (stackHists->GetSize() == 0) {
232 Warning("TRatioPlot", "Stack does not have histograms");
233 return;
234 }
235
236 auto tmpHist = static_cast<TH1 *>(stackHists->At(0)->Clone());
237 tmpHist->Reset();
238
239 for (int i = 0; i < stackHists->GetSize(); ++i) {
240 tmpHist->Add(static_cast<TH1 *>(stackHists->At(i)));
241 }
242
243 fHistDrawProxy = st;
244 fHistDrawProxyStack = kTRUE;
245
246 Init(tmpHist, h2, option);
247
248}
249
250////////////////////////////////////////////////////////////////////////////////
251/// Constructor which accepts a `THStack` and a histogram. Converts the
252/// stack to a regular sum of its containing histograms for processing.
253///
254/// \param h1 The other histogram
255/// \param st The THStack object
256/// \param option Steers the calculation of the lower plot
257
259{
260 if (!st || !h1) {
261 Warning("TRatioPlot", "Need a histogram and a stack");
262 return;
263 }
264
265 TList *stackHists = st->GetHists();
266
267 if (stackHists->GetSize() == 0) {
268 Warning("TRatioPlot", "Stack does not have histograms");
269 return;
270 }
271
272 auto tmpHist = static_cast<TH1 *>(stackHists->At(0)->Clone());
273 tmpHist->Reset();
274
275 for (int i = 0; i < stackHists->GetSize(); ++i) {
276 tmpHist->Add(static_cast<TH1 *>(stackHists->At(i)));
277 }
278
279 fHistDrawProxy = h1;
280
281 Init(h1, tmpHist, option);
282
283}
284
285////////////////////////////////////////////////////////////////////////////////
286/// Constructor for one histogram and a fit.
287///
288/// \param h1 The histogram
289/// \param option Steers the error calculation
290/// \param fitres Explicit fit result to be used for calculation. Uses last fit if left empty
291
293{
294 fH1 = h1;
295 if (!fH1) {
296 Warning("TRatioPlot", "Need a histogram.");
297 return;
298 }
299
300 Bool_t h1IsTH1 = fH1->InheritsFrom(TH1::Class());
301
302 if (!h1IsTH1) {
303 Warning("TRatioPlot", "Need a histogram deriving from TH2 or TH3.");
304 return;
305 }
306
307 TList *h1Functions = fH1->GetListOfFunctions();
308
309 if (h1Functions->GetSize() < 1) {
310 Warning("TRatioPlot", "Histogram given needs to have a (fit) function associated with it");
311 return;
312 }
313
314
315 fHistDrawProxy = h1;
316
317 fFitResult = fitres;
318
319 fMode = CalculationMode::kFitResidual;
320
321 TString optionString = option;
322
323 // determine which error style
324 if (optionString.Contains("errasym")) {
325 fErrorMode = ErrorMode::kErrorAsymmetric;
326 optionString.ReplaceAll("errasym", "");
327 }
328
329 if (optionString.Contains("errfunc")) {
330 fErrorMode = ErrorMode::kErrorFunc;
331 optionString.ReplaceAll("errfunc", "");
332 }
333
334 fOption = optionString;
335
336 if (!BuildLowerPlot()) return;
337
338 // emulate option behaviour of TH1
339 if (fH1->GetSumw2N() > 0) {
340 fH1DrawOpt = "E";
341 } else {
342 fH1DrawOpt = "hist";
343 }
344 fGraphDrawOpt = "LX"; // <- default
345
346 fSharedXAxis = static_cast<TAxis *>(fH1->GetXaxis()->Clone());
347 fUpYaxis = static_cast<TAxis *>(fH1->GetYaxis()->Clone());
348 fLowYaxis = static_cast<TAxis *>(fRatioGraph->GetYaxis()->Clone());
349
350 //SyncAxesRanges();
351
352 SetupPads();
353
354}
355
356////////////////////////////////////////////////////////////////////////////////
357/// Sets the drawing option for h1
358
360{
361 fH1DrawOpt = opt;
362}
363
364////////////////////////////////////////////////////////////////////////////////
365/// Sets the drawing option for h2
366
368{
369 TString optString = opt;
370 optString.ReplaceAll("same", "");
371 optString.ReplaceAll("SAME", "");
372
373 fH2DrawOpt = optString;
374}
375
376////////////////////////////////////////////////////////////////////////////////
377/// Sets the drawing option for the lower graph
378
380{
381 fGraphDrawOpt = opt;
382}
383
384////////////////////////////////////////////////////////////////////////////////
385/// Sets the drawing option for the fit in the fit residual case
386
388{
389 fFitDrawOpt = opt;
390}
391
392////////////////////////////////////////////////////////////////////////////////
393/// Setup the pads.
394
396{
397 // this method will delete all the pads before recreating them
398
399 if (fUpperPad) {
400 delete fUpperPad;
401 fUpperPad = nullptr;
402 }
403
404 if (fLowerPad) {
405 delete fLowerPad;
406 fLowerPad = nullptr;
407 }
408
409 if (!gPad) {
410 Error("SetupPads", "need to create a canvas first");
411 return;
412 }
413
414 double pm = fInsetWidth;
415 double width = gPad->GetWNDC();
416 double height = gPad->GetHNDC();
417 double f = height/width;
418
419 fUpperPad = new TPad("upper_pad", "", pm*f, fSplitFraction, 1.-pm*f, 1.-pm);
420 fLowerPad = new TPad("lower_pad", "", pm*f, pm, 1.-pm*f, fSplitFraction);
421
423
424 // connect to the pads signal
425
426 if (fTopPad) {
427 delete fTopPad;
428 fTopPad = nullptr;
429 }
430
431 fTopPad = new TPad("top_pad", "", pm*f, pm, 1-pm*f, 1-pm);
432
433 fTopPad->SetBit(kCannotPick);
434}
435
436////////////////////////////////////////////////////////////////////////////////
437/// Connect some signals from the pads to handle them
438/// Allows correctly work also after reading ratioplot from the file
439
441{
442 static const char *rangeSignal = "RangeAxisChanged()";
443
444 if (fUpperPad->HasConnection(rangeSignal) && fLowerPad->HasConnection(rangeSignal))
445 return;
446
447 fUpperPad->Connect(rangeSignal, ClassName(), this, "RangeAxisChanged()");
448 fLowerPad->Connect(rangeSignal, ClassName(), this, "RangeAxisChanged()");
449
450 fUpperPad->Connect("UnZoomed()", ClassName(), this, "UnZoomed()");
451 fLowerPad->Connect("UnZoomed()", ClassName(), this, "UnZoomed()");
452
453 fUpperPad->Connect("Resized()", ClassName(), this, "SubPadResized()");
454 fLowerPad->Connect("Resized()", ClassName(), this, "SubPadResized()");
455
456}
457
458////////////////////////////////////////////////////////////////////////////////
459/// Sets the top margin of the upper pad.
460///
461/// \param margin The new margin
462
464{
465 fUpTopMargin = margin;
467}
468
469////////////////////////////////////////////////////////////////////////////////
470/// Sets the bottom margin of the upper pad.
471///
472/// \param margin The new margin
473
475{
476 fUpBottomMargin = margin;
478}
479
480////////////////////////////////////////////////////////////////////////////////
481/// Sets the top margin of the lower pad.
482///
483/// \param margin The new margin
484
486{
487 fLowTopMargin = margin;
489}
490
491////////////////////////////////////////////////////////////////////////////////
492/// Sets the bottom margin of the lower pad.
493///
494/// \param margin The new margin
495
497{
498 fLowBottomMargin = margin;
500}
501
502////////////////////////////////////////////////////////////////////////////////
503/// Sets the left margin of both pads.
504/// \param margin The new margin
505
507{
508 fLeftMargin = margin;
510}
511
512////////////////////////////////////////////////////////////////////////////////
513/// Sets the right margin of both pads.
514///
515/// \param margin The new margin
516
518{
519 fRightMargin = margin;
521}
522
523////////////////////////////////////////////////////////////////////////////////
524/// Sets the margin that separates the two pads. The margin is split according
525/// to the relative sizes of the pads
526///
527/// \param margin The new margin
528///
529/// Begin_Macro(source)
530/// ../../../tutorials/hist/hist034_TRatioPlot_fit_margin.C
531/// End_Macro
532
534{
536 fUpBottomMargin = margin/2./(1-sf);
537 fLowTopMargin = margin/2./sf;
539}
540
541////////////////////////////////////////////////////////////////////////////////
542/// Return the separation margin value.
543
545{
547 Float_t up = fUpBottomMargin * (1-sf);
548 Float_t down = fLowTopMargin * sf;
549 return up+down;
550}
551
552////////////////////////////////////////////////////////////////////////////////
553/// Draws the ratio plot to the currently active pad. Therefore it requires that
554/// a TCanvas has been created first.
555///
556/// It takes the following options
557///
558/// | Option | Description |
559/// | ---------- | ------------------------------------------------------------ |
560/// | grid / nogrid | enable (default) or disable drawing of dashed lines on lower plot |
561/// | hideup | hides the first label of the upper axis if there is not enough space |
562/// | fhideup | always hides the first label of the upper axis |
563/// | hidelow (default) | hides the last label of the lower axis if there is not enough space |
564/// | fhidelow | always hides the last label of the lower axis |
565/// | nohide | does not hide a label if there is not enough space |
566/// | noconfint | does not draw the confidence interval bands in the fit residual case |
567/// | confint | draws the confidence interval bands in the fit residual case (default) |
568
569void TRatioPlot::Draw(Option_t *option)
570{
571
572 TString drawOpt = option;
573
574 if (drawOpt.Contains("nogrid")) {
575 drawOpt.ReplaceAll("nogrid", "");
577 } else if (drawOpt.Contains("grid")) {
578 drawOpt.ReplaceAll("grid", "");
580 }
581
582 if (drawOpt.Contains("noconfint")) {
583 drawOpt.ReplaceAll("noconfint", "");
585 } else if (drawOpt.Contains("confint")) {
586 drawOpt.ReplaceAll("confint", "");
587 fShowConfidenceIntervals = kTRUE; // <- default
588 }
589
590 if (drawOpt.Contains("fhideup")) {
592 } else if (drawOpt.Contains("fhidelow")) {
594 } else if (drawOpt.Contains("hideup")) {
596 } else if (drawOpt.Contains("hidelow")) {
598 } else if (drawOpt.Contains("nohide")) {
600 } else {
602 }
603
604 if (!gPad) {
605 Error("Draw", "need to create a canvas first");
606 return;
607 }
608
610
611 // draw ratio plot as very first object
612 // when painting one can update all attributes before other objects are painted
613 AppendPad();
614
615 fUpperPad->SetLogy(fParentPad->GetLogy());
616 fUpperPad->SetLogx(fParentPad->GetLogx());
617 fLowerPad->SetLogx(fParentPad->GetLogx());
618
619 fUpperPad->SetGridx(fParentPad->GetGridx());
620 fUpperPad->SetGridy(fParentPad->GetGridy());
621 fLowerPad->SetGridx(fParentPad->GetGridx());
622 fLowerPad->SetGridy(fParentPad->GetGridy());
623
624 // we are a TPad
625
626 fUpperPad->Draw();
627 fLowerPad->Draw();
628
629 fTopPad->SetFillStyle(0);
630 fTopPad->Draw();
631
632 fUpperPad->cd();
633
634 fConfidenceInterval1->SetFillColor(fCi1Color);
635 fConfidenceInterval2->SetFillColor(fCi2Color);
636
638 // use last function in the list
639 TF1 *func = nullptr;
640 for (int i = fH1->GetListOfFunctions()->GetSize()-1; i >= 0; i--) {
641 auto obj = fH1->GetListOfFunctions()->At(i);
642 if (obj->InheritsFrom(TF1::Class()) ) {
643 func = dynamic_cast<TF1*>(obj);
644 break;
645 }
646 }
647 if (!func) {
648 // this is checked in constructor and should thus not occur
649 Error("Draw", "h1 does not have a fit function");
650 return;
651 }
652
653 fH1->Draw("A"+fH1DrawOpt);
654 func->Draw(fFitDrawOpt+"same");
655
656 fLowerPad->cd();
657
659 fConfidenceInterval2->Draw("IA3");
660 fConfidenceInterval1->Draw("3");
661 fRatioGraph->Draw(fGraphDrawOpt+"SAME");
662 } else {
663 fRatioGraph->Draw("IA"+fGraphDrawOpt+"SAME");
664 }
665 } else {
666
667 if (fHistDrawProxy) {
668 if (fHistDrawProxyStack || fHistDrawProxy->InheritsFrom(TH1::Class())) {
669 fHistDrawProxy->Draw("A"+fH1DrawOpt);
670 } else {
671 Warning("Draw", "Draw proxy not of type TH1 or THStack, not drawing it");
672 }
673 }
674
675 fH2->Draw("A"+fH2DrawOpt+"same");
676
677 fLowerPad->cd();
678
679 TString opt = fGraphDrawOpt;
680 fRatioGraph->Draw("IA"+fGraphDrawOpt);
681
682 }
683
684 // assign same axis ranges to lower pad as in upper pad
685 // the visual axes will be created on paint
687
689
691
692 // restore active pad at the end
693 fParentPad->cd();
694
695 // only after object drawn connect signals
697}
698
699////////////////////////////////////////////////////////////////////////////////
700/// Returns the reference graph for the lower pad, which means the graph that
701/// is responsible for setting the coordinate system. It is the first graph
702/// added to the primitive list of the lower pad.
703/// This reference can be used to set the minimum and maximum of the lower pad.
704/// Note that `TRatioPlot::Draw` needs to have been called first, since the
705/// graphs are only created then.
706///
707/// Begin_Macro(source)
708/// ../../../tutorials/hist/hist031_TRatioPlot_residual_fit.C
709/// End_Macro
710
712{
713 if (!fLowerPad) {
714 Error("GetLowerRefGraph", "Lower pad has not been defined");
715 return nullptr;
716 }
717
718 TList *primlist = fLowerPad->GetListOfPrimitives();
719 if (primlist->GetSize() == 0) {
720 Error("GetLowerRefGraph", "Lower pad does not have primitives");
721 return nullptr;
722 }
723
724 TObjLink *lnk = primlist->FirstLink();
725
726 while (lnk) {
727 TObject *obj = lnk->GetObject();
728
729 if (obj->InheritsFrom(TGraph::Class()))
730 return static_cast<TGraph *>(obj);
731
732 lnk = lnk->Next();
733 }
734
735 Error("GetLowerRefGraph", "Did not find graph in list");
736 return nullptr;
737}
738
739////////////////////////////////////////////////////////////////////////////////
740/// Return the reference object. Its the first TH1 or THStack type object
741/// in the upper pads list of primitives.
742/// Note that it returns a `TObject`, so you need to test and cast it to use it.
743
745{
746 TList *primlist = fUpperPad->GetListOfPrimitives();
747 for (Int_t i = 0; i < primlist->GetSize(); ++i) {
748 auto refobj = primlist->At(i);
749 if (refobj->InheritsFrom(TH1::Class()) || refobj->InheritsFrom(THStack::Class())) {
750 return refobj;
751 }
752 }
753
754 Error("GetUpperRefObject", "No upper ref object of TH1 or THStack type found");
755 return nullptr;
756}
757
758////////////////////////////////////////////////////////////////////////////////
759/// Gets the x axis of the object returned by `TRatioPlot::GetUpperRefObject`.
760
762{
763 TObject *refobj = GetUpperRefObject();
764
765 if (!refobj)
766 return nullptr;
767
768 if (refobj->InheritsFrom(TH1::Class())) {
769 return static_cast<TH1 *>(refobj)->GetXaxis();
770 } else if (refobj->InheritsFrom(THStack::Class())) {
771 return static_cast<THStack *>(refobj)->GetXaxis();
772 }
773
774 return nullptr;
775}
776
777////////////////////////////////////////////////////////////////////////////////
778/// Gets the y axis of the object returned by `TRatioPlot::GetUpperRefObject`.
779
781{
782 TObject *refobj = GetUpperRefObject();
783
784 if (!refobj)
785 return nullptr;
786
787 if (refobj->InheritsFrom(TH1::Class())) {
788 return static_cast<TH1 *>(refobj)->GetYaxis();
789 } else if (refobj->InheritsFrom(THStack::Class())) {
790 return static_cast<THStack *>(refobj)->GetYaxis();
791 }
792
793 return nullptr;
794}
795
796////////////////////////////////////////////////////////////////////////////////
797/// Gets the x axis of the lower ref graph.
798/// Shortcut for:
799///
800/// ~~~{.cpp}
801/// rp->GetLowerRefGraph()->GetXaxis();
802/// ~~~
803
805{
806 auto gr = GetLowerRefGraph();
807 return gr ? gr->GetXaxis() : nullptr;
808}
809
810////////////////////////////////////////////////////////////////////////////////
811/// Gets the y axis of the lower ref graph.
812/// Shortcut for:
813///
814/// ~~~{.cpp}
815/// rp->GetLowerRefGraph()->GetYaxis();
816/// ~~~
817
819{
820 auto gr = GetLowerRefGraph();
821 return gr ? gr->GetYaxis() : nullptr;
822}
823
824////////////////////////////////////////////////////////////////////////////////
825/// Create a grid lines
826
828{
829
830 if (!fShowGridlines)
831 return; // don't draw them
832
833 while (fGridlines.size() < fGridlinePositions.size()) {
834 TLine *newline = new TLine(0, 0, 0, 0);
835 newline->SetLineStyle(2);
836 fLowerPad->Add(newline);
837 fGridlines.emplace_back(newline);
838 }
839
841}
842
843////////////////////////////////////////////////////////////////////////////////
844/// Update positions of grid lines
845
847{
848 Double_t first = fSharedXAxis->GetBinLowEdge(fSharedXAxis->GetFirst());
849 Double_t last = fSharedXAxis->GetBinUpEdge(fSharedXAxis->GetLast());
850
851 Double_t lowYFirst = fLowerPad->GetUymin();
852 Double_t lowYLast = fLowerPad->GetUymax();
853
854 for (size_t i = 0; i < fGridlines.size(); ++i) {
855 auto line = fGridlines.at(i);
856 Bool_t visible = kFALSE;
857 Double_t y = 0.;
858 if (i < fGridlinePositions.size()) {
860 visible = (y >= lowYFirst && y <= lowYLast);
861 }
862
863 if (visible) {
864 line->SetX1(first);
865 line->SetX2(last);
866 line->SetY1(y);
867 line->SetY2(y);
868 } else {
869 line->SetX1(first);
870 line->SetX2(first);
871 line->SetY1(lowYFirst);
872 line->SetY2(lowYFirst);
873 }
874 }
875}
876
877
878////////////////////////////////////////////////////////////////////////////////
879/// Update the visual axes and grid lines when painting
880
881void TRatioPlot::Paint(Option_t * /*opt*/)
882{
883 // painting invoked before object drawn to the end - just ignore here
884 if (!fUpperGXaxis)
885 return;
886
888
891
892 // in any case reset flag after painting
894}
895
896////////////////////////////////////////////////////////////////////////////////
897/// Syncs the axes ranges from the shared ones to the actual ones.
898
900{
901 // get ranges from the shared axis clone
902 Double_t first = fSharedXAxis->GetBinLowEdge(fSharedXAxis->GetFirst());
903 Double_t last = fSharedXAxis->GetBinUpEdge(fSharedXAxis->GetLast());
904
905 // set range on computed graph, have to set it twice because
906 // TGraph's axis looks strange otherwise
907 TAxis *ref = GetLowerRefXaxis();
908 ref->SetLimits(first, last);
909 ref->SetRangeUser(first, last);
910
911 GetUpperRefXaxis()->SetRangeUser(first, last);
912}
913
914////////////////////////////////////////////////////////////////////////////////
915/// Build the lower plot according to which constructor was called, and
916/// which options were passed.
917
919{
920 static const char *thisMethod = "BuildLowerPlot";
921
922 // Clear and delete the graph if not exists
923 if (fRatioGraph) {
924 delete fRatioGraph;
925 fRatioGraph = nullptr;
926 }
927
929 fConfidenceInterval1 = new TGraphErrors();
930
932 fConfidenceInterval2 = new TGraphErrors();
933
934 static Double_t divideGridlines[] = {0.7, 1.0, 1.3};
935 static Double_t diffGridlines[] = {0.0};
936 static Double_t signGridlines[] = {1.0, 0.0, -1.0};
937
938 // Determine the divide mode and create the lower graph accordingly
939 // Pass divide options given in constructor
941 // use TGraphAsymmErrors Divide method to create
942
943 SetGridlines(divideGridlines, 3);
944
945 TH1 *tmpH1 = static_cast<TH1 *>(fH1->Clone());
946 TH1 *tmpH2 = static_cast<TH1 *>(fH2->Clone());
947
948 tmpH1->Scale(fC1);
949 tmpH2->Scale(fC2);
950
951 TGraphAsymmErrors *ratioGraph = new TGraphAsymmErrors();
952 ratioGraph->Divide(tmpH1, tmpH2, fOption.Data());
953 fRatioGraph = ratioGraph;
954
955 delete tmpH1;
956 delete tmpH2;
957
958 } else if (fMode == CalculationMode::kDifference) {
959 SetGridlines(diffGridlines, 3);
960
961 TH1 *tmpHist = static_cast<TH1 *>(fH1->Clone());
962
963 tmpHist->Reset();
964
965 tmpHist->Add(fH1, fH2, fC1, -1*fC2);
966 fRatioGraph = new TGraphErrors(tmpHist);
967
968 delete tmpHist;
970
971 SetGridlines(signGridlines, 3);
972
973 fRatioGraph = new TGraphAsymmErrors();
974 Int_t ipoint = 0;
975
976 for (Int_t i = 0; i <= fH1->GetNbinsX(); ++i) {
977 Double_t val = fH1->GetBinContent(i);
978 Double_t val2 = fH2->GetBinContent(i);
979 Double_t error = 0.;
980
982
983 Double_t errUp = fH1->GetBinErrorUp(i);
984 Double_t errLow = fH1->GetBinErrorLow(i);
985
986 if (val - val2 > 0) {
987 // h1 > h2
988 error = errLow;
989 } else {
990 // h1 < h2
991 error = errUp;
992 }
993
995 error = fH1->GetBinError(i);
996 } else {
997 Warning(thisMethod, "error mode is invalid");
998 }
999
1000 if (error != 0.) {
1001
1002 Double_t res = (val - val2) / error;
1003
1004 ((TGraphAsymmErrors*)fRatioGraph)->SetPoint(ipoint, fH1->GetBinCenter(i), res);
1005 ((TGraphAsymmErrors*)fRatioGraph)->SetPointError(ipoint, fH1->GetBinWidth(i)/2., fH1->GetBinWidth(i)/2., 0.5, 0.5);
1006
1007 ++ipoint;
1008
1009 }
1010 }
1011
1012 } else if (fMode == CalculationMode::kFitResidual) {
1013
1014 SetGridlines(signGridlines, 3);
1015
1016 TF1 *func = dynamic_cast<TF1*>(fH1->GetListOfFunctions()->At(0));
1017
1018 if (!func) {
1019 // this is checked in constructor and should thus not occur
1020 Error(thisMethod, "h1 does not have a fit function");
1021 return 0;
1022 }
1023
1024 fRatioGraph = new TGraphAsymmErrors();
1025 Int_t ipoint = 0;
1026
1027 std::vector<double> ci1, ci2;
1028
1029 Int_t nbinsx = fH1->GetNbinsX();
1030
1031 std::vector<Double_t> x_arr(nbinsx, 0.), ci_arr1(nbinsx, 0.), ci_arr2(nbinsx, 0);
1032 for (Int_t i = 0; i < nbinsx; ++i)
1033 x_arr[i] = fH1->GetBinCenter(i+1);
1034
1035 Double_t cl1 = fCl1, cl2 = fCl2;
1036
1037 if (fFitResult) {
1038 // use this to get conf int
1039
1040 fFitResult->GetConfidenceIntervals(nbinsx, 1, 1, x_arr.data(), ci_arr1.data(), cl1);
1041 for (Int_t i = 1; i <= nbinsx; ++i)
1042 ci1.push_back(ci_arr1[i - 1]);
1043
1044 fFitResult->GetConfidenceIntervals(nbinsx, 1, 1, x_arr.data(), ci_arr2.data(), cl2);
1045 for (Int_t i = 1; i <= nbinsx; ++i)
1046 ci2.push_back(ci_arr2[i - 1]);
1047 } else {
1048 TVirtualFitter::GetFitter()->GetConfidenceIntervals(nbinsx, 1, x_arr.data(), ci_arr1.data(), cl1);
1049 for (Int_t i = 1; i <= nbinsx; ++i)
1050 ci1.push_back(ci_arr1[i - 1]);
1051 TVirtualFitter::GetFitter()->GetConfidenceIntervals(nbinsx, 1, x_arr.data(), ci_arr2.data(), cl2);
1052 for (Int_t i = 1; i <= nbinsx; ++i)
1053 ci2.push_back(ci_arr2[i - 1]);
1054 }
1055
1056 for (Int_t i = 1; i <= nbinsx; ++i) {
1057 Double_t val = fH1->GetBinContent(i);
1058 Double_t x = fH1->GetBinCenter(i);
1059 Double_t error = 0.;
1060
1062
1063 Double_t errUp = fH1->GetBinErrorUp(i);
1064 Double_t errLow = fH1->GetBinErrorLow(i);
1065
1066 if (val - func->Eval(fH1->GetBinCenter(i)) > 0) {
1067 // h1 > fit
1068 error = errLow;
1069 } else {
1070 // h1 < fit
1071 error = errUp;
1072 }
1073
1074 } else if (fErrorMode == ErrorMode::kErrorSymmetric) {
1075
1076 error = fH1->GetBinError(i);
1077
1078 } else if (fErrorMode == ErrorMode::kErrorFunc) {
1079
1080 error = sqrt(func->Eval(x));
1081
1082 } else {
1083
1084 Warning(thisMethod, "error mode is invalid");
1085
1086 }
1087
1088 if (error != 0.) {
1089
1090 Double_t res = (fH1->GetBinContent(i) - func->Eval(fH1->GetBinCenter(i))) / error;
1091
1092 ((TGraphAsymmErrors*)fRatioGraph)->SetPoint(ipoint, fH1->GetBinCenter(i), res);
1093 ((TGraphAsymmErrors*)fRatioGraph)->SetPointError(ipoint, fH1->GetBinWidth(i)/2., fH1->GetBinWidth(i)/2., 0.5, 0.5);
1094
1095 fConfidenceInterval1->SetPoint(ipoint, x, 0);
1096 fConfidenceInterval1->SetPointError(ipoint, x, i <= (Int_t)ci1.size() ? ci1[i-1] / error : 0);
1097 fConfidenceInterval2->SetPoint(ipoint, x, 0);
1098 fConfidenceInterval2->SetPointError(ipoint, x, i <= (Int_t)ci2.size() ? ci2[i-1] / error : 0);
1099
1100 ++ipoint;
1101
1102 }
1103 }
1104 } else if (fMode == CalculationMode::kDivideHist){
1105 SetGridlines(divideGridlines, 3);
1106
1107 // Use TH1's Divide method
1108 TH1 *tmpHist = static_cast<TH1 *>(fH1->Clone());
1109 tmpHist->Reset();
1110
1111 tmpHist->Divide(fH1, fH2, fC1, fC2, fOption.Data());
1112 fRatioGraph = new TGraphErrors(tmpHist);
1113
1114 delete tmpHist;
1115 } else {
1116 // this should not occur
1117 Error(thisMethod, "Invalid fMode value");
1118 return 0;
1119 }
1120
1121 // need to set back to "" since recreation. we don't ever want
1122 // title on lower graph
1123
1124 if (!fRatioGraph) {
1125 Error(thisMethod, "Error creating lower graph");
1126 return 0;
1127 }
1128
1129 fRatioGraph->SetTitle("");
1130 fConfidenceInterval1->SetTitle("");
1131 fConfidenceInterval2->SetTitle("");
1132
1133 return 1;
1134}
1135
1136////////////////////////////////////////////////////////////////////////////////
1137/// Creates the TGaxis objects that are used for consistent display of the axes.
1138
1140{
1141 Bool_t mirroredAxes = fParentPad->GetFrameFillStyle() == 0;
1142 Bool_t axistop = fParentPad->GetTickx() == 1 || mirroredAxes;
1143 Bool_t axisright = fParentPad->GetTicky() == 1 || mirroredAxes;
1144
1145 Double_t first = fSharedXAxis->GetBinLowEdge(fSharedXAxis->GetFirst());
1146 Double_t last = fSharedXAxis->GetBinUpEdge(fSharedXAxis->GetLast());
1147
1148 Double_t upYFirst = fUpperPad->GetUymin();
1149 Double_t upYLast = fUpperPad->GetUymax();
1150 Double_t lowYFirst = fLowerPad->GetUymin();
1151 Double_t lowYLast = fLowerPad->GetUymax();
1152
1153 if (!fUpperGXaxis) {
1154 fUpperGXaxis = new TGaxis(0, 0, 1, 1, 0, 1, 510, "+U");
1155 fTopPad->Add(fUpperGXaxis);
1156 }
1157
1158 if (!fUpperGYaxis) {
1159 fUpperGYaxis = new TGaxis(0, 0, 1, 1, upYFirst, upYLast, 510, "S");
1160 fTopPad->Add(fUpperGYaxis);
1161 }
1162
1163 if (!fLowerGXaxis) {
1164 fLowerGXaxis = new TGaxis(0, 0, 1, 1, first, last, 510, "+S");
1165 fTopPad->Add(fLowerGXaxis);
1166 }
1167
1168 if (!fLowerGYaxis) {
1169 fLowerGYaxis = new TGaxis(0, 0, 1, 1, lowYFirst, lowYLast, 510, "-S");
1170 fTopPad->Add(fLowerGYaxis);
1171 }
1172
1173 // Create the axes on the other sides of the graphs
1174 // This is steered by an option on the containing pad or self
1175
1176 if (!fUpperGXaxisMirror && axistop) {
1177 fUpperGXaxisMirror = static_cast<TGaxis *>(fUpperGXaxis->Clone());
1179 }
1180
1181 if (!fLowerGXaxisMirror && axistop) {
1182 fLowerGXaxisMirror = static_cast<TGaxis *>(fLowerGXaxis->Clone());
1184 }
1185
1186 if (!fUpperGYaxisMirror && axisright) {
1187 fUpperGYaxisMirror = static_cast<TGaxis *>(fUpperGYaxis->Clone());
1189 }
1190
1191 if (!fLowerGYaxisMirror && axisright) {
1192 fLowerGYaxisMirror = static_cast<TGaxis *>(fLowerGYaxis->Clone());
1194 }
1195
1197}
1198
1199
1200////////////////////////////////////////////////////////////////////////////////
1201/// Update TGaxis attributes
1202
1204{
1205 // this is for errors
1206 static const char *thisMethod = "UpdateVisualAxes";
1207
1208 // figure out where the axis has to go.
1209 // Implicit assumption is, that the top pad spans the full other pads
1210 Double_t upTM = fUpperPad->GetTopMargin();
1211 Double_t upBM = fUpperPad->GetBottomMargin();
1212 Double_t upLM = fUpperPad->GetLeftMargin();
1213 Double_t upRM = fUpperPad->GetRightMargin();
1214
1215 Double_t lowTM = fLowerPad->GetTopMargin();
1216 Double_t lowBM = fLowerPad->GetBottomMargin();
1217 Double_t lowLM = fLowerPad->GetLeftMargin();
1218 Double_t lowRM = fLowerPad->GetRightMargin();
1219
1220 Double_t first = fSharedXAxis->GetBinLowEdge(fSharedXAxis->GetFirst());
1221 Double_t last = fSharedXAxis->GetBinUpEdge(fSharedXAxis->GetLast());
1222
1223 Double_t upYFirst = fUpperPad->GetUymin();
1224 Double_t upYLast = fUpperPad->GetUymax();
1225 Double_t lowYFirst = fLowerPad->GetUymin();
1226 Double_t lowYLast = fLowerPad->GetUymax();
1227
1229
1230 Bool_t logx = fUpperPad->GetLogx() || fLowerPad->GetLogx();
1231 Bool_t uplogy = fUpperPad->GetLogy();
1232 Bool_t lowlogy = fLowerPad->GetLogy();
1233
1234 if (uplogy) {
1235
1236 upYFirst = TMath::Power(10, upYFirst);
1237 upYLast = TMath::Power(10, upYLast);
1238
1239 if (upYFirst <= 0 || upYLast <= 0) {
1240 Error(thisMethod, "Cannot set upper Y axis to log scale");
1241 }
1242 }
1243
1244 if (lowlogy) {
1245 lowYFirst = TMath::Power(10, lowYFirst);
1246 lowYLast = TMath::Power(10, lowYLast);
1247
1248 if (lowYFirst <= 0 || lowYLast <= 0) {
1249 Error(thisMethod, "Cannot set lower Y axis to log scale");
1250 }
1251
1252 }
1253
1254 // this is different than in y, y already has pad coords converted, x not...
1255 if (logx) {
1256 if (first <= 0 || last <= 0) {
1257 Error(thisMethod, "Cannot set X axis to log scale");
1258 }
1259 }
1260
1261 // determine axes options to create log axes if needed
1262 TString xopt = logx ? "G" : "";
1263 TString upyopt = uplogy ? "G" : "";
1264 TString lowyopt = lowlogy ? "G" : "";
1265
1266 // import infos from TAxis
1271
1272 // lower x axis needs to get title from upper x
1273 fLowerGXaxis->SetTitle(fUpperGXaxis->GetTitle());
1274
1275 // (re)set all the axes properties to what we want them
1276 fUpperGXaxis->SetTitle("");
1277
1278 fUpperGXaxis->SetX1(upLM);
1279 fUpperGXaxis->SetX2(1-upRM);
1280 fUpperGXaxis->SetY1(upBM*(1-sf)+sf);
1281 fUpperGXaxis->SetY2(upBM*(1-sf)+sf);
1282 fUpperGXaxis->SetWmin(first);
1283 fUpperGXaxis->SetWmax(last);
1284
1285 fUpperGYaxis->SetX1(upLM);
1286 fUpperGYaxis->SetX2(upLM);
1287 fUpperGYaxis->SetY1(upBM*(1-sf)+sf);
1288 fUpperGYaxis->SetY2( (1-upTM)*(1-sf)+sf );
1289 fUpperGYaxis->SetWmin(upYFirst);
1290 fUpperGYaxis->SetWmax(upYLast);
1291
1292 fLowerGXaxis->SetX1(lowLM);
1293 fLowerGXaxis->SetX2(1-lowRM);
1294 fLowerGXaxis->SetY1(lowBM*sf);
1295 fLowerGXaxis->SetY2(lowBM*sf);
1296 fLowerGXaxis->SetWmin(first);
1297 fLowerGXaxis->SetWmax(last);
1298
1299 fLowerGYaxis->SetX1(lowLM);
1300 fLowerGYaxis->SetX2(lowLM);
1301 fLowerGYaxis->SetY1(lowBM*sf);
1302 fLowerGYaxis->SetY2((1-lowTM)*sf);
1303 fLowerGYaxis->SetWmin(lowYFirst);
1304 fLowerGYaxis->SetWmax(lowYLast);
1305
1306 fUpperGXaxis->SetNdivisions(fSharedXAxis->GetNdivisions());
1307 fUpperGYaxis->SetNdivisions(fUpYaxis->GetNdivisions());
1308 fLowerGXaxis->SetNdivisions(fSharedXAxis->GetNdivisions());
1309 fLowerGYaxis->SetNdivisions(fLowYaxis->GetNdivisions());
1310
1311 fUpperGXaxis->SetOption("+U"+xopt);
1312 fUpperGYaxis->SetOption("S"+upyopt);
1313 fLowerGXaxis->SetOption("+S"+xopt);
1314 fLowerGYaxis->SetOption("-S"+lowyopt);
1315
1316 // normalize the tick sizes. y axis ticks should be consistent
1317 // even if their length is different
1318 Double_t ratio = ( (upBM-(1-upTM))*(1-sf) ) / ( (lowBM-(1-lowTM))*sf );
1319 fUpperGXaxis->SetLabelSize(0.);
1320 Double_t ticksize = fUpperGYaxis->GetTickSize()*ratio;
1321 fLowerGYaxis->SetTickSize(ticksize);
1322
1324
1325 fUpperGYaxis->ChangeLabel(1, -1, 0);
1326
1328
1329 fLowerGYaxis->ChangeLabel(-1, -1, 0);
1330
1331 } else {
1332 if (GetSeparationMargin() < 0.025) {
1333
1336 fUpperGYaxis->ChangeLabel(1, -1, 0);
1338 fLowerGYaxis->ChangeLabel(-1, -1, 0);
1339 }
1340 }
1341
1342 } else {
1343 // reset
1345 fUpperGYaxis->ChangeLabel(0);
1347 fLowerGYaxis->ChangeLabel(0);
1348 }
1349
1350 }
1351 }
1352
1353 // move them about and set required positions
1354 if (fUpperGXaxisMirror) {
1356 fUpperGXaxisMirror->SetTitle("");
1357 fUpperGXaxisMirror->SetX1(upLM);
1358 fUpperGXaxisMirror->SetX2(1-upRM);
1359 fUpperGXaxisMirror->SetY1((1-upTM)*(1-sf)+sf);
1360 fUpperGXaxisMirror->SetY2((1-upTM)*(1-sf)+sf);
1361 fUpperGXaxisMirror->SetWmin(first);
1362 fUpperGXaxisMirror->SetWmax(last);
1363 fUpperGXaxisMirror->SetOption("-S"+xopt);
1364 fUpperGXaxisMirror->SetNdivisions(fSharedXAxis->GetNdivisions());
1365 fUpperGXaxisMirror->SetLabelSize(0.);
1366 }
1367
1368 if (fUpperGYaxisMirror) {
1370 fUpperGYaxisMirror->SetTitle("");
1371 fUpperGYaxisMirror->SetX1(1-upRM);
1372 fUpperGYaxisMirror->SetX2(1-upRM);
1373 fUpperGYaxisMirror->SetY1(upBM*(1-sf)+sf);
1374 fUpperGYaxisMirror->SetY2( (1-upTM)*(1-sf)+sf );
1375 fUpperGYaxisMirror->SetWmin(upYFirst);
1376 fUpperGYaxisMirror->SetWmax(upYLast);
1377 fUpperGYaxisMirror->SetOption("+S"+upyopt);
1378 fUpperGYaxisMirror->SetNdivisions(fUpYaxis->GetNdivisions());
1379 fUpperGYaxisMirror->SetLabelSize(0.);
1380 }
1381
1382 if (fLowerGXaxisMirror) {
1384 fLowerGXaxisMirror->SetTitle("");
1385 fLowerGXaxisMirror->SetX1(lowLM);
1386 fLowerGXaxisMirror->SetX2(1-lowRM);
1387 fLowerGXaxisMirror->SetY1((1-lowTM)*sf);
1388 fLowerGXaxisMirror->SetY2((1-lowTM)*sf);
1389 fLowerGXaxisMirror->SetWmin(first);
1390 fLowerGXaxisMirror->SetWmax(last);
1391 fLowerGXaxisMirror->SetOption("-S"+xopt);
1392 fLowerGXaxisMirror->SetNdivisions(fSharedXAxis->GetNdivisions());
1393 fLowerGXaxisMirror->SetLabelSize(0.);
1394 }
1395
1396 if (fLowerGYaxisMirror) {
1398 fLowerGYaxisMirror->SetTitle("");
1399 fLowerGYaxisMirror->SetX1(1-lowRM);
1400 fLowerGYaxisMirror->SetX2(1-lowRM);
1401 fLowerGYaxisMirror->SetY1(lowBM*sf);
1402 fLowerGYaxisMirror->SetY2((1-lowTM)*sf);
1403 fLowerGYaxisMirror->SetWmin(lowYFirst);
1404 fLowerGYaxisMirror->SetWmax(lowYLast);
1405 fLowerGYaxisMirror->SetOption("+S"+lowyopt);
1406 fLowerGYaxisMirror->SetTickSize(ticksize);
1407 fLowerGYaxisMirror->SetNdivisions(fLowYaxis->GetNdivisions());
1408 fLowerGYaxisMirror->SetLabelSize(0.);
1409 }
1410
1411}
1412
1413////////////////////////////////////////////////////////////////////////////////
1414/// Sets the margins of all the pads to the value specified in class members.
1415/// This one is called whenever those are changed, e.g. in setters
1416
1418{
1419 fUpperPad->SetTopMargin(fUpTopMargin);
1420 fUpperPad->SetBottomMargin(fUpBottomMargin);
1421 fUpperPad->SetLeftMargin(fLeftMargin);
1422 fUpperPad->SetRightMargin(fRightMargin);
1423 fLowerPad->SetTopMargin(fLowTopMargin);
1424 fLowerPad->SetBottomMargin(fLowBottomMargin);
1425 fLowerPad->SetLeftMargin(fLeftMargin);
1426 fLowerPad->SetRightMargin(fRightMargin);
1427}
1428
1429////////////////////////////////////////////////////////////////////////////////
1430/// Figures out which pad margin has deviated from the stored ones,
1431/// to figure out what the new nominal is and set the other pad to it
1432/// subsequently.
1433
1435{
1436 Bool_t horizontalChanged = kFALSE, verticalChanged = kFALSE;
1437
1438 if (fUpperPad->GetLeftMargin() != fLeftMargin) {
1439 fLeftMargin = fUpperPad->GetLeftMargin();
1440 horizontalChanged = kTRUE;
1441 } else if (fLowerPad->GetLeftMargin() != fLeftMargin) {
1442 fLeftMargin = fLowerPad->GetLeftMargin();
1443 horizontalChanged = kTRUE;
1444 }
1445
1446 if (fUpperPad->GetRightMargin() != fRightMargin) {
1447 fRightMargin = fUpperPad->GetRightMargin();
1448 horizontalChanged = kTRUE;
1449 } else if (fLowerPad->GetRightMargin() != fRightMargin) {
1450 fRightMargin = fLowerPad->GetRightMargin();
1451 horizontalChanged = kTRUE;
1452 }
1453
1454
1455 if (fUpperPad->GetBottomMargin() != fUpBottomMargin) {
1456 fUpBottomMargin = fUpperPad->GetBottomMargin();
1457 verticalChanged = kTRUE;
1458 }
1459
1460 if (fLowerPad->GetTopMargin() != fLowTopMargin) {
1461 fLowTopMargin = fLowerPad->GetTopMargin();
1462 verticalChanged = kTRUE;
1463 }
1464
1465 if (fLowerPad->GetBottomMargin() != fLowBottomMargin) {
1466 fLowBottomMargin = fLowerPad->GetBottomMargin();
1467 verticalChanged = kTRUE;
1468 }
1469
1470 if (fUpperPad->GetTopMargin() != fUpTopMargin) {
1471 fUpTopMargin = fUpperPad->GetTopMargin();
1472 }
1473
1474 // only reset margins, if any of the margins changed
1475 if (horizontalChanged || verticalChanged)
1476 SetPadMargins();
1477
1478 return horizontalChanged || verticalChanged;
1479}
1480
1481////////////////////////////////////////////////////////////////////////////////
1482/// Slot that receives the RangeAxisChanged signal from any of the pads and
1483/// reacts correspondingly.
1484
1486{
1487 // Only run this concurrently once, in case it's called async
1488 if (fIsUpdating)
1489 return;
1490
1492
1493 // find out if logx has changed
1494 if (fParentPad->GetLogx()) {
1495 if (!fUpperPad->GetLogx() || !fLowerPad->GetLogx()) {
1496 fParentPad->SetLogx(kFALSE);
1497 }
1498 } else {
1499 if (fUpperPad->GetLogx() || fLowerPad->GetLogx()) {
1500 fParentPad->SetLogx(kTRUE);
1501 }
1502 }
1503
1504 // set log to pads
1505 if (fUpperPad->GetLogx() != fParentPad->GetLogx())
1506 fUpperPad->SetLogx(fParentPad->GetLogx());
1507 if (fLowerPad->GetLogx() != fParentPad->GetLogx())
1508 fLowerPad->SetLogx(fParentPad->GetLogx());
1509
1510 // get axis ranges for upper and lower
1511 TAxis *uprefx = GetUpperRefXaxis();
1512 Double_t upFirst = uprefx->GetBinLowEdge(uprefx->GetFirst());
1513 Double_t upLast = uprefx->GetBinUpEdge(uprefx->GetLast());
1514
1515 TAxis *lowrefx = GetLowerRefXaxis();
1516 Double_t lowFirst = lowrefx->GetBinLowEdge(lowrefx->GetFirst());
1517 Double_t lowLast = lowrefx->GetBinUpEdge(lowrefx->GetLast());
1518
1519 Double_t globFirst = fSharedXAxis->GetBinLowEdge(fSharedXAxis->GetFirst());
1520 Double_t globLast = fSharedXAxis->GetBinUpEdge(fSharedXAxis->GetLast());
1521
1522 Bool_t upChanged = kFALSE;
1523 Bool_t lowChanged = kFALSE;
1524
1525 // determine which one has changed
1526 if (upFirst != globFirst || upLast != globLast) {
1527 fSharedXAxis->SetRangeUser(upFirst, upLast);
1528 upChanged = kTRUE;
1529 } else if (lowFirst != globFirst || lowLast != globLast) {
1530 fSharedXAxis->SetRangeUser(lowFirst, lowLast);
1531 lowChanged = kTRUE;
1532 }
1533
1534 if (upChanged || lowChanged)
1536
1537 // sync the margins in case the user has dragged one of them
1538 Bool_t marginsChanged = SyncPadMargins();
1539
1540 if (upChanged || lowChanged || marginsChanged) {
1541 fUpperPad->Modified();
1542 fLowerPad->Modified();
1543 fTopPad->Modified();
1544 fParentPad->Modified();
1545 }
1546
1550}
1551
1552////////////////////////////////////////////////////////////////////////////////
1553/// Slot for the UnZoomed signal that was introduced to TPad.
1554/// Unzoom both pads
1555
1557{
1558 if (fIsUpdating)
1559 return;
1560
1562
1563 // this is what resets the range
1564 fSharedXAxis->SetRange(0, 0);
1566
1567 // Flushing
1568 fUpperPad->Modified();
1569 fLowerPad->Modified();
1570 fTopPad->Modified();
1571 fParentPad->Modified();
1572
1574}
1575
1576////////////////////////////////////////////////////////////////////////////////
1577/// Slot that handles common resizing of upper and lower pad.
1578
1580{
1581 if (fIsUpdating)
1582 return;
1583
1585
1586 Float_t upylow = fUpperPad->GetYlowNDC();
1587 Float_t lowylow = fLowerPad->GetYlowNDC();
1588 Float_t lowh = fLowerPad->GetHNDC();
1589 Float_t lowyup = lowylow + lowh;
1590
1591 Bool_t changed = kFALSE;
1592
1593 if (upylow != fSplitFraction) {
1594 // up changed
1595 SetSplitFraction(upylow);
1596 changed = kTRUE;
1597 } else if (lowyup != fSplitFraction) {
1598 // low changed
1599 SetSplitFraction(lowyup);
1600 changed = kTRUE;
1601 }
1602
1603 if (changed)
1605
1607}
1608
1609////////////////////////////////////////////////////////////////////////////////
1610/// Set the fraction of the parent pad, at which the to sub pads should meet
1611
1613{
1614 if (!fParentPad) {
1615 Warning("SetSplitFraction", "Can only be used after TRatioPlot has been drawn.");
1616 return;
1617 }
1618
1619 if ((sf < 0.0001) || (sf > 0.9999)) {
1620 Warning("SetSplitFraction", "Value %f is out of allowed range", sf);
1621 return;
1622 }
1623
1624 fSplitFraction = sf;
1625 double pm = fInsetWidth;
1626 double width = fParentPad->GetWNDC();
1627 double height = fParentPad->GetHNDC();
1628 double f = height/width;
1629
1630 fUpperPad->SetPad(pm*f, fSplitFraction, 1.-pm*f, 1.-pm);
1631 fLowerPad->SetPad(pm*f, pm, 1.-pm*f, fSplitFraction);
1632}
1633
1634////////////////////////////////////////////////////////////////////////////////
1635/// Set the inset on the outer sides of all the pads. It's used to make the outer
1636/// pad draggable.
1637
1639{
1640 if (!fParentPad) {
1641 Warning("SetInsetWidth", "Can only be used after TRatioPlot has been drawn.");
1642 return;
1643 }
1644
1645 fInsetWidth = width;
1647
1648 double pm = fInsetWidth;
1649 double w = fParentPad->GetWNDC();
1650 double h = fParentPad->GetHNDC();
1651 double f = h/w;
1652 fTopPad->SetPad(pm*f, pm, 1-pm*f, 1-pm);
1653}
1654
1655////////////////////////////////////////////////////////////////////////////////
1656/// Sets the confidence levels used to calculate the bands in the fit residual
1657/// case. Defaults to 1 and 2 sigma.
1658
1660{
1661 fCl1 = c1;
1662 fCl2 = c2;
1663 if (!BuildLowerPlot()) return;
1664}
1665
1666////////////////////////////////////////////////////////////////////////////////
1667/// Set where horizontal, dashed lines are drawn on the lower pad.
1668/// Can be used to override existing default lines (or disable them).
1669///
1670/// \param gridlines Vector of y positions for the dashes lines
1671///
1672/// Begin_Macro(source)
1673/// ../../../tutorials/hist/hist032_TRatioPlot_fit_lines.C
1674/// End_Macro
1675
1676void TRatioPlot::SetGridlines(std::vector<double> gridlines)
1677{
1678 fGridlinePositions = gridlines;
1679}
1680
1681////////////////////////////////////////////////////////////////////////////////
1682/// Set where horizontal, dashed lines are drawn on the lower pad.
1683/// Can be used to override existing default lines (or disable them).
1684///
1685/// \param gridlines Double_t array of y positions for the dashed lines
1686/// \param numGridlines Length of gridlines
1687
1688void TRatioPlot::SetGridlines(Double_t *gridlines, Int_t numGridlines)
1689{
1690 fGridlinePositions.clear();
1691
1692 for (Int_t i = 0; i < numGridlines; ++i)
1693 fGridlinePositions.emplace_back(gridlines[i]);
1694}
1695
1696////////////////////////////////////////////////////////////////////////////////
1697/// Set the confidence interval colors.
1698///
1699/// \param ci1 Color of the 1 sigma band
1700/// \param ci2 Color of the 2 sigma band
1701/// Sets the color of the 1 and 2 sigma bands in the fit residual case.
1702/// Begin_Macro(source)
1703/// ../../../tutorials/hist/hist033_TRatioPlot_fit_confidence.C
1704/// End_Macro
1705
1707{
1708 fCi1Color = ci1;
1709 fCi2Color = ci2;
1710}
1711
1712
1713////////////////////////////////////////////////////////////////////////////////
1714/// Set the confidence interval colors.
1715
1717{
1718 fCi1Color = ci1.number();
1719 fCi2Color = ci2.number();
1720}
1721
1722////////////////////////////////////////////////////////////////////////////////
1723/// Internal method to import TAxis attributes to a TGaxis. Copied from
1724/// `TGaxis::ImportAxisAttributes`
1725
1727{
1728 gaxis->SetLineColor(axis->GetAxisColor());
1729 gaxis->SetTextColor(axis->GetTitleColor());
1730 gaxis->SetTextFont(axis->GetTitleFont());
1731 gaxis->SetLabelColor(axis->GetLabelColor());
1732 gaxis->SetLabelFont(axis->GetLabelFont());
1733 gaxis->SetLabelSize(axis->GetLabelSize());
1734 gaxis->SetLabelOffset(axis->GetLabelOffset());
1735 gaxis->SetTickSize(axis->GetTickLength());
1736 gaxis->SetTitle(axis->GetTitle());
1737 gaxis->SetTitleOffset(axis->GetTitleOffset());
1738 gaxis->SetTitleSize(axis->GetTitleSize());
1746 if (axis->GetDecimals()) gaxis->SetBit(TAxis::kDecimals); //the bit is in TAxis::fAxis2
1747 gaxis->SetTimeFormat(axis->GetTimeFormat());
1748}
#define f(i)
Definition RSha256.hxx:104
#define h(i)
Definition RSha256.hxx:106
int Int_t
Signed integer 4 bytes (int).
Definition RtypesCore.h:59
bool Bool_t
Boolean (0=false, 1=true) (bool).
Definition RtypesCore.h:77
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
short Color_t
Color number (short).
Definition RtypesCore.h:99
float Float_t
Float 4 bytes (float).
Definition RtypesCore.h:71
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char).
Definition RtypesCore.h:80
if(name) objname
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:252
externTStyle * gStyle
Definition TStyle.h:442
#define gPad
virtual Color_t GetTitleColor() const
Definition TAttAxis.h:47
virtual Color_t GetLabelColor() const
Definition TAttAxis.h:39
virtual Color_t GetAxisColor() const
Definition TAttAxis.h:38
virtual Style_t GetTitleFont() const
Definition TAttAxis.h:48
virtual Float_t GetLabelOffset() const
Definition TAttAxis.h:41
virtual Style_t GetLabelFont() const
Definition TAttAxis.h:40
virtual Float_t GetTitleSize() const
Definition TAttAxis.h:45
virtual Float_t GetLabelSize() const
Definition TAttAxis.h:42
virtual Float_t GetTickLength() const
Definition TAttAxis.h:46
virtual Float_t GetTitleOffset() const
Definition TAttAxis.h:44
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition TAttLine.h:46
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition TAttLine.h:44
virtual void SetTextColor(Color_t tcolor=1)
Set the text color.
Definition TAttText.h:50
virtual void SetTextFont(Font_t tfont=62)
Set the text font.
Definition TAttText.h:52
Class to manage histogram axis.
Definition TAxis.h:32
const char * GetTitle() const override
Returns title of object.
Definition TAxis.h:137
@ kTickMinus
Definition TAxis.h:65
@ kCenterTitle
Definition TAxis.h:67
@ kRotateTitle
Definition TAxis.h:69
@ kNoExponent
Definition TAxis.h:71
@ kMoreLogLabels
Definition TAxis.h:77
@ kTickPlus
Definition TAxis.h:64
@ kDecimals
Definition TAxis.h:63
@ kCenterLabels
Bit 13 is used by TObject.
Definition TAxis.h:68
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition TAxis.cxx:522
Bool_t GetDecimals() const
Definition TAxis.h:122
Int_t GetLast() const
Return last bin on the axis i.e.
Definition TAxis.cxx:473
virtual void SetLimits(Double_t xmin, Double_t xmax)
Definition TAxis.h:166
virtual void SetRangeUser(Double_t ufirst, Double_t ulast)
Set the viewing range for the axis from ufirst to ulast (in user coordinates, that is,...
Definition TAxis.cxx:1090
virtual const char * GetTimeFormat() const
Definition TAxis.h:134
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition TAxis.cxx:532
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition TAxis.cxx:462
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Int_t number() const
Definition TColor.h:151
virtual Double_t Eval(Double_t x, Double_t y=0, Double_t z=0, Double_t t=0) const
static TClass * Class()
void Draw(Option_t *option="") override
Default Draw method for all objects.
Extends the ROOT::Fit::Result class with a TNamed inheritance providing easy possibility for I/O.
Definition TFitResult.h:34
void SetTimeFormat(const char *tformat)
void SetTitleOffset(Float_t titleoffset=1)
Definition TGaxis.h:130
void SetLabelFont(Int_t labelfont)
Definition TGaxis.h:107
void SetTitleSize(Float_t titlesize)
Definition TGaxis.h:131
void SetLabelOffset(Float_t labeloffset)
Definition TGaxis.h:108
void SetLabelColor(Int_t labelcolor)
Definition TGaxis.h:106
void SetTickSize(Float_t ticksize)
Definition TGaxis.h:124
void SetLabelSize(Float_t labelsize)
Definition TGaxis.h:109
virtual void SetTitle(const char *title="")
virtual void Divide(const TH1 *pass, const TH1 *total, Option_t *opt="cp")
static TClass * Class()
TAxis * GetXaxis() const
TAxis * GetYaxis() const
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:109
static TClass * Class()
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
Definition TH1.cxx:7228
virtual Bool_t Add(TF1 *h1, Double_t c1=1, Option_t *option="")
Performs the operation: this = this + c1*f1 if errors are defined (see TH1::Sumw2),...
Definition TH1.cxx:836
virtual void Scale(Double_t c1=1, Option_t *option="")
Multiply this histogram by a constant c1.
Definition TH1.cxx:6719
virtual Bool_t Divide(TF1 *f1, Double_t c1=1)
Performs the operation: this = this/(c1*f1) if errors are defined (see TH1::Sumw2),...
Definition TH1.cxx:2873
TList * GetHists() const
Definition THStack.h:72
static TClass * Class()
virtual void SetY2(Double_t y2)
Definition TLine.h:70
virtual void SetX2(Double_t x2)
Definition TLine.h:68
virtual void SetX1(Double_t x1)
Definition TLine.h:67
virtual void SetY1(Double_t y1)
Definition TLine.h:69
A doubly linked list.
Definition TList.h:38
virtual TObjLink * FirstLink() const
Definition TList.h:107
TObject * At(Int_t idx) const override
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx:487
Mother of all ROOT objects.
Definition TObject.h:42
Bool_t TestBit(UInt_t f) const
Definition TObject.h:204
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition TObject.cxx:243
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:227
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1084
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:204
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:888
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:549
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1098
TObject()
TObject constructor.
Definition TObject.h:259
@ kCannotPick
if object in a pad cannot be picked
Definition TObject.h:76
void SubPadResized()
@ kForceHideUp
Always hide the first label of the upper y axis.
Definition TRatioPlot.h:68
@ kHideUp
Hide the first label of the upper y axis when there is low space.
Definition TRatioPlot.h:65
@ kNoHide
Do not hide labels when there is low space.
Definition TRatioPlot.h:67
@ kHideLow
Hide the last label of the lower y axis when there is low space.
Definition TRatioPlot.h:66
@ kForceHideLow
Always hide the last label of the lower y axis.
Definition TRatioPlot.h:69
TGraphErrors * fConfidenceInterval2
Stores the graph for the 2 sigma band.
Definition TRatioPlot.h:97
TAxis * GetLowerRefXaxis() const
virtual void SetGridlines(Double_t *gridlines, Int_t numGridlines)
Int_t fErrorMode
Stores the error mode, sym, asym or func.
Definition TRatioPlot.h:86
TAxis * GetLowerRefYaxis() const
TGaxis * fUpperGXaxisMirror
Upper mirror of the x axis.
Definition TRatioPlot.h:116
TGaxis * fLowerGXaxisMirror
Lower mirror of the x axis.
Definition TRatioPlot.h:117
virtual Bool_t SyncPadMargins()
TAxis * GetUpperRefYaxis() const
Float_t fLowBottomMargin
Stores the bottom margin of the lower pad.
Definition TRatioPlot.h:134
void CreateGridlines()
Int_t BuildLowerPlot()
void SetUpBottomMargin(Float_t margin)
Float_t fUpBottomMargin
Stores the bottom margin of the upper pad.
Definition TRatioPlot.h:132
TH1 * fH1
Stores the primary histogram.
Definition TRatioPlot.h:80
void SetH2DrawOpt(Option_t *opt)
virtual void CreateVisualAxes()
TFitResult * fFitResult
Stores the explicit fit result given in the fit residual case. Can be 0.
Definition TRatioPlot.h:109
virtual void Init(TH1 *h1, TH1 *h2, Option_t *option="")
Color_t fCi1Color
Stores the color for the 1 sigma band.
Definition TRatioPlot.h:98
virtual void SetupPads()
TGaxis * fUpperGYaxis
Upper graphical y axis.
Definition TRatioPlot.h:114
Double_t fC2
Stores the scale factor for h2.
Definition TRatioPlot.h:107
void UpdateGridlines()
virtual void ConnectPadsSignals()
void SetLowBottomMargin(Float_t margin)
void SetConfidenceIntervalColors(Color_t ci1=kYellow, Color_t ci2=kGreen)
Double_t fC1
Stores the scale factor for h1 (or THStack sum).
Definition TRatioPlot.h:106
Float_t fLowTopMargin
Stores the top margin of the lower pad.
Definition TRatioPlot.h:133
TString fH2DrawOpt
Stores draw option for h2 given in constructor.
Definition TRatioPlot.h:89
void SetUpTopMargin(Float_t margin)
TGaxis * fLowerGXaxis
Lower graphical x axis.
Definition TRatioPlot.h:113
Bool_t fIsUpdating
! Keeps track of whether its currently updating to reject other calls until done
Definition TRatioPlot.h:141
virtual void SyncAxesRanges()
void SetGraphDrawOpt(Option_t *opt)
Double_t fCl1
Stores the confidence level for the inner confidence interval band.
Definition TRatioPlot.h:103
@ kErrorAsymmetric
Use TH1::GetBinErrorUp and TH1::GetBinErrorLow for the error, depending on y values.
Definition TRatioPlot.h:60
@ kErrorFunc
Use the square root of the function value as the error.
Definition TRatioPlot.h:61
@ kErrorSymmetric
Use the regular TH1::GetBinError as the error.
Definition TRatioPlot.h:59
Float_t GetSeparationMargin() const
void ImportAxisAttributes(TGaxis *gaxis, TAxis *axis)
void SetFitDrawOpt(Option_t *opt)
std::vector< TLine * > fGridlines
Keeps TLine objects for the gridlines.
Definition TRatioPlot.h:124
void SetPadMargins()
TPad * fLowerPad
The pad which contains the calculated lower plot part.
Definition TRatioPlot.h:77
TAxis * fSharedXAxis
X axis that stores the range for both plots.
Definition TRatioPlot.h:111
TString fFitDrawOpt
Stores draw option for the fit function in the fit residual case.
Definition TRatioPlot.h:91
TGaxis * fUpperGYaxisMirror
Upper mirror of the y axis.
Definition TRatioPlot.h:118
TAxis * fUpYaxis
Clone of the upper y axis.
Definition TRatioPlot.h:121
TVirtualPad * fParentPad
Stores the pad the ratio plot was created in.
Definition TRatioPlot.h:75
Float_t fUpTopMargin
Stores the top margin of the upper pad.
Definition TRatioPlot.h:131
void SetH1DrawOpt(Option_t *opt)
TGraph * fRatioGraph
Stores the lower plot's graph.
Definition TRatioPlot.h:95
Int_t fMode
Stores which calculation is supposed to be performed as specified by user option.
Definition TRatioPlot.h:85
void SetSplitFraction(Float_t sf)
TObject * fHistDrawProxy
The object which is actually drawn, this might be TH1 or THStack.
Definition TRatioPlot.h:82
virtual TObject * GetUpperRefObject() const
Float_t fRightMargin
Stores the common right margin of both pads.
Definition TRatioPlot.h:137
virtual void UpdateVisualAxes()
TGaxis * fLowerGYaxisMirror
Lower mirror of the y axis.
Definition TRatioPlot.h:119
Int_t fHideLabelMode
Stores which label to hide if the margin is to narrow, if at all.
Definition TRatioPlot.h:127
TPad * fTopPad
The Pad that drawn on top on the others to have consistent coordinates.
Definition TRatioPlot.h:78
void SetInsetWidth(Double_t width)
void RangeAxisChanged()
@ kDifference
Calculate the difference between the histograms.
Definition TRatioPlot.h:53
@ kDivideHist
Use TH1::Divide to create the ratio.
Definition TRatioPlot.h:51
@ kFitResidual
Calculate the fit residual between the histogram and a fit stored within it.
Definition TRatioPlot.h:54
@ kDifferenceSign
Calculate the difference divided by the error.
Definition TRatioPlot.h:55
@ kDivideGraph
Use TGraphAsymmErrors::Divide to create the ratio.
Definition TRatioPlot.h:52
void UnZoomed()
TH1 * fH2
Stores the secondary histogram, if there is one.
Definition TRatioPlot.h:81
Double_t fCl2
Stores the confidence level for the outer confidence interval band.
Definition TRatioPlot.h:104
TAxis * fLowYaxis
Clone of the lower y axis.
Definition TRatioPlot.h:122
TString fOption
Stores the option which is given in the constructor as a string.
Definition TRatioPlot.h:87
TPad * fUpperPad
The pad which contains the upper plot part.
Definition TRatioPlot.h:76
Bool_t fShowConfidenceIntervals
Stores whether to show the confidence interval bands. From Draw option.
Definition TRatioPlot.h:101
void SetLowTopMargin(Float_t margin)
void SetSeparationMargin(Float_t)
Bool_t fHistDrawProxyStack
If stack was assigned as proxy.
Definition TRatioPlot.h:83
Float_t fInsetWidth
Definition TRatioPlot.h:139
TAxis * GetXaxis() const
Definition TRatioPlot.h:187
void SetLeftMargin(Float_t margin)
Float_t fLeftMargin
Stores the common left margin of both pads.
Definition TRatioPlot.h:136
TAxis * GetUpperRefXaxis() const
Float_t fSplitFraction
Stores the fraction at which the upper and lower pads meet.
Definition TRatioPlot.h:93
void Paint(Option_t *opt="") override
This method must be overridden if a class wants to paint itself.
TGraphErrors * fConfidenceInterval1
Stores the graph for the 1 sigma band.
Definition TRatioPlot.h:96
TGaxis * fUpperGXaxis
Upper graphical x axis.
Definition TRatioPlot.h:112
virtual TGraph * GetLowerRefGraph() const
std::vector< double > fGridlinePositions
Stores the y positions for the gridlines.
Definition TRatioPlot.h:125
TString fH1DrawOpt
Stores draw option for h1 given in constructor.
Definition TRatioPlot.h:88
Bool_t fShowGridlines
Stores whether to show the gridlines at all.
Definition TRatioPlot.h:126
void Draw(Option_t *chopt="") override
Default Draw method for all objects.
TString fGraphDrawOpt
Stores draw option for the lower plot graph given in constructor.
Definition TRatioPlot.h:90
~TRatioPlot() override
Color_t fCi2Color
Stores the color for the 2 sigma band.
Definition TRatioPlot.h:99
void SetRightMargin(Float_t margin)
TGaxis * fLowerGYaxis
Lower graphical y axis.
Definition TRatioPlot.h:115
void SetConfidenceLevels(Double_t cl1, Double_t cl2)
Basic string class.
Definition TString.h:138
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:713
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:641
virtual void GetConfidenceIntervals(Int_t n, Int_t ndim, const Double_t *x, Double_t *ci, Double_t cl=0.95)
return confidence intervals in array x of dimension ndim implemented in TFitter and TLinearFitter
static TVirtualFitter * GetFitter()
static: return the current Fitter
TLine * line
return c1
Definition legend1.C:41
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
TGraphErrors * gr
Definition legend1.C:25
for(Int_t i=0;i< n;i++)
Definition legend1.C:18
TH1F * h1
Definition legend1.C:5
return c2
Definition legend2.C:14
VecExpr< UnaryOp< Sqrt< T >, VecExpr< A, T, D >, T >, T, D > sqrt(const VecExpr< A, T, D > &rhs)
double ratio(double numerator, double denominator)
Definition MathFuncs.h:106
void Init(TClassEdit::TInterpreterLookupHelper *helper)
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition TMath.h:732