ROOT scripts
Overview
Teaching: min
Exercises: minQuestions
How to use ROOT scripts?
Objectives
Learn about using C++ scripts with ROOT
This section is dedicated to the introduction to using ROOT scripts or macros.
ROOT scripts
A unique feature of ROOT is the possibility to use C++ scripts, also called “ROOT macros”. A ROOT script contains valid C++ code and uses as entrypoint a function with the same name as the script. Let’s take as example the file myScript.C
with the following content.
void myScript() {
auto file = TFile::Open("tmva_class_example.root");
auto newtree = (TTree*)file->Get("TreeS");
auto entries = newtree->GetEntries();
std::cout << "Entried in TreeS : " << entries << std::endl;
}
Scripts can be processed by passing them as argument to the root
executable:
$ root myScript.C
root [0]
Processing myScript.C...
Entried in TreeS : 6000
There are other ways to run scripts, try them.
Plotting from file ith script
void myScript_plot() {
TH1F *h_var1 = new TH1F("h_var1", "var1", 100, -4.0, 4.0);
TFile *file = new TFile("/Users/sar/Desktop/TestROOT/tmva_class_example.root");
TTree *tree1 = (TTree*)file->Get("TreeS");
float var1;
tree1->SetBranchAddress("var1", &var1);
int nentries = (int)tree1->GetEntries();
for(int i=0; i < nentries; i++){
tree1->GetEntry(i);
h_var1->Fill(var1);
}
TCanvas *c1 = new TCanvas();
h_var1->Draw();
}
Examples of creating histogam:
void scriptHist(){
auto cnt_r_h=new TH1F("count_rate",
"Count Rate;N_{Counts};# occurencies",
100, // Number of Bins
-0.5, // Lower X Boundary
15.5); // Upper X Boundary
auto mean_count=3.6f;
TRandom3 rndgen;
// simulate the measurements
for (int imeas=0;imeas<400;imeas++)
cnt_r_h->Fill(rndgen.Poisson(mean_count));
auto c= new TCanvas();
cnt_r_h->Draw();
auto c_norm= new TCanvas();
cnt_r_h->DrawNormalized();
// Print summary
cout << "Moments of Distribution:\n"
<< " - Mean = " << cnt_r_h->GetMean() << " +- "
<< cnt_r_h->GetMeanError() << "\n"
<< " - Std Dev = " << cnt_r_h->GetStdDev() << " +- "
<< cnt_r_h->GetStdDevError() << "\n"
<< " - Skewness = " << cnt_r_h->GetSkewness() << "\n"
<< " - Kurtosis = " << cnt_r_h->GetKurtosis() << "\n";
}
Using graphs
// Builds a graph with errors, displays it and saves it as
// image. First, include some header files
// (not necessary for Cling)
#include "TCanvas.h"
#include "TROOT.h"
#include "TGraphErrors.h"
#include "TF1.h"
#include "TLegend.h"
#include "TArrow.h"
#include "TLatex.h"
void macro1(){
// The values and the errors on the Y axis
const int n_points=10;
double x_vals[n_points]=
{1,2,3,4,5,6,7,8,9,10};
double y_vals[n_points]=
{6,12,14,20,22,24,35,45,44,53};
double y_errs[n_points]=
{5,5,4.7,4.5,4.2,5.1,2.9,4.1,4.8,5.43};
// Instance of the graph
TGraphErrors graph(n_points,x_vals,y_vals,nullptr,y_errs);
graph.SetTitle("Measurement XYZ;lenght [cm];Arb.Units");
// Make the plot estetically better
graph.SetMarkerStyle(kOpenCircle);
graph.SetMarkerColor(kBlue);
graph.SetLineColor(kBlue);
// The canvas on which we'll draw the graph
auto mycanvas = new TCanvas();
// Draw the graph !
graph.DrawClone("APE");
// Define a linear function
TF1 f("Linear law","[0]+x*[1]",.5,10.5);
// Let's make the function line nicer
f.SetLineColor(kRed); f.SetLineStyle(2);
// Fit it to the graph and draw it
graph.Fit(&f);
f.DrawClone("Same");
// Build and Draw a legend
TLegend leg(.1,.7,.3,.9,"Lab. Lesson 1");
leg.SetFillColor(0);
graph.SetFillColor(0);
leg.AddEntry(&graph,"Exp. Points");
leg.AddEntry(&f,"Th. Law");
leg.DrawClone("Same");
// Draw an arrow on the canvas
TArrow arrow(8,8,6.2,23,0.02,"|>");
arrow.SetLineWidth(2);
arrow.DrawClone();
// Add some text to the plot
TLatex text(8.2,7.5,"#splitline{Maximum}{Deviation}");
text.DrawClone();
mycanvas->Print("graph_with_law.pdf");
}
int main(){
macro1();
}
Examples of creating a ROOT file:
void myScript_file() {
TH1F *h_var1 = new TH1F("h_var1", "var1", 100, -4.0, 4.0);
TFile *file = new TFile("tmva_class_example.root");
TTree *tree1 = (TTree*)file->Get("TreeS");
float varx;
tree1->SetBranchAddress("var1", &varx);
TFile* newFile( TFile::Open("newfile.root", "RECREATE") );
auto newtree = std::make_unique<TTree>("newtree", "The Tree Title");
newtree->Branch("branch0", &varx);
int nentries = (int)tree1->GetEntries();
for(int i=0; i < nentries; i++){
tree1->GetEntry(i);
h_var1->Fill(varx);
newtree->Fill();
}
TCanvas *c1 = new TCanvas();
h_var1->Draw();
newFile->cd();
newtree->Write();
h_var1->Write();
newFile->Write();
newFile->Close();
}
The advantage of such scripts is the simple interaction with C++ libraries (such as ROOT) and running your code at C++ speed with the convenience of a script.
Compiled C++
You can improve the runtime of your programs if you compile them upfront. Therefore, ROOT tries to make the compilation of ROOT macros as convenient as possible!
ACLiC
ROOT provides a mechanism called ACLiC to compile the script in a shared library and call the compiled code from interactive C++, all automatically!
The only change required to our script is that we need to include all required headers:
#include "TFile.h"
#include "TTree.h"
#include <iostream>
void myScript() {
// The body of the myScript function goes here
}
Now, let’s compile and run the script again. Note the +
after the script name!
$ root myScript.C+
ACLiC has many more features, for example compiling your program with debug symbols using +g
. You can find the documentation here.
C++ compilers
Of course, the C++ code can also just be compiled with C++ compilers such as g++
or clang++
with the advantage that you have full control of all compiler settings, most notable the optimization flags such as -O3
!
To do so, we have to add the main
function to the script, which is the default entrypoint for C(++) programs.
#include "TFile.h"
#include "TTree.h"
#include <iostream>
void myScript() {
// The body of the myScript function goes here
}
int main() {
myScript();
return 0;
}
Now, you can use the following command with your C++ compiler of choice to compile the script into an executable.
$ g++ -O3 -o myScript myScript.C $(root-config --cflags --libs)
$ ./myScript
TreeS : 6000
TreeB : 6000
Computationally heavy programs and long running analyses may benefit greatly from the optimized compilation with -O3
and can save you hours of computing time!
Key Points
ROOT provides many features from histogramming, fitting and plotting to investigating data interactively in C++ and Python but scripts can help with advanced work
Learn about C/C++ scripts for ROOT.