Introductory School to Terascale Physics 2012 - DESY, 5-9 March 2012

ROOT tutorial

Overview

Tutorial

ROOT is a C++ based framework for data analysis that is widely used in High Energy Physics. This tutorial aims to help getting started with ROOT and will introduce ROOT's basic features (histograms, functions, graphs) as well as more complex objects (files, trees). A number of further references and online tutorials are compiled to guide the user during the first steps throughout the rest of the school.

Further references, additional material and a collection of tutorials can be found here.

Introductory slides for this tutorial can be found here.

Prerequisites

Some basic knowledge of C++ is required for the successful completion of the tutorial and the work with ROOT. A short overview and reminder on the basics of C++ can be found in the references.

Structure

The tutorial is split into several exercises:

Steps marked with * are advanced exercises and can be solved if the time allows. A proposal for homework is also given.

Exercises

Exercise 1 - Getting started

In the first exercise you open an interactive ROOT session and try some useful objects and methods.

  1. Open an interactive root session.
  2. Define a variable x of type double and set it to π/2.
  3. Calculate sin2(x).
  4. Create the Lorentz vector of a particle with E=125.9GeV, px=-29.4GeV, py=-26.2GeV, pz=119.6GeV.
  5. Create a second Lorentz vector of a particle with E=167.8GeV, η=1.82, φ=0.91, pT=53.0GeV.
  6. Create a third LorentzVector which is the sum of the other two. Calculate the invariant mass. What kind of reaction could have happend?
  7. * Boost the particle into it's rest frame and calculate the energy. Hint: remember that β=p/E.
  8. Quit root.

Classes and methods

You will need the following classes and methods for the exercise which we have already seen:

Solution

> root 
  *******************************************
  *                                         *
  *        W E L C O M E  to  R O O T       *
  *                                         *
  *   Version   5.32/00   2 December 2011   *
  *                                         *
  *  You are welcome to visit our Web site  *
  *          http://root.cern.ch            *
  *                                         *
  *******************************************

ROOT 5.32/00 (tags/v5-32-00@42375, Dec 02 2011, 12:42:25 on linuxx8664gcc)

CINT/ROOT C/C++ Interpreter version 5.18.00, July 2, 2010
Type ? for help. Commands must be C++ statements.
Enclose multiple statements between { }.
root [0] double x = TMath::Pi()/2.
root [1] double sinx = TMath::Sin(x)
root [2] sinx*sinx
(double)1.00000000000000000e+00
root [3] TLorentzVector vec1(-29.4,-26.2,119.6,125.9)
root [4] TLorentzVector vec2
root [5] vec2.SetPtEtaPhiE(53.,1.82,0.91,167.8)
root [6] TLorentzVector vec3=vec1+vec2
root [7] vec3.M()
(const Double_t)9.07852492341699104e+01
root [8] vec3.Boost(-vec3.Px()/vec3.E(),-vec3.Py()/vec3.E(),-vec3.Pz()/vec3.E())
root [9] vec3.E()
(const Double_t)9.07852492341698252e+01
root [10] .q

Hide solution

Exercise 2 - Histograms

This exercise shows you how to create a histogram and how to work with it. Write a small ROOT macro for the following purposes:

  1. Create a histogram with 10 bins ranging from 0. to 100. with no title and x-axis label "x"
  2. Fill the histogram with the following numbers: 11.3, 25.4, 18.1
  3. Fill the histogram with the square of all integers from 0. to 9. (Hint: A simple loop will save you from typing several lines of code)
  4. Draw the histogram.
  5. Calculate the mean value and the standard deviation (σ).
  6. Calculate the integral of the histogram. Which value did you expect?
  7. * Identify the bin with the maximum number of entries.
  8. * Calculate the maximum bin content.
  9. Set the y-axis label to "entries".
  10. Set the line color of the histogram to red.

Classes and methods

You will need the following classes and methods for the exercise:

