# How to use ROOT in a Jupyter notebook¶

ROOT is integrated with the Jupyter notebook technology. There are two alternatives for using ROOT in a notebook:

1. Python flavour: the default language of the notebook is Python and ROOT is accessed via the PyROOT interface. The user can mark cells to be C++ with the %%cpp magic.
2. C++ flavour: the notebook is entirely written in C++, thus emulating the ROOT C++ prompt.

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

In [1]:
import ROOT

Welcome to ROOTaaS 6.05/01


Now we are ready to use PyROOT. For example, we create a histogram.

In [2]:
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.

In [3]:
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.

In [4]:
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!

In [5]:
ROOT.enableJSVis()
c.Draw()
ROOT.disableJSVis()


### Interleave Python with C++: the %%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.

In [6]:
%%cpp
cout << "This is a C++ cell" << endl;

This is a C++ cell


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.

In [7]:
%%cpp
class A{
public:
A(){cout << "Constructor of A!" << endl;}
};

In [8]:
a = ROOT.A()

Constructor of 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.

In [9]:
%%cpp
gauss->Fit("gaus", "S");
myCanvasName->Draw();

 FCN=65.0502 FROM MIGRAD    STATUS=CONVERGED      54 CALLS          55 TOTAL
EDM=9.21369e-07    STRATEGY= 1      ERROR MATRIX ACCURATE
EXT PARAMETER                                   STEP         FIRST
NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE
1  Constant     1.57425e+02   2.76819e+00   8.89596e-03  -5.39870e-04
2  Mean         1.38321e-02   1.43799e-02   5.69927e-05   8.22299e-04
3  Sigma        1.00178e+00   1.04857e-02   1.11224e-05  -4.31183e-01


Complete interoperability is possible. Let's move now to the options offered by the %%cpp magic.

### The options of the %%cpp magic¶

The %%cpp magic accepts two options: -d and -a. Their documentation can be seen by typing:

In [10]:
%%cpp?


A window will appear at the bottom of the page, showing the documentation.

#### ACliC¶

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.

In [11]:
%%cpp -a
class CompileMe {
public:
CompileMe() {}
void run() {}
};

Info in <TUnixSystem::ACLiC>: creating shared library /home/rw15u099/64a4a5eb_C.so


Let's verify that the dictionary is there:

In [12]:
ROOT.TClass.GetClass("CompileMe").HasDictionary()

Out[12]:
True

Note that the previously created class A has no dictionary.

In [13]:
ROOT.TClass.GetClass("A").HasDictionary()

Out[13]:
False

#### Declaration of functions¶

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.

In [14]:
%%cpp -d
void f() {
cout << "This is function f" << endl;
}


As usual, function f can also be accessed from Python.

In [15]:
print "This is again Python"
ROOT.f()

This is again Python
This is function f


## C++ flavour¶

ROOT allows to run pure C++ notebooks.

This can be achieved in two ways:

1. When choosing to instantiate that kernel, the user is presented with a fully-C++ notebook
2. Switching to C++ programmatically

The manual switch to C++ mentioned above can be done by typing:

In [16]:
ROOT.toCpp()

Notebook is in Cpp mode


Now our notebook behaves as the ROOT prompt, with no need of any magic.

In [17]:
cout << "From this point on..." << endl;

From this point on...

In [18]:
cout << "... it's only C++ ..." << endl;

... it's only C++ ...

In [19]:
cout << "... With the usual goodies!" << endl;
std::unordered_map<int, string> m = {{1, "one"}, {2, "two"}, {3, "three"}}

... With the usual goodies!
(std::unordered_map<int, std::string> &) { 3 => "three", 1 => "one", 2 => "two" }


Remember our C++ function f? ROOT does!

In [20]:
f

(void (*)()) Function @0x7fe5af0b1030
at :1:
void f() {
cout << "This is function f" << endl;
}



### "Magics"¶

We put the title in quotes because as for to the Python flavour, the C++ flavour also provides the ACLiC and Declare options. In order to use them, the first line in the cell must contain the word .cpp followed by the option.

In [21]:
.cpp -a
class CompileMe2 {
public:
CompileMe2() {}
void run() {}
};

Info in <TUnixSystem::ACLiC>: creating shared library /home/rw15u099/4040e501_C.so

In [22]:
.cpp -d
void f2() {
cout << "This is function f" << endl;
}

In [23]:
auto cm2 = CompileMe2()

(CompileMe2 &) @0x7fe5db453080

In [24]:
f2()

This is function f