SLAC PEP-II
BABAR
SLAC<->RAL
Babar logo
Workbook HEPIC Databases PDG HEP preprints
Organization Detector Computing Physics Documentation
Personnel Glossary Sitemap Search Hypernews
Unwrap page!
Wkbk. Search
Wkbk. Sitemap
Introduction
Non SLAC
HOWTO's
Introduction
Logging In
QuickTour
Detector
Info Resources
Software Infrastructure
CM2 Introduction
Unix
OO
SRT
Objectivity
Event Store
Framework
Beta
Modifying Code
Writing and Editing
Compiling
Debugging
Analysis
Framework II
Analysis
Find Data
Batch Processing
PAW
PAW II
ROOT I
ROOT II
ROOT III
Advanced Infrastructure
New Releases
Workdir
Main Packages
Event Displays
Gen/Sim/Reco
Contributing Software
SRT and CVS
Coding
Advanced Topics
Make CM2 Ntuples
New Packages
New Packages 2
Persistent Classes
Java
Site Installation
Check this page for HTML 4.01 Transitional compliance with the
W3C Validator
(More checks...)

Workbook for BaBar Offline Users -
Analysis in ROOT I

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


What is ROOT?

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.

CINT I - the ROOT Command Line Language

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, ...


Starting a New ROOT Session

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  4.04/02b       3 June 2005   *
  *                                         *
  *  You are welcome to visit our Web site  *
  *          http://root.cern.ch            *
  *                                         *
  *******************************************

FreeType Engine v2.1.9 used to render TrueType fonts.
Compiled on 23 June 2005 for linux with thread support.

CINT/ROOT C/C++ Interpreter version 5.15.169, Mar 14 2005
Type ? for help. Commands must be C++ statements.
Enclose multiple statements between { }.
...using style 'Plain'
...found RELEASE directory
...found PARENT directory
...running in release 18.6.2a

    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. There is information about this problem in the Quicktour section of the Workbook.

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.)

Histograms in ROOT

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.

Making your first ROOT histogram

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:

first_histo.gif

This is an empty histogram with the title "My first histo".

Filling your new histogram

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:

fill_histo.gif

The Stats Box

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 six 1's and 0's. (1="on", and 0="off")
mode = "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 of entries plus the histogram are printed. If less than 6 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);

Legends

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();

Changing Histogram Attributes

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:
1black
2red
3light green
4blue
5yellow
6magenta
7cyan
8green
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 };

Comparing Histograms

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
  gStyle->SetOptStat(11); // title and total number of events only

  hist_2.Draw();          //draw hist_2 first as it has a larger range
  hist_1.Draw("same");

  leg_hist = new TLegend(0.6,0.7,0.89,0.89);
  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:

two_hists.gif

Note that unless you manually set the axis ranges, these will be set to those most appropriate to the first histogram which was drawn.

normalize

Copying Histograms

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.

More Drawing Options

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.

Including Error Bars in Histograms

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:


Getting Help with ROOT

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 redirect to [file]
             2> [file] : error redirect 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.

Saving Histograms as Image Files

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.

Saving Source Code for Histograms

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.

Opening and Inspecting ROOT Histograms Saved in Files

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();

Changing between files

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();

ROOT Tutorials

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, PAW and h2root

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.


General Related Documents:

Back to Workbook Front Page

Author: Jenny Williams

Last modification: 20 January 2006
Last significant update: 13 June 2005