Solution
Content of ex2.C:
#include "TH1.h"
#include "TAxis.h"
#include <iostream>

void ex2() {
    TH1F* hist = new TH1F("histogram1", ";x", 10, 0., 100.);
    hist->Fill(11.3);
    hist->Fill(25.4);
    hist->Fill(18.1);
    for (unsigned int i=0; i<10; i++) {
        hist->Fill(i*i);
    }
    hist->Draw();
    std::cout << "mean=" << hist->GetMean() << " sigma=" << hist->GetRMS() << std::endl;
    std::cout << "integral=" << hist->Integral() << std::endl;
    std::cout << "bin with maximum value=" << hist->GetMaximumBin() << std::endl;
    std::cout << "maximum value=" << hist->GetBinContent(hist->GetMaximumBin()) << std::endl;
    hist->GetYaxis()->SetTitle("entries");
    hist->SetLineColor(kRed);
}
        
Output:
> root -l ex2.C
root [0]
Processing ex2.C...
<TCanvas::MakeDefCanvas>: created default TCanvas with name c1
mean=26.1385 sigma=24.1017
integral=13
bin with maximum value=1
maximum value=4
        

The histogram should look like this:

Hide solution

Exercise 3 - Canvases and Legends

This exercise shows you how to use different canvases and draw histograms into them. Additionally you will add a legend to a canvas.

  1. Create two histograms with 10 bins ranging from -5. to 5. with no title and two different names.
  2. Fill the first histogram with a Gaussian distribution by using
     hist1->FillRandom("gaus", 500);
  3. Fill the second histogram with a second order polynomial distribution by using
     hist2->FillRandom("pol2", 500);
  4. Create a new TCanvas with name "c1" and title "gauss" and draw the first histogram.
  5. Create a new TCanvas with name "c2" and title "poly" and draw the second histogram.
  6. Set the line color of the first histogram to red (kRed) and the second to blue (kBlue).
  7. Clone both histograms with new names.
  8. Scale both cloned histograms by the inverse of their respective integral, i.e. normalise them to unit area.
  9. Create a third canvas and draw the first cloned histogram. Then draw the second cloned histogram with option "same" to have both histograms in the same plot.
  10. * Create a legend at position (0.16, 0.63, 0.45, 0.91) and add entries for both histograms to it. Draw the legend.
  11. * Save the third canvas as a PDF file and open the PDF.
  12. Save the third canvas as a ROOT file (gaussian-polynomial.root).

Classes and methods

You will need the following classes and methods for the exercise:

Solution
Content of ex3.C:
#include "TH1.h"
#include "TCanvas.h"
#include "TLegend.h"

#include <iostream>

void ex3() {
    // create two histograms with identical binning
    TH1F* hist1 = new TH1F("gausshisto", "", 10, -5., 5.);
    TH1F* hist2 = new TH1F("polyhisto", "", 10, -5., 5.);
    // fill each randomly with 500 entries
    hist1->FillRandom("gaus", 500);
    hist2->FillRandom("pol2", 500);
    // create canvases and draw the histograms
    TCanvas* c1 = new TCanvas("c1", "gauss");
    hist1->Draw();
    TCanvas* c2 = new TCanvas("c2", "polynomial");
    hist2->Draw();
    // set line colors
    hist1->SetLineColor(kRed);
    hist2->SetLineColor(kBlue);

    // clone the histograms with new names
    TH1F *hist1b = (TH1F*)hist1->Clone("gaus2");
    TH1F *hist2b = (TH1F*)hist2->Clone("pol2");
    // Sumw2 is needed for correct error scaling
    hist1b->Sumw2();
    hist2b->Sumw2();
    // hint: it would be better here to check
    // first whether hist1b->Integral() is larger 0 !
    hist1b->Scale(1./hist1b->Integral());
    hist2b->Scale(1./hist2b->Integral());
    // create new canvas and draw both histogram in same plot
    TCanvas* c3 = new TCanvas("c3", "both");
    hist1b->Draw();
    hist2b->Draw("same");
    // add legend
    TLegend* legend = new TLegend(0.16, 0.63, 0.45, 0.91);
    legend->AddEntry(hist1b, "Gaussian", "l");
    legend->AddEntry(hist2b, "Polynomial", "l");
    legend->Draw();
    // save canvas as PDF file
    c3->Print("gaussian-polynomial.pdf");
    // save canvas as ROOT file
    c3->Print("gaussian-polynomial.root");
}
        
