ROOT Exercises

This is a guide for the ROOT exercise sessions at the ROOT class at Fermi lab. The exercises cover the following areas:

Session A covers three ways you can use ROOT: the command line, the script processor, and the graphical user interface (GUI). We also show you how to generate a PostScript file.

Session B covers histograms, and the input/output capabilities.

Session C is an example of an analysis using real physics data.

C++ Refresher

ROOT is a C++ framework; it is not only written in C++, it also uses C++ as the scripting language. To use ROOT effectively you will need to know the basics of C++. The User's Guide chapter 3 6 "A Little C++" page 25, explains the basic concepts.

In addition, there is a "C++ Guide for ROOT Users" at:


You need to setup root with the local setup command. The setup script will take care of setting the environment variables. If you are taking this class at Fermi lab, look here for setup instructions:

They are: $ROOTSYS , $H1 and $ATLFASTwhich points to the top root directory. It will also add the needed directories to $LD_LIBRARY_PATH and $PATH.

LD_LIBRARY_PATH must contain $ROOTSYS/lib, and $PATH must contain the current directory (.) and $ROOTSYS/bin.

To understand the installation and building of ROOT as you would do it on your own machine see Appendix A in the ROOT User's Guide, or the ROOT website:




Start and Quit ROOT

To start a ROOT session:

> root

To exit at any time:

root[] .q

To run a script:

root [] .x <scriptname.C>


Session A


In this session you will:

·         Use the ROOT command line

·         Write an un-named and a named script

·         Use the GUI to create objects and change their attributes.

·         Save your canvas to a PostScript file

·         Fit a graph

The ROOT Command Line

Start with simple C expressions, defining simple type variables, making additions, multiplications, up to more complex operations.

root [] 35 + 89.3
const double)1.24299999999999997e+02
root [] float x = 45.6
root [] float y = 56.2 + sqrt(x);
root [] float z = x+y;
root [] x
root [] y
root [] z

Creating a Function Object from the Command Line

ROOT has several function classes. The most basic is the TF1. Note that all class names in ROOT start with "T". "F" is for function, and "1" is for one-dimensional. Locate the class description page for TF1 on the ROOT website.

You will see several constructors, one of which as four argument.

TF1 TF1(const char* name, const char* formula, Double_t xmin = 0, Double_t xmax = 1)

Create the following 1-D function and draw it with:

root [] TF1 f1("f1","sin(x)/x",0,10);

root [] f1.Draw();

The constructor arguments are: the name (f1), and expression (sin(x)/x) and a lower and upper limit (0,10).

You can use the tab key to complete the command or list the argument. For example to list all the methods of f1 type:

root [] f1.<TAB>

You can recall commands with the up-arrow and down-arrows. You can use emacs commands to move the cursor on the command line.

Find the appropriate methods in the TF1 class description and call them with the f1 object to answer the following questions:

Question A1:         What is the value of the function derivative at x=2?

Question A2:        What is the function integral between 0 and 3?

Question A3:        What is the value of the function at x=1.2456789?

Writing and Running an Un-Named Script

Quit the ROOT session and create a new directory $HOME/tutorials where you have write permissions. Copy the contents of the $ROOTSYS/tutorials to this new directory. You need to do this so that you can change and save your work.

Change directory to $HOME/tutorials.

Ø       mkdir $HOME/tutorials

Ø       cd $HOME/tutorials

Ø       cp $ROOTSYS/tutorials/*.* .


Open the file graph.C with your favorite editor. This is an example of an un-named script. An un-named script is a collection of commands enclosed in "{ }". All variables defined in an un-named script are available on the global scope including the command line.

Execute the script graph.C on the command line:

root [] .x graph.C

You can see that the script prints the coordinates of each point to the command line window. Redirect the output with the ">", and verify that the coordinates.log was written.

root [] .x graph.C > coordinates.log

root [] .! more coordinates.log

The ".!" command prefix allows you to enter a shell command.

Find the class description page for TGraph to answer the following questions:

Question A4:        The draw command specifies the option ACP, what does this mean?

Question A5:        Copy graph.C to graph2.C and change it to:
1. Center the title of the axis.
2. Add two more points to the graph, one at (2.5,6 and 3,4) 

Question A6:        How would you modify the script graph2.C to draw two arrows starting from the same point at x=1, y = -5, one pointing to the point 6, the other pointing to the last point.


Using the GUI

Question A7:                                      Use the context menu to change the graph line thickness, line color, marker style, and marker color. Change the background of the canvas. Zoom the graph so that it starts at 0.5 and ends at 3.5. The finished canvas should look like this:

Question A8:                                      With the GUI Editor add another arrow, this time from  x = 3, y = 0 to  x = 2, y = 5-5.

Pull down the File menu and select Save as This creates a PostScript file of the canvas named after the canvas name ( Print the file on the local printer.

Fitting a Graph

Re-execute the script graph2.C. We would like to add a fit for each section of the graph. Look at the TGraph::Fit method on the TGraph class description page. At first fit the graph with the GUI:

1.Select the graph with the mouse

2. Right-click to bring up the context menu.

3. Select FitPanel.

Fit the first part with a polynomial of degree 4, and the second part with a polynomial of degree 1, using the slider. In the end, use the "Add to list of function" and "same picture" options to see both fits on the graph.

Question A9:         How would you modify the first script graph.C adding a loop to fit the graph with polynomials of degree 2 to 7 keeping all the fits on the canvas and assigning a different color to each function?  The added statements should not produce any output in the alphanumeric window. 

To access the list of fitted functions for the graph, you can do:

root [] TList *lfits = gr->GetListOfFunctions();

root [] lfits->ls();

To get a pointer to the fitted function with a polynomial of degree 4, do

root [] TF1 *pol4 = (TF1*)lfits->FindObject(“pol4”)


root [] TF1 *pol4 = gr->GetFunction(“pol4”);

Question A10:     Why is it necessary to cast to (TF1*) in the first case?

The Command History

Find the information in the User's Guide about the command history file to answer the next question.

Question A11:     How can you find all the commands you have entered so far?

A Named Script

A named script differs from an un-named script in that it contains function definitions. The function with the same name as the file is executed when the .x filename command is given. All variables on the stack are local in scope, and the variables created on the heap are still global.

Copy the graph2.C file into graph3.C; edit this file, replacing the first line “{” by “void graph3() {” and execute the script.

root [] .x graph3.C

Comment the line out that creates the variable gr on the heap and add a line to create it on the stack:

// gr = new TGraph(n,x,y);

TGraph gr(n,x,y);

Now, reset the ROOT environment and execute graph3 again:

root[] gROOT->Reset()

root[] .x graph3.C

Question A12:     What happened and why?



Session B

In this session you will:

·         Fit and rotate a histogram

·         Use the Object Browser and the Tree Viewer

·         Make a profile and contour graphs

·         Build an event list from a cut

·         Fill a histograms with random numbers

·         Use ACLiC

Fitting a Histogram

Execute the tutorials hsimple.C and hsum.C. 

Question B1:          In the canvas generated by hsum.C, how would you add the fit of the second signal s2 using a Landau distribution in a sub-range?  Keep the original histograms are kept on the same picture.same.

The Object Browser

Exit the current ROOT session and start a new one. Create a ROOT Browser Object and select the File:Open menu item.

root[] TBrowser b;

Open the file hsimple.root. Double click on the ROOT files folder to see hsimple.root. Double click on hsimple.root and you can see the contents of the file. Find the tree ntuple and double click on it. You can see several variables.

Question B2:          How do you histogram the variable pz from the ntuple in hsimple.root.

Using the Tree Viewer

On the ROOT command line, start the Tree Viewer for the ntuple.

root[] ntuple->StartViewer();

Use the information in the User's Guide on the Tree Viewer (pg. 181)Viewer and the TH1::Draw options (pg. 81) to answer the next question.

Question B3:          Using the Tree Viewer how would you make a profile histogram of pz versus px.

Question B4:          Fit the profile with a polynomial of degree 2.

Cuts and Contour Graphs

Question B5:          Using the Tree Viewer show py versus px with the condition that px^2 + py^2 < 20 using different graphics options (see User's Guide pg. 81).

Use the option contz,list as the final draw option. On the command line reset the global color palette. Notice that the Draw command from the Tree Viewer was printed to the command line. Now you can use the up-arrow to recall the command.


root[] gStyle->SetPalette(1)

root[] ntuple->Draw("py:pz","px*px+py*py< 20","contz,list", 25000, 0);


NOTE: To execute FirstContour.C you need ROOT version 2.26!

Locate theDownload the script FirstContour.C. from

 Study it to answer the following questions

Question B6:          What is done by these lines?

   TObjArray *contours =


   TList *lcontour1 = (TList*)contours->At(0);

   TGraph *gc1 = (TGraph*)lcontour1->First();


Question B7:          What does this loop do in FirstContour.C?

while(1) {

      Double_t x = -4 +8*gRandom->Rndm();

      Double_t y = -4 +8*gRandom->Rndm();

      if (cutg->IsInside(x,y)) {



         if (np == npmax) break;



Making an Event List

Use the User's Guide (pg. 198) or the TTree class description to look up the syntax to create an event list. From the command line and using the ntuple in file hsimple.root, generate a TEventList with entries having pz > 10.  Print the lists of events on the screen. 

Question B8:          How many events are in the list?

Use this list to display the px for the events in the list.

Look at the history file and see the commands that were generated. From the history file, take the commands that you typed in interactively and make a script.

Question B9:          Write a script to do what you just did interactively: open hsimple.root, make an event list with entries having pz > 10, print the event list and the number of entries on the screen.

Question B10:      What is the RMS of the selected px distribution?

Rotating Lego Plots

Execute the tutorial h1draw.C. Rotate the Lego histogram in the top right part by left clicking on it and dragging the mouse.

Question B11:      Using a command, how do you get the current viewing angle theta?

Hint: the viewing angle, theta is an attribute of TPad.

Filling Histograms

This next exercise will show you how to fill histograms and take time measurements. Open the file hrandom.C. If you can not find hrandom.C in the tutorials directory you can find it at:

Study how it fills 2 histograms and prints the time it takes to fill them. Execute the script.


root [] .x hrandom.C

While this is executing, study the script and notice how it is written so it can be compiled.

Question B12:      Copy hrandom.C to hrandom1.C and modify it to add two morefill the histograms with two more nfills  using TRandom2 and TRandom3 to fill them. For each case, print the CPU time spent in the random generator.

Using the Compiler interface ACLiC

Start a new ROOT session and run the same script using ACLiC. You should see a considerable improvement in the CUP time:

root [] .x hrandom1.C++


Question B13:      Copy the hrandom1.C script to hrandom2.C and modify it so to draw the first  histogram and display it after the script has finished.



Session C

In this session you will:

·         Study an example analysis from DESY

·         Learn about the TTree::MakeSelector method to automatically create a class that loops over each entry in a tree.

·         Save and retrieve a canvas to and from a ROOT file

·         Compute the integral of a histogram

·         Compute the integral of a function within a range

The data are taken from the DESY H1 micro-DSTs. Copy the file dstarmb.root from: to your $HOME/tutorials directory

The example data file is in your directory $H1/dstarmb.root.

Example Script from TTree::MakeSelector

First, you need to understand how the TTree::MakeSelector method creates a class that loops over the entries in the TTree. Please read the Chapter 12 "Example Analysis" in the User's Guide "Example Analysis" pg.218.

Change directory to $HOME/tutorials, the directory you copied in the last session. Now open the script $HOME/tutorials/h1analysis.C and read the comments.

The script shows how to use a class (the skeleton has been automatically generated by the TTree::MakeSelector method) to loop on the files, perform some cuts and fill two histograms with some physics quantities.

     Start a root session and open the file $H1/dstarmb.root.

root[] TFile f("$H1/dstarmb.root");

Using the TBrowser, display some of the variables in the TTree named h42.

root[] new TBrowser();

Execute the script h1analysis.C on the h42 tree.


root[] h42->Process("h1analysis.C")

Saving and Retrieving a Canvas

Save the canvas with the dm_d histogram as a ROOT file ("c1.root") with the File:Save as canvas.root menu option. Start a new session. Read the saved ROOT file.

root[] .q


root[] TFile f("c1.root")

root[] c1->Draw()


Computing Integrals

Get a pointer to the Dstar histogram named “hdmd”. 

Get a pointer to the fitted function “f5”.

Compute hint = the histogram bin integral. 

Compute fint = the f5 integral where the function is positive (0.139 – 0.17).

Use the TH1 and TF1 class description web page to find the right method to calculate the integral for each object.


Question C1:     What is the value of ratio = fint/hint?