AliPainter & AliDrawStyle

Description and usage of QA visualization tools
Boris Rumyantsev
Marian Ivanov
July 2018

Content:

1. Introduction

2. Getting the sources

3. Styling

3.1. Syntax of CSS

3.2. Simple examples

3.3. Local styles

3.4. Applications

4. Projections analysis of n-dimensional histograms

4.1. Purposes

4.2. Interface of AliPainter::DrawHistogram()

4.3. Examples of usage AliPainter::DrawHistogram()

4.3.1 Data preparation

4.3.2 Projection analysis

5. Division of plotting area

5.1. Interface of AliPainter::DivideTPad()

5.2 Usage of AliPainter::DivideTPad()

6. Building reports



1. Introduction

This is the jupyter notebook with description of principles for working with AliPainter and AliDrawStyle prototypes. This tools provide to users opportunity to set style of their objects and use simple generators for drawing.

Requirements
  • root6 for jupyter usage and terminal;
  • root5 only from terminal;

2. Getting the sources:

First of all, you should take last version of AliPainter and AliDrawStyle. Now the last changes into the master branch, but this is the [github repositoriy](https://github.com/miranov25/AliRoot), which you could also check for the latest modifications.


AliTMinuitToolkit unstable in root6, so be carefull with usage it in fitting part of AliPainter.


Definitions of used variables

Here we defined variables, which we will use below. We are using root and it's not allowing redefinition of variables, unlike python.


In [1]:
%jsroot off

In [2]:
//define all used variables
//%jsroot //allows to get dynamic plots
TH1D *eHis = new TH1D("eHis", "eHis", 100,-5,5);
TCanvas *exC1;
TCanvas *C;
TH1F *hsBeforeStyling[5];
TH1F *hsAfterStyling[5];
TRandom3 rng;
Double_t px,py;
TObjArray *styleArray;
TString cssString;
TPad *cPad;

TFile::SetCacheFileDir(".");
TFile *finput;
TTree *tree;
TObjArray *hisArray;
TList *keys;

TCanvas *canvasQA;

TString elementID = "";
TString classID = "";
TString objectID = "";
TString localStyle = "";


3. Styling

The default tools for modifying of objects style in root looks not so good, because you should create macro in which you should describe all objects and styles manually. It is the reason why we provide to users special tools for styling based on CSS syntax. Let's closer look to syntax of our tool:


3.1 Syntax of CSS

A CSS rule-set consists of a selector and a declaration block:

As you can see on this pictures css provide us the opportunity to select object using selector, and set value for the property. In our case we have 3 type of selectors:

  • elementID ↦ root class name;
  • classID ↦ something like tag in object name;
  • objectID ↦ the name of object;

You can see how our parser works:


In [3]:
//let initialize empty string,which will be filled after parsing
elementID = "";
classID = "";
objectID = "";
localStyle = "";

//You can see here, how you can set classID,styleID,objectID and elementID to the your element: 
pHis = new TH1D("someName.class(classA,classB).style(marker-size:10px;)", "someTitle", 100,-5,5);
AliDrawStyle::GetIds((TObject *) pHis, elementID, classID, objectID, localStyle, 4);


Info in <AliDrawStyle>: Object with name "someName.class(classA,classB).style(marker-size:10px;)" was parsed via AliDrawStyle::GetIds() to elementID = "TH1D", classID = "classA,classB", objectID = "someName", localStyle = "marker-size:10px;"

As you can see in Info message (you can manage it using (int) 4 as last argument. In this case you will get detailed output), our objects with the name "someName.class(classA,classB).style(marker-size:10px;)" was parsed to the next things:

  • elementID ↦ TH1D
  • classID ↦ classA,classB
  • objectID ↦ someName
  • objectID ↦ marker-size:10px;

You can use these selectors separately or combine them for managing style of your object

Let's go to the exampes!
3.2 Simple examples

Let's create a some object and closer look to how we can create css file, register it into our active environment and apply it:

First of all, let's remember how we can change the style using standart tools:


In [4]:
// We will take real example from root documentation (a bit simplified). You can see it here:
//https://root.cern/doc/master/histpalettecolor_8C.html
C = new TCanvas("C", "C",980,450);
C->Divide(2,1);
C->cd(1);
for (Int_t j = 0; j <5; ++j) {
    hsBeforeStyling[j] = new TH1F (TString::Format("h%d", j).Data(),"",100,-4,4);
    hsBeforeStyling[j]->SetStats(kFALSE);
    for (Int_t i = 0; i < 25000; ++i) {
        rng.Rannor(px,py);
        hsBeforeStyling[j]->Fill(px,10-j*2);
    }
    if (j == 0)
      hsBeforeStyling[j]->Draw("");
    else
      hsBeforeStyling[j]->Draw("SAME");
      hsAfterStyling[j] = (TH1F *)hsBeforeStyling[j]->Clone(TString::Format("hn%d", j).Data());
}

C->cd(2);
hsAfterStyling[0]->SetMarkerStyle(kFullCircle);
hsAfterStyling[1]->SetMarkerStyle(kFullSquare);
hsAfterStyling[2]->SetMarkerStyle(kFullTriangleUp);
hsAfterStyling[3]->SetMarkerStyle(kFullTriangleDown);
hsAfterStyling[4]->SetMarkerStyle(kOpenCircle);
hsAfterStyling[0]->SetMarkerColor(928);
hsAfterStyling[1]->SetMarkerColor(kAzure+1);
hsAfterStyling[2]->SetMarkerColor(kTeal-1);
hsAfterStyling[3]->SetMarkerColor(kYellow+1);
hsAfterStyling[4]->SetMarkerColor(5);
for (Int_t j = 0; j <5; ++j) {
     if (j == 0)
      hsAfterStyling[j]->Draw("");
    else
      hsAfterStyling[j]->Draw("SAME");
}
C->Draw();


Now we've got our canvas with 5 simple gauses or TH1F objects and we modified the style of it using macro style coding.

Now lets see how it looks like with CSS file:

Before we start, let's clearify one moment: here we are using jupyter notebook, so I will define style right here, but in real case more native is create file with .css extension for it. Almost all modern editors and ide supports hightlighting of css syntax, so you css style could looks like:

In order to add your style you should use this function:

AliDrawStyle::RegisterCssStyle(const char *nameOfAddingStyle, TObjArray *arrayWithStyle);

arrayWithStyle consists from TNamed objects, Name of this objects describes selectors and Title describes declarations. In normal case you can parse your .css file into array using

AliDrawStyle::ReadCSSFile("fullName.css"));

