Welcome to the first hands-on session. We will focus on introductory exercises for getting started working with the ROOT environment and writing our first ROOT macro. Two levels of help will be provided: a hint and a full solution. Try not to jump to the solution even if you experience some frustration. The help is organised as follow:

Here the hint is shown.

Here the solution is shown.

Some points linked to the exercises are optional and marked with a icon: they are useful to scrutinise in more detail some aspects. Try to solve them if you have the time.

Before starting the exercise 1, follow what is written in the lecture

First of all open a Visual Studio Command window on your computer and type

rootIf this does not work, then it means ROOT is not properly installed in your system. Stop here and ask for help to fix the installation. If it works then start playing with the prompt. Use as a calculator and type:

root [0] 2+2or whatever you like (see for example the lecture slide) or page 5 of the booklet ("A ROOT Guide for Beginners"). Note that after having issue a statement from the ROOT prompt, you can omit the

`;`

required by C++. This will make ROOT
printing the returned value, if there is one. For example:
root [0] TMath::Pi();will not print anything, while

root [0] TMath::Pi() (Double_t)3.14159265358979312e+00

Afterwards start writing your first ROOT macro. A ROOT macro is a file containing some C++ code which can be run from
the ROOT prompt. You need to define a function and in the function scope you write the code.
For example, you create a file, which you will call `mymacro.C`

.
Inside the file you define a function `mymacro(int value)`

and you write the code of slide 8 of the lecture (or something else, if you prefer).
The you can run the macro from the ROOT prompt by typing:

root [0] .x mymacro.C(42)Note that if the function name is different than the macro (file) name, you need two steps to run. First you load the macro:

root [0] .L mymacro.CThen you run the function in the macro. Let's assume the function name is

`test(int value)`

:
root [1] test(42)

After having followed this introduction, you can try to solve the first exercise.

The aim of this exercise is to write a ROOT macro which can compute the number PI. You can deduce the number PI from the area of a circle with unitary radius. You can compute the area of the first quadrant of the circle by generating random points (x,y) , which are uniform distributed in the interval [0,1]. The function to generate uniform random number in the interval [0,1] is

root [0] gRandom->Rndm()If you throw for example one million random points, which value of PI do you obtain ? How is it different from the real value of PI, which you can get in ROOT by using

`TMath::Pi()`

?

To solve the exercise you would need:

- make a loop on the
`n`

number of points you want to generate - inside the loop you throw two random numbers, uniformly distributed between [0,1], that we can call
`x`

and`y`

- compute the radius of the point (x,y) :
`r = x^2 + y^2`

- if
`r <`

1= accept the point and increase a counter - if
`r > 1`

do nothing and continue - the ratio of the number of accepted points to n, will then be equal to the area of the first quadrant, which is PI/4

This we can do in C++ by making a `for`

loop and we call the function to generate the random x and y numbers:

