Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 11:56:54

0001 #ifndef ALIGNMENT_OFFLINEVALIDATION_JDRAWER_H
0002 #define ALIGNMENT_OFFLINEVALIDATION_JDRAWER_H
0003 
0004 // C++ includes
0005 #include <iostream>
0006 
0007 // Root includes
0008 #include "TROOT.h"
0009 #include "TStyle.h"
0010 #include "TCanvas.h"
0011 #include "TPad.h"
0012 #include "TString.h"
0013 #include "TH1.h"
0014 #include "TF1.h"
0015 #include "TH2.h"
0016 #include "TAxis.h"
0017 #include "TGraph.h"
0018 #include "TLegend.h"
0019 
0020 /*
0021  * Class for drawing histograms and graphs in the standard style of the group
0022  */
0023 class JDrawer {
0024 private:
0025   // Margins for the drawn canvases
0026   double fMarginLeft;    // left margin for the canvas
0027   double fMarginRight;   // right margin for the canvas
0028   double fMarginBottom;  // bottom margin for the canvas
0029   double fMarginTop;     // top margin for the canvas
0030 
0031   // Place and size for the canvas
0032   int fTopLeftX;      // Number of pixels the the canvas is out of the top left corner of the screen in x-direction
0033   int fTopLeftY;      // Number of pixels the the canvas is out of the top left corner of the screen in y-direction
0034   int fCanvasWidth;   // Width of the canvas
0035   int fCanvasHeight;  // Height of the canvas
0036 
0037   // Appearance settings for histogram
0038   double fTitleOffsetX;  // Offset of the x-axis title
0039   double fTitleOffsetY;  // Offset of the y-axis title
0040   double fTitleOffsetZ;  // Offset of the z-axis title
0041   double fTitleSizeX;    // Size of the x-axis title
0042   double fTitleSizeY;    // Size of the y-axis title
0043   double fTitleSizeZ;    // Size of the z-axis title
0044   double fLabelOffsetX;  // Offset of the x-axis label
0045   double fLabelOffsetY;  // Offset of the y-axis label
0046   double fLabelOffsetZ;  // Offset of the z-axis label
0047   double fLabelSizeX;    // Size of the x-axis label
0048   double fLabelSizeY;    // Size of the y-axis label
0049   double fLabelSizeZ;    // Size of the z-axis label
0050   double fDivisionsX;    // The number of divisions in x-axis
0051   double fDivisionsY;    // The number of divisions in y-axis
0052   int fFont;             // Font index for titles and labels
0053 
0054   // TPad appearance settings
0055   int fLogX;   // 1: Logarithmic x-axis, 0: linear x-axis
0056   int fLogY;   // 1: Logarithmic y-axis, 0: linear y-axis
0057   int fLogZ;   // 1: Logarithmic z-axis, 0: linear z-axis
0058   int fGridX;  // 1: Grid in x-axis, 0: no grid
0059   int fGridY;  // 1: Grid in y-axis, 0: no grid
0060   int fTickX;  // 1: Ticks in x-axis, 0: no ticks
0061   int fTickY;  // 1: Ticks in y-axis, 0: no ticks
0062 
0063   // Canvas displacement settings
0064   int fCanvasDisplacementX;  // Displacement of the canvas for one index in x-direction
0065   int fCanvasDisplacementY;  // Displacement of the canvas for one index in y-direction
0066   int fCanvasesInOneRow;     // Number of canvases in a row before a new row is started
0067 
0068   // Handles needed for custom canvas creation
0069   TCanvas *fCanvas;      // If only a custom canvas is drawn, we need to keep on handle on that
0070   TPad *fSinglePad;      // Single pad for single canvas
0071   TPad *fUpperSplitPad;  // Upper pad in split canvas
0072   TPad *fLowerSplitPad;  // Lower pad in split canvas
0073   TPad *fLeftRowPad;     // Left pad in a row of three pads
0074   TPad *fMiddleRowPad;   // Middle pad in a row of three pads
0075   TPad *fRightRowPad;    // Right pad in the row of three pads
0076 
0077   // Settings for canvas splitting
0078   double fSplitRatio;  // The percentage of the lower pad from the total canvas when splitting the canvas
0079 
0080   // Index for generating names
0081   int fNameIndex;  // Names for canvases and pads are generated using this index. Static so that unique naming is ensured
0082       // This used to be static, but for some reason does not compile if defined as static. Should work like this also though
0083       // Remember: static means that only one fNameIndex is used by all the JDrawers that are created in the code
0084 
0085   /*
0086    * Trim the styles of given axes
0087    *
0088    * TAxis *xAxis = The styled x-axis
0089    * TAxis *yAxis = The styled y-axis
0090    * TAxis *zAxis = The styled z-axis
0091    * TString xtit = Title of the x-axis
0092    * TString ytit = Title of the y-axis
0093    */
0094   void SetAxisStyles(TAxis *xAxis, TAxis *yAxis, TAxis *zAxis, TString xtit, TString ytit) {
0095     xAxis->CenterTitle(true);  // Axis titles are centered
0096     yAxis->CenterTitle(true);  // Axis titles are centered
0097     if (zAxis)
0098       zAxis->CenterTitle(true);  // Axis titles are centered
0099 
0100     xAxis->SetTitleOffset(fTitleOffsetX);  // Give a small offset to the title so that it does overlap with axis
0101     yAxis->SetTitleOffset(fTitleOffsetY);  // Give a small offset to the title so that it does overlap with axis
0102     if (zAxis)
0103       zAxis->SetTitleOffset(fTitleOffsetZ);  // Give a small offset to the title so that it does overlap with axis
0104 
0105     xAxis->SetTitleSize(fTitleSizeX);  // Define the size of the title
0106     yAxis->SetTitleSize(fTitleSizeY);  // Define the size of the title
0107     if (zAxis)
0108       zAxis->SetTitleSize(fTitleSizeZ);  // Define the size of the title
0109 
0110     xAxis->SetLabelOffset(fLabelOffsetX);  // Give a small offset to the label so that it does overlap with axis
0111     yAxis->SetLabelOffset(fLabelOffsetY);  // Give a small offset to the label so that it does overlap with axis
0112     if (zAxis)
0113       zAxis->SetLabelOffset(fLabelOffsetZ);  // Give a small offset to the label so that it does overlap with axis
0114 
0115     xAxis->SetLabelSize(fLabelSizeX);  // Define the sixe of the label
0116     yAxis->SetLabelSize(fLabelSizeY);  // Define the sixe of the label
0117     if (zAxis)
0118       zAxis->SetLabelSize(fLabelSizeZ);  // Define the sixe of the label
0119 
0120     xAxis->SetNdivisions(fDivisionsX);  // Set the number of division markers
0121     yAxis->SetNdivisions(fDivisionsY);  // Set the number of division markers
0122 
0123     xAxis->SetTitle(xtit);  // Set the axis title
0124     yAxis->SetTitle(ytit);  // Set the axis title
0125 
0126     xAxis->SetLabelFont(fFont);  // Set the label font
0127     yAxis->SetLabelFont(fFont);  // Set the label font
0128     if (zAxis)
0129       zAxis->SetLabelFont(fFont);  // Set the label font
0130     xAxis->SetTitleFont(fFont);    // Set the title font
0131     yAxis->SetTitleFont(fFont);    // Set the title font
0132     if (zAxis)
0133       zAxis->SetTitleFont(fFont);  // Set the title font
0134   }
0135 
0136   /*
0137    * Trim the style of a histogram using the defined style values
0138    *
0139    * TH1 *hid = Histogram which is styled
0140    * TString xtit = Title of the x-axis
0141    * TString ytit = Title of the y-axis
0142    */
0143   void SetHistogramStyle(TH1 *hid, TString xtit, TString ytit) {
0144     SetAxisStyles(hid->GetXaxis(), hid->GetYaxis(), hid->GetZaxis(), xtit, ytit);
0145   }
0146 
0147   /*
0148    * Trim the style of a function using the defined style values
0149    *
0150    * TF1 *hid = Function which is styled
0151    * TString xtit = Title of the x-axis
0152    * TString ytit = Title of the y-axis
0153    */
0154   void SetFunctionStyle(TF1 *hid, TString xtit, TString ytit) {
0155     SetAxisStyles(hid->GetXaxis(), hid->GetYaxis(), hid->GetZaxis(), xtit, ytit);
0156   }
0157 
0158   /*
0159    * Trim the style of a graph using the defined style values
0160    *
0161    * TGraph *hid = Histogram which is styled
0162    * TString xtit = Title of the x-axis
0163    * TString ytit = Title of the y-axis
0164    */
0165   void SetGraphStyle(TGraph *hid, TString xtit, TString ytit) {
0166     SetAxisStyles(hid->GetXaxis(), hid->GetYaxis(), nullptr, xtit, ytit);
0167   }
0168 
0169   /*
0170    *  Set the pad specific values to the given pad
0171    */
0172   void SetPadValues(TPad *pad) {
0173     pad->SetLogy(fLogY);
0174     pad->SetLogx(fLogX);
0175     pad->SetLogz(fLogZ);
0176     pad->SetGridx(fGridX);
0177     pad->SetGridy(fGridY);
0178     pad->SetTickx(fTickX);
0179     pad->SetTicky(fTickY);
0180   }
0181 
0182   /*
0183    * Generate a name for an object that does not exist yet
0184    */
0185   TString GenerateName(const char *objectName) {
0186     TString name = Form("%s%d%d%d", objectName, fNameIndex++, fTopLeftX, fTopLeftY);
0187     return name.Data();
0188   }
0189 
0190   /*
0191    * Generate a name for a canvas
0192    */
0193   TString GenerateNameForCanvas() {
0194     TString name;
0195     name = Form("canvas%d%d", fTopLeftX, fTopLeftY);
0196     while (true) {
0197       // If a canvas with a specified name does not exist, accept the name
0198       if (gROOT->GetListOfCanvases()->FindObject(name) == nullptr) {
0199         return name.Data();
0200       }
0201 
0202       // If a canvas with a specified name does exist, try a new name
0203       name = Form("canvas%d%d%d", fTopLeftX, fTopLeftY, fNameIndex++);
0204     }
0205   }
0206 
0207 public:
0208   /*
0209    * Constructor for JDrawer
0210    */
0211   JDrawer() {
0212     Reset();  // Set all the style values to default
0213     fNameIndex = 0;
0214   }
0215 
0216   /*
0217    * Destructor for JDrawer
0218    */
0219   ~JDrawer() = default;
0220 
0221   /*
0222    *  Draw a histogram to a canvas
0223    *
0224    *  TH1 *histo = histogram to be drawn
0225    *  char *xTitle = title for the x-axis
0226    *  char *yTitle = title for the y-axis
0227    *  char *title = title of the histogram
0228    *  char *drawOption = options for drawing given in root documentation
0229    */
0230   void DrawHistogramToCurrentCanvas(
0231       TH1 *histo, const char *xTitle, const char *yTitle, const char *title = "", const char *drawOption = "") {
0232     // If no titles are given, keep the original ones
0233     if (strcmp(xTitle, "") == 0)
0234       xTitle = histo->GetXaxis()
0235                    ->GetTitle();  // To compare char*:s we need to use strcmp function provided by <cstring> library
0236     if (strcmp(yTitle, "") == 0)
0237       yTitle = histo->GetYaxis()->GetTitle();
0238     if (strcmp(title, "") == 0)
0239       title = histo->GetTitle();
0240 
0241     // Set up the histogram and draw it to current canvas
0242     histo->SetTitle(title);
0243     SetHistogramStyle(histo, xTitle, yTitle);
0244     histo->Draw(drawOption);
0245   }
0246 
0247   /*
0248    *  Draw a histogram to a canvas
0249    *
0250    *  TH1 *histo = histogram to be drawn
0251    *  char *xTitle = title for the x-axis
0252    *  char *yTitle = title for the y-axis
0253    *  char *title = title of the histogram
0254    *  char *drawOption = options for drawing given in root documentation
0255    */
0256   void DrawHistogram(
0257       TH1 *histo, const char *xTitle, const char *yTitle, const char *title = "", const char *drawOption = "") {
0258     // If no titles are given, keep the original ones
0259     if (strcmp(xTitle, "") == 0)
0260       xTitle = histo->GetXaxis()
0261                    ->GetTitle();  // To compare char*:s we need to use strcmp function provided by <cstring> library
0262     if (strcmp(yTitle, "") == 0)
0263       yTitle = histo->GetYaxis()->GetTitle();
0264     if (strcmp(title, "") == 0)
0265       title = histo->GetTitle();
0266 
0267     // Set up the histogram and draw it to canvas
0268     CreateCanvas();
0269     histo->SetTitle(title);
0270     SetHistogramStyle(histo, xTitle, yTitle);
0271     histo->Draw(drawOption);
0272   }
0273 
0274   /*
0275    * Draw histogram without changing the titles
0276    *
0277    *  TH1 *histo = histogram to be drawn
0278    *  char *drawOption = options for drawing given in root documentation
0279    */
0280   void DrawHistogram(TH1 *histo, const char *drawOption = "") { DrawHistogram(histo, "", "", "", drawOption); }
0281 
0282   /*
0283    *  Draw a histogram to a pad of a split canvas
0284    *
0285    *  TH1 *histo = histogram to be drawn
0286    *  char *xTitle = title for the x-axis
0287    *  char *yTitle = title for the y-axis
0288    *  char *title = title of the histogram
0289    *  char *drawOption = options for drawing given in root documentation
0290    */
0291   void DrawHistogramToPad(TH1 *histo,
0292                           TPad *drawPad,
0293                           const char *xTitle = "",
0294                           const char *yTitle = "",
0295                           const char *title = "",
0296                           const char *drawOption = "") {
0297     // If no titles are given, keep the original ones
0298     if (strcmp(xTitle, "") == 0)
0299       xTitle = histo->GetXaxis()
0300                    ->GetTitle();  // To compare char*:s we need to use strcmp function provided by <cstring> library
0301     if (strcmp(yTitle, "") == 0)
0302       yTitle = histo->GetYaxis()->GetTitle();
0303     if (strcmp(title, "") == 0)
0304       title = histo->GetTitle();
0305 
0306     // Change to the desired pad
0307     SetPadValues(drawPad);
0308     drawPad->cd();
0309 
0310     // Remove statistics box and title
0311     gStyle->SetOptStat(0);
0312     gStyle->SetOptTitle(0);
0313 
0314     // Set up the histogram and draw it to the pad
0315     histo->SetTitle(title);
0316     SetHistogramStyle(histo, xTitle, yTitle);
0317     histo->Draw(drawOption);
0318   }
0319 
0320   /*
0321    *  Draw a histogram to an upper pad of a split canvas
0322    *
0323    *  TH1 *histo = histogram to be drawn
0324    *  char *xTitle = title for the x-axis
0325    *  char *yTitle = title for the y-axis
0326    *  char *title = title of the histogram
0327    *  char *drawOption = options for drawing given in root documentation
0328    */
0329   void DrawHistogramToUpperPad(TH1 *histo,
0330                                const char *xTitle = "",
0331                                const char *yTitle = "",
0332                                const char *title = "",
0333                                const char *drawOption = "") {
0334     // If there is no upper pad, create one
0335     if (fUpperSplitPad == nullptr) {
0336       //SetDefaultAppearanceSplitCanvas();
0337       CreateSplitCanvas();
0338     }
0339 
0340     DrawHistogramToPad(histo, fUpperSplitPad, xTitle, yTitle, title, drawOption);
0341   }
0342 
0343   /*
0344    *  Draw a histogram to an upper pad of a split canvas
0345    *
0346    *  TH1 *histo = histogram to be drawn
0347    *  char *xTitle = title for the x-axis
0348    *  char *yTitle = title for the y-axis
0349    *  char *title = title of the histogram
0350    *  char *drawOption = options for drawing given in root documentation
0351    */
0352   void DrawHistogramToLowerPad(TH1 *histo,
0353                                const char *xTitle = "",
0354                                const char *yTitle = "",
0355                                const char *title = "",
0356                                const char *drawOption = "") {
0357     // If there is no lower pad, create one
0358     if (fLowerSplitPad == nullptr) {
0359       //SetDefaultAppearanceSplitCanvas();
0360       CreateSplitCanvas();
0361     }
0362 
0363     DrawHistogramToPad(histo, fLowerSplitPad, xTitle, yTitle, title, drawOption);
0364   }
0365 
0366   /*
0367    *  Draw a graph to a canvas
0368    *
0369    *  TGraph *graph = graph to be drawn
0370    *  double xlow = lowest x-axis value drawn
0371    *  double xhigh = highest x-axis value drawn
0372    *  double ylow = lowest y-axis value drawn
0373    *  double yhigh = highest y-axis value drawn
0374    *  char *xTitle = title for the x-axis
0375    *  char *yTitle = title for the y-axis
0376    *  char *title = title of the histogram
0377    *  char *drawOption = options for drawing given in root documentation
0378    */
0379   void DrawGraph(TGraph *graph,
0380                  double xlow,
0381                  double xhigh,
0382                  double ylow,
0383                  double yhigh,
0384                  const char *xTitle = "",
0385                  const char *yTitle = "",
0386                  const char *title = "",
0387                  const char *drawOption = "") {
0388     // Create the canvas with right specs and a graph into it
0389     CreateCanvas(xlow, xhigh, ylow, yhigh, xTitle, yTitle, title);
0390     graph->Draw(drawOption);
0391   }
0392 
0393   /*
0394    *  Draw a graph to a canvas. Notice that with custom axes the option "a" should be given for the first graph in each canvas.
0395    *
0396    *  TGraph *graph = graph to be drawn
0397    *  double xlow = lowest x-axis value drawn
0398    *  double xhigh = highest x-axis value drawn
0399    *  double ylow = lowest y-axis value drawn
0400    *  double yhigh = highest y-axis value drawn
0401    *  char *xTitle = title for the x-axis
0402    *  char *yTitle = title for the y-axis
0403    *  char *title = title of the histogram
0404    *  char *drawOption = options for drawing given in root documentation
0405    */
0406   void DrawGraphCustomAxes(TGraph *graph,
0407                            double xlow,
0408                            double xhigh,
0409                            double ylow,
0410                            double yhigh,
0411                            const char *xTitle = "",
0412                            const char *yTitle = "",
0413                            const char *title = "",
0414                            const char *drawOption = "") {
0415     // If no titles are given, keep the original ones
0416     if (strcmp(xTitle, "") == 0)
0417       xTitle = graph->GetXaxis()
0418                    ->GetTitle();  // To compare char*:s we need to use strcmp function provided by <cstring> library
0419     if (strcmp(yTitle, "") == 0)
0420       yTitle = graph->GetYaxis()->GetTitle();
0421     if (strcmp(title, "") == 0)
0422       title = graph->GetTitle();
0423 
0424     // Set up the histogram and draw it to canvas
0425     CreateCanvas();
0426     graph->SetTitle(title);
0427     graph->GetXaxis()->SetRangeUser(xlow, xhigh);
0428     graph->GetYaxis()->SetRangeUser(ylow, yhigh);
0429     SetGraphStyle(graph, xTitle, yTitle);
0430     graph->Draw(drawOption);
0431   }
0432 
0433   /*
0434    *  Draw a function to a canvas
0435    *
0436    *  TF1 *myFun = histogram to be drawn
0437    *  char *xTitle = title for the x-axis
0438    *  char *yTitle = title for the y-axis
0439    *  char *title = title of the histogram
0440    *  char *drawOption = options for drawing given in root documentation
0441    */
0442   void DrawFunction(
0443       TF1 *myFun, const char *xTitle, const char *yTitle, const char *title = "", const char *drawOption = "") {
0444     // If no titles are given, keep the original ones
0445     if (strcmp(xTitle, "") == 0)
0446       xTitle = myFun->GetXaxis()
0447                    ->GetTitle();  // To compare char*:s we need to use strcmp function provided by <cstring> library
0448     if (strcmp(yTitle, "") == 0)
0449       yTitle = myFun->GetYaxis()->GetTitle();
0450     if (strcmp(title, "") == 0)
0451       title = myFun->GetTitle();
0452 
0453     // Set up the histogram and draw it to canvas
0454     CreateCanvas();
0455     myFun->SetTitle(title);
0456     SetFunctionStyle(myFun, xTitle, yTitle);
0457     myFun->Draw(drawOption);
0458   }
0459 
0460   /*
0461    * Draw histogram without changing the titles
0462    *
0463    *  TF1 *myFun = function to be drawn
0464    *  char *drawOption = options for drawing given in root documentation
0465    */
0466   void DrawFunction(TF1 *myFun, const char *drawOption = "") { DrawFunction(myFun, "", "", "", drawOption); }
0467 
0468   /*
0469    * Set all the values back to default
0470    */
0471   void Reset() {
0472     // Set default values for margins
0473     fMarginLeft = 0.15;    // left margin
0474     fMarginRight = 0.06;   // right margin
0475     fMarginBottom = 0.15;  // bottom margin
0476     fMarginTop = 0.06;     // top margin
0477 
0478     // Set default values for the size and place of the canvas
0479     fTopLeftX = 10;       // Number of pixels the the canvas is out of the top left corner of the screen in x-direction
0480     fTopLeftY = 10;       // Number of pixels the the canvas is out of the top left corner of the screen in y-direction
0481     fCanvasWidth = 700;   // Width of the canvas
0482     fCanvasHeight = 500;  // Height of the canvas
0483 
0484     // Set default values for histogram appearance settings
0485     fTitleOffsetX = 1.1;    // Offset of the x-axis title
0486     fTitleOffsetY = 1.1;    // Offset of the y-axis title
0487     fTitleOffsetZ = 1.3;    // Pffset of the z-axis title
0488     fTitleSizeX = 0.06;     // Size of the x-axis title
0489     fTitleSizeY = 0.06;     // Size of the y-axis title
0490     fTitleSizeZ = 0.06;     // Size of the z-axis title
0491     fLabelOffsetX = 0.01;   // Offset of the x-axis label
0492     fLabelOffsetY = 0.001;  // Offset of the y-axis label
0493     fLabelOffsetZ = 0.001;  // Offset of the z-axis label
0494     fLabelSizeX = 0.05;     // Size of the x-axis label
0495     fLabelSizeY = 0.05;     // Size of the y-axis label
0496     fLabelSizeZ = 0.05;     // Size of the z-axis label
0497     fDivisionsX = 505;      // The number of divisions in x-axis
0498     fDivisionsY = 505;      // The number of divisions in y-axis
0499     fFont = 42;             // Font index for titles and labels
0500 
0501     // Axes are linear by default
0502     fLogX = 0;  // 1: Logarithmic x-axis, 0: linear x-axis
0503     fLogY = 0;  // 1: Logarithmic y-axis, 0: linear y-axis
0504     fLogZ = 0;  // 1: Logarithmic z-axis, 0: linear z-axis
0505 
0506     // Set default values for canves displacement information
0507     fCanvasDisplacementX = 100;  // Displacement of the canvas for one index in x-direction
0508     fCanvasDisplacementY = 100;  // Displacement of the canvas for one index in y-direction
0509     fCanvasesInOneRow = 10;      // Number of canvases in a row before a new row is started
0510 
0511     // Set defauls values for pad properties
0512     fGridX = 0;  // 1: Grid in x-axis, 0: no grid
0513     fGridY = 0;  // 1: Grid in y-axis, 0: no grid
0514     fTickX = 1;  // 1: Ticks in x-axis, 0: no ticks
0515     fTickY = 1;  // 1: Ticks in y-axis, 0: no ticks
0516 
0517     // Default setting values for splitted canvas
0518     fSplitRatio = 0.4;  // The percentage of the lower pad from the total canvas when splitting the canvas
0519 
0520     // Set the canvas handles to null
0521     fCanvas = nullptr;
0522     fSinglePad = nullptr;
0523     fUpperSplitPad = nullptr;
0524     fLowerSplitPad = nullptr;
0525     fLeftRowPad = nullptr;
0526     fMiddleRowPad = nullptr;
0527     fRightRowPad = nullptr;
0528   }
0529 
0530   /*
0531    * Create a canvas and one pad to it
0532    */
0533   void CreateCanvas() {
0534     // Create a canvas and set up its appearance
0535     gStyle->SetOptStat(0);  // remove statistics box
0536     TString cname = GenerateNameForCanvas();
0537     fCanvas = new TCanvas(cname.Data(), cname.Data(), fTopLeftX, fTopLeftY, fCanvasWidth, fCanvasHeight);
0538     fSinglePad = new TPad("pad", "pad", 0.01, 0.01, 0.99, 0.99, 0, 0, 0);
0539     fSinglePad->SetLeftMargin(fMarginLeft);
0540     fSinglePad->SetBottomMargin(fMarginBottom);
0541     fSinglePad->SetTopMargin(fMarginTop);
0542     fSinglePad->SetRightMargin(fMarginRight);
0543     SetPadValues(fSinglePad);
0544     fSinglePad->Draw();
0545     fSinglePad->cd();
0546   }
0547 
0548   /*
0549    *  Create a canvas with a grid of desired size and titles
0550    *
0551    *  double xlow = lowest x-axis value drawn
0552    *  double xhigh = highest x-axis value drawn
0553    *  double ylow = lowest y-axis value drawn
0554    *  double yhigh = highest y-axis value drawn
0555    *  char *xTitle = title for the x-axis
0556    *  char *yTitle = title for the y-axis
0557    *  char *title = title of the histogram
0558    */
0559   void CreateCanvas(double xlow,
0560                     double xhigh,
0561                     double ylow,
0562                     double yhigh,
0563                     const char *xTitle = "",
0564                     const char *yTitle = "",
0565                     const char *title = "") {
0566     // First make a canvas
0567     CreateCanvas();
0568 
0569     // Create a dummy 2D-histogram to set the drawing ranges and titles
0570     TString dummyName = GenerateName("histo");
0571     TH2F *dummyHisto = new TH2F(dummyName.Data(), title, 10, xlow, xhigh, 10, ylow, yhigh);
0572     SetHistogramStyle(dummyHisto, xTitle, yTitle);
0573     dummyHisto->Draw();
0574   }
0575 
0576   /*
0577    * Create a canvas that is split to two pads that are on top of each other
0578    */
0579   void CreateSplitCanvas() {
0580     TString dummyName;  // dummy name generator
0581     dummyName = GenerateNameForCanvas();
0582 
0583     // Create the canvas
0584     fCanvas = new TCanvas(dummyName.Data(), dummyName.Data(), fTopLeftX, fTopLeftY, fCanvasWidth, fCanvasHeight);
0585     fCanvas->SetFillStyle(4000);     // The created canvas is completely transparent
0586     fCanvas->SetFillColor(10);       // Canvas is filled with white color
0587     gStyle->SetOptStat(0);           // Disable the drawing of the statistics box to the canvas
0588     gStyle->SetOptTitle(0);          // Disable the drawing of titles to the canvas
0589     fCanvas->SetMargin(0, 0, 0, 0);  // Remove the margins from the bottom canvas
0590     fCanvas->Draw();                 // Draw the canvas to the screen
0591 
0592     // ---- Create the two pads to the canvas ----
0593 
0594     // The upper pad stretches from the top of the canvas to the defined split ratio
0595     dummyName = GenerateName("UpperPad");
0596     fUpperSplitPad = new TPad(dummyName.Data(), dummyName.Data(), 0, fSplitRatio, 1, 1, 0);
0597     fUpperSplitPad->SetTopMargin(fMarginTop / (1 - fSplitRatio));  // Adjust top margin according to the split ratio
0598     fUpperSplitPad->SetBottomMargin(
0599         0.0015);  // Make the bottom margin small so that the pads fit nicely on top of each other
0600     fUpperSplitPad->SetLeftMargin(fMarginLeft);
0601     fUpperSplitPad->SetRightMargin(fMarginRight);
0602     fUpperSplitPad->Draw();
0603 
0604     // The lower pad stretches from the defined split ratio to the bottom of the canvas
0605     dummyName = GenerateName("LowerPad");
0606     fLowerSplitPad = new TPad(dummyName.Data(), dummyName.Data(), 0, 0, 1, fSplitRatio, 0);
0607     fLowerSplitPad->SetTopMargin(0.0015);  // Make the top margin small so that the pads fit nicely on top of each other
0608     fLowerSplitPad->SetBottomMargin(fMarginBottom / fSplitRatio);  // Adjust bottom margin according to the split ratio
0609     fLowerSplitPad->SetLeftMargin(fMarginLeft);
0610     fLowerSplitPad->SetRightMargin(fMarginRight);
0611     fLowerSplitPad->Draw();
0612   }
0613 
0614   /*
0615    * Create a canvas where three graphs can be drawn in one row (to show all xlong bins in one figure for example)
0616    */
0617   void CreateCanvasGraphRow() {
0618     TString dummyName;  // dummy name generator
0619     dummyName = GenerateNameForCanvas();
0620 
0621     // Create the canvas
0622     fCanvas = new TCanvas(dummyName.Data(), dummyName.Data(), fTopLeftX, fTopLeftY, fCanvasWidth, fCanvasHeight);
0623     fCanvas->SetFillStyle(4000);     // The created canvas is completely transparent
0624     fCanvas->SetFillColor(10);       // Canvas is filled with white color
0625     gStyle->SetOptStat(0);           // Disable the drawing of the statistics box to the canvas
0626     gStyle->SetOptTitle(0);          // Disable the drawing of titles to the canvas
0627     fCanvas->SetMargin(0, 0, 0, 0);  // Remove the margins from the bottom canvas
0628     fCanvas->Draw();                 // Draw the canvas to the screen
0629 
0630     // ---- Create the two pads to the canvas ----
0631 
0632     // First, find the correct relation between different pads based on the required margins
0633     double smallMargin = 0.0006;
0634     double evenSmallerMargin = 0.0002;
0635     double relativePlotSizeLeftPad = 1 - (fMarginLeft + evenSmallerMargin);
0636     double relativePlotSizeMiddlePad = 1 - (2 * smallMargin);
0637     double relativePlotSizeRightPad = 1 - (fMarginRight + smallMargin);
0638     double firstSeparator = 1 / (1 + relativePlotSizeLeftPad / relativePlotSizeMiddlePad +
0639                                  relativePlotSizeLeftPad / relativePlotSizeRightPad);
0640     double secondSeparator = firstSeparator + (relativePlotSizeLeftPad / relativePlotSizeMiddlePad) * firstSeparator;
0641 
0642     // The first pad stretches from the left corner 1/3 of the total horizontal space, taking into account marginals
0643     dummyName = GenerateName("LeftPad");
0644     fLeftRowPad = new TPad(dummyName.Data(), dummyName.Data(), 0, 0, firstSeparator, 1, 0);
0645     fLeftRowPad->SetTopMargin(fMarginTop);
0646     fLeftRowPad->SetBottomMargin(fMarginBottom);
0647     fLeftRowPad->SetLeftMargin(fMarginLeft);
0648     fLeftRowPad->SetRightMargin(
0649         evenSmallerMargin);  // Make the right margin small so that the pads fit nicely on top of each other
0650     SetPadValues(fLeftRowPad);
0651     fLeftRowPad->Draw();
0652 
0653     // The second pad stretches from 1/3 of the total horizontal space to 2/3, taking into account marginals
0654     dummyName = GenerateName("MiddlePad");
0655     fMiddleRowPad = new TPad(dummyName.Data(), dummyName.Data(), firstSeparator, 0, secondSeparator, 1, 0);
0656     fMiddleRowPad->SetTopMargin(fMarginTop);
0657     fMiddleRowPad->SetBottomMargin(fMarginBottom);
0658     fMiddleRowPad->SetLeftMargin(
0659         smallMargin);  // Make the left margin small so that the pads fit nicely on top of each other
0660     fMiddleRowPad->SetRightMargin(
0661         smallMargin);  // Make the right margin small so that the pads fit nicely on top of each other
0662     SetPadValues(fMiddleRowPad);
0663     fMiddleRowPad->Draw();
0664 
0665     // The third pad stretches from 2/3 of the total horizontal space right corner, taking into account marginals
0666     dummyName = GenerateName("RightPad");
0667     fRightRowPad = new TPad(dummyName.Data(), dummyName.Data(), secondSeparator, 0, 1, 1, 0);
0668     fRightRowPad->SetTopMargin(fMarginTop);
0669     fRightRowPad->SetBottomMargin(fMarginBottom);
0670     fRightRowPad->SetLeftMargin(
0671         smallMargin);  // Make the left margin small so that the pads fit nicely on top of each other
0672     fRightRowPad->SetRightMargin(fMarginRight);
0673     SetPadValues(fRightRowPad);
0674     fRightRowPad->Draw();
0675   }
0676 
0677   /*
0678    *  Create a canvas with a grid of desired size and titles
0679    *
0680    *  double xlow = lowest x-axis value drawn
0681    *  double xhigh = highest x-axis value drawn
0682    *  double ylow = lowest y-axis value drawn
0683    *  double yhigh = highest y-axis value drawn
0684    *  char *xTitle = title for the x-axis
0685    *  char *yTitle = title for the y-axis
0686    *  char *title = title of the histogram
0687    */
0688   void CreateCanvasGraphRow(double xlow,
0689                             double xhigh,
0690                             double ylow,
0691                             double yhigh,
0692                             const char *xTitle = "",
0693                             const char *yTitle = "",
0694                             const char *title = "") {
0695     // First make a canvas
0696     CreateCanvasGraphRow();
0697 
0698     // Create a dummy 2D-histogram to set the drawing ranges and titles
0699     SelectPad(0);
0700     TString dummyName = GenerateName("histo");
0701     TH2F *dummyHisto = new TH2F(dummyName.Data(), "", 10, xlow, xhigh, 10, ylow, yhigh);
0702     SetHistogramStyle(dummyHisto, xTitle, yTitle);
0703     dummyHisto->Draw();
0704 
0705     // Create a dummy 2D-histogram to set the drawing ranges and titles
0706     SelectPad(1);
0707     dummyName = GenerateName("histo");
0708     dummyHisto = new TH2F(dummyName.Data(), title, 10, xlow, xhigh, 10, ylow, yhigh);
0709     SetHistogramStyle(dummyHisto, xTitle, "");
0710     dummyHisto->Draw();
0711 
0712     // Create a dummy 2D-histogram to set the drawing ranges and titles
0713     SelectPad(2);
0714     dummyName = GenerateName("histo");
0715     dummyHisto = new TH2F(dummyName.Data(), "", 10, xlow, xhigh, 10, ylow, yhigh);
0716     SetHistogramStyle(dummyHisto, xTitle, "");
0717     dummyHisto->Draw();
0718   }
0719 
0720   /*
0721    * Create split canvas with default settings defining the canvas displacement info
0722    *
0723    *  int canvasIndex = index number for the canvas, this is used to calculate the canvas displacement
0724    *  int canvasesInRow = number of canvases in a row before the next row is started
0725    */
0726   void CreateSplitCanvas(int canvasIndex, int canvasesInRow) {
0727     SetDefaultAppearanceSplitCanvas();
0728     SetNumberOfCanvasesInOneRow(canvasesInRow);
0729     SetCanvasDisplacement(canvasIndex);
0730     CreateSplitCanvas();
0731   }
0732 
0733   // Setter for left margin
0734   void SetLeftMargin(double margin) { fMarginLeft = margin; }
0735 
0736   // Setter for right margin
0737   void SetRightMargin(double margin) { fMarginRight = margin; }
0738 
0739   // Setter for bottom margin
0740   void SetBottomMargin(double margin) { fMarginBottom = margin; }
0741 
0742   // Setter for top margin
0743   void SetTopMargin(double margin) { fMarginTop = margin; }
0744 
0745   /*
0746    * Set all the margins for canvas
0747    *
0748    * double left = new left margin
0749    * double right = new right margin
0750    * double top = new top margin
0751    * doulbe bottom = new bottom margin
0752    */
0753   void SetMargins(double left, double right, double top, double bottom) {
0754     fMarginLeft = left;
0755     fMarginRight = right;
0756     fMarginTop = top;
0757     fMarginBottom = bottom;
0758   }
0759 
0760   // Setter for x-axis title offset
0761   void SetTitleOffsetX(double offset) { fTitleOffsetX = offset; }
0762 
0763   // Setter for y-axis title offset
0764   void SetTitleOffsetY(double offset) { fTitleOffsetY = offset; }
0765 
0766   // Setter for x-axis title size
0767   void SetTitleSizeX(double size) { fTitleSizeX = size; }
0768 
0769   // Setter for y-axis title size
0770   void SetTitleSizeY(double size) { fTitleSizeY = size; }
0771 
0772   // Setter for x-axis label offset
0773   void SetLabelOffsetX(double offset) { fLabelOffsetX = offset; }
0774 
0775   // Setter for y-axis label offset
0776   void SetLabelOffsetY(double offset) { fLabelOffsetY = offset; }
0777 
0778   // Setter for x-axis label size
0779   void SetLabelSizeX(double size) { fLabelSizeX = size; }
0780 
0781   // Setter for y-axis label size
0782   void SetLabelSizeY(double size) { fLabelSizeY = size; }
0783 
0784   // Setter for number of divisions in x-axis
0785   void SetNDivisionsX(int div) { fDivisionsX = div; }
0786 
0787   // Setter for number of divisions in y-axis
0788   void SetNDivisionsY(int div) { fDivisionsY = div; }
0789 
0790   // Setter for the font
0791   void SetFont(int fontIndex) { fFont = fontIndex; }
0792 
0793   /*
0794    * Apply the settings that are given to JDrawer to a given histogram
0795    *
0796    *  TH1 *histo = Histogram that is styled
0797    *  TString xTitle = title for the x axis
0798    *  TString yTitle = title for the y axis
0799    */
0800   void ApplyStyleSettings(TH1 *histo, TString xTitle = "", TString yTitle = "") {
0801     SetHistogramStyle(histo, xTitle, yTitle);
0802   }
0803 
0804   /*
0805    * Set all the appearance factors for the histogram
0806    *
0807    * double titoffx = Offset of the x-axis title
0808    * double titoffy = Offset of the y-axis title
0809    * double titsizex = Size of the x-axis title
0810    * double titsizey = Size of the y-axis title
0811    * double labeloffx = Offset of the x-axis label
0812    * double labeloffy = Offset of the y-axis label
0813    * double labelsizex = Size of the x-axis label
0814    * double labelsizey = Size of the y-axis label
0815    * int divx = The number of divisions in x-axis
0816    * int divy = The number of divisions in y-axis
0817    * int fontIndex = Font index for titles and labels
0818    */
0819   void SetHistogramAppearance(double titoffx,
0820                               double titoffy,
0821                               double titsizex,
0822                               double titsizey,
0823                               double labeloffx,
0824                               double labeloffy,
0825                               double labelsizex,
0826                               double labelsizey,
0827                               int divx,
0828                               int divy,
0829                               int fontIndex) {
0830     fTitleOffsetX = titoffx;    // Offset of the x-axis title
0831     fTitleOffsetY = titoffy;    // Offset of the y-axis title
0832     fTitleSizeX = titsizex;     // Size of the x-axis title
0833     fTitleSizeY = titsizey;     // Size of the y-axis title
0834     fLabelOffsetX = labeloffx;  // Offset of the x-axis label
0835     fLabelOffsetY = labeloffy;  // Offset of the y-axis label
0836     fLabelSizeX = labelsizex;   // Size of the x-axis label
0837     fLabelSizeY = labelsizey;   // Size of the y-axis label
0838     fDivisionsX = divx;         // The number of divisions in x-axis
0839     fDivisionsY = divy;         // The number of divisions in y-axis
0840     fFont = fontIndex;          // Font index for titles and labels
0841   }
0842 
0843   /*
0844    * Setter for the scale of the x-axis
0845    *
0846    * bool log = true, if logarithmic axis, false if linear axis
0847    */
0848   void SetLogX(bool log = true) {
0849     if (log) {
0850       fLogX = 1;
0851     } else {
0852       fLogX = 0;
0853     }
0854   }
0855 
0856   /*
0857    * Setter for the scale of the y-axis
0858    *
0859    * bool log = true, if logarithmic axis, false if linear axis
0860    */
0861   void SetLogY(bool log = true) {
0862     if (log) {
0863       fLogY = 1;
0864     } else {
0865       fLogY = 0;
0866     }
0867   }
0868 
0869   /*
0870    * Setter for the scale of the z-axis
0871    *
0872    * bool log = true, if logarithmic axis, false if linear axis
0873    */
0874   void SetLogZ(bool log = true) {
0875     if (log) {
0876       fLogZ = 1;
0877     } else {
0878       fLogZ = 0;
0879     }
0880   }
0881 
0882   // Getter for the displacement of the drawn canvas in x-direction
0883   int GetCanvasDisplacementX() { return fTopLeftX; }
0884 
0885   // Getter for the displacement of the drawn canvas in y-direction
0886   int GetCanvasDisplacementY() { return fTopLeftY; }
0887 
0888   // Setter for the displacement of the drawn canvas in x-direction
0889   void SetCanvasDisplacementX(int displacement) { fTopLeftX = displacement; }
0890 
0891   // Setter for the displacement of the drawn canvas in y-direction
0892   void SetCanvasDisplacementY(int displacement) { fTopLeftY = displacement; }
0893 
0894   /*
0895    * Setter for the displacement of the canvas from the top left corner
0896    *
0897    * int x = displacement in x-direction
0898    * int y = displacement in y-direction
0899    */
0900   void SetCanvasDisplacement(int x, int y) {
0901     SetCanvasDisplacementX(x);
0902     SetCanvasDisplacementY(y);
0903   }
0904 
0905   /*
0906    * Setter for displacement using an index
0907    *
0908    *  int index = index number for the canvas
0909    *
0910    *  The position of the canvas is decided in the following way:
0911    *  The displacement of two consecutive canvases in the x-direction is fCanvasDisplacementX.
0912    *  The canvases are put it one row, until there is fCanvasesInOneRow canvases in that row.
0913    *  After this, the next canvas is put in the next row fCanvasDisplacementY under the first
0914    *  canvas in the preceeding row. Then the next row is filled as the previous.
0915    */
0916   void SetCanvasDisplacement(int index) {
0917     SetCanvasDisplacementX(fCanvasDisplacementX * (index % fCanvasesInOneRow) + 10);
0918     SetCanvasDisplacementY(fCanvasDisplacementY * (index - index % fCanvasesInOneRow) / fCanvasesInOneRow + 10);
0919   }
0920 
0921   /*
0922    * Setter for canvas displacement settings
0923    *
0924    *  int displacementX = Displacement of the canvas for one index in x-direction
0925    *  int displacementY = Displacement of the canvas for one index in y-direction
0926    *  int canvasesInRow = Number of canvases in a row before a new row is started
0927    */
0928   void SetCanvasDisplacementSettings(int displacementX, int displacementY, int canvasesInRow) {
0929     fCanvasDisplacementX = displacementX;
0930     fCanvasDisplacementY = displacementY;
0931     fCanvasesInOneRow = canvasesInRow;
0932   }
0933 
0934   /*
0935    * Setter for number of canvases in one row
0936    *
0937    *  int canvasesInRow = Number of canvases in a row before a new row is started
0938    */
0939   void SetNumberOfCanvasesInOneRow(int canvasesInRow) { fCanvasesInOneRow = canvasesInRow; }
0940 
0941   /*
0942    * Setter for the size of the drawn canvas
0943    *
0944    * int width = width of the canvas
0945    * int height = height of the canvas
0946    */
0947   void SetCanvasSize(int width, int height) {
0948     fCanvasWidth = width;
0949     fCanvasHeight = height;
0950   }
0951 
0952   /*
0953    * Setter for grid in x-axis
0954    */
0955   void SetGridX(bool grid = true) {
0956     if (grid) {
0957       fGridX = 1;
0958     } else {
0959       fGridX = 0;
0960     }
0961   }
0962 
0963   /*
0964    * Setter for grid in y-axis
0965    */
0966   void SetGridY(bool grid = true) {
0967     if (grid) {
0968       fGridY = 1;
0969     } else {
0970       fGridY = 0;
0971     }
0972   }
0973 
0974   /*
0975    * Setter for grids in both axes
0976    */
0977   void SetGrid(int gridX, int gridY) {
0978     SetGridX(gridX);
0979     SetGridY(gridY);
0980   }
0981 
0982   /*
0983    * Setter for grid in x-axis
0984    */
0985   void SetTickX(bool tick = true) {
0986     if (tick) {
0987       fTickX = 1;
0988     } else {
0989       fTickX = 0;
0990     }
0991   }
0992 
0993   /*
0994    * Setter for grid in y-axis
0995    */
0996   void SetTickY(bool tick = true) {
0997     if (tick) {
0998       fTickY = 1;
0999     } else {
1000       fTickY = 0;
1001     }
1002   }
1003 
1004   /*
1005    * Setter for grids in both axes
1006    */
1007   void SetTick(int tickX, int tickY) {
1008     SetTickX(tickX);
1009     SetTickY(tickY);
1010   }
1011 
1012   /*
1013    * Setter for split ratio
1014    */
1015   void SetSplitRatio(double split) { fSplitRatio = split; }
1016 
1017   /*
1018    * Set the appearance values for splitted canvas as their default values
1019    * Different values than for single canvas are needed, so there is a different setter too
1020    *
1021    * Note: SetHistogramAppearance(titoffx, titoffy, titsizex, titsizey, labeloffx, labeloffy, labelsizex, labelsizey, divx, divy, fontIndex)
1022    */
1023   void SetDefaultAppearanceSplitCanvas() {
1024     Reset();
1025     //SetHistogramAppearance(2.5, 2.5, 20, 20, 0.01, 0.001, 16, 16, 505, 505, 43); // Smaller label size for axes
1026     SetHistogramAppearance(2.5, 2.3, 25, 25, 0.01, 0.001, 20, 20, 505, 505, 43);  // Increased label size for axes
1027     SetSplitRatio(0.4);
1028     SetRelativeCanvasSize(1.1, 0.7);
1029     SetMargins(0.21, 0.05, 0.09, 0.1);  // Left, right, top, bottom
1030   }
1031 
1032   /*
1033    * Set the appearance values for graph to default values
1034    */
1035   void SetDefaultAppearanceGraph() {
1036     Reset();
1037     SetHistogramAppearance(0.9, 1.3, 0.06, 0.05, 0.01, 0.001, 0.05, 0.05, 505, 505, 42);
1038     SetRelativeCanvasSize(0.8, 1);
1039     SetLeftMargin(0.17);
1040   }
1041 
1042   /*
1043    * Set the appearance values for row of graphs
1044    */
1045   void SetDefaultAppearanceGraphRow() {
1046     Reset();
1047     SetHistogramAppearance(0.9, 1.3, 0.06, 0.05, 0.01, 0.001, 0.05, 0.05, 505, 505, 42);
1048     SetRelativeCanvasSize(0.8, 3);
1049     SetLeftMargin(0.17);
1050   }
1051 
1052   /*
1053    * Getter for pad according to the ID number
1054    */
1055   TPad *GetPad(int padNumber) {
1056     switch (padNumber) {
1057       case 0:
1058         return fLeftRowPad;
1059 
1060       case 1:
1061         return fMiddleRowPad;
1062 
1063       case 2:
1064         return fRightRowPad;
1065 
1066       case 3:
1067         return fUpperSplitPad;
1068 
1069       case 4:
1070         return fLowerSplitPad;
1071 
1072       default:
1073         return nullptr;
1074     }
1075   }
1076 
1077   /*
1078    * Getter for pad according to the ID number
1079    */
1080   void SelectPad(int padNumber) {
1081     switch (padNumber) {
1082       case 0:
1083         fLeftRowPad->cd();
1084         break;
1085 
1086       case 1:
1087         fMiddleRowPad->cd();
1088         break;
1089 
1090       case 2:
1091         fRightRowPad->cd();
1092         break;
1093 
1094       case 3:
1095         fUpperSplitPad->cd();
1096         break;
1097 
1098       case 4:
1099         fLowerSplitPad->cd();
1100         break;
1101 
1102       default:
1103         std::cout << "Pad " << padNumber << " not found" << std::endl;
1104         break;
1105     }
1106   }
1107 
1108   /*
1109    * Getter for the upper pad
1110    */
1111   TPad *GetUpperPad() { return fUpperSplitPad; }
1112 
1113   /*
1114    * Getter for the lower pad
1115    */
1116   TPad *GetLowerPad() { return fLowerSplitPad; }
1117 
1118   /*
1119    * Select the upper pad
1120    */
1121   void SelectUpperPad() { fUpperSplitPad->cd(); }
1122 
1123   /*
1124    * Select the upper pad
1125    */
1126   void SelectLowerPad() { fLowerSplitPad->cd(); }
1127 
1128   /*
1129    * Set the canvas size using scaling factor and aspect ratio
1130    *
1131    *  double relativeSize = multiplication factor for the default canvas height of 600 pixels
1132    *  double aspectRatio = the ratio canvas width / canvas height
1133    */
1134   void SetRelativeCanvasSize(double relativeSize, double aspectRatio) {
1135     fCanvasHeight = 600 * relativeSize;
1136     fCanvasWidth = aspectRatio * fCanvasHeight;
1137   }
1138 
1139   /*
1140    * Get the name of the considered canvas
1141    */
1142   TString GetCanvasName() {
1143     if (fCanvas == nullptr) {
1144       std::cout << "Error: No canvas defined! Cannot return name." << std::endl;
1145       return "";
1146     }
1147     TString name = Form("%s", fCanvas->GetName());
1148     return name;
1149   }
1150 
1151   /*
1152    * Set the drawing range for a pad to draw geometric objects to it
1153    *
1154    *  double xLow = minimum x-axis range
1155    *  double yLow = minimum y-axis range
1156    *  double xHigh = maximum x-axis range
1157    *  double yHigh = maximum y-axis range
1158    */
1159   void SetPadRange(double xLow, double yLow, double xHigh, double yHigh) {
1160     // TODO: Setting range also for split canvas
1161     fSinglePad->Range(xLow, yLow, xHigh, yHigh);
1162     fSinglePad->Clear();
1163   }
1164 };
1165 
1166 #endif