A.4 ROOT Basics
Complete:
Goals of this workbook page
When you finish this page, you will be able to
- Open and close an interactive ROOT session
- Create and manipulate simple histograms
- Use provided resources to learn how to do further tasks with ROOT
For further information on fitting a distribution, go to the page
WorkBookHowToFit.
Contents
Introduction
ROOT
is an analysis package written in an object-oriented structure in C++. It uses built-in functions and user-compiled code to produce graphics and histograms, as well as
trees with data objects. ROOT files can be easily navigated using a GUI
Object Browser.
The new CMS event data model (
EDM) is based around the idea that people will use ROOT both in a normal
"framework application", and by interactive manipulation of tree objects and histograms. The full CMS software structure to use ROOT has an analysis environment is currently under construction, and will become a powerful tool for CMS physics analyses.
Interactive ROOT sessions are conducted using an extension to C++ called
CINT. This allows a slightly lazy use of C++, including allowing the use of a dot
'.'
to access a pointer object rather than the strict C++ arrow '->', and further shortcuts in creating new pointer objects. A help menu of CINT commands can be accessed using
'.?'
.
Most objects in ROOT can be accessed by familiar names, adding a
'_t'
as a suffix to data types, and a
'T'
prefix to object classes, e.g.
Float_t
,
Double_t
,
TClass
,
TFile
, ...
The ROOT homepage
The ROOT system homepage is hosted at CERN, and contains many example files, tutorials, How-Tos, FAQs, program downloads and other help. The homepage URL is
http://root.cern.ch
Starting a ROOT session
Linux
These instructions enable you to start a ROOT session when logged into a CERN lxplus machine. You will need to contact your local system expert for information on using ROOT on local machines.
The best way to use ROOT is to run it from a software release that you have already checked out and you are working in. Details of how to set up a software release are given in the WorkBook chapter on
Setting up your Working Environment.
If you don't have a release checked out, you can quickly set one up in order to continue this workbook chapter and learn about ROOT with the following commands:
setenv SCRAM_ARCH slc6_amd64_gcc700
cmsrel CMSSW_10_2_18
cd CMSSW_10_2_18/src
cmsenv
If you already have a software release setup, leave out the
cmsrel
command and do the rest.
You need to do this (apart from
cmsrel
) every time you want to use the CMS software environment and to use ROOT, as this method sets up the correct paths for you to be able to access the ROOT program which is compatible with the software release that you are currently using.
With those preliminaries completed, start your ROOT session:
root -l
The
-l
is optional and it speeds up the startup by skipping the start screen.
You are now in an interactive ROOT session, and should see the root prompt.
Most commands in ROOT are delimited by a semicolon, and all commands saved in macros (small files containing several ROOT commands designed to work together to complete a specific task) should be written in strict C++. Additionally, most objects created in ROOT are really pointers to objects. To fully appreciate this distinction you will need to become familiar with the concepts of pointer objects in C++, though the greatest necessity to understand pointer objects when using ROOT is in writing correct C++ syntax for macros, which comes a little later in this WorkBook topic.
Omitting the semicolon at the end of a command, ROOT can be used as a quick calculator, e.g.
45+6
The system should respond with something like:
(int) 51
If you put the semicolon at the end of this line, no return value would be displayed.
The next important step that you must know if you are to use ROOT is how to end a session. To exit a root session, use a dot followed by a
q:
.q
Windows and Macintosh (10.12/10.13)
Instructions to set up processes like X11 forwarding to run ROOT remotely from Windows and Macintosh machine are on
WorkBookSetComputerNode#XeleVen
Enough ROOT to Run WorkBook Tutorials
Say you have a file called
MyOutputFile.root
that you wish to examine using one of the analysis modes described in
WorkBook chapters 3 and 4. The following sequence of commands loads the file and opens a browsing window, known in ROOT as a TBrowser.
$ root
root[0] TFile f("MyOutputFile.root");
root[1] new TBrowser
Once you get to the browser, double click down the chain till you get what you're looking for (for example tracks:
MyOutputFile.root
->
Events
->
recoTracks_generalTracks__RECO
->
recoTracks_generalTracks__RECO.obj
). When you get to a plottable "leaf" (the end of a branch in the tree structure), a double-click will create the plot.
Instead of going through the TBrowser each time, you can set an alias for a branch you want to access. Select a branch name visible in the TBrowser, add
obj
at the end, and think of a short alias. It's up to you to choose which aliases to use. E.g., set the alias for an object named
recoTracks_generalTracks__RECO.obj
to
tracks
:
root[2] Events->SetAlias("tracks","recoTracks_generalTracks__RECO.obj");
Using this alias, go ahead and plot some aspect of the track, e.g., its normalized chi-squared (chi-squared over number of degrees of freedom) :
root[3] Events.Draw("tracks.chi2_/tracks.ndof_");
To use the Python interpreter in ROOT rather than the CINT interpreter, the commands for startup are:
python
>>> from ROOT import *
>>> gSystem.Load("libFWCoreFWLite.so")
>>> FWLiteEnabler.enable()
To load a file and to open a browser, type:
>>> myFile = TFile("MyOutputFile.root")
>>> myBrowser = TBrowser()
For more information, see
FWLite in Python.
ROOT Histograms
The main analysis use in ROOT is the production of histograms to represent usefully-binned data. ROOT can produce 1-D, 2-D and 3-D histograms. This WorkBook section will teach you to make create your first histogram, display it, put some data in it, and perform basic histogram manipulations.
Making your first ROOT histogram
We shall create a basic 1-D histogram, declaring it as a pointer object, and will fill it with floating point numbers - the most general histogram application you are likely to want. The required syntax to "book" a histogram is:
TH1F *hist_name= new TH1F("hist_name","hist_title",num_bins,x_low,x_high);
where the various components are:
- TH1F
- the ROOT 1-D histogram class
- hist_name
- the name of your histogram - this is how you refer to your histogram to perform manipulations on it. If you save the histo into a file this will be the name by which the histo is stored
- hist_title
- this title will appear when you print your histogram (either to screen or in hardcopy)
- num_bins
- an integer defining the number of bins that will appear in the histogram
- x_low
- the value of the lower edge of the first bin
- x_high
- the value of the upper edge of the last bin
Histograms in ROOT have two additional bins which are reserve for entries that fall below the bin limits (underflow - bin 0), and for entries that are equal to or larger than
x_high
(overflow - bin
num_bins+1
). When booking your histograms you should specify
x-low
and
x-high
as real numbers rather than integers, using 10. rather than 10 for example, if you want a bin limit to be the value 10 but to store real numbers rather than have them truncated to integers before being stored.
To book 2-D or 3-D histograms, an analogous syntax is used, for example:
TH2D *h2= new TH2F("2","2d hist title",num_xbins,x_low,x_high,num_ybins,y_low,y_high);
Now to put this into practice. Start up a ROOT session, and book a brand new histogram by entering:
TH1F *hist1= new TH1F("hist1", "My First Histogram", 100, 5., 50.);
Nothing happens! While you have booked your histogram, and therefore created a pointer to a 1-D histogram, to be filled with floats which will be put into 100 bins ranging from 5 to 50, you haven't yet told ROOT to draw it. Do this now with:
hist1->Draw();
The system should respond with something like:
root [1] hist1.Draw()
<TCanvas::MakeDefCanvas>: created default TCanvas with name c1
and a new window (a ROOT "canvas") will be with your new histogram. You should see an empty histogram with the title "My First Histogram", which should look something like:
Histogram manipulations
Filling a histogram with discrete data
Histograms can be filled using the
Fill() function in ROOT. Depending on the type of histogram you have declared (number of dimensions, type of data to be input - double/float/...), you can pass numbers to your histogram of the appropriate datatype and the corresponding bin will be incremented. Our new histogram,
hist1 has type TH1F, which means that it expects data in the form of floating point numbers. The
Fill()
function can take individual numbers (which are then filled with weight 1), or can accept weights for numbers (e.g. representing a number of entries at the particular x-value). For example, enter:
hist1->Fill(41,1);
hist1->Fill(12,2);
hist1->Fill(34,3);
hist1->Draw("e");
The last command gets ROOT to draw the updated histogram, producing a result which should look something like:
The ROOT histogram "Print" function
To see information about a particular histogram you need ROOT's
Print()
function
hist1->Print();
For the histogram created and filled above, the system should respond with:
TH1.Print Name = hist1, Entries= 3, Total sum= 6
To see the entire histogram contents, you want:
hist1->Print("all");
for which the system responds by printing the bin number, the number of entries in each bin, and the values for the upper edge of each bin. Our histogram is fairly empty, so most entries are zero, however a snippet of the output which contains a non-zero entry is:
...
fSumw[61]=0, x=32.225, error=0
fSumw[62]=0, x=32.675, error=0
fSumw[63]=0, x=33.125, error=0
fSumw[64]=0, x=33.575, error=0
fSumw[65]=3, x=34.025, error=3
fSumw[66]=0, x=34.475, error=0
fSumw[67]=0, x=34.925, error=0
fSumw[68]=0, x=35.375, error=0
fSumw[69]=0, x=35.825, error=0
fSumw[70]=0, x=36.275, error=0
fSumw[71]=0, x=36.725, error=0
fSumw[72]=0, x=37.175, error=0
fSumw[73]=0, x=37.625, error=0
...
To save these numbers, you can dump the contents of a histogram into an ASCII (text) file by directing this output to a file with
hist1->Print("all"); > hist1contents.txt
(remembering to use the semicolon in the command).
Using the stats box
When you plot a histogram using ROOT's default settings, a statistics box appears at the top-right of the plot showing information such as the histogram's name (the histogram
title appears at the top left, and is separate to the stats box), the number of entries, mean, etc. The attributes shown in this box are set with the command:
gStyle->SetOptStat(mode);
where
mode is a 6-digit number with 1's (on) and 0's (off), represented by the quantities (
ourmen)
o |
number of entries in overflow box |
u |
number of entries in underflow box |
r |
rms of distribution |
m |
mean of distribution |
e |
total number of entries |
n |
histogram name |
The default is (001111) which means that rms, mean, total number of entries and histogram name are shown in the stats box.
Some useful points about the stats box:
- if less than 6 numbers are given, e.g.
gStyle->SetOptStat(11);
, the parameters are read from the right - i.e. in this example, only the number of entries and the histogram name will be shown.
- after changing the
SetOptStat()
options, you need to redraw the histogram using Draw()
to display these updated options
- the stats box options are a property of the ROOT pad - as such, all histograms plotted on the same pad will have a stats box made with the current settings
- to reset to the default settings, use:
gStyle->SetOptStat();
- to turn off the stats box entirely, use:
gStyle->SetOptStat(0);
Changing the histogram appearance
Other improvements can be made to the readability and presentation of your histogram - for example changing colours, labelling axes, changing font types and sizes. Some of these options are described in this section, while further options for improving the presentation of your histogram are given in the section on
legends.
Colours in ROOT are defined through 8 default numbered colour references (plus White) and through a selection of enumerated colour types. The numbers you can use to refer to colours are:
Colour |
Number |
White |
0 |
Black |
1 |
Red |
2 |
Light Green |
3 |
Blue |
4 |
Yellow |
5 |
Magenta |
6 |
Cyan |
7 |
Green |
8 |
While the enumerated types that can also be used are:
kWhite
,
kBlack
,
kRed
,
kGreen
,
kBlue
,
kYellow
,
kMagenta
,
kCyan
.
To change the colours of the lines plotted in your histogram, try
hist1->SetLineColor(2);
hist1->Draw();
hist1->SetLineColor(kBlue);
hist1->Draw();
Please do not use colours 3 (light green), 5 (yellow) and 7 (cyan) in your presentations as they will not be visible when your slides are projected.
A few other options that you can explore to enhance the appearance of your histogram are:
hist1->GetXaxis()->SetTitle("Label of x axis");
hist1->GetYaxis()->SetTitle("Label of y axis");
gROOT->SetStyle("Plain"); // Turns off ROOT default style
gPad->UseCurrentStyle(); // removes red box about histo, all Black/White
gROOT->ForceStyle(); // ROOT needs encouragement to change its style
Finally, to get larger labels, put in some axis titles and add Greek fonts to your histogram:
gPad->SetLeftMargin(0.15); // experiment with the best value for you.
// Depends on font size for your text
gPad->SetBottomMargin(0.15);
hist1->SetLabelSize(0.05,"y");
hist1->GetYaxis()->SetTitleSize(0.05);
hist1->SetLabelSize(0.05,"x");
hist1->GetXaxis()->SetTitleSize(0.05);
hist1->SetXTitle("`f[#circ]"); // degree symbol, just like LaTeX,
// (using "#" instead of "\")
hist1->SetYTitle("Entries / bin");
hist1->Draw();
Comparing two histograms
A common use of histogramming ROOT is to compare two (or more) distributions. This can be achieved by plotting the histograms on the same canvas (in fact, on the same pad, to see them overlapped). More usefully, the histograms should be plotted in different colours and a key (referred to in ROOT as a
legend) should be provided to clearly distinguish between the distributions.
Plotting two histos on one canvas
To show how to plot two histograms on one canvas (one pad, in fact, in this example), we need to quickly book and fill a few bins of a new histogram:
TH1F *hist2 = new TH1F("hist2","Another Histogram", 100,2.,100);
hist2->Fill(45,10);
hist2->Fill(20,6);
hist2->Fill(13);
When you draw the histogram,
hist2->Draw();
, by default ROOT clears the current active pad and freshly draws the new histogram. We can however force ROOT to display both histograms at the same time, with:
hist2->Draw(); //draw our brand new histogram
hist1->Draw("same"); //draw our original histogram on the same pad as hist2
Putting this new knowledge together with what we have learned about setting colours, we can clear the canvas and plot both histograms with different colours:
c1->Clear(); //remember that this is the name of the default canvas
hist1->SetLineColor(8) //green
hist2->SetLineColor(4) //blue
gStyle->SetOptStat(11); //Display title and total number of events only
hist2->Draw(); //draw hist2 first as it has a larger range
hist1->Draw("same");
The two histograms on the same canvas should look something like:
Note that unless you manually set the axis ranges, these will be set to the most appropriate values for the first histogram which was drawn.
Adding a legend and further text to your histogram
We now need to add a legend to our masterpiece to be able to distinguish between the two plots. It is often also useful to add some additional descriptive text. Since these tasks are similar, they will both be handled in this section.
To add a legend to your histogram, we can do:
leg = new TLegend(0.6,0.7,0.89,0.89); //the coordinates put the legend corners
//various fractions of the way along the canvas
leg->AddEntry(hist1,"First histo","l") //"l" for a line
leg->AddEntry(hist2,"2nd histo","l") //use "f" for a box to show which colour
leg->Draw();
leg->SetHeader("My first histos"); //Might as well add a label to the legend box
leg->Draw(); //Draw updated legend with title
Other useful legend drawing options include:
leg->SetTextSize(0.04); //change size of legend text
leg->SetFillColor(0); //have a white background on the legend box
Text boxes are added similarly, they are called
TPaveText objects.
TPaveText *pt = new TPaveText(0.20,0.7,0.5,0.87,"NDC");
//note the strict C++ syntax (not required for interactive CINT)
// NDC sets the coordinates relative to the dimensions of the pad
// useful if you might change the layout of your histos
pt->SetFillColor(0); //text now is black on white
pt->SetTextSize(0.04);
pt->SetTextAlign(12);
text = pt->AddText("Whatever you want");
pt->Draw(); //to draw your text object
Copying histograms
Identical copies of histograms can be made by cloning, with the command
TH1F *new_hist=(TH1F*)hist1->Clone();
new_hist->SetName("new_hist");
Adding error bars
Error bars can be added to ROOT histograms by drawing the histogram with the option
esame:
hist1->Draw("esame");
By defaut, errors shown are the square root of the bin entries. To show error bars as
sqrt(sum of weights)
, before filling your histogram, issue the command:
hist1->Sumw2();
Some drawing options for 2-dimensional histograms
There are many different drawing options available for histogramming in ROOT - you could consult
http://root.cern.ch
to discover some of the possibilities. Drawing options that you might like to experiment with for 2-D histograms include
hist2->Draw("text");
hist2->Draw("col");
hist2->Draw("colz");
hist2->Draw("box");
hist2->Draw("surf");
Saving and printing histograms
Saving histograms as image files
Histograms can be saved from the ROOT canvas as image files in ps, eps or gif formats (as well as in C++ macros see
Source Code section)
To save your histogram to an image file, plot it (assuming here it is plotted on the default canvas
c1), then save your file in the desired format by stating the extension you want:
c1->SaveAs("histoimage.eps");
c1->SaveAs("histoimage.ps");
c1->SaveAs("histoimage.gif");
Alternatively you can click on "File" in the upper left corner of the canvas and use the save options in that menu.
Saving histogram source code
Any histogram which is plotted is described by an underlying set of C++ source code. You can save that source code in a file to later rerun (e.g. to change titles or other attributes of the histogram) with the command (assuming your histogram is printed on the default canvas, "c1"):
c1->SaveAs("myimage.C");
Alternatively, you can save the file by clicking on the options "File", "Save", and selecting
c1.C.
You can then recreate the histogram in exactly the same from that you saved it in a brand new ROOT session by entering:
.x c1.C
(or select "SaveAs", and select
myImage.C). To execute the macro
c1.C and create a histogram with the entries and layout that you saved. It is also possible to directly edit the
c1.C file that you created.
You should try saving an empty histogram (so that the data doesn't hide the details of the histogram definition) and look through the resultant source code file, as it contains useful commands for defining how your histogram looks.
Inspecting histograms saved infiles
You can look at histograms which were created in ROOT and saved to files, generally with the extension
.root. Say you have a ROOT file called "myHistofile.root", you can open it with:
TFile f("myHistofile.root");
where this command is a CINT shorthand to open the file and and load its contents into a temporary file in your ROOT session called "*f*". To look at the contents of the file enter:
f.ls();
And a listing will show the filename, list histograms, and also list any directories or other objects that are present in the ROOT file. Having just opened the file, the ROOT focus is on that file, and you can draw the contents, say of a histogram called
h1d4 if it was contained within that file with:
h1d4.Draw();
As in the earlier examples, you can add entries to the bins in the histogram with the
Fill(...)
command, and redraw the output with another
Draw()
command.
Accessing histograms saved in files
Loading an existing ROOT histogram
A histogram which is already loaded into a ROOT session, e.g. having been created or loaded from a file, can be accessed by creating a pointer to it with the command
TH1F myHist=(TH1F) gDirectory->Get("name of histogram");
Changing between active files
When you have more than one open ROOT file, ROOT keeps its focus on only one file at a time. You can operate on any of the opened files by referring directly to those files using their reference names (e.g. "file1" in the example below). Additionally, if you have opened two files with, say,
TFile *file1=new TFile("firstfile.root");
TFile *file2=new TFile("secondfile.root");
you can perform actions on the first file you opened by changing ROOT's focus to that file with:
file1.cd();
Similarly, you can change back to the other file when you want to address file2. This enables you to open several files and move between them using potentially the same commands on objects saved in each file.
Getting help with ROOT
ROOT tutorials
Many useful ROOT tutorials can be found on the web. Often these provide solutions to problems, or at least some sample code to get started on a particular task. You should beware that some of the information in the following tutorials is specific to the particular experiment or institute the tutorial was designed for, however the following tutorials contain very useful information:
Acknowledgement
This Introduction to ROOT WorkBook topic originates from the Babar Workbook chapter
Root I
(original author:
JennyWilliams).
Review Status
Responsible:
SudhirMalik
Last reviewed by:
JennyWilliams - 21 Nov 2006