for (int i = 0; i < n; ++i) { double x = gRandom->Rndm(); double y = gRandom->Rndm(); // count the number of accepted points (x^2 + y^2 <= 1) }

After having written and run the macro, try to compile it using ACLIC. For compiling the macro, you need to add to include the required header files, thus you need to add at the beginning of the code:

#include "TRandom.h" // for using gRandom #include "TMath.h" // for using TMathThen, you can compile with ACLIC, by adding a

`+`

at the end
root[0] .x computePI.C+Note the difference in time by using ACLIC, by generating for example more points (e.g. 10E8).

#include"TRandom.h"#include"TStopwatch.h"#include"TMath.h"#include<iostream>voidcomputePI(intn = 1000000) {intnin = 0; TStopwatch w;// for measuring the timefor(inti = 0; i < n; ++i) {doublex = gRandom->Rndm();doubley = gRandom->Rndm();if( (x*x + y*y) < 1.) nin++; }doublepi4 = nin/double(n);std::cout <<"Computed PI is "<< pi4*4 << std::endl;std::cout <<"Real PI is "<< TMath::Pi() <<" difference = "<< TMath::Pi()-pi4*4 << std::endl; w.Print(); }

Can you measure the time of generating 10E8 points using CINT or ACLIC. How much faster is ACLIC ?
You can use the ROOT class `TStopwatch`

for measuring the elapsed time. Add at the begining of the macro (before the loop)

TStopwatch w;and after the end of the macro

w.Print();

Following slide 13 of the lecture or page 6 of the Introductory Guide, create a TF1 class using the `sin(x)/x`

function and draw it.

Create then a function with parameters, `p0 * sin ( p1 * x) /x`

and also draw it for different parameter values.
You can try to change the parameter values using `TF1::SetParameters`

or by using the ROOT GUI.
Try also to change the style of the line and its color. You can either use the ROOT GUI and/or use the methods of the class TAttLine
(see TAttLine reference documentation).
Since TF1 derives from TAttLine, it inherits all its functions. Try for example to set the colour of the parametric function to blue.

After having drawn the function, compute for the parameter values (p0=1, p1=2):

- function value for x = 1.
- function derivative for x = 1
- integral of the function between 0 and 3.

To solve the exercise you need to :

- create a TF1 object using a formula expression. In the case of a parametric functions, the two parameters are defined as [0] and [1]
- call TF1::Draw()

You can also find the available function of the class TF1, by using the Tab key on the ROOT prompt, for example

root [0] TF1 * f1 = .... root [1] f1-><TAB>And you can get the full signature of a method by doing for example:

root [1] f1->Derivative(<TAB>

#include"TF1.h"voidplotFunction() { TF1 * f1 =newTF1("f1","sin(x)/x",0,10); f1->Draw(); TF1 * fp =newTF1("fp","[0]*sin([1]*x)/x",0,10); fp->SetParameters(1,2); fp->Draw("same"); fp->SetLineColor(kBlue);// to change axis y margins// (or invert the order of plotting the functions)f1->SetMaximum(2); f1->SetMinimum(-2);std::cout <<"Value of f(x) at x = 1 is "<< fp->Eval(1.) << std::endl;std::cout <<"Derivative of f(x) at x = 1 is "<< fp->Derivative(1.) << std::endl;std::cout <<"Integral of f(x) in [0,3] is "<< fp->Integral(0,4) << std::endl; }

You can try to use a different function, for example the Gamma distribution, defined in `ROOT::Math::gamma_pdf`

.
Try to make a plot as the one in Wikipedia, see here, where the function is plot for different parameter values. See the here the reference documentation of the gamma distribution in ROOT.

#include"TF1.h"#include"Math/DistFunc.h"voidplotGamma() {// Note that parameter [0] is called alpha in definition of gamma_pdf or kappa in Wikipedia// Note that parameter [1] is theta// use range [0,20] as in Wikipedia plotTF1 * f1 =newTF1("f","ROOT::Math::gamma_pdf(x,[0],[1])",0,20); f1->SetLineColor(kRed); f1->SetParameter(0,1); f1->SetParameter(1,2);// use DrawClone because we will plot many different copies of same object but with different// parameter valuesf1->DrawClone();// now change parameters and draw at different parameter valuesf1->SetLineColor(kGreen); f1->SetParameter(0,2); f1->DrawClone("SAME"); f1->SetLineColor(kBlue); f1->SetParameter(0,3); f1->DrawClone("SAME"); f1->SetLineColor(kCyan); f1->SetParameter(0,5); f1->SetParameter(1,1); f1->DrawClone("SAME"); f1->SetLineColor(kOrange); f1->SetParameter(0,9); f1->SetParameter(1,0.5); f1->DrawClone("SAME"); }

We will learn in this exercise how to plot a set of points in ROOT using the TGraph class.

Suppose you have this set of points:

- x = 1; y = 0.4
- x = 2; y = 0.3
- x = 3; y = 0.5
- x = 4; y = 0.7
- x = 5; y = 1.3

Plot these points using the TGraph class. Use as a marker point a black box. Looking at the possible options for drawing the TGraph in TGraphPainter, plot a line connecting the points.

To solve the exercise you need to :

- create an array for the X points:
`double x[] = {1,2...`

- create an array for the y points
- create the TGraph from the X and Y arrays

Alternatively you can create first an empty TGraph object and set the point one by one by calling `TGraph::SetPoint`

voidplotGraph() {doublex[] = {1.,2.,3.,4.,5.};doubley[] = {0.4,0.3,0.5.,0.7,1.3}; TGraph * g =newTGraph(5,x,y); g->Draw("AP"); g->SetMarkerStyle(21); }

Make a TGraphError by adding an error of 0.3 in X and 0.2 in Y for every point.

We will learn in this exercise how to create a one-dimensional histogram in ROOT, how to fill it with data and how to plot it.

Create a one-dimensional histogram with 50 bins between 0 10 and fill it with 10000 gaussian distributed random numbers with mean 5 and sigma 2. Plot the histogram and, looking at the documentation in the THistPainter, show in the statistic box the number of entries, the mean, the RMS, the integral of the histogram, the number of underflows, the number of overflows, the skewness and the kurtosis.

For generating gaussian random numbers use

`gRandom->Gaus(mean, sigma)`

#include"TH1.h"#include"TRandom.h"#include"TStyle.h"voidplotHistogram() { TH1D * h1 =newTH1D("h1","h1",50,0,10);for(inti = 0; i < 10000; ++i) {doublex = gRandom->Gaus(5,2); h1->Fill(x); } h1->Draw(); gStyle->SetOptStat(111111110); }

After calling the function `TH1::ResetStats()`

, you will see that the statistics (mean, RMS,..) of the histogram is slightly different. Try to understand the reason for this, by trying for example to compute the mean of the histogram yourself.

The initial statistics is computed using the original (un-binned) data, while after calling ResetStats(), the statistics is computed using the bin contents and centres (binned data).

The following macro, creating, filling and plotting histogram contains an error, which one ?

#include"TH1.h"voidtestPlotHistogram() { TH1D h1("h1","h1",50,-5,5); h1.FillRandom("gaus",10000); h1.Draw(); }

The histogram objected is deleted at the end of the macro, therefore it is not shown in the plot after exiting the macro. To fix it, either call

`TH1::DrawClone`

or create the histogram using operator new as in the previous example.

This topic: Main > WebPreferences > RootIRMMTutorial2013 > RootIRMMTutorial2013StartingROOTExercises

Topic revision: r8 - 2013-02-28 - LorenzoMoneta

Copyright &© 2008-2020 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.

or Ideas, requests, problems regarding TWiki? use Discourse or Send feedback

or Ideas, requests, problems regarding TWiki? use Discourse or Send feedback