So registration of style should looks like:

AliDrawStyle::RegisterCssStyle("nameOfyourStyle", AliDrawStyle::ReadCSSFile("path/to/your/file.css"));

But I want to make my notebook regardless of side files, so we will create array manually:


In [5]:
// Let's define TString with the same style as in example above: selector and declaration
// Pay your attention to the csv interface for values for properties. 
// This is a main difference with the real css.
cssString = "TH1F {\n\
                   marker-style: 20,21,22,23,24;\n\
                   marker-color: 928,861,839,401,5;\n\
                  }";
// Then we should register our style, it means upload all values into the memory.
// Do not forget register your style after moifications.
AliDrawStyle::RegisterCssStyle("test", AliDrawStyle::ReadCssString(cssString));
// Finally just apply your style to pad or canvas with your objects, 
// it works recursively for each object including pads or canvas.
AliDrawStyle::ApplyCssStyle(((TPad *)C->cd(2)), "test");
C->Draw();


Exercise 1:

Try to play with style. Change styles of markers, colors, sizes:


In [6]:
// please try to play with it
// try to change style as you wish
cssString = "TH1* {\n\
                    marker-style: 2,3,4,5,2;\n\
                    marker-color: 1,2,3,4,4;\n\
                    marker-size:10px,15px,20px,25px,30px;\n\
                  }";
AliDrawStyle::RegisterCssStyle("exc1", AliDrawStyle::ReadCssString(cssString));
AliDrawStyle::ApplyCssStyle(((TPad *)C->cd(2)), "exc1");
C->Draw();


3.3 Local styles

As in real web development you can set style right in name of your object. In this case such style will have highest priority and the rest style in file will be ignore for this object and specified property. Let see how it works:


In [7]:
hsAfterStyling[0]->SetName("nm.style(marker-color:#ff69b4;marker-size:2;)");
// As you can see color and size of first object will not change after reading string with style, because it
// defined locally in the name of object;
cssString = "TH1F {\n\
                    marker-style: 20,21,22,23,24;\n\
                    marker-color: 928,861,839,401,5;\n\
                    marker-size:10px;\n\
                  }";
AliDrawStyle::RegisterCssStyle("test", AliDrawStyle::ReadCssString(cssString));
AliDrawStyle::ApplyCssStyle(((TPad *)C->cd(2)), "test");
C->Draw();


3.4 Applications

Untill now we used only elementID let's see how we can use css in simple alarm application:

</p>Let's imagine that we have some parameter, which should not be more than some value. You can specify style for three cases:</p>

  • Normal: a <= 4000;
  • Warning: 4000 < a < 6000;
  • Alarm: a >= 6000;

