ROOT Tricks

Aus HERMESwiki
Zur Navigation springen Zur Suche springen

Also check the cern root / Hanna++ mailing list archive for lots of other Q&A

Systematic error bands

ROOT Tricks systErrors.png

As with most other cases you have several options to add systematic error bars to a plot in ROOT. One way to do this is to use a TGraphAsymmErrors with X of the data points being the actual X values of your bins and the Y values being all at the same value. Both errors in X and the lower error in Y are set to 0. The upper error in Y is set to the systematic error. To plot the error band use "3 C" (or input your bin edges as the x-axis error and use option 2) as a drawing option. If you use some hatched fill style it is also nice to add a second graph with the same data points and errors but no fill style as an outline of the area. Here is an example:

{
  TCanvas * c = new TCanvas("c", "c", 0, 0, 700, 500);
  TH1F * frame = c->DrawFrame(0, -0.12, 0.85, 0.15);
  frame->SetTitle("Systematic Errors in ROOT");

  const Int_t nbins = 8;
 
  Double_t x1[] = { 0.125, 0.175, 0.225, 0.275, 0.325, 0.375, 0.425, 0.475 };
  Double_t y1[] = { 0.1018, 0.0667, 0.0589, 0.0366, 0.0341, 0.0254, 0.0179, 0.0136 };
  Double_t e1[] = { 0.0110, 0.0070, 0.0040, 0.0030, 0.0050, 0.0020, 0.0010, 0.0010 };
  Double_t cb[] = { 0.125, 0.175, 0.225, 0.175, 0.225, 0.125, 0.225, 0.175 };
 
  TGraphErrors * gr = new TGraphErrors(nbins);
  TGraphAsymmErrors * syst = new TGraphAsymmErrors(nbins);
  TGraphAsymmErrors * systoutline = new TGraphAsymmErrors(nbins);

  for (Int_t i=0;i<nbins;i++) {
    gr->SetPoint(i, x1[i], y1[i]);
    gr->SetPointError(i, 0, e1[i]);

    syst->SetPoint(i, x1[i], -0.1);
    syst->SetPointError(i, 0, 0, 0, cb[i]*cb[i]);

    systoutline->SetPoint(i, x1[i], -0.1);
    systoutline->SetPointError(i, 0, 0, 0, cb[i]*cb[i]);
  }

  gr->SetMarkerStyle(25);
  gr->Draw("P");

  syst->SetFillColor(kYellow);
  syst->SetFillStyle(1001);
  syst->Draw("3");

  systoutline->SetFillStyle(0);
  systoutline->SetLineWidth(2);
  systoutline->Draw("3");

  c->Print("ROOT_Tricks_systErrors.png");
}

