1.2.5. Important modifications going from ROOT v5 to ROOT v6

This part summarises the important modifications that are brought when changing ROOT versions. This affects some of the Uranie macros and if you’ve used Uranie before version 4.X, this part can be useful to understand the modifications that will mainly affect the constructor of some Uranie’s objects.

The main subject is the way to handle function. As an example, we will considerer the “very” simple function that with two inputs returns the sum of these two values (c.f. the Addition function below).

void Addition(double *x, double *y)
{
    y[0] = x[0] + x[1] ;
}

In C++, within the Uranie framework, there are three ways to use this function in a macro, that would be called analysis.C:

  1. Having the function in a separated file MyFunction.C and load it through ROOT by calling

    gROOT->LoadMacro("MyFunction.C");
    
  2. Having the function in a separated file MyFunction.C and include this file in the header of analysis.C as

    #include "MyFunction.C"
    
  3. Having the function in the same file (analysis.C) before the main function.

This is common practice both for the 5 and 6 versions of ROOT.

From this, the way to handle this function is a little bit different going from one ROOT major-version (i.e. 5.X) to another one (i.e. 6.X).

ROOT 5.X:

Disregarding the chosen option to read the function (1, 2, or 3 discussed above) the interpreter (CInt for these versions of ROOT) is associating to the pointer of the function Addition (which is a pointer of the form (void *)(double *, double*) a name, which it uses as a tag by CInt. The name is in this case “Addition”. For the 3 configuration defined up there, one can use the name and/or the pointer to access the function.

ROOT 6.X:

On the other hand, for these versions of ROOT, the interpreter is, as stated previously, a runtime compiler, so it behaves very much like expected from properly C++ compiled code. When calling the function thanks to its pointer (the (void *)(double *, double*) object) no information on a name is accessible. Compared to ROOT 5, there is no pointer to the function if it is loaded through LoadMacro (which is perfectly logic from a C++ point of view). The second and third access method can, on the other hand, use both the pointer and the name.

This obliges us to change several constructor that had been (over ?) simplified: in ROOT 5 versions, the compulsory information were often just a pointer to the TDataServer object and either the name of the function or a pointer to it. From this, if nothing else was specified, all current inputs in the TDataServer were used as inputs (this behaviour could be changed usually providing at third argument) and the output variables were named using the tag taken from CInt (this behaviour could be changed as well usually providing a fourth argument). Having no tag anymore from CInt when running ROOT 6, the (usually) optional third and fourth arguments become now compulsory.