In [8]:
%%cpp
void CheckState(TH1F *his) {
  exC1 = new TCanvas("exC1", "exC1",980,450);
  exC1->cd(1);
  if(his->GetMaximum()<=4000)
    his->SetName("h.class(normal)");
  else if (his->GetMaximum()>4000 && his->GetMaximum()<6000)
    his->SetName("h.class(warning)");
  else if (his->GetMaximum()>600)
    his->SetName("h.class(alarm)");
  his->Draw();
}

In [9]:
cssString = ".normal {\n\
                        marker-style:20;\n\
                        marker-color:#00ff00;\n\
                        marker-size:15px;\n\
                      }\n\
                      \
             .warning {\n\
                        marker-style:21;\n\
                        marker-color:rgb((0,0,255);\n\
                        marker-size:2;\n\
                        }\n\
                        \
             .alarm {\n\
                        marker-style:22;\n\
                        marker-color:2;\n\
                        marker-size:15px;\n\
                    }";
CheckState(hsBeforeStyling[3]);
AliDrawStyle::RegisterCssStyle("alarm", AliDrawStyle::ReadCssString(cssString));
AliDrawStyle::ApplyCssStyle(exC1, "alarm");
exC1->Draw();


Exercise 2:

Below I provide canvas with objects for you and show list of part properties which you can manage. Try to do with it whatever you want:

Some properties of objects which you can change using css:

  • marker-color
  • marker-size
  • marker-style
  • line-color
  • line-width
  • line-style
  • fill-color
  • fill-style
  • gridX
  • gridY
  • fill-color
  • tickX
  • tickY

In [10]:
// please try to play with it
// try to change style as you wish
C = new TCanvas("C", "C",980,450);
pad = new TPad("pad", "pad",0,0,1,1);
pad->Draw();
pad->cd();
hsBeforeStyling[0]->Fit("gaus");
hsBeforeStyling[0]->Draw("");
C->Draw();

//let's change something:
cssString = "TH1* {\n\
                    marker-style:20;\n\
                    marker-color: 928;\n\
                    marker-size:10px;\n}\n\
                                          \
             TF1* {\n\
                    line-color:7;\n\
                    line-width:3;\n\
                  }\n\
                     \
             TPad {\n\
                    gridX:1;\n\
                    gridY:1;\n\
                    fill-color:#e4e4e4;\n\
                    tickX:1;\n\
                    tickY:1;\n\
                    }";

AliDrawStyle::RegisterCssStyle("exc2", AliDrawStyle::ReadCssString(cssString));
AliDrawStyle::ApplyCssStyle(C, "exc2");

C->Draw();


Warning in <TCanvas::Constructor>: Deleting canvas with same name: C
 FCN=73.3518 FROM MIGRAD    STATUS=CONVERGED      54 CALLS          55 TOTAL
                     EDM=1.1917e-07    STRATEGY= 1      ERROR MATRIX ACCURATE 
  EXT PARAMETER                                   STEP         FIRST   
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE 
   1  Constant     8.01647e+03   6.21626e+01   2.13784e-01   9.41206e-06
   2  Mean        -1.06142e-03   6.29589e-03   2.65062e-05   8.75563e-03
   3  Sigma        9.92526e-01   4.45151e-03   5.12724e-06   2.81539e-01

4. Projections analysis of n-dimensional histograms

Here we closer look to the tools for drawing, fitting, slicing of projections of n-dimensional histograms. This class called AliPainter.

4.1 Purposes

Our goal is provide to user full access to the data. You can work with n-dimensional histogram and build your own projections don't care about lost data.

Two main functions called:

1. AliPainter::DrawHistogram();

2. AliPainter::DivideTPad();

4.2 Interface of AliPainter::DrawHistogram()

Let see what you can do with our tool. Now we've next features:

1. Building 1d,2d,3d projections;

2. Setting ranges, including smart slicers (python arrays syntax);

3. Standart root fitters and only for root5 fitter created by AliTMinuitToolkit;

4. Drawing option including adding classes, local styles and divisions;


Here is the interface which we provide to you for working with THnBase.

static void AliPainter::DrawHistogram(THnBase *hisN, const char *expression, TPad *pad=nullptr,\
                                      TObjArray *keepArray=nullptr, TObjArray *metaData=nullptr,\
                                      Int_t verbose=0);

static void AliPainter::DrawHistogram(const TObjArray *histogramArray, const char *expression, TPad *=nullptr,\
                                      TObjArray *=nullptr, TObjArray *=nullptr, Int_t =0);

As you can see here AliPainter::DrawHistogram() is overloaded method, wich allows to use array of THnBase objects or directly THnBase object.

Description of arguments:

◉ hisN(histogramArray) - input n-dimensional histogram (array of n-dim histograms) which projections you want to draw;

◉ expression - special query which allows to specify ranges, projections, fitters, drawing options. In general, input expression looks like

