ROOT: An Object-Oriented Data Analysis Framework

A report on a data analysis tool currently being developed at CERN.
The GUI Classes and Object Browser

Embedded in the ROOT system is an extensive set of GUI classes. The GUI classes provide a full OO-GUI framework as opposed to a simple wrapper around a GUI such as Motif. All GUI elements do their drawing via the TGXW low-level graphics abstract base class. Depending on the platform on which you run ROOT, the concrete graphics class (inheriting from TGXW) is either TGX11 or TGWin32. All GUI widgets are created from “first principles”, i.e., they use only routines like DrawLine, FillRectangle, CopyPixmap, etc., and therefore, the TGX11 implementation needs only the X11 and Xpm libraries. The advantage of the abstract base class approach is that porting the GUI classes to a new, non X11/Win32, platform requires only the implementation of an appropriate version of TGXW (and of TSystem for the OS interface).

All GUI classes are fully scriptable and accessible via the interpreter. This allows for fast prototyping of widget layouts.

The GUI classes are based on the XClass'95 library written by David Barth and Hector Peraza. The widgets have the well-known Windows 95 look and feel. For more information on XClass'95, see

Figure 3. ROOT Object Browser

Using the ROOT Object Browser, all objects in the ROOT system can be browsed and inspected. To create a browser object, type:

root [0] TBrowser *b = new TBrowser

The browser, as shown in Figure 3, displays in the left pane the browse-able ROOT collections and in the right pane the objects in the selected collection. Double clicking on an object will execute a default action associated with the class of the object. Double clicking on a histogram object will draw the histogram. Double clicking on an Ntuple quantity will produce a histogram showing the distribution of the quantity by looping over all tuples in the Ntuple. Right clicking on an object will bring up a context menu (just as in a canvas).

Integrating Your Own Classes into ROOT

In this section, I'll give a step-by-step method for integrating your own classes into ROOT. Once integrated, you can save instances of your class in a ROOT database, inspect objects at run-time, create and manipulate objects via the interpreter, generate HTML documentation, etc. A very simple class describing some person attributes is shown in Listing 1. The Person implementation file Person.cxx is shown in Listing 2.

The macros ClassDef and ClassImp provide some member functions that allow a class to access its interpreter dictionary information. Inheritance from the ROOT basic object, TObject, provides the interface to the database and inspection services.

Now run the rootcint program to create a dictionary, including the special I/O streamer and inspection methods for class Person:

bash$ rootcint -f dict.cxx -c Person.h

Next, compile and link the source of the class and the dictionary into a single shared library:

bash$ g++ -fPIC -I$ROOTSYS/include -c dict.cxx
bash$ g++ -fPIC -I$ROOTSYS/include -c Person.cxx
bash$ g++ -shared -o Person.o dict.o
Now start the ROOT interactive program and see how we can create and manipulate objects of class Person using the CINT C++ interpreter:
bash$ root
root [0] gSystem->Load("")
root [1] Person rdm(37, 181.0)
root [2] rdm.get_age()
root [3] rdm.get_height()
root [4] TFile db("test.root","new")
root [5] rdm.Write("rdm") // Write is inherited from the
TObject class
root [6]
TFile** test.root
 TFile* test.root
 KEY: Person rdm;1
root [7] .q
Here, the key statement was the command to dynamically load the shared library containing the code of your class and the class dictionary.

In the next session, we access the rdm object we just stored on the database test.root:

bash$ root
root [0] gSystem->Load("")
root [1] TFile db("test.root")
root [2] rdm->get_age()
root [3] rdm->Dump() // Dump is inherited from the TObject
age     37      age of person
height  181     height of person
fUniqueID       0       object unique identifier
fBits   50331648        bit field status word
root [4] .class Person
[follows listing of full dictionary of class Person]
root [5] .q

A C++ macro that creates and stores 1000 persons in a database is shown in Listing 3. To execute this macro, do the following:

bash$ root
root [0] .x fill.C
root [1] .q

This method of storing objects would be used only for several thousands of objects. The special Tree object containers should be used to store many millions of objects of the same class.

Listing 4 is a C++ macro that queries the database and prints all persons in a certain age bracket. To execute this macro, do the following:

bash$ root
root [0] .x find.C(77,80)
age = 77, height = 10077.000000
age = 78, height = 10078.000000
age = 79, height = 10079.000000
age = 80, height = 10080.000000
root [1] find(888,895)
age = 888, height = 10888.000000
age = 889, height = 10889.000000
age = 890, height = 10890.000000
age = 891, height = 10891.000000
age = 892, height = 10892.000000
age = 893, height = 10893.000000
age = 894, height = 10894.000000
age = 895, height = 10895.000000
root [2] .q

With Person objects stored in a Tree, this kind of analysis can be done in a single command.

Finally, a small C++ macro that prints all methods defined in class Person using the information stored in the dictionary is shown in Listing 5. To execute this macro, type:

bash$ root
root [0] .x method.C
class Person Person(int a = 0, float h = 0)
int get_age()
float get_height()
void set_age(int a)
void set_height(float h)
const char* DeclFileName()
int DeclFileLine()
const char* ImplFileName()
int ImplFileLine()
Version_t Class_Version()
class TClass* Class()
void Dictionary()
class TClass* IsA()
void ShowMembers(class TMemberInspector& insp, char* parent)
void Streamer(class TBuffer& b)
class Person Person(class Person&)
void ~Person()
root [1] .q

The above examples prove the functionality that can be obtained when you integrate, with a few simple steps, your classes into the ROOT framework.



Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.


Leo Tilson's picture

I am often a little nervous when approaching a software package for the first time. This is exactly the sort of article to help me overcome my fears. From what I hear, ROOT is probably one of the most powerful databases out there - I am impressed for instance by the way in which the data can be highly compressed - but you also seem to have devoted a huge amount of effort into making it as user friendly as possible.

I have been reviewing my use of databases over the last few days because of some concern about MySQL, these concerns being prompted by the legal action being taken by Oracle against Google, and Oracle's reduction in support for OpenSolaris. I had never considered ROOT as an alternative to MySQL, until recently thinking of it as a rather specialised tool. I was pleased to note however that there are bindings for Ruby amongst other languages.

I wonder about your figures for OS shares? I have just installed ROOT, but instead of downloading it from its official site I have installed it from the Debian repository. If many people do this, then the numbers you record for Linux usage may underestimate its Linux usage.

Thank you.