Printing nice characters: < > #perp ...

  • < = #LT
  • > = #GT
  • perp -- I (Rebecca) could never get the #prep to print nicely as a subscript, it was always aligned too low
    • using #scale[0.6]{#perp} help a bit
    • in the end for the cos(phi) release plots I drew my own symbol with TLine :(

Color palettes

The default color looks rather ugly when drawing plots with options "lego" or "col". A simple way to get rid of this and use a nice rainbow type palette is to use a statement

gStyle->SetPalette(1, 0);

before you draw the histogram.

Colorpalette root.png

To create an individual color palette use something like the following code snippet

TColor::InitializeColors();

const Int_t NRGBs = 4;
const Int_t NCont = 64;

Double_t Stops[NRGBs] = { 0.00, 0.25, 0.75, 1.00 };
Double_t Red[NRGBs] =   { 1.00, 1.00, 0.60, 0.40 };
Double_t Green[NRGBs] = { 0.95, 0.80, 0.30, 0.20 };
Double_t Blue[NRGBs] =  { 0.80, 0.00, 0.00, 0.00 };

TColor::CreateGradientColorTable(NRGBs, Stops, Red, Green, Blue, NCont);

This definition of TColor::CreateGradientColorTable() is similar to the povray-definition of gradient color tables.

CINT Tricks

An interactive root session is basically a C/C++ interpreter which is called CINT. It provides most features known from C/C++, however, it has a few limitations and extensions. Here is a collection of useful non-C/C++ specific commands and tricks that you can use in an interactive ROOT session

Exiting the interactive ROOT session

root [0] .q       <--- the normal way
root [0] .qqq     <--- in case there is something going wrong
root [0] .qqqqqq  <--- use this if the other two options fail

Executing a macro

root [0] .x Macro.C

If the function Macro in the file takes one or more arguments you can use the following statement:

root [0] .x Macro.C(arg1, arg2, arg3, ...)

To compile the macro before execution add a "+" or "++" after the filename

root [0] .x Macro.C+(arg1, arg2, arg3, ...)

See the next subsection for more information on the meaning of the "+" and "++".

Loading a macro

To load the contents of a macro use

root [0] .L Macro.C

The functions provided in the file will now be available from the interpreter. If you change the contents of the file you can repeat the .L statement to load the new version of the file. In order to compile the macro before loading use

root [0] .L Macro.C+

or

root [0] .L Macro.C++

Both statements will run the compiler and create a shared object that is loaded. The statement with "++" in the end will force recompiling while the statement with the single "+" will only compile the macro file if it is younger than the previously compiled shared object.

Using the interpreter from within a macro or code

A powerful feature of ROOT is that you can execute any statement that is understood by CINT from within a macro or compiled code. This means that the interactive line

root [0] .x SomeMacro.C

can also be written as

root [0] gROOT->ProcessLineFast(".x SomeMacro.C");

The advantage is that the last line can be used in any code (also compiled). Another example is

root [0] TObject * obj = (TObject*) gROOT->ProcessLineFast("new TLine()");
root [1] obj->Print();
TLine  X1=0.000000 Y1=0.000000 X2=0.000000 Y2=0.000000

With the above statement you created a TLine object by using the class name as a string.

Getting information on a class

To get some sort of quick reference on a class known to ROOT type

root [0] .class ClassName

This will dump a list of member variables and methods as well as information on the inheritance of the class.

Executing a shell command

root [0] .! cmd

Will execute the command cmd in the shell.

The ROOT Dictionary

Each class known to ROOT usually has a so called dictionary. It provides information on all member variables, all methods and the inheritance of the class during runtime. The dictionary also knows how a certain class should be written to a ROOT file. Please see the Adding a Class section of the ROOT users guide on how to add your own classes. Here is a collection of things the dictionary has to offer

root [0] TH2F * h2 = new TH2F("h2", "h2", 10, 0, 10, 10, 0, 10)
root [1] TClass * cl = h2->IsA()         (or TClass * cl = TH2F::Class() if you do not have an object)
root [2] cl->GetName()
(const char* 0x8838a70)"TH2F"

root [3] cl->Print()
OBJ: TClass     TH2F    2-Dim histograms (one float per channel)

root [4] cl->GetListOfBases()->Print()
OBJ: TBaseClass TH2     2-Dim histogram base class
OBJ: TBaseClass TArrayF Array of floats

root [5] TH2::Class()->GetListOfBases()->Print()
OBJ: TBaseClass TH1     1-Dim histogram base class

root [6] TH1::Class()->GetListOfBases()->Print()
OBJ: TBaseClass TH1     1-Dim histogram base class
OBJ: TBaseClass TAttLine        Line attributes
OBJ: TBaseClass TAttFill        Fill area attributes
OBJ: TBaseClass TAttMarker      Marker attributes

root [7] h2->IsA()->InheritsFrom("TH3D")
(const Bool_t)(0)
root [8] h2->IsA()->InheritsFrom(TAttFill::Class())
(const Bool_t)(1)

root [9] h2->IsA()==TH3D::Class()
(const Bool_t)(1)
root [10] h2->IsA()==TH2F::Class()
(const Bool_t)(1)

root [11] TH2F * h2_2 = cl->New()
root [12] h2_2->IsA()->Print()
OBJ: TClass     TH2F    2-Dim histograms (one float per channel)

Most Useful Links

Root Class Index: [1]

Root Tutorials: [2]