Workbook for BaBar Offline Users - Analysis in ROOT II
In this section of the Workbook the information presented in the first
ROOT section Analysis in ROOT I is
extended to include fitting histograms with functions, applying cuts,
macros, and an introduction to the ROOT Object Browser. Most of the
information in this section was taken from the documents listed in ROOT I.
Contents
For this exercise we will need a root file with more than one 1-D
histogram. The file example.root will
suffice (you can copy it from the link by right-clicking on
here and selecting "save link as"
- and remember to be careful which directory you save the file into).
At this time you should also download the example file myrootfile.root which will be used in later
sections of this tutorial.
Now start up a new ROOT session with bbrroot and load
the root file with
TFile *f = new TFile("example.root"); //load the file
This ROOT file has a more complicated
directory structure than the simple file used in the first Workbook
section on ROOT. To have a look
around the directories and files in example.root use
f->ls(); (list the directories, histograms and ntuples)
In this example file there are lots of histograms, but they are all
contained in directories. The output from the previous command should
look like:
root [1] f->ls();
TFile** example.root
TFile* example.root
KEY: TDirectory event_dir;1 Event Property Histograms
KEY: TDirectory pipi_dir;1 pi pi Histograms
KEY: TDirectory bkg_dir;1 Background events
KEY: TDirectory track_dir;1 Track Histograms
KEY: TDirectory gamma_dir;1 gamma Histograms
KEY: TDirectory pi0_dir;1 pi0 Histograms
To change into a directory, say, event_dir:
gDirectory->cd("event_dir"); //or, possibly best
f->cd("event_dir"); //where f is the name of the currently
//open file
(Note that anything that follows "//" is a comment and is
ignored by the ROOT interpreter.)
You can now list the contents of that directory with
gDirectory->ls(); //or
f->ls()
The output this time lists the available directories, but also the
histograms in the open directory (event_dir):
root [5] f->ls()
TFile** example.root
TFile* example.root
TDirectory* event_dir Event Property Histograms
KEY: TH1F eTag_p_CM;1 eTag_p_CM
KEY: TDirectory event_dir;1 Event Property Histograms
KEY: TDirectory pipi_dir;1 pi pi Histograms
KEY: TDirectory bkg_dir;1 Background events
KEY: TDirectory track_dir;1 Track Histograms
KEY: TDirectory gamma_dir;1 gamma Histograms
KEY: TDirectory pi0_dir;1 pi0 Histograms
To change into the base directory of the ROOT file:
f->cd();
If you don't use a semi-colon at the end of the line, you'll get a
message like:
(Bool_t)1
This is a return value indicating if the operation (changing
directory) has been successfully executed. If the value is 0, it will
be accompanied by an error message - usually a message saying you
haven't entered a valid directory name).
Now change into the "gamma_dir" directory:
gamma_dir->cd();
list its contents:
root [12] f->ls()
TDirectory* gamma_dir gamma Histograms
OBJ: TH2F gammaEvsMassM gammaEvsMassM : 0
KEY: TH1F num_good_neutM;1 num_good_neutM
KEY: TH1F num_good_neutD;1 num_good_neutD
KEY: TH1F lateralMomentM38;1 Cluster Lateral Moment
KEY: TH1F lateralMomentD38;1 Cluster Lateral Moment
KEY: TH1F lateralMomentSig38;1 Cluster Lateral Moment
KEY: TH1F gammaEM38;1 gammaEM
KEY: TH1F gammaED38;1 gammaED
KEY: TH1F gammaESig38;1 gammaESig
KEY: TH1F nCrysM38;1 nCrysM
KEY: TH1F nCrysD38;1 nCrysD
KEY: TH1F nCrysSig38;1 nCrysSig
KEY: TH1F gammaCosThM38;1 gammaCosThM
KEY: TH1F gammaCosThD38;1 gammaCosThD
KEY: TH1F gammaCosThSig38;1 gammaCosThSig
KEY: TH1F lateralMomentM;1 Cluster Lateral Moment
KEY: TH1F lateralMomentD;1 Cluster Lateral Moment
KEY: TH1F lateralMomentSig;1 Cluster Lateral Moment
KEY: TH1F gammaEM;1 gammaEM
KEY: TH1F gammaED;1 gammaED
KEY: TH1F gammaESig;1 gammaESig
KEY: TH1F gammaEMFine;1 gammaEMFine
KEY: TH1F gammaEDFine;1 gammaEDFine
KEY: TH1F gammaESigFine;1 gammaESigFine
KEY: TH2F gammaEvsMassD;1 gammaEvsMassD
KEY: TH2F gammaEvsMassM;1 gammaEvsMassM
KEY: TH2F gammaEvsMassSig;1 gammaEvsMassSig
KEY: TH1F nCrysM;1 nCrysM
KEY: TH1F nCrysD;1 nCrysD
KEY: TH1F nCrysSig;1 nCrysSig
KEY: TH1F gammaThetaM;1 gammaThetaM
KEY: TH1F gammaThetaD;1 gammaThetaD
KEY: TH1F gammaThetaSig;1 gammaThetaSig
KEY: TH1F gammaCosThM;1 gammaCosThM
KEY: TH1F gammaCosThD;1 gammaCosThD
KEY: TH1F gammaCosThSig;1 gammaCosThSig
and display a couple of histograms:
gammaEvsMassM.Draw("surf4"); //display 2-d histogram (surf4 is a
//display command specifying a surface style)
nCrysM.Draw(); //display 1-d histogram called nCrysD
Note that you can always check which directory you are in by typing
gDirectory->pwd();
Where, when you have file "f" open, and are in its root directory, you
should see:
root [42] gDirectory->pwd()
example.root:/
Changing the way your histogram looks
The following commands alter the way your histogram is
displayed. Each time you change the display attributes, for example,
change between logarithmic and linear axes, you will need to refresh
the display with the command:
gPad->Modified();
To zoom and unzoom:
nCrysM->SetAxisRange(10, 30.5, "x");
gPad->Modified(); // Needs a refresh from the command line
To change to logarithmic axes (note that this is a display command,
not a histogram method, so won't affect any fits):
gPad->SetLogy(1);
gPad->Modified();
To set up gridlines:
gPad->SetGridx(1);
gPad->SetGridy(1);
gPad->Modified();
These options are controlled by boolean variables, and can be switched
off using a "0" option, e.g.:
gPad->SetLogy(0);
gPad->Modified();
To change the drawing style (e.g.markers, color)
nCrysM->Draw("p"); //draw with points - not joined up
nCrysM->SetMarkerStyle(20); //round dots
nCrysM->SetMarkerSize(1.); //fat, round dots
nCrysM->SetMarkerColor(kBlue); //fat, blue, round dots
gPad->Modified();
To enlarge axis labels and add axis titles:
nCrysM->SetTitleSize(0.06, "x"); // Title size, offset and text
nCrysM->SetTitleOffset(1., "x");
nCrysM->SetXTitle("Axis title text");
gPad->SetBottomMargin(0.15);
gPad->SetLeftMargin(0.15);
nCrysM->Draw();
You can also set axis titles with
nCrysM->GetXaxis()->SetTitle("X-axis");
nCrysM->GetXaxis()->CenterTitle(1); // center the name of the x-axis
This command structure should start to become familiar pretty quickly:
you access the object you are interested in (in this case, the x-axis
object), then you set one of its attributes (SetTitle, CenterTitle,...)
(Note: (e)ps output can be missing if you cut off too much, so be sure
that you have sufficient margins.)
You can also change the y-axis range of your histogram either before or
after drawing the histogra using the functions
TH1F::SetMinimum(minValue) and
TH1F::SetMaximum(maxValue), e.g.
nCrysM->SetMaximum(1000);
You can also do it with the GUI (see below), moving the cursor over
the axis and left-clicking. A pair of lines will appear, one staying
where you started, the other following your mouse movements.
You can modify the binning of your histo with the command:
nCrysM->GetXaxis()->Set(nbins,xmin,xmax);
where you need to input actual numbers here.
In addition to ROOT's built-in functions, you can define functions of
your own. There are one-, two-, and three-dimensional
functions (TF1, TF2 and TF3).
To define a function with predefined components:
TF1 *f1a = new TF1("f1a","sin(x)", -5., 5.);
// built-in, this defines the function over the range -5<x<+5
TF1 *f1b = new TF1("f1b","x*sin(x)", -2., 2.); // combined
TF1 *f1c = new TF1("f1c", "[0]*x + [1] + gaus(2)",0.,15.);
gaus() is a 3-parameter Gaussian function used for
fitting. The combination here is a Gaussian plus a linear
function. gaus(2) means that the parameter numbering on
the Gaussian starts at 2. Here f1c is defined with 5
parameters, which by default are set to zero, but which you can set
before drawing the function. You can also use functions defined with
parameters for fitting, and use the fitting to determine the best
values for the parameters. For the 5-parameter function above, this is
done with, e.g.
f1c->SetParameters(0.1, 10., 50., 0.5, 0.01);
Now define a 2-dimensional function:
TF2 *f2 = new TF2("f2", "sin(x)*sin(y)", -10., 10., -10., 10.);
To draw a 1D function, say f1c, enter:
f1c->Draw();
The above command calls the default drawing option for
functions. Other drawing options for functions include:
f1c->Draw("p"); // use markers
f1c->Draw("h"); // histogram
Note that you may have to set the markers to something sensible before
getting output. See above for instructions on how to do this.
2D functions are handled in a very similar manner
f2.Draw(); //2-d projection - not very impressive
f2.Draw("surf4"); // surface plot - much nicer
surf1-5 are different surface plot options.
To change the colours, you can do, e.g.
gStyle->SetPalette(1) //and plot again
How to generate histograms from functions
To generate a 1D histogram from a 1D function and plot it:
TF1 *f1=new TF1("f1","sin(x)",0,10);
f1.Draw(); // need to draw the function first!
(f1->GetHistogram())->Draw();
To generate a 2D histogram from a 2D function and plot it:
f2->Draw();
(f2->GetHistogram())->Draw();
For the 1D function the smooth function line will be jagged in a
histo, and for the 2D function, the only clear difference is possibly
the appearance of a statistics box for the histogrammed function
(depending on your stats settings).
Errors, already defined functions/histograms/...
Sometimes you'll want to use the same name for a function definition -
usually when you're finished with the first. This is not a problem -
you simply delete the first function, e.g.
f2.Delete();
This function now no longer exists and cannot be called, plotted,
etc. You can then define f2 afresh, or using something
else, e.g.
TF2 *f2 = new TF2("fun2","sin(x)*sin(y)",0.,3.14,0.,3.14);
How to get greek characters and primes into an axis title
For example, with the ROOT file we opened at the start of this session:
f->cd("pi0_dir");
gg_massD_>Draw();
gg_massD->SetXTitle("f[#circ]");
gg_massD_>Draw();
Apart from the newest versions of ROOT, it is not possible to include
primes in axis or graph titles. Later versions have this facility with
the command #prime. Otherwise, the best workaround found
so far is to put a comma as a superscript.
The official ROOT website provides
many useful tutorials and HOWTOs for a wide range of ROOT tasks. One
of these is a macro for reading in data from an ascii file and
creating from it a ROOT file with a histogram and an ntuple. That
example is reproduced here.
The macro basic.C can be used to
read in data from an ascii file containing numbers laid out in
columns. The file basic.C is a simple macro which expects the input to
come from a simple ascii file, called basic.dat containing, in this example,
three columns of numbers.
To run this macro, from within ROOT execute the following command:
.x basic.C
The file reads in the numbers from basic.dat, histograms
the values from the first column, and writes all the entries into an
ntuple. This output, the histogram and ntuple, are saved to a file
called basic.root. This output
file can then be studied, ntuple entries printed, and cuts performed
on the three histogrammed quantities just like any other ROOT file.
You can use pre-defined functions, or user-defined functions, or
compositions of pre-defined functions to fit histograms. ROOT uses
the minimisation package Minuit for fitting.
How to fit histograms with predefined functions (these commands
assume you are running ROOT from the same directory as you have saved
the example file myrootfile.root):
TFile f("myrootfile.root");
h1->Draw();
h1->Fit("gaus");
h1->Fit("landau","R", "", 1., 5.);
// where "R" indicates to fit only in
// a range, given in the last two arguments
h1->Fit("landau","R", "P", 1., 5.);
// where "P" is an option indicating
// to plot markers instead of histograms
How to fit with a user-defined function
In a file myfunc.C define
double myfunc(double *x, double *par) {
double arg = 0;
if (par[2]) arg = (x[0] - par[1])/par[2];
return par[0]*TMath::Exp(-0.5*arg*arg);
}
Load this macro into ROOT and perform a fit with this function
.L myfunc.C
TF1 *f1 = new TF1("f1",myfunc, -1., 1., 3); // where 3 is the number of
// parameters for the function
f1->SetParameters(10.,h1->GetMean(), h1->GetRMS());
h1->Fit("f1");
A further example (from the ROOT site) of generating histograms with
random numbers from a function and then fitting those histograms is
provided here. There are some
more examples of fits and functions reproduced here.
How to use the Fit Panel
Move the pointer over the histogram line (the cursor should change
from cross to arrow) and click on the right mouse button. A context
menu on TH1 should appear, from which you can choose
FitPanel.
The FitPanel "slider" can be used to graphically restrict the fit
range. The slider is the grey bar near the bottom of the fit panel,
directly above the words "Fit", "Default", and "Close". If you move
the mouse pointer over this slider, at the ends of its ranges the
pointer changes from a cross to "|<-" at the left-hand edge and "->|"
at the right-hand edge. When the pointer is displayed in this way, you
can change the fit ranges by holding down the left mouse button and
dragging the left- or right-hand edge of the slider to a new
position. The changing fit range is shown graphically on your canvas
as a vertical line that moves along as you move the slider.
Related Documents
To provide concrete examples of how to use cuts in ROOT, the file taufile.root is required. It can be downloaded
from this link.
The ROOT file in this example contains two separate ntuples, or
trees. Trees are discussed later in this workbook
chapter, but for now, is it sufficienct to follow the instructions
below to access one of the trees in this file.
First open the file and access the tree called h2013:
TFile* myfile = new TFile("taufile.root");
TTree* mytree = (TTree*)gDirectory->Get("h2013");
A cut is defined in ROOT by way of a TCut object. For example,
TCut *cut1= new TCut("nPi0s>2");
where here the fully correct C++ syntax is provided to allow this
command to be used in a macro. "nPi0s" is a property of the
objects about which information is to be plotted. This could be used,
for example, to plot thrust vs the minimum angle between particles in
each hemisphere of an event for events, but only selecting those
events in which there were more than two pi0s detected. The object
would then be drawn with, e.g.
mytree->Draw("thrustMag:MinAngBtwHemis",*cut1);
c1->Update(); //update canvas called c1
In this case it is assumed that there is one entry in the ntuple
(compare: one row in a spreadsheet, where the columns represent
different information about that entry). Note also that in the
Draw(...) function call, the actual TCut object (*cut1)
is passed, rather than just the pointer (cut1).
Also, to plot only a section of the data:
mytree->Draw("ch_px_cms","ch_px_cms>0");
The above command displays "ch_px_cms", where
"ch_px_cms" is greater than zero. (Compare with the result
when plotting without the cut). In this case, the cut wasn't defined
as a TCut object, instead it was simply included in the
Draw(...) function call, in quotes.
You can use more than one cut, using logical operators to choose the
inter-relation of the cuts, for example
mytree->Draw("ch_px_cms","(ch_py_cms<.5)&&(ch_pz_cms>1)");
While you can clearly use cuts without having to define a TCut object,
it does become cumbersome, particularly if several cuts are to be
used, or if the cut is to be used repeatedly and the value of it might
be changed. In which case it is much better to define several TCut
objects at the start of your code and only have to edit them in one
well-defined place.
Related Documents
The ROOT information in the Workbook has so far discussed using
command line entries to display and manipulate histograms and
functions in ROOT. There is also a ROOT Object Browser which provides
a graphical view of your files and allows you to navigate through
large ROOT ntuples and directories quickly.
A ROOT Object Browser is instantiated with a command like
TBrowser* tb = new TBrowser();
or, simply
TBrowser tb
A new Object Browser window should appear which looks like this
Using a specific example, download the file SimpleTree.root (which we'll actually
generate later in this tutorial) and
start ROOT in the directory where you have put SimpleTree.root.
Now start a TBrowser with:
root[0] TBrowser tb
Open the file by selecting File->Open in the menu bar
and choosing "SimpleTree.root".
You can now look at the contents of this file by double-clicking on
ROOT files (in the right-hand pane of the TBrowser) and
then double-clicking on the filename. This file contains a single tree
(see the Trees section later in this WorkBook
chapter) called SimpleTree. To look at the contents of the tree,
double-click on that. The display will now list the contents of the
tree - namely E, Px, Py, Pz, n.
You can display the data in any of these leaves of the tree by
double-clicking on the name of the leaf. Try this by double-clicking
on the Px label. You should see a histogram which
looks like this file.
Now click on Options in the menu bar of the canvas and
select Event Status. Click on the Canvas again and point
to the histogram line with the mouse pointer. You should see a display
of the bin contents (and other things) in the lowest row of the
canvas - this is particularly useful when looking at a log plot to
determine the x and y coordinates of a particular point on a line.
Now get the Editor by clicking on Edit->Editor in
the menu bar of the canvas containing the histogram:
Get a DrawPanel by moving the mouse pointer to the histogram line in any
bin (the pointer should change from a cross to a pointer), clicking
the right mouse button and choosing DrawPanel:
Have a play with some of the options (lego1 is nice) by clicking on
the option and then clicking on "Draw".
Get a FitPanel by moving the mouse pointer to the histogram line in any
bin (the pointer should change from a cross to a pointer), clicking
the right mouse button and choosing FitPanel:
Again, have a go by clicking some options and then clicking
"Fit" (we'll do a bit more with this later in this Workbook
Chapter.
Back in the ROOT Browser: Show the variables contained in the tree by
double clicking on the tree icon (SimpleTree):
Display the variable by double-clicking on its name:
Try clicking the right mouse button on the SimpleTree icon, you'll
get a context menu. To start the GUI for working with Trees, choose
StartViewer from this context menu. (If a pop-up window
appears prompting you for width (ww) and height (wh) settings, select
OK in that window.
We saw earlier how to draw a histogram. The graphics window which your
histogram was displayed in is called a "canvas". (This
canvas is similar to the HIGZ window in PAW.) By default, the first
canvas generated in a ROOT session has the name c1.
In this section we will see some of the power of the ROOT canvas
First load in a root file as above, e.g. myrootfile.root, and display the
histogram:
h1.Draw();
You can enlarge the canvas like any window by click-and-dragging
e.g. a corner of the window containing the canvas.
By right-clicking on different areas of the canvas, you are
presented with a drop-down menu with different options for displaying
your picture. For example (assuming the graph is displayed with a
legend and a stats box):
| Click on | Options |
| x-axis | attributes of x-axis |
| y-axis | attributes of y-axis |
| graph title | title display |
| area inside histogram | histogram attributes such as fill style |
| area outside histogram | canvas display options such as
log scales |
| legend box | legend display |
| stats box | stats box display |
You can also left-click-and-hold and drag the legend and stats boxes
around the canvas, and resize them.
How to divide a Canvas into smaller canvases (aka
zone 2 2 in PAW)
Assuming you have a canvas c1, the CINT way is
c1->Clear();
c1->Divide(2,2); // divisions in x and y
To select the subdivision of the canvas to change the focus to, the
command-line entry required is, for example,
c1->cd(3); //where c1 is the canvas name, and 3 is one of
//the subdivisions of the 2x2 canvas
(You can test this by plotting your histogram again,
h1->Draw(); and seeing that it appears in the 3rd place.)
The GUI-way is to right-button click on the canvas, choose
"Properties", then select "Divide" and fill in the
nx and ny attributes. You can then move the mouse
pointer over the pad you want to access and click the middle button.
A "Pad" is a subdivision of a canvas. (Similar to a zone in
PAW.) By default each canvas is created with one pad which fills the
entire canvas. Your histograms and other text and graphics objects are
drawn on a pad. You can draw several histograms on one canvas by
creating more pads. Opening a new pad also allows the drawing of
insets, as in the example that follows (where here we assume you have
a canvas c1 (the default canvas), and also that you have the example
file example.root in the directory that you
are running PAW from):
c1->Clear(); //clear the contents of the current canvas
TFile f("example.root");
f.ls(); //just to check what's there
f.cd("pi0_dir"); //to change into a subdirectory of the file
TPad *npad = new TPad("npad", "", 0.6, 0.2, 0.9, 0.5);
npad->Draw();
npad->cd();
gg_massM->Draw();
c1->Clear();
c1->Divide(2,2);
c1->cd(1);
pi0CosThM->Draw();
c1->cd(2);
mass_v_energyM.Draw("surf");
c1->cd(3);
gg_massD.Draw();
c1->cd(4);
mass_v_energyD.Draw();
The last set of commands creates a 2x2 pad and steps through each
element of the pad drawing a different histogram. The output should
look like this:
The following command clears the canvas and returns it to having just
one pad on the canvas:
c1->Clear()
CINT is quite sophisticated, but not perfect. You can crash it
badly. You will restart ROOT much more often than PAW. You need
some experience to know when you can continue with CINT after having
had an error. Some people (sometimes) would not bet on results
obtained with CINT. Keep that in mind when your macro gets
complicated. Nothing beats the security and reassurance of a
trustworthy C++ compiler.
That said, CINT is great for all the interactive display stuff
usually needed for getting plots into a form suited for presentation.
CINT completes partially typed commands, provides you with a list
of arguments a given function expects and completes filenames you have
to enter. Try
root[0] TFi<TAB>
root[1] TFile f(<TAB>
root[2] TFile f("fr<TAB>
where <TAB> indicates you have to hit
the TAB key.
Further, if you type in a variable followed by an arrow, for
example:
gStyle-> and then enter a tab
This will print out a listing of all the methods and members of
gStyle, and lists all the things that you can dowith gStyle. You can
continue it by typing in
gStyle->SetOptS<tab>
etc.
If you enter the name of a function, say
gStyle->SetOptStat( and then a tab
a list of the parameters that are expected for this function will
appear. If the method has multiple definitions, called with different
parameter lists, then all of them are displayed.
CINT allows you to scroll through your history of commands with the
arrow keys (just like PAW). It keeps this history between sessions and
you can scroll through previous sessions (unlike PAW). This is a very
useful feature.
CINT also provides you with a search facility in its history,
accessible with <Ctrl-r>. Try
root[3] <CTRL-r> TF
rootlogon.C
The equivalent of pawlogon.kumac. It is good to keep it as short as
possible.
.root_hist
This text file stores a history of the commands you entered during a ROOT
session. These commands can be copied out of this text file and into a
macro (see below) to be used later.
The aim of this section is to show how to create macros in
ROOT. Macros are user-defined functions that are written in separate
files and then loaded and executed in a ROOT session. Several
functions can be defined in a given macro, and once the macro has been
loaded, the functions defined in these files can be called. A large
analysis job will usually call several macros to carry out individual
tasks.
In the section about fitting you created a
macro called myfunc.C to define a new function,
myfunc();. A macro is a C++ function defined with the
syntax:
return_type function_name(arg1_type arg1_name, arg2_type,
arg2_name, ...) {
commands with ";%quot; at the end of each line;
}
Macros can be loaded with the command
.L mymacro.C
And the macro is then called with the command
function_name(parm1, parm2...);
You can also load and execute statements saved in a file using
.x myfile.C
For example, load the macro myfunc.C you created earlier
with
.L myfunc.C
and define a function with it:
TF1 *f1 = new TF1("f1", myfunc, -1.,1., 3);
// here 3 is the number of parameters for the function
You can now use this function for fitting, plot it, etc.
You can also write unnamed macros as a bunch of commands, enclosed in
braces, and with each line ending in a semi-colon, and put them in a
file (e.g. macro1.C)
// macro.C
{
cout << "hello world" <<
endl;
}
and execute them in a ROOT session with
.x macro1.C
You can put functions into a file e.g. macro2.C
//macro2.C
void helloWorld() {
cout << "Hello World" << endl;
}
and load and execute any function in that file in two steps:
root[2] .L macro2.C
root[3] helloWorld()
By the way, after you loaded the file, ROOT knows about your function,
so instead of the above, try to hit <TAB>:
root[3] helloWo<TAB>
Further example macros are here. These
files are copies of the ROOT distribution examples.
There are various BaBar-specific tools for booking and filling ROOT
histograms in the BaBar framework, and a conventional way to include
the required statements in BaBar code. This is described in detail in
babar_histos.html.
You can link multiple ROOT files together using TChain,
provided those files have the same internal structure. In that way,
you can treat them as one contiguous ROOT file. For example, if you
have two ROOT files, fil1.root and fil2.root, you can link them using
the command:
void
input_data( TChain* dataChain )
{
dataChain->Add("fil1.root");
dataChain->Add("fil2.root");
}
As discussed in the Workbook section, ROOT I, a ROOT Tree is similar to a PAW
Ntuple. It has branches which can hold many other objects,
for example vectors. An ntuple in ROOT (TNtuple) is just a simple
TTree, where each branch contains floating point (Float_t) data.
A single ROOT file can hold several trees, as in the example file
taufile.root first introduced in the Cuts section in this workbook chapter. Each tree is
independent, like an individual file, and it is not possible to plot
quantities in one tree subject to cuts on quantities in another tree.
Opening the example file:
root [0] TFile *myfile=new TFile("taufile.root");
We can list the objects (trees and histograms) contained in the file:
root [1] myfile.ls()
TFile** taufile.root HBOOK file: .../tau-1571.hbook converted to ROOT
TFile* taufile.root HBOOK file: .../tau-1571.hbook converted to ROOT
KEY: TTree h2013;1 1-3
KEY: TTree h2033;1 3-3
This tells you the irrelevant information that this file was actually
made by converting a PAW file to ROOT format. It also shows that there
are two trees in the file, h2013 and h2033,
and no histograms.
To access the contents of a tree, you can make a tree object which
holds the contents of one of the trees in the file:
myfile.cd() //make sure ROOT's focus is on myfile
TTree* mytree = (TTree*)gDirectory->Get("h2013");
By calling TTree functions of the mytree object, you
can now access the contents of the tree h2013 from taufile.root. For
example, to get a list of branch or leaf names, enter:
mytree->GetListOfBranches()->Print();
mytree->GetListOfLeaves()->Print();
You can also inspect the contents of a tree with the TBrowser
described here.
The macro roottest.C is a slightly-modified
version of the example from a SLAC ROOT
tutorial.
Executing the example with
.x roottest.C
creates a tree with up to 200,000 variables per event. It creates a
tree called "SimpleTree" which contains 5 branches, n, E, Px, Py,
Pz. The last 4 entries are array-valued entries, containing n
elements for each entry, which could be the energy and 3 momenta of
tracks for BaBar events containing n tracks per event. The
energy and momentum components have Gaussian distributions, as defined
in the macro.
The resulting tree is written into a file called SimpleTree.root. This root file, and the
tree in it can be inspected in the manner described in this Workbook
chapter, and in ROOT I.
It is often desirable to save a copy of the ascii ROOT output which
appears during an interactive ROOT session (in analogy with the
OUTPUT_LP facility in PAW). There are two easy ways to print this
output to a text file:
- Piping macro output to a text file
You can simply execute a macro which contains all the commands you
want to save the responses from and redirect that to a file with the
command
.x someMacro.cc > outFile.txt
- Sending selected output to a text file
So save only selected command outputs to a text file, another option
is to use commands of the form:
ofstream fout;
int count;
fout.open("outputFile.dat");
for (count=0; count<total; ++count) {
fout << sig[count].name << " "
<< sig[count].slope << " "
<< sig[count].coeff << endl;
}
Finally, you can dump the output of an ntuple directly to a text file
with the commands
ntp->Print(); > output.log
ntp1->Scan("momentum"); > output.log
to get the output (of a tree ntp1) into a file. Don't forget the ';'.
To execute shell command in a shell
.! command
for example,
.! ls
will list the contents of the current shell directory, i.e. the
directory from which you started the present ROOT session.
To display a message:
printf("Welcome\n");
The RooFit
packages provide a toolkit for modelling the expected distribution of
events in a physics analysis. Models can be used to perform likelihood
fits, produce plots, and generate "toy Monte Carlo" samples for
various studies. The RooFit tools are integrated with the
object-oriented and interactive ROOT environment.
Follow the link above for instructions for setting up and using
RooFit for BaBar analyses. During BaBar Collaboration meetings, there
are often RooFit tutorials conducted by experts.
General Related Documents:
Author:
Jenny Williams
Contributions taken from various hypernews postings and user feedback
Last modification: 13 June 2005
Last significant update: 10 February 2003
|