Output:

> root -l ex3.C
root [0]
Processing ex3.C...
Info in <TCanvas::Print>: pdf file gaussian-polynomial.pdf has been created
Info in <TCanvas::SaveAs>: ROOT file gaussian-polynomial.root has been created
root [1]
        

The canvases should look like this:

Hide solution

Exercise 4 - Files and the GUI

A simple example on how to use the TBrowser object and how to handle files. Do the following interactively, i.e. without a ROOT script:

  1. Create a browser object and open the file gaussian-polynomial.root you created in the previous exercise. You may also download the file from here.
  2. Open the canvas and draw it.
  3. In the canvas window select "View->Editor". With the mouse you can select the histogram by clicking on it. Now you can set the histogram properties (colors, etc) with the GUI. Just play around a bit...
  4. Now open the file hist.root.
  5. Get the histogram with name "pol2" from the file.
  6. Create a new file.
  7. Write the histogram to the new file.

Classes and methods

You will need the following classes and methods for the exercise:

Solution

> root -l gaussian-polynomial.root
root [0]                                                                            
Attaching file gaussian-polynomial.root as _file0...                                
root [1] new TBrowser()
(class TBrowser*)0x1117c00
root [2] TFile* histfile = new TFile("hist.root", "read")
root [3] histfile->ls()
TFile**         hist.root
 TFile*         hist.root
  KEY: TH1F     pol2;1   
  KEY: TH1F     gaus2;1  
root [6] TH1F* hist = (TH1F*) histfile->Get("pol2")
root [7] hist->Draw()
root [8] TFile* myfile = new TFile("myhist.root", "RECREATE")
root [9] hist->Write();
root [10] myfile->Close();
          

The editor looks like this:

Hide solution

Exercise 5 - Trees

