ROOT is integrated with the Jupyter notebook technology. There are two alternatives for using ROOT in a notebook:
%%cpp
magic.This Python notebook will show how to use the Python flavour.
In order to use ROOT in a Python notebook, we first need to import the ROOT module. During the import, all notebook related functionalities are activated.
import ROOT
Now we are ready to use PyROOT. For example, we create a histogram.
h = ROOT.TH1F("gauss","Example histogram",100,-4,4)
h.FillRandom("gaus")
Next we create a canvas, the entity which holds graphics primitives in ROOT.
c = ROOT.TCanvas("myCanvasName","The Canvas Title",800,600)
h.Draw()
For the histogram to be displayed in the notebook, we need to draw the canvas.
c.Draw()
It is not active by default yet, but Javascript visualisation can be activated for testing purposes. The plot below will be interactive: click on it and discover the JSROOT capabilities!
%jsroot on
c.Draw()
%%cpp
magic¶Thanks to ROOT, it is possibile to write cells in C++ within a Python notebook.
This can be done using the %%cpp
magic. Magics are a feature of Jupyter notebooks and when importing the ROOT module, the %%cpp
magic was registered.
%%cpp
cout << "This is a C++ cell" << endl;
Not bad. On the other hand, ROOT offers much more than this. Thanks to its type system, entities such as functions, classes and variables, created in a C++ cell, can be accessed from within Python.
%%cpp
class A{
public:
A(){cout << "Constructor of A!" << endl;}
};
a = ROOT.A()
The Python and C++ worlds are so entangled that we can find back in C++ the entities created in Python. To illustrate this, from within a C++ cell, we are going to fit a function in the gauss
histogram displayed above and then re-draw the canvas.
%%cpp
gauss->Fit("gaus", "S");
myCanvasName->Draw();
Complete interoperability is possible. Let's move now to the options offered by the %%cpp
magic.
%%cpp
magic¶The %%cpp
magic accepts two options: -d
and -a
. Their documentation can be seen by typing:
%%cpp?
A window will appear at the bottom of the page, showing the documentation.
The first option (-a
) allows to compile the cell code with ACLiC. This is not so relevant for performance since the ROOT interpreter just in time compiles the C++ code. Nevertheless, ACLiC is most useful when the automatic creation of dictionaries is required, for example in presence of I/O operations.
%%cpp -a
class CompileMe {
public:
CompileMe() {}
void run() {}
};
Let's verify that the dictionary is there:
ROOT.TClass.GetClass("CompileMe").HasDictionary()
Note that the previously created class A
has no dictionary.
ROOT.TClass.GetClass("A").HasDictionary()
The second option (-d
) needs to be used when declaring functions. The interpreter cannot yet detect function declarations by itself: we need to be explicit. This is a limitation which will be lifted in the near future.
%%cpp -d
void f() {
cout << "This is function f" << endl;
}
As usual, function f
can also be accessed from Python.
print "This is again Python"
ROOT.f()