Introduction to ROOT
An introduction to histogramming and analysis with ROOT. In this
section command line entries are used to start a ROOT session, make a
histogram and inspect ROOT files.
The information presented in this Workbook section is extended in
the next section Analysis in ROOT II
which covers fitting histograms in ROOT and introduces the ROOT
Graphical User Interface, the Object Browser.
Contents
ROOT is an object-oriented C++ analysis package. It allows
user-compiled code to be called and can produce 1-, 2- and 3-d
graphics and histograms. It comes with a graphical Object Browser
which makes navigating through ROOT files very easy.
ROOT uses a language called CINT which contains several extensions to
C++. The main difference between CINT and C++ is that with CINT you
are allowed to use a dot '.' where in C++ an arrow '->' is used. CINT
commands always start with a dot '.'. Entering just ".?" (followed by
"enter") at the ROOT command prompt will generate a list of all the
CINT commands.
Most familiar objects exist in ROOT with either capitalisation and
a "_t" suffix or a "T" prefix, for example:
Float_t, Double_t, ..., TClass, TFile, ...
To start a ROOT session at SLAC, run the script
bbrroot (this only works after srtpath has
been executed):
> bbrroot
On most computers, you would start root by typing "root." But
at BaBar it is better to use the wrapper script "bbrroot" because
it starts up the same version of ROOT as was used to produce your
rootfile (in your original BetaMiniApp job, for example):
While ROOT is starting up a pop-up window with a picture of a naked
lady with tree roots instead of legs, twirling a hoop over her head,
may appear briefly, and on the terminal where you entered the startup
command, the resulting output should look something like the following:
*******************************************
* *
* W E L C O M E to R O O T *
* *
* Version 5.14/00e 29 March 2007 *
* *
* You are welcome to visit our Web site *
* http://root.cern.ch *
* *
*******************************************
FreeType Engine v2.1.9 used to render TrueType fonts.
Compiled on 31 March 2007 for linux with thread support.
CINT/ROOT C/C++ Interpreter version 5.16.16, November 24, 2006
Type ? for help. Commands must be C++ statements.
Enclose multiple statements between { }.
...using style 'Plain'
...found RELEASE directory
...found PARENT directory
...running in release 22.1.1
For approved plots use: gROOT->SetStyle("BABAR");
To add a BABAR label use: BABARLabel();
To add a better-scaling BABAR label use: BABARSmartLabel();
Type "BABARSmartLabel(-2);" for options
If, instead of ROOT starting up, you get some sort of error message
referring to the display, there is probably a problem with the setup
of the display environment. You'll need to fix this before you can
start.
You can use ROOT as a quick calculator - just leave off the
semi-colon at the end of the statement, e.g.
23+5
The system should respond with
(const int)28
If you put the semi-colon at the end of this line, there will be no
return value printed.
Now comes a step that you must know - how to exit ROOT at the end of a
session!
.q
(Don't forget the dot.)
You can access a histogram that is currently loaded into a ROOT
session with the command:
TH1F *myHist=(TH1F*) gDirectory->Get("name of your histogram");
This is basically creating a pointer called "myHist" to a
pre-existing histogram.
The following sections teach you to make new histograms and manipulate
histos.
ROOT provides you with 3-d histograms as well as 1-d and 2-d options.
To declare a 1-d histogram which will be filled by giving it
floating point numbers, for example, you would enter:
TH1F *hist_name = new TH1F("hist_name", "hist_title",num_bins, x_low, x_high);
where hist_name is the name by which the histogram is
referenced in ROOT, hist_title is the title which appears
on the histogram, num_bins is the number of bins that
will appear in the histogram (an integer), x_low is the
value of the lower edge of the first bin, and x_high is
the value of the upper edge of the last bin.
Histograms in ROOT also have two bins for values that fall outside
the binning values. The left-most bin (bin 0) is reserved for
underflow (entries that are less than x_low) and the
right-most (bin num_bins+1) bin is reserved for overflow (entries that
are equal to or larger than x_high).
Booking 2- and 3-d histograms is analogous. An example of a 2-d
histogram declaration is:
TH2D *h2 = new TH2D("h2", "histogram title",100, 0., 10., 18, 0., 180.);
To book your first histogram, start up a ROOT session and enter:
TH1F *hist_1 = new TH1F("hist_1", "My first histo", 100, 2, 200);
Nothing happens!
This is because you must now tell ROOT to draw your
histogram. "Draw()" is one of the functions defined in the
ROOT histogram class. To draw your new histogram, enter
hist_1.Draw();
The system should respond with something like
root [1] h1.Draw();
<TCanvas::MakeDefCanvas>: created default TCanvas with name c1
and a new window (a "canvas") should appear with your new
histogram. You should see something like:
This is an empty histogram with the title "My first histo".
The ROOT function "Fill()" is designed for filling
histograms. Depending on the type of histogram you have declared
(TH1F, TH1D, etc.) you can pass numbers to your histogram of a
particular data type and the appropriate bin will be incremented. For
example, hist_1 has type TH1F, which means that you can
pass it floating point numbers. The Fill() function can take
individual numbers (x=0.2, etc.), or also weights for the numbers
(x=0.2, num_entries=5, etc.). For example, enter
root [33] hist_1.Fill(50.0);
root [34] hist_1.Fill(120,2);
root [35] hist_1.Fill(130,2);
root [36] hist_1.Draw();
The last command is needed to force ROOT to redraw the updated
histogram.
The result should look something like:
The box that appears in the upper-right corner of the histogram is the
"stats box". Depending on the histogram type, this box gives
information like the histogram name, the number of entries, mean,
distribution statistics, etc. For a general histogram, this box is
setup with:
gStyle->SetOptStat(mode);
Where "mode" is up to nine 0's, 1's and 2's:
| mode = "ksiourmen" |
| n = the name of the histogram is printed |
| e = the number of entries |
| m = the mean value |
| m = the mean and mean error values |
| r = the root mean square (RMS) |
| r = the RMS and RMS error |
| u = the number of underflows |
| o = the number of overflows |
| i = the integral of bins |
| s = the skewness |
| s = the skewness and the skewness error |
| k = the kurtosis |
| k = the kurtosis and the kurtosis error |
The default is (000001111) which means that rms, mean, total of entries
plus the histogram are printed. If less than 9 parameters are given as
the mode, they are read starting from the end (i.e. histogram
name). For example, enter
gStyle->SetOptStat(11);
hist_1.Draw();
Now the stats box just shows the last two options; the total number of
entries plus the name of the histogram! Note that this has changed an
attribute of the ROOT pad. Therefore, until you change the gStyle
attribute SetOptStat again, all histograms plotted on this pad will
have a stats box showing only number of entries and histogram name.
You can return to the default stats box settings with
gStyle->SetOptStat();
or remove the stats box entirely with
gStyle->SetOptStat(0);
We want to move towards being able to compare two or more histograms
by plotting them on the same axes. In order to do this we need two
more skills - one is to be able to plot histograms with different
colours, and the other is some sort of information on which histo is
which. The latter is done with a "legend". Use the following
code to add a legend to your histogram:
leg = new TLegend(0.6,0.7,0.89,0.89); //coordinates are fractions
//of pad dimensions
leg->AddEntry(hist_1,"First histo","l"); // "l" means line
// use "f" for a box
leg->Draw();
// oops we forgot the header (or "title") for the legend
leg->SetHeader("The Legend Title");
leg->Draw();
In the above, the numbers in the legend declaration determine the size
and position of the legend box. Use
c1.Clear();
to clear your canvas and experiment with sizes and placement of the
legend box by redrawing hist_1 and changing the numbers in the legend
declaration.
Other options for drawing your legend include:
leg->SetTextSize(0.04);
// set size of text
leg->SetFillColor(0);
// Have a white background
leg->AddEntry(hist_1, "text 1", "p");
// p shows points,
// other options exist
// (Check documentation)
leg->Draw();
How to get a box with text
A text box with lines of text is produced with
pt = new TPaveText(0.20,0.7,0.5,0.87, "NDC"); // NDC sets coords
// relative to pad dimensions
pt->SetFillColor(0); // text is black on white
pt->SetTextSize(0.04);
pt->SetTextAlign(12);
text = pt->AddText("Whatever you want");
pt->Draw(); //to draw your text object
To get larger labels, axis titles and Greek fonts onto a histogram:
gPad->SetLeftMargin(0.15); // experiment with the best value for you.
// Depends on font size:
gPad->SetBottomMargin(0.15);
hist_1->SetLabelSize(0.05,"y");
hist_1->GetYaxis()->SetTitleSize(0.05);
hist_1->SetLabelSize(0.05,"x");
hist_1->GetXaxis()->SetTitleSize(0.05);
hist_1->SetXTitle("`f[#circ]"); // degree symbol, just like PAW,
// and like LaTeX
// (using "#" instead of "\")
hist_1->SetYTitle("Entries / bin");
hist_1->Draw();
Drawing two histograms on the same canvas isn't a great deal of use
unless you can draw them with different colours. Some of the colours
available in ROOT are:
| 1 | black |
| 2 | red |
| 3 | light green |
| 4 | blue |
| 5 | yellow |
| 6 | magenta |
| 7 | cyan |
| 8 | green |
To change the colour of the lines plotted on your histogram, try
hist_1->SetLineColor(2);
hist_1->Draw();
Now your histogram should be red.
Here are a few other commands that you can use to enhance the
appearance of your histogram to give you an idea of some of the power
of ROOT:
hist_1->GetXaxis()->SetTitle("Label of x axis");
hist_1->GetYaxis()->SetTitle("Label of y axis");
gROOT->SetStyle("Plain"); // Switches off the ROOT default style
gPad->UseCurrentStyle(); // this makes everything black and white,
// removing the default red border on images
gROOT->ForceStyle(); // forces the style chosen above to be used,
// not the style the rootfile was made with
This gives an appearance rather similar to PAW.
Finally, to get a better colour set than the ROOT default:
gStyle->SetPalette(1);
Colours can be accessed by numbers (like in PAW) or with names:
enum EColor { kWhite, kBlack, kRed, kGreen, kBlue, kYellow,
kMagenta, kCyan };
To illustrate how to plot two histograms on the same canvas, we will
need to set up another histogram:
TH1F *hist_2 = new TH1F("hist_2", "Another histo", 100, 2, 300);
Let's fill a few bins:
hist_2->Fill(20,10);
hist_2->Fill(50,4);
hist_2->Fill(3);
When you draw a histogram, the default behaviour for ROOT is for it to
clear the canvas that is currently being used and then draw the new
histogram on it. So, for example, if we now enter:
hist_2->Draw();
The new histogram appears on the canvas and the old one is lost. We
can bring back hist_1 and force the ROOT canvas to display both
histograms at the same time with the command
hist_1->Draw("histsame");
Putting everything together, we shall now clear the canvas and start
afresh, plot both histograms, with different colours, and make a
legend to remind ourselves of which histo is which:
c1->Clear();
hist_1->SetLineColor(8) // green
hist_2->SetLineColor(4) // blue
hist_2.Draw(); //draw hist_2 first as it has a larger range
hist_1.Draw("same");
leg_hist = new TLegend(0.5,0.6,0.79,0.79);
leg_hist->SetHeader("Some histograms");
leg_hist->AddEntry(hist_1,"First histo","l");
leg_hist->AddEntry(hist_2,"Second histo","l");
leg_hist->Draw();
Your graph should now look something like:
Note that unless you manually set the axis ranges, these will be set
to those most appropriate to the first histogram which was drawn.
You can make an identical copy of a histogram by cloning, with
the command
TH1F *hist_new=(TH1F*)hist_1->Clone();
hist_new->SetName("hist_new");
Where the last command is needed to set the name of your new histogram
to something unique.
You should consult the official ROOT documentation for the many
options for histogramming in ROOT. Here are some Draw options that you
might like to experiment with for a 2-dimensional histogram:
h2->Draw("text");
h2->Draw("col"),
h2->Draw("colz");
h2->Draw("box");
h2->Draw("surf");
A complete list is available in the official
documentation.
You can plot errors on histograms (perhaps more appropriate to plot
them on first to histograms!) by entering
hist_2.Draw("esame");
By default, errors are sqrt(entries). To get the error as sqrt(sum of
weights), enter
hist_1->Sumw2()
before filling the histogram.
Related Documents:
To get a list of CINT commands, enter:
.?
The system should respond with:
Note1: Cint is not aimed to be a 100%% ANSI/ISO compliant C/C++ language
processor. It rather is a portable script language environment which
is close enough to the standard C++.
Note2: Regulary check either of /tmp /usr/tmp /temp /windows/temp directory
and remove temp-files which are accidentally left by cint.
Note3: Cint reads source file on-the-fly from the file system. Do not change
the active source during cint run. Use -C option or C1 command otherwise.
Note4: In source code trace mode, cint sometimes displays extra-characters.
This is harmless. Please ignore.
CINT/ROOT C/C++ interpreter interface.
All commands must be preceded by a . (dot), except
for the evaluation statement { } and the ?.
===========================================================================
> [file] : output redirection to [file]
2> [file] : error redirection to [file]
>& [file] : output&error redirection to [file]
Help: ? : help
...
To see information about a particular histogram, you need ROOT's
"Print()" function. For example
hist_1.Print();
The system should respond with:
TH1.Print Name= hist_1, Entries= 3, Total sum= 5
To get the entire histogram contents, you want:
hist_1.Print("all");
The system should respond with bin number, number of entries in each
bin, and the values for low-edge of each bin. Part of that output is:
...
fSumw[59]=0, x=117.83
fSumw[60]=2, x=119.81
fSumw[61]=0, x=121.79
fSumw[62]=0, x=123.77
fSumw[63]=0, x=125.75
fSumw[64]=0, x=127.73
fSumw[65]=2, x=129.71
fSumw[66]=0, x=131.69
...
The first non-zero response for entries-per-bin are from the two
values filled for x=120, while the next is from the two entries filled
for x=130. You can dump the histogram contents into an ASCII file by
directing this output to a file with
hist_1->Print("all"); > filename.txt
Note the semicolon after the parenthesis.
Now save your masterpiece to a file (this assumes that your histogram is
printed on canvas "c1"):
c1->SaveAs("myimage.eps");
c1->SaveAs("myimage.ps");
c1->SaveAs("myimage.gif");
Alternatively you can click on "File" in the upper left-hand
corner of the canvas, and selecting the "save as" option
and file-type that suits you.
Underlying any histogram you plot using ROOT is a pile of CINT/C++
source code, even if you just made the histogram from an existing ROOT
file using h1->Draw();.
You can access and save that source code as a ROOT file which you
can edit and later rerun (e.g. to change the titles, histogram
attributes, etc). This is done by (assuming that your histogram is
printed on canvas "c1"):
c1->SaveAs("myimage.C");
Alternatively you can click on "File" in the upper left-hand
corner of the canvas, and select "save as" option for
canvas.C. This will save the file as a ROOT macro under the
name of your canvas, which in this example is
c1.C.
Assuming you have saved your histogram as myimage.C,
you can recreate the histogram in exactly the form that you saved it
in a brand new ROOT session by entering:
.x myimage.C
That is, the file myimage.C is just ROOT macro which
creates a histogram with the entries and layout that you want. You can
easily edit the myimage.C macro also.
Now you can look at histograms which were created by running BaBar, or
other analysis, code and stored in ROOT files. Start up a ROOT
session, and open the ROOT file,
myHistogram.root, you created
in the Quicktour (note also that ROOT has built-in tab completion!):
To inspect your ROOT histogram enter:
TFile f("myHistogram.root");
This will loads the contents of the root file
myHistogram.root into a temporary file in your ROOT
session called "f". To look at the contents of
this file, enter:
f.ls();
You should see a response like:
TFile** myHistogram.root Created for you by RooTupleManager
TFile* myHistogram.root Created for you by RooTupleManager
KEY: TH1F h1d1;1 MC reco abs mtm difference
KEY: TH1F h1d2;1 Reco track momentum
KEY: TH1F h1d3;1 Tracks per Event
KEY: TH1F h1d4;1 Momentum
KEY: TH1F h1d5;1 TagInspector Status
Now display the contents of histogram h1d4 with:
h1d4.Draw();
As in the previous example, you can add entries to bins in the
histogram and redraw the output (notice that the stats box is
automatically updated when you redraw the file:
h1d4.Fill(2,4);
h1d4.Draw();
Note that your Fill command actually affects only the
histogram drawn on the canvas. This histogram is a copy of the
one in the file. So the histogram in myHistogram.root
remains unchanged.
If you have opened two ROOT files, it could be that you want to carry
out an action on the first file that you opened. ROOT keeps its focus
on the most recently opened file, unless you tell it to access another
file.
For example, if you opened two files with:
TFile *f1=new TFile("first.root");
TFile *f2=new TFile("second.root");
If you want to perform actions on the first file you opened, for those
functions which do not directly use the file's reference name (in
ROOT, "f1"), you will need to change ROOT's focus to that file:
f1.cd();
There are many tutorials available on the web for ROOT users,
including some very useful tutorials with example code and output from
SLAC, CERN and Fermilab. Much of the information in this Workbook
chapter was copied from the ROOT tutorials listed below.
Related Documents:
ROOT was created by the authors of PAW, and there are many similarities
between the two systems. Within the BaBar one can create histograms in either
ROOT or PAW formats, and it is easy to change code to alter the output
between the two.
ROOT files contain histograms and trees (and, occasionally, other
ROOT objects). A tree is (approximately) the equivalent of a PAW ntuple,
albeit far more powerful: You can store objects (e.g. vectors) as well as
numbers.
You can convert your PAW files to ROOT files using the ROOT utililty
h2root. The original PAW file may contain histograms, ntuples and
have subdirectories. PAW Ntuples become (simple) ROOT trees, and the
subdirectory structure of PAW files is preserved. Once the
you have issued the srtpath command (see Workbook: Quicktour) to set up
the BaBar environment, you can run the wrapper script
bbrh2root
to access this utility.
The syntax is:
bbrh2root oldname.hbook newname.root
If you do not supply the second argument, then the new file
will be called oldname.root. So if you have a directory full of
.hbook files, you can just do "bbrh2root *" to change them all
to .root files with the same names (except for the .root extension
of course). How to access the trees and histograms in the new ROOT file
was explained in previous sections.
One disadvantage of ROOT is that it will not run properly unless the display
environment is properly set up. In PAW this was not always necessary, as PAW
would produce histograms made of ascii characters for graphically-challenged
computers. But ROOT needs a graphical display set up in order
to work.
(Note: If you are working at SLAC, and your h2root command does not work,
try logging into a Sun machine like flora and using the command there.
This works for many people - I am not sure why.)
General Related Documents:
Page maintained by Adam Edwards
Last modified: January 2008
|