A first example on how to use trees. Again do this exercise interactively at the ROOT prompt.

  1. Open the file ntu_8843.root (available for download at http://inpp.ohiou.edu/~rochej/group_page/tips/ntu_8843.root).
  2. Open the tree "ntu1". It is listed as "ntu1;1" in the ROOT browser, showing its version number 1.
  3. Draw the distribution of ene.
  4. Draw the distribution ene vs. kpx.
  5. Draw the distribution ene vs. kpx for those jets which fulfill y > 0.
  6. Draw the distribution sqrt(kpx*kpx+kpy*kpy).
  7. * Draw the distribution ene vs. kpz with histogram style "colz" (colored bins with z-axis shown) instead of the "scatter plot" used by default.

Classes and methods

You will need the following classes and methods for the exercise:

Solution
> root -l ntu_8843.root
Setting default style
root [0]
Attaching file ntu_8843.root as _file0...
root [1] ntu1->Draw("ene")
 <TCanvas::MakeDefCanvas>: created default TCanvas with name c1
root [2] ntu1->Draw("ene:kpx")
root [3] ntu1->Draw("ene:kpx", "y>0")
(Long64_t)30221
root [4] ntu1->Draw("sqrt(kpx*kpx+kpy*kpy)")
root [5] gStyle->SetPalette(1)
          
root [6] ntu1->Draw("ene:kpz", "", "colz") Hide solution

Exercise 6 - Functions

This exercise shows how to use a one dimensional function.

  1. Create a one dimensional function f(x)=sin(x)/x+a in the region 0 - 10.
  2. Set the parameter a=5.
  3. Draw the function.
  4. Calculate the function at x = 5.
  5. Calculate the integral of the function between 0 and 3.
  6. * Calculate the derivative of the function at x = 7.
  7. * Set the number of points used to draw the function to 1000. Hint: the number is denoted by Npx.

Classes and methods

You will need the following classes and methods for the exercise:

Solution

> root -l
Setting default style
root [0] TF1 f1("f1", "sin(x)/x+[0]", 0., 10.)
root [1] f1.SetParameter(0, 5.)
root [2] f1.Draw()
<TCanvas::MakeDefCanvas>: created default TCanvas with name c1
root [3] f1.Eval(5.)
(const Double_t)4.80821514506737202e+00
root [4] f1.Integral(0., 3.)
(Double_t)1.68486525279994694e+01
root [5] f1.Derivative(7.)
(const Double_t)9.42924322788899899e-02
root [6] f1.SetNpx(1000)
root [7] f1.Draw()
        

The function should look like this:

Hide solution

Exercise 7 - Graphs and fitting functions

This exercise shows how to use graphs and errors on graphs.

  1. Create a graph with symmetric errors and 5 points.
  2. Set the following points: (1.0, 2.1), (2.0, 2.9), (3.0, 4.05), (4.0, 5.2), (5.0, 5.95)
  3. Set the errors on x to 0.0 and the errors on y to 0.1.
  4. Draw the graph including the axes and error bars.
  5. Create a one dimensional function f(x)=mx + b and fit it to the graph.
  6. Obtain the two parameters a and b from the function and their estimated uncertainties.
  7. * Take again the file gaussian-polynomial.root you created before and try to fit a Gaussian distribution to the histogram using the FitPanel (right-click on the histogram to open its context menu and select "FitPanel").

Classes and methods

You will need the following classes and methods for the exercise:

Solution
Content of ex7.C:
#include "TCanvas.h"
#include "TGraphErrors.h"
#include "TF1.h"

#include <iostream>

void ex7() {
    TGraphErrors* graph = new TGraphErrors(5);
    graph->SetPoint(0, 1., 2.1);
    graph->SetPoint(1, 2., 2.9);
    graph->SetPoint(2, 3., 4.05);
    graph->SetPoint(3, 4., 5.2);
    graph->SetPoint(4, 5., 5.95);
    graph->SetPointError(0, 0., 0.1);
    graph->SetPointError(1, 0., 0.1);
    graph->SetPointError(2, 0., 0.1);
    graph->SetPointError(3, 0., 0.1);
    graph->SetPointError(4, 0., 0.1);
    TCanvas* c1 = new TCanvas("c1", "fitting graphs");
    graph->Draw("APE");
    TF1* f = new TF1("f", "[0]*x+[1]", 0., 6.);
    graph->Fit("f");
    double m = f->GetParameter(0);
    double merr = f->GetParError(0);
    double b = f->GetParameter(1);
    double berr = f->GetParError(1);
    std::cout << "m = " << m << " +- " << merr << std::endl;
    std::cout << "b = " << b << " +- " << berr << std::endl;
}

        
Output:
root -l ex7.C
Setting default style
root [0]
Processing ex7.C...
 FCN=5.7 FROM MIGRAD    STATUS=CONVERGED      33 CALLS          34 TOTAL
                     EDM=2.71359e-21    STRATEGY= 1      ERROR MATRIX ACCURATE
  EXT PARAMETER                                   STEP         FIRST
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE
   1  p0           1.00000e+00   3.16228e-02   1.70422e-05  -2.08465e-09
   2  p1           1.04000e+00   1.04881e-01   5.65226e-05  -1.21781e-09
m = 1 +- 0.0316228
b = 1.04 +- 0.104881
root [1]
      

The graph and the fit function should look like this:

Hide solution

Homework


Further material and documentation

References

Documentation on ROOT can be found here:

Other tutorials can be found here:

Other useful links and material:



Sebastian Fleischmann