histogramName(`)(`)(`)(`

◆ ` - string specify which slice of your THn you want to draw:

1. (0,10,0,20,0,30) using integer numbers will return:

THn::GetAxis(0)->SetRange(0,10)
                              THn::GetAxis(1)->SetRange(0,20)
                              THn::GetAxis(2)->SetRange(0,30)

2. (0.,10.,0.,20.,0.,30.) using float numbers will return:

THn::GetAxis(0)->SetRangeUser(0.,10.)
                              THn::GetAxis(1)->SetRangeUser(0.,20.)
                              THn::GetAxis(2)->SetRangeUser(0.,30.)

3. (0,10,0:20:10:10,0,30) using python array slicers (:) will return to user array of histograms. Algorithm of generating slices is (start:finish:step:delta)

for (auto i = start; i <= finish - delta; i+=step)
                              {
                                  startVal = i;
                                  finishVal = i + delta;
                              }

E.g. 0:20:10:10 will be transform into

0,10;10,20;

So, in our example ranges will be:

//hisN1
                              THn::GetAxis(0)->SetRange(0,10)
                              THn::GetAxis(1)->SetRange(0,10)
                              THn::GetAxis(2)->SetRange(0,30)
                              //hisN2
                              THn::GetAxis(0)->SetRange(0,10)
                              THn::GetAxis(1)->SetRange(10,20)
                              THn::GetAxis(2)->SetRange(0,30)

◆ ` - specify what projections you want to get:

new projection created THn his = hisInput->Projection(i0,i1....);

at minimum one dimension should be specified, maximum 3D;

◆ ` - (fitterName,fitOption,ranges):

1. fitterName - standard root fit functions. Also supports AliTMinuitToolkit fitters, but only in root5);

2. fitOption - standard root fit options. For root 5 also you can look to AliTMinuitToolkit fitOptions;

3. range - {x0min,x0max,x1min,xm1max,...} in case not specified - range is not set;

◆ ` - (div, lims, className, drawOpt):

1. padDiv - parameter which specified switch pad option:

div = 0 - use the same pad for drawing; (default value);

div = 1 - switch from current pad to the next pad for drawing;

2. lims - allows to set limits for specified axis(not specified by default). Support statistical units and expressions:

xlim = [xmin, xmax] - set the minima and maxima for x-axes;

ylim = [ymin, ymax] - set the minima and maxima for y-axes;

2.1 Numbers: ylim=[100,200];

2.2 Stats units: ylim=[, ];

2.3 Expression with stat units:

ylim=[0.5*`,1.5*`] - or whatever according with TFormula rules;

zlim = [zmin, zmax] - set the minima and maxima for z-axes;

3. className - adds name of class to each object of drawing. It necessary for applying css style. [See AliDrawStyle](http://alidoc.cern.ch/AliRoot/master/class_ali_draw_style.html)

class = [Raw,Error] - in the end of name of object will add ".class(Raw,Error)";

class = Raw - the same with class=[Raw] will add .class(Raw);

class = [] - in this case nothing will add to the end of the name of object (default);

4. drawOpt - root standard draw options [see docs](https://root.cern.ch/root/htmldoc/guides/users-guide/Histograms.html#draw-options)


◉ pad - you can specify which pad you want to use for drawing. In case div=1 in drawingOptions this pad will be starting point. (by default NULL and DrawHistogram use gPad)

◉ keepArray - array for keeping temporary objects.

◉ metaData - array with metadata describing histogram.

4.3. Examples of usage AliPainter::DrawHistogram()

First of all let's prepare the data. Let's use something more real then our histogram before.

4.3.1 Data preparation

In [11]:
// we prepared file which you can download without registration. let's use it:
finput = TFile::Open("http://aliqatrkeos.web.cern.ch/aliqatrkeos/performance/AliPainterTest.root","CACHEREAD");
tree = (TTree *) finput->Get("hisPtAll");
keys = finput->GetListOfKeys();
// then we created array with THn histograms
hisArray = new TObjArray();
for (Int_t iKey = 0; iKey<keys->GetEntries();iKey++) {
    TObject *o = finput->Get(TString::Format("%s;%d", keys->At(iKey)->GetName(), ((TKey *) keys->At(iKey))->GetCycle()).Data());
    hisArray->AddLast(o);
}


Info in <TFile::OpenFromCache>: using local cache copy of http://aliqatrkeos.web.cern.ch/aliqatrkeos/performance/AliPainterTest.root [./aliqatrkeos/performance/AliPainterTest.root]

4.3.2 Projection analysis

Let's move step by step. First of all for the projections analysis we should get the projections:


In [12]:
canvasQA = new TCanvas("canvasQA", "canvasQA", 1200, 800);
AliPainter::DrawHistogram(hisArray, "hisK0DMassQPtTgl()(0)()()");
canvasQA->Draw();


Now let's choose some part of ranges:


In [13]:
// if you don't remember numbers of bin you can use float numbers for ranges, it means that SetRangeUser will be used:
canvasQA = new TCanvas("canvasQA", "canvasQA", 1200, 800);
canvasQA->Divide(1,3);
canvasQA->cd(1);
AliPainter::DrawHistogram(hisArray, "hisK0DMassQPtTgl(-0.01,0.01)(0)()()");
canvasQA->Draw();
// in the other case you can use just number of bins:
canvasQA->cd(2);
AliPainter::DrawHistogram(hisArray, "hisK0DMassQPtTgl(20,80)(0)()()");
canvasQA->Draw();
// let's see how we can use slicers. Imagine that you can see all bins of first projections and
// two periods of second projection, let it bee 40,60 and 60,80, if we know that total of bins are 80:
canvasQA->cd(3);
AliPainter::DrawHistogram(hisArray, "hisK0DMassQPtTgl(0,100,40:80:20:20)(0)()()");
canvasQA->Draw();


Warning in <TCanvas::Constructor>: Deleting canvas with same name: canvasQA

Pay your attention to the last pad. As you can see here it provide us two histogram on the one pad, but you be able to change it using [div](#div) flag in [drawString](#drawString). Let's see what happend if we add it, but first of all we should prepare two pads:


In [14]:
canvasQA = new TCanvas("canvasQA", "canvasQA", 1200, 800);
canvasQA->Divide(1,2);
canvasQA->cd(1);
AliPainter::DrawHistogram(hisArray, "hisK0DMassQPtTgl(0,100,40:80:20:20)(0)()(div=1)");
canvasQA->Draw();


Warning in <TCanvas::Constructor>: Deleting canvas with same name: canvasQA
Warning in <TFile::Append>: Replacing existing TH1: hisK0DMassQPtTgl.ranges(0,100,40,60)_proj_0 (Potential memory leak).
Warning in <TFile::Append>: Replacing existing TH1: hisK0DMassQPtTgl.ranges(0,100,40,60,0,100,60,80)_proj_0 (Potential memory leak).

As you can see in output of previous cell AliPainter switched active pad automatically. It means that you can use set of pads and we also provided to you opportunity to dividing pads, but we will tell about it later. Let's go further and let's see to fitting option and add drawOpt:


In [15]:
canvasQA = new TCanvas("canvasQA", "canvasQA", 1200, 800);
AliPainter::DrawHistogram(hisArray, "hisK0DMassQPtTgl(20,80,40,60,0,10)(0)(name=gaus,option=W)(drawOpt=E)");
canvasQA->Draw();


 FCN=1.81567e+07 FROM MIGRAD    STATUS=CONVERGED      73 CALLS          74 TOTAL
                     EDM=9.80376e-12    STRATEGY= 1  ERROR MATRIX UNCERTAINTY   2.3 per cent
  EXT PARAMETER                                   STEP         FIRST   
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE 
   1  Constant     1.01328e+04   3.57940e-01  -2.34384e-04   1.07188e-05
   2  Mean        -1.50485e-04   1.70800e-07   2.94877e-10   2.72341e+01
   3  Sigma        4.41587e-03   1.97307e-07  -1.96861e-08   3.52321e-02
Warning in <TCanvas::Constructor>: Deleting canvas with same name: canvasQA

Now let's talk about divisions of canvas.


5. Division of plotting area

How you already know in root we have canvases and pads. We can use our dividing function to both of this classes.


5.1 Interface of AliPainter::DivideTPad()

Let see what you can do with our tool. Now we've next features:

1. You can get any combinations of pads on the canvas;

2. Share axis in order to combine pads;

3. Set any margin values in pixels;


Main function for dividing is:

AliPainter::DivideTPad(TPad *pad, const char *division, const char *classID="",\
                       const char *style="", Int_t verbose=0)

◉ pad - input pad or canvas.

◉ division string - ``[numberOfPads`[sharedMargin`]`[units`]`, numberOfPads`[shareMargin`]`[units`]`, ...].

◆ orientation - (vertical, horizontal):

vertical - it's allows to you choose vertical orientation

horizontal - it's allows to you choose vertical orientation (default)

◆ numberOfPads - it should be specify like csv array. E.g. "1,1" it means two pads. If orientation is vertical it will looks like column, if horizontal like row. Also you can specify more than one pad: e.g in this case "2,1" it means in case horizontal orientation two pads in first row and one in the second raw. So in case of horizontal orientation count of numbers will be count of rows and the number will be specify number of pads in row. In case vertical orientation it will look like you transpose you horizontal orientation.

◆ sharedMargin - this option allows to you choose wich margin you want to make equal to 0: Each pad has 4 margin(b-bottom, l-left, t-top, r-right). So in case you specify t, it will set top margin to 0, etc. One more useful value is "m" - middle, in case of horizontal orientation it will set right and left margin to 0, in case of vertical orientation top and bottom margin will set to 0.

◆ units - you can set value to the chosen margin explicitly. For that you should specify value and units. E.g. b0.3 means set bottom margin 0.3, or rpx100 means set right margin 100 pixels.

◆ classID - optional parameter for [styling](#style_css_syn).

Let's look to some examples:


5.2 Usage of AliPainter::DivideTPad()

We will use already created histograms.


In [16]:
//horizontal orientation
C = new TCanvas("C", "C",980,450);
AliPainter::DivideTPad(C, "horizontal[1,1]");
C->cd(1);
AliPainter::DrawHistogram(hisArray, "hisK0DMassQPtTgl(20,80,20:80:20:20,0,10)(0)(name=gaus,option=W)(drawOpt=E, div=1)");
C->Draw();


 FCN=3.46253e+09 FROM MIGRAD    STATUS=CONVERGED      67 CALLS          68 TOTAL
                     EDM=2.86699e-11    STRATEGY= 1  ERROR MATRIX UNCERTAINTY   2.1 per cent
  EXT PARAMETER                                   STEP         FIRST   
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE 
   1  Constant     5.44882e+04   3.07508e-01   6.77020e-04   2.33802e-05
   2  Mean        -3.63144e-04   4.12936e-08   1.12338e-10  -6.79076e+01
   3  Sigma        7.06094e-03   5.61047e-08  -4.62395e-09  -1.55287e+00
 FCN=1.81567e+07 FROM MIGRAD    STATUS=CONVERGED      65 CALLS          66 TOTAL
                     EDM=9.76987e-12    STRATEGY= 1  ERROR MATRIX UNCERTAINTY   2.3 per cent
  EXT PARAMETER                                   STEP         FIRST   
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE 
   1  Constant     1.01328e+04   3.57939e-01  -2.34090e-04   1.07059e-05
   2  Mean        -1.50485e-04   1.70800e-07   2.94613e-10   2.71973e+01
   3  Sigma        4.41587e-03   1.97307e-07  -1.96694e-08   3.57854e-02
 FCN=1.48515e+06 FROM MIGRAD    STATUS=CONVERGED      65 CALLS          66 TOTAL
                     EDM=3.68721e-14    STRATEGY= 1  ERROR MATRIX UNCERTAINTY   1.7 per cent
  EXT PARAMETER                                   STEP         FIRST   
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE 
   1  Constant     2.28994e+03   3.49236e-01   1.32828e-04  -7.04605e-07
   2  Mean        -5.37051e-04   7.83511e-07   4.50792e-10   4.99401e-04
   3  Sigma        4.75457e-03   9.35040e-07   5.62589e-08   2.80953e-03
Warning in <TCanvas::Constructor>: Deleting canvas with same name: C

In [17]:
//vertical orientation
C = new TCanvas("C", "C",980,450);
AliPainter::DivideTPad(C, "vertical[1,1]");
C->cd(1);
AliPainter::DrawHistogram(hisArray, "hisK0DMassQPtTgl(20,80,20:80:20:20,0,10)(0)(name=gaus,option=W)(drawOpt=E, div=1)");
C->Draw();


 FCN=3.46253e+09 FROM MIGRAD    STATUS=CONVERGED      66 CALLS          67 TOTAL
                     EDM=2.87864e-11    STRATEGY= 1  ERROR MATRIX UNCERTAINTY   2.1 per cent
  EXT PARAMETER                                   STEP         FIRST   
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE 
   1  Constant     5.44882e+04   3.07507e-01   6.77024e-04   2.34560e-05
   2  Mean        -3.63144e-04   4.12936e-08   1.12338e-10  -6.74948e+01
   3  Sigma        7.06094e-03   5.61047e-08  -4.62401e-09  -1.55287e+00
 FCN=1.81567e+07 FROM MIGRAD    STATUS=CONVERGED      65 CALLS          66 TOTAL
                     EDM=9.76008e-12    STRATEGY= 1  ERROR MATRIX UNCERTAINTY   2.3 per cent
  EXT PARAMETER                                   STEP         FIRST   
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE 
   1  Constant     1.01328e+04   3.57939e-01  -2.34090e-04   1.07123e-05
   2  Mean        -1.50485e-04   1.70800e-07   2.94613e-10   2.71711e+01
   3  Sigma        4.41587e-03   1.97307e-07  -1.96694e-08   3.59699e-02
 FCN=1.48515e+06 FROM MIGRAD    STATUS=CONVERGED      65 CALLS          66 TOTAL
                     EDM=3.67343e-14    STRATEGY= 1  ERROR MATRIX UNCERTAINTY   1.7 per cent
  EXT PARAMETER                                   STEP         FIRST   
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE 
   1  Constant     2.28994e+03   3.49236e-01   1.32828e-04  -7.03872e-07
   2  Mean        -5.37051e-04   7.83511e-07   4.50791e-10   0.00000e+00
   3  Sigma        4.75457e-03   9.35040e-07   5.62589e-08   2.80022e-03
Warning in <TCanvas::Constructor>: Deleting canvas with same name: C

In [18]:
//horizontal for 2 by 2
C = new TCanvas("C", "C",980,450);
AliPainter::DivideTPad(C, "horizontal[2,2]");
C->cd(1);
AliPainter::DrawHistogram(hisArray, "hisK0DMassQPtTgl(20,80,0:80:20:20,0,10)(0)(name=gaus,option=W)(drawOpt=E, div=1)");
C->Draw();


 FCN=1.56598e+10 FROM MIGRAD    STATUS=CONVERGED      70 CALLS          71 TOTAL
                     EDM=2.00411e-09    STRATEGY= 1  ERROR MATRIX UNCERTAINTY   0.8 per cent
  EXT PARAMETER                                   STEP         FIRST   
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE 
   1  Constant     1.46484e+05   2.60688e-01   3.53247e-04  -2.34974e-04
   2  Mean         3.29816e-04   1.68991e-08   3.89125e-11  -4.39693e+03
   3  Sigma        8.74400e-03   2.11459e-08  -1.44756e-09  -3.80797e+01
 FCN=3.46253e+09 FROM MIGRAD    STATUS=CONVERGED      75 CALLS          76 TOTAL
                     EDM=2.83006e-11    STRATEGY= 1  ERROR MATRIX UNCERTAINTY   2.1 per cent
  EXT PARAMETER                                   STEP         FIRST   
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE 
   1  Constant     5.44882e+04   3.07509e-01   6.77002e-04   2.31149e-05
   2  Mean        -3.63144e-04   4.12936e-08   1.12337e-10  -6.83204e+01
   3  Sigma        7.06094e-03   5.61049e-08  -4.62378e-09  -1.55764e+00
 FCN=1.81567e+07 FROM MIGRAD    STATUS=CONVERGED      65 CALLS          66 TOTAL
                     EDM=9.78299e-12    STRATEGY= 1  ERROR MATRIX UNCERTAINTY   2.3 per cent
  EXT PARAMETER                                   STEP         FIRST   
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE 
   1  Constant     1.01328e+04   3.57940e-01  -2.34090e-04   1.07123e-05
   2  Mean        -1.50485e-04   1.70800e-07   2.94613e-10   2.72131e+01
   3  Sigma        4.41587e-03   1.97307e-07  -1.96694e-08   3.56932e-02
 FCN=1.48515e+06 FROM MIGRAD    STATUS=CONVERGED      65 CALLS          66 TOTAL
                     EDM=3.66334e-14    STRATEGY= 1  ERROR MATRIX UNCERTAINTY   1.7 per cent
  EXT PARAMETER                                   STEP         FIRST   
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE 
   1  Constant     2.28994e+03   3.49236e-01   1.32828e-04  -7.01672e-07
   2  Mean        -5.37051e-04   7.83511e-07   4.50792e-10   1.24850e-03
   3  Sigma        4.75457e-03   9.35040e-07   5.62589e-08   2.80488e-03
Warning in <TCanvas::Constructor>: Deleting canvas with same name: C

In [19]:
//vertical for 2 by 1
C = new TCanvas("C", "C",980,450);
AliPainter::DivideTPad(C, "vertical[2m,1tpx50]");
C->cd(1);
AliPainter::DrawHistogram(hisArray, "hisK0DMassQPtTgl(20,80,0:80:20:20,0,10)(0)(name=gaus,option=W)(drawOpt=E, div=1)");
C->Draw();


 FCN=1.56598e+10 FROM MIGRAD    STATUS=CONVERGED      78 CALLS          79 TOTAL
                     EDM=5.58847e-06    STRATEGY= 1  ERROR MATRIX UNCERTAINTY   0.8 per cent
  EXT PARAMETER                                   STEP         FIRST   
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE 
   1  Constant     1.46484e+05   2.60687e-01  -0.00000e+00   1.91044e-03
   2  Mean         3.29816e-04   1.68991e-08  -0.00000e+00   2.13981e+05
   3  Sigma        8.74400e-03   2.11459e-08   0.00000e+00  -2.90531e+03
 FCN=3.46253e+09 FROM MIGRAD    STATUS=CONVERGED      75 CALLS          76 TOTAL
                     EDM=2.82991e-11    STRATEGY= 1  ERROR MATRIX UNCERTAINTY   2.1 per cent
  EXT PARAMETER                                   STEP         FIRST   
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE 
   1  Constant     5.44882e+04   3.07509e-01   6.77019e-04   2.31907e-05
   2  Mean        -3.63144e-04   4.12935e-08   1.12338e-10  -6.74948e+01
   3  Sigma        7.06094e-03   5.61049e-08  -4.62392e-09  -1.54811e+00
 FCN=1.81567e+07 FROM MIGRAD    STATUS=CONVERGED      65 CALLS          66 TOTAL
                     EDM=9.77311e-12    STRATEGY= 1  ERROR MATRIX UNCERTAINTY   2.3 per cent
  EXT PARAMETER                                   STEP         FIRST   
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE 
   1  Constant     1.01328e+04   3.57939e-01  -2.34091e-04   1.06962e-05
   2  Mean        -1.50485e-04   1.70800e-07   2.94614e-10   2.72026e+01
   3  Sigma        4.41587e-03   1.97307e-07  -1.96694e-08   3.52321e-02
 FCN=1.48515e+06 FROM MIGRAD    STATUS=CONVERGED      65 CALLS          66 TOTAL
                     EDM=3.67267e-14    STRATEGY= 1  ERROR MATRIX UNCERTAINTY   1.7 per cent
  EXT PARAMETER                                   STEP         FIRST   
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE 
   1  Constant     2.28994e+03   3.49236e-01   1.32828e-04  -7.02405e-07
   2  Mean        -5.37051e-04   7.83511e-07   4.50792e-10   1.49820e-03
   3  Sigma        4.75457e-03   9.35040e-07   5.62589e-08   2.80953e-03
Warning in <TCanvas::Constructor>: Deleting canvas with same name: C

6. Building reports

Let's do something more sophisticated and real.



In [20]:
canvasQA = new TCanvas("canvasQA", "canvasQA", 1200, 800);
AliPainter::DivideTPad(canvasQA,"horizontal[1,1,1,1]", "Canvas41");
AliPainter::GetNextPad(canvasQA);
//you can find this styles in your sources of AliRoot
AliDrawStyle::RegisterCssStyle("figTemplateHex", AliDrawStyle::ReadCSSFile("$AliRoot_SRC/STAT/test/figTemplateHex.css"));
AliPainter::DrawHistogram(hisArray, "hisPtAll(0,10)(0)()(div=1,drawOpt=E,class=PtAll)");
AliPainter::DrawHistogram(hisArray, "hisPtITS(0,10)(0)()(div=1,drawOpt=E,class=PtIts)");
AliPainter::DrawHistogram(hisArray, "hisK0DMassQPtTgl(1,1)(2)()(div=1,drawOpt=E,class=Tgl)");
AliPainter::DrawHistogram(hisArray, "hisK0DMassQPtTgl(20,80,40:80:20:20,0,10)(0)(name=gaus,option=W)(class=Mass,drawOpt=E)");
AliDrawStyle::ApplyCssStyle(canvasQA, "figTemplateHex");
canvasQA->Draw();


Warning in <TCanvas::Constructor>: Deleting canvas with same name: canvasQA
 FCN=1.81567e+07 FROM MIGRAD    STATUS=CONVERGED      61 CALLS          62 TOTAL
                     EDM=9.78594e-12    STRATEGY= 1  ERROR MATRIX UNCERTAINTY   2.3 per cent
  EXT PARAMETER                                   STEP         FIRST   
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE 
   1  Constant     1.01328e+04   3.57940e-01  -2.34089e-04   1.07059e-05
   2  Mean        -1.50485e-04   1.70800e-07   2.94613e-10   2.72183e+01
   3  Sigma        4.41587e-03   1.97307e-07  -1.96694e-08   3.53243e-02
 FCN=1.48515e+06 FROM MIGRAD    STATUS=CONVERGED      65 CALLS          66 TOTAL
                     EDM=3.67816e-14    STRATEGY= 1  ERROR MATRIX UNCERTAINTY   1.7 per cent
  EXT PARAMETER                                   STEP         FIRST   
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE 
   1  Constant     2.28994e+03   3.49236e-01   1.32828e-04  -7.03872e-07
   2  Mean        -5.37051e-04   7.83511e-07   4.50792e-10   2.49701e-03
   3  Sigma        4.75457e-03   9.35040e-07   5.62589e-08   2.80488e-03

In [ ]: