ROOT provides the
class to store large quantities of same-class objects.
A tree is a typical data container used for example by all LHC (Large Hadron Collider) experiments.
Trees are optimized to reduce disk space and enhance access speed.
A tree consists of a list of independent columns, called branches. The TBranch class represents a branch. A branch can contain all kind of data, such as objects or arrays in addition to all the simple types.→ Tree tutorials
ROOT provides numerous classes for trees and branches, of which the following are among the most used:
TTree: Represents a columnar data set. Any C++ type can be stored in its columns.
TNtuple: A simple
TTreerestricted to a list of float variables only.
TBranch: Organizes columns, i.e. branches, of a
TChain: A list of ROOT files containing
Working with trees
ROOT offers many possibilities to work with trees, for example:
- Creating a tree
- Creating a tree from a folder structure
- Filling a tree
- Writing a tree
- Printing the summary of a tree
- Showing an entry of a tree
- Scanning trees
Creating a tree
- Use the TTree constructor to create a tree.
It creates a tree with the title
Example: A simple tree
The following script builds a
from an ASCII file containing
statistics about the staff at CERN. Both,
staff.dat are in available in
The following script declares a structure called
staff_t. It opens the ASCII file, creates
a ROOT file and a
TTree. Then it creates one branch with the
The first parameter of the
Branch() method is the branch name.
The second parameter is the address from which the first leaf is to be read. In this example, it is the address of the structure staff. Once the branch is defined, the script reads the data from the ASCII file into the
structure and fills the tree. The ASCII file is closed, and the ROOT file is written to
disk saving the tree. Trees and histograms are created in the current directory, which is
the ROOT file in our example. Hence an
f->Write() saves the tree.
Example: Building a tree from an ASCII file
cernbuild.C ROOT macro creates a root file (
cernstaff.root) and prints the tree
T and its branches with TTree::Print().
Creating a tree from a folder structure
You can build a folder structure and create a tree with branches for each of the sub-folders.
MyFolder is the top folder.
/ indicates the
constructor that a folder is being used.
You can fill the tree by placing the data into the folder structure and then calling the TTree::Fill() method.
Filling a tree
A loop on all defined branches (see → Branches) is executed.
Writing a tree
The data of a tree are saved in a ROOT file (see → ROOT files).
- Use the TTree::Write() method to write the tree into a ROOT file.
TTree::Write() method is needed to write the ROOT file header.
When writing a
to a ROOT file and if the ROOT file size reaches the value stored in the TTree::GetMaxTreeSize(), the current ROOT file is closed and a new ROOT file is created. If the original ROOT file is named
myfile.root, the subsequent ROOT files are named
Autosave gives you the option to save all branch buffers every n byte. It is recommended to use
Autosave for large acquisitions. If the acquisition fails to complete, you can recover the ROOT file and all the contents since the last
- Use the TTree::SetAutosave() method to set the number of bytes between
You can also use TTree::SetAutosave() in the acquisition loop every n entry.
Printing the summary of a tree
Use the TTree::Print(Option_t * option = “”) method to print a summary of the tree contents.
option = "all": Friend trees are also printed.
option = "toponly": Only the top level branches are printed.
option = "clusters": Information about the cluster of baskets is printed.
Showing an entry of a tree
- Use the TTree::Show() method to access one entry of a tree.
Showing an entry from the
cernstaff.root file (see → Building a tree from an ASCII file).
- Use the TTree::Scan() method to display all values of the list of leaves.
cernstaff.root file (see → Building a tree from an ASCII file).
- Use TTree::BuildIndex() method to build an index table using expressions depending on the value in the leaves.
The index is built in the following way:
- A pass on all entries is made like in TTree::Draw().
sel = 231× majorname + minorname
- For each entry in the tree the
selexpression is evaluated and the result array is sorted into
Once the index is calculated, an entry can be retrieved with TTree::GetEntryWithIndex(majornumber, minornumber).
minorname can be expressions using original tree variables e.g.,
In case an expression is specified, the equivalent expression must be computed when calling
To build an index with only
Once the index is built, it can be saved with the
TTree object with
The most convenient place to create the index is at the end of the filling process just before saving the tree header. If a previous index was calculated, it will be redefined by this new call.
Note that this function can also be applied to a TChain . The return value is the number of entries in the Index (< 0 indicates failure).
With the Tree Viewer you can examine a tree in a GUI.
You can also use the ROOT Object Browser to examine a tree that is saved in a ROOT file. See → ROOT Object Browser.
- Use the TTreeViewer class to open the ROOT file (containing the tree) in the Tree Viewer.
Open the Tree Viewer for the
cernstaff.root file (see → Building a tree from an ASCII file) that contains the tree
Figure: Tree Viewer.
The left panel contains the list of trees and their branches. The right panel displays the leaves or variables in the tree.
Drawing correlating variables in a scatterplot
You can show the correlation between the variables, listed in the TTreeViewer , by drawing a scatterplot.
- Select a variable in the
and drag it to the
- Select a second variable and drag it to the
Figure: Variables Age and Cost selected for the scatterplot.
Figure: Scatterplot icon.
The scatterplot is drawn.
Figure: Scatterplot of the variables Age and Cost.
Note that not each `(x,y) point on a scatterplot represents two values in your N−tuple. In fact, the scatterplot is a grid and each square in the grid is randomly populated with a density of dots that’s proportional to the number of values in that grid.
You can organize columns, this is branches, of a tree with the
class. A variable on a
TBranch is called a leaf (
). If two variables are independent and it is certain that the variables will not be used together, they should be placed on separate branches.
The branch type differs by what is stored in it. A branch can contain the following data:
- an entire object,
- a list of simple variables,
- contents of a folder,
- contents of a TList ,
- an array of objects.
If two variables are independent and the variables will not be used together, place them on separate branches. If the variables are related, such as the coordinates of a point, create one branch with both coordinates on it.
Adding a branch
address is the address of the first item of a structure.
leaflist is the concatenation of all the variable names and types separated by a colon character. The variable name and the variable type are separated by a slash (/). The variable type must be one character.
For more information on adding a branch to tree, see →
Do not use the TBranch constructor to add a branch to a tree.
Adding a branch with a folder
- Use the following syntax to add a branch with a folder:
This creates one branch for each element in the folder. The method returns the total number of branches created.
Adding a branch with STL collections
STLcollection is a address of a pointer to
std::multiset containing pointers to objects.
- Use the following syntax of the TTree::Branch() method to add a
splitlevel is a value bigger than 100 TTree::kSplitCollectionOfPointers then the
STLcollection will be written in split mode.
If a dynamic structures changes with each entry, you have to redefine the branch address with TBranch::SetAddress before filling the branch again.
Adding a branch with objects
- Use the following syntax of the TTree::Branch() method to add objects to a tree:
The following values are available for the
The object is serialized in the branch buffer.
This branch is automatically into sub-branches, with one sub-branch for each data member or object of the object itself. If the object member is a TClonesArray, it is processed as it is with
This branch is automatically split into sub-branches, with one sub-branch for each data member or object of the object itself. If the object member is a TClonesArray it is processed as a TObject, but only for one branch.
Adding a branch to an existing tree
You can add a branch to an existing tree.
If one variable in the tree was computed with a certain algorithm, you may want to try another algorithm and compare the results. To do this, you can add a new branch, fill it, and save the tree.
kOverwrite in the
Write() method causes the tree to be overwritten.
Examples for writing and reading trees
The following sections are examples of writing and reading trees that range in complexity from a simple tree with a few variables to a tree with folders and complex event objects.
A tree with a C structure
In this tutorial is shown:
- how to build branches from a C structure
- how to make a branch with a fixed length array
- how to make a branch with a variable length array
- how to read selective branches
- how to fill a histogram from a branch
- how to TTree::Draw to draw a 3D plot
Adding friends to trees
Adding a branch is often not possible because the tree is a read-only file and you do not have permission to save the modified tree with the new branch. Even if you do have the permission, you risk loosing the original tree with an unsuccessful attempt to save the modification. Since trees are usually large, adding a branch could extend it over the 2 GB limit. In this case, the attempt to write the tree fails, and the original data is may also be corrupted. In addition, adding a branch to a tree enlarges the tree and increases the amount of memory needed to read an entry, and therefore decreases the performance.
For these reasons ROOT offers the concept of friends for trees (and chains) by adding a branch manually with TTree::AddFriend().
The TTree::AddFriend() method has two parameters, the first is the tree name and the second is the name of the ROOT file where the friend tree is saved. TTree::AddFriend() automatically opens the friend file.
Importing an ASCII file into a tree
Using trees for data analysis
The following methods are available for data analysis using trees:
With the TTree::Draw() method, you can easily plot a variable (a leaf).
cernstaff.root file (see → Building a tree from an ASCII file) and lists its content.
cernstaff.root file contains the
T. A pointer is created to the tree.
To show the different
Draw() options, a canvas with four sub-pads is created.
The first pad with is activated with TCanvas::cd.
Figure: The variable
Cost drawn in a histogram.
Next, the second pad is activated and scatter plot is drawn. Two dimensions (here
Age) are separated by a colon (“x:y”).
In general, this parameter is a string containing up to three expressions, one for each dimension, separated by a colon (“e1:e2:e3”).
Figure: The variable
Age drawn in a histogram.
Next, the third pad is activated and a selection is added.
Age for the entries where the nation is equal to
"CH" is drawn.
You can use any C++ operator. The value of the selection is used as a weight when filling the histogram. If the expression includes only Boolean operations the result is 0 (histogram is not filled) or 1 (histogram is filled).
Figure: The variable
Age with a selection drawn in a histogram.
Next, the fourth pad is activated and the histogram is drawn with the draw option
Refer to the
class for possible draw options.
Figure: The variable
Age with a selection and a draw option drawn in a histogram.
- Use the TTree::MakeClass() method, to generate a skeleton class for looping over the entries of a tree.
- Use the TTree::MakeSlelector() class, to generate a skeleton selector class for looping over a tree.
Example: Using a ROOT macro for data analysis
The following example shows a simple ROOT macro for analyzing a tree. The ROOT macro calculates the sum of all event sizes.
Now you can create a histogram, for example for the X position of the particles (
hPosX). For more information on creating a histogram for this data analysis, see → Example: Histogramming a data analysis
There are three ROOT files
file3.root. Each ROOT file contains a tree
T. A chain is created with
The name of the TChain is the same as the name of the tree.
To generate an histogram corresponding to the attribute
x in the tree
T by processing sequentially the three files of this chain, you can write:
The next example illustrates how to set the address of an object to be read and how to loop on all events of all files of the chain.
Writing simple N-tuples
In the following example, three independent variables (voltage, pressure and temperature) and one variable (current) which depends on the others according to very simple law, and an additional Gaussian smearing, are written to a ROOT file.
In the ROOT Object Browser you can find the columns of your n-tuple written as leafs. Clicking on one of the leafs obtains the histogram of the appropriate variable.
Figure: N-tuple in the ROOT Object Browser.
Use the following commands at the system prompt or in the ROOT shell to draw a simple correlation plot:
Figure: Current/Potential correlation plot.
The following example shows how to read the data from a ROOT N-tuple.
Writing arbitrary N-tuples
The same N-tuple as before is created, but the branches are booked directly. The
Fill() function then fills the current values of the connected variables to the tree.
Reading TTrees, TChains and TNtuples
A simple example using a