Mu2e Home
Porting to ROOT 6

This page holds some hints on how migrating root scripts from ROOT 5 to ROOT 6. It is not comprehensive; if you learn somethinig - add it to this page.


Until the end of the ROOT v5 series of releases, ROOT interactive command lines and ROOT macros were parsed and executed by a custom written interpreter named CINT. CINT was advertised as an interpreter for code written in C and C++. A more accurate description is that the CINT language shares many features with C and C++ but it misses many important features and adds other features that are not part of either language. Indeed there is code that is both legal CINT and legal C++ but they do different things.

Starting with ROOT v6, CINT has been replaced by a new interpretter named cling. Quoting from the Cling web site:

Cling is an interactive C++ interpreter, built on the top of LLVM and Clang libraries. Its advantages over the standard interpreters are that it has command line prompt and uses just-in-time (JIT) compiler for compilation.

In addition, Cling can also parse and execute some Cling-specific extensions to C++. These extensions are much less extensive than the extensions supported by CINT.

General Comments and Guidelines

  1. Consider running a ROOT macro from the command line:
    root -l myMacro.C
    The file "myMacro.C" may contain either a macro named myMacro or it may contain an unnamed macro. In both ROOT 5 and ROOT 6, objects instantiated in named macros are destroyed on return from the macro (normal C++ lifetime and scope rules). On the other hand, objects instantiated in an unnamed macro have their lifetime and scope extended; they remain accessible on the command line after return from the unnamed macro.

  2. In ROOT 5 the CINT command to compile and load externally supplied code is:
    In ROOT 6 this has been replaced with the syntax.
    #include "file.C+"
    I have not learned the rules for resolving user supplied header files that are included in file.C; they are not what I expected.

  3. CINT automatically created many variables that are pointers to certain TObjects and that are visible at the ROOT prompt. For example if your compiled ROOT script created a TCanvas object with the TName of mycan, then a variable mycan, of type TCanvas*, was created in the scope of the ROOT prompt. Variables visible at the ROOT prompt were also visible in top level ROOT macros.

    ROOT 6 does not do this. If you create a TObject inside a class or function called from the command line and if you want a pointer to it to be available at the command line, then it is your responsibity to provide a mechanism to communicate the pointer to the command line.

Case Study 1

The two ROOT scripts that are used to make one of the standard sets of tracking efficiency and resolution plots are:

KalFit.C does all of the physics work; ce.C manages I/O and calls KalFit.C.

These scripts operate on a ROOT TTree created by TrkDiag/src/; for an example you can use Analyses/test/genReco.fcl; running it for 2000 events will take about 15 minutes and will produce enough reconstructed tracks to explore.

To run these scripts, setup the Mu2e run-time environment and:

root -l TrkDiag/test/ce.C
This will pop up two TCanvas windows and return control to the ROOT prompt.

These files are available in Mu2e Offline and copies are available here:

The following text is the output of: diff -wbB v5/KalFit.C v6/KalFit.C
>   TCanvas* rcan;
>   TCanvas* acan;
<   TCanvas* acan = new TCanvas("acan","Acceptance",1200,800);
>   acan = new TCanvas("acan","Acceptance",1200,800);
<   TCanvas* rcan = new TCanvas("rcan","Momentum Resolution",1200,800);
>   rcan = new TCanvas("rcan","Momentum Resolution",1200,800);
In the ROOT 5 version, variables acan and rcan were function-local; in the ROOT 6 version they are public member data.

The following text is the output of: diff -wbB v5/ce.C v6/ce.C

< // Version for use with root v5.
> // Version for use with root v6.
<   gROOT->Reset();
<   gROOT->LoadMacro("TrkDiag/test/KalFit.C+");
> #include "TrkDiag/test/KalFit.C+"
<   acan->Print("acan_ce.pdf");
<   rcan->Print("rcan_ce.pdf");
>   fit.acan->Print("acan_ce.pdf");
>   fit.rcan->Print("rcan_ce.pdf");
In the ROOT 6 code, the LoadMacro call is replaced as described in item 2 from General Comments section. In the ROOT 6 code, the TCanvas* pointers acan and rcan are accessed as public member data of the class KalFit.C; in the ROOT 5 code they were automagicaly provided by CINT.

I am not sure if it was necessary to remove the gROOT->Reset() or if it is an artifact of debugging.

Fermilab at Work ]  [ Mu2e Home ]  [ Mu2e @ Work ]  [ Mu2e DocDB ]  [ Mu2e Search ]

For web related questions:
For content related questions:
This file last modified Sunday, 25-Sep-2016 17:33:46 CDT
Security, Privacy, Legal Fermi National Accelerator Laboratory