SLAC PEP-II
BABAR
SLAC<->RAL
Babar logo
Workbook HEPIC Databases PDG HEP preprints
Organization Detector Computing Physics Documentation
Personnel Glossary Sitemap Search Hypernews
Unwrap page!
Wkbk. Search
Wkbk. Sitemap
Introduction
Non SLAC
HOWTO's
Introduction
Logging In
QuickTour
Detector
Info Resources
Software Infrastructure
CM2 Introduction
Unix
OO
SRT
Objectivity
Event Store
Framework
Beta
Modifying Code
Writing and Editing
Compiling
Debugging
Analysis
Framework II
Analysis
Find Data
Batch Processing
PAW
PAW II
ROOT I
ROOT II
ROOT III
Advanced Infrastructure
New Releases
Workdir
Main Packages
Event Displays
Gen/Sim/Reco
Contributing Software
SRT and CVS
Coding
Advanced Topics
Make CM2 Ntuples
New Packages
New Packages 2
Persistent Classes
Java
Site Installation
Check this page for HTML 4.01 Transitional compliance with the
W3C Validator
(More checks...)

Workbook for BaBar Offline Users - Analysis in ROOT III

This WorkBook section is intended to extend the knowledge gained in the WorkBook sections Root1 and Root2 to the higher level needed for a real BaBar physics analysis. The tutorial in this section was written by Chris Hearty, and provides a walkthrough of a physics analysis session in ROOT.

Contents


Preliminary

This WorkBook section will allow you to make histograms from chains or individual files, with the histograms subdivided into various MC and data types. It shows you how to add functions to the standard MakeSelector class, or to use your own functions from outside the class. It uses ntuples produced using BtaTupleMaker in the Make CM2 Ntuples tutorial, but the concepts are applicable to any ntuple structure.

The original version of this tutorial was created using ROOT 3.10/02 on a standalone system (i.e. one not connected to the BaBar disk system). You can also run it on a noric machine using the analysis-26 release using the modified instruction located at the end of some sections. In this case, you start root 4.04/02b by typing bbrroot in the workdir directory. Remember to srtpath first (from the release directory). In general, I find it tidier to make a new release to analyze the ntuples, instead of using the same one I used to make the ntuples in the first place.

A slight familiarity with ROOT is assumed in this tutorial. For example, you should first have completed the WorkBook sections Root1 or Root2 or the FNAL root class.

This WorkBook section does not cover fitting of histograms.


Some basics

a. Define your Macro path:

Edit the file .rootrc, located in your home directory, to specify the path that root uses to look for macros. As you can see from the snippet from my .rootrc, I put my macros in the directory ~/Work/paw/root/Macros:
[~]: more .rootrc 
# @(#)root/config:$Name: $:$Id: rootrc.in,v 1.46 2003/05/08 09:07:16 brun Exp $
# Author: Fons Rademakers 22/09/95

# ROOT Environment settings are handled via the class TEnv. To see
# which values are active do: gEnv->Print().

# Path used by dynamic loader to find shared libraries and macros
# Paths are different for Unix and Windows. The example shows the defaults
# for all ROOT applications for either Unix or Windows.
Unix.*.Root.DynamicPath: .:$(ROOTSYS)/lib
Unix.*.Root.MacroPath: .:$(HOME)/Work/paw/root/Macros:$(ROOTSYS)/macros
WinNT.*.Root.DynamicPath: .;$(ROOTSYS)/bin;$(PATH)
WinNT.*.Root.MacroPath: .;$(HOME)/Work/paw/root/Macros;$(ROOTSYS)/macros

b. Edit rootlogin.C

The macro rootlogin.C is run whenever you start root. I put mine in the macro directory defined in the previous step, but you could put it in your analysis directory if you wanted to specialize it for a particular analysis. Here is mine:
[~/Work/paw/root/Macros]: cat rootlogon.C
{
printf("\nWelcome to my rootlogon.C \n\n"); <-- print a message
gROOT->SetStyle("Plain"); <-- plain histogram style
gStyle->SetOptStat(1111111); <-- expanded stats box
gStyle->SetPadTickX(1); <-- tic marks on all axes
gStyle->SetPadTickY(1); <--
}

c. Special for analysis-26 on yakut

.rootrc is located in the workdir directory, not in your home directory.

The macro that is run when starting ROOT is called RooLogon.C, and is also located in workdir. It contains a reasonable default set of commands, but you can edit it if you would like something different.


Make a selector for sample ROOtuples

Sample rootuples are available as SP-989-Run1-1.root and SP-989-Run1-2.root. These were produced as PAW ntuples with BtaTupleMaker in the Make CM2 Ntuples tutorial, then converted to rootuples using h2root on a tersk machine. We are interested in the "h3" ntuple. (There are several other directories in the hbook files.)

Create a directory "data" of your analysis directory and place the two files in it.

Now use MakeSelector to create a C++ program (histAnalysis.h and histAnalysis.C) to analyze the data:

[~/Work/tutorials/root26]: root
*******************************************
* *
* W E L C O M E to R O O T *
* *
* Version 3.10/02 14 March 2004 *
* *
* You are welcome to visit our Web site *
* http://root.cern.ch *
* *
*******************************************

FreeType Engine v2.1.3 used to render TrueType fonts.
Compiled for macosx with thread support.

CINT/ROOT C/C++ Interpreter version 5.15.115, Dec 9 2003
Type ? for help. Commands must be C++ statements.
Enclose multiple statements between { }.
^[[A
Welcome to my rootlogon.C <-- note the message from rootlogin.C
For approved plots use: gROOT->SetStyle("BABAR");

root [0] TFile f("data/SP-989-Run1-1.root") <-- either file will do
root [1] .ls
TFile** data/SP-989-Run1-1.root HBOOK file: SP-989-Run1-1.hbook converted to ROOT
TFile* data/SP-989-Run1-1.root HBOOK file: SP-989-Run1-1.hbook converted to ROOT
KEY: TTree h3;1 myNtuple
KEY: TTree h2;1 Analysis
KEY: TTree h1;1 SmpListInfo
root [2] h3->MakeSelector("histAnalysis")
Info in <TTreePlayer::MakeClass>: Files: histAnalysis.h and histAnalysis.C generated from Tree: h3
(Int_t)0
root [3] .q
[~/Work/tutorials/root26]: ls histAnalysis.*
histAnalysis.C histAnalysis.h

This is what the original files look like:

Note: the MakeSelector function works correctly for ROOT files created from ntuples with h2root. If you are using files created directly as ROOtuples, you will need to manually edit histAnalysis.h and increase array sizes. By default, they will be set to the largest value needed for the particular file used with MakeSelector. For example, if no event has more than 3 B0 candidates, Bmass will be declared Float_t Bmass[3] instead of the correct value Bmass[50].

Special for analysis-26 on yakut

Here is what you should see when you start ROOT by typing bbrroot: yakut-log.txt,  and here are the original files: histAnalysis-orig-yakut.C, histAnalysis-orig-yakut.h.


Fill some basic histograms

There are a lot of comments in the histAnalysis.C as generated. I delete most of them to tidy the file up.

There are three steps to creating a histogram. First, it must be declared. I put all of my declarations in a separate file, dec.C, just to keep main file tidier. This simple version declares two 1D histograms:

[~/Work/tutorials/root26]: cat dec.C
//..dec.C contains variable declarations for histAnalysis.C

TH1F *hnJpsi, *hmassJpsi;

To include dec.C into the program, just add

#include "dec.C"

before the Begin function in histAnalysis.C

Next, define the histograms in the Begin function:

  //..Define histograms (declared in dec.C)
hnJpsi = new TH1F("hnJpsi", "Number of Jpsi", 20, -0.5, 19.5);
hmassJpsi = new TH1F("hmassJpsi", "Raw Jpsi Mass", 60, 2.9, 3.3);

Fill the histograms in Process

If you are using only a few variables, it can be faster to read only the data you need from the ntuple. In practice, I generally just read the whole thing.

  //..Just read the full event
fChain->GetTree()->GetEntry(entry);

//..Fill some simple histograms
hnJpsi->Fill(njpsi);
for(Int_t i=0; i<njpsi; i++) {
hmassJpsi->Fill(Jpsiuncmass[i]);
}

Run the job

Start root, define the data file, then compile the code and run on ntuple h3. I always compile the code, as opposed to running in interpreted mode. I have found bugs in the interpreter when processing the sample data used in this tutorial.

root [0] TFile f("data/SP-989-Run1-1.root");
root [1] h3->Process("histAnalysis.C+");

To run only 100 events, you would say

   h3->Process("histAnalysis.C+","",100,0);

The following commands create a canvas and display the two histograms on it. You can save the canvas using the File menu if you wish.

root [2] TCanvas MyC("MyC");
root [3] MyC.Divide(2,1);
root [4] MyC.cd(1);
root [5] hnJpsi->Draw()
root [6] MyC.cd(2);
root [7] hmassJpsi->Draw()

Here is a screen capture of the root session:

And the resulting histograms: This version of the code is

Special for analysis-26 on yakut

Here is the code from running on yakut: histAnalysis-1-yakut.C.

Chains

You will generally want to chain many files together.
TChain chain("h3");
chain.Add("data/SP-989-Run1-1.root");
chain.Add("data/SP-989-Run1-2.root");

chain.Process("histAnalysis.C+");
We will use this later.

If your ntuple is in a root subdirectory, the syntax is (for example) TChain chain("TauMicroFilter/ntpl"); The remaining commands are the same.


Write the histograms to a file

By writing the histograms to a file, you can separate their generation from their presentation or subsequent fitting.

a. After filling the histograms, it is convenient to write them to a file:

  • add #include <iostream.h> to histAnalysis.C (so you can use cout)
  • declare the output file in dec.C: TFile *fHistFile;
  • create the file in Begin before defining the histograms. (RECREATE replaces the current version if there is one).
      //..Output file for histograms
    fHistFile = new TFile("histAnalysis.root","RECREATE");
  • in the Terminate function, write the histograms into the file:
      //..Write out histograms to file
    fHistFile->cd();
    fHistFile->Write();
    fHistFile->Close();
    cout << "Output file written" << endl;
Some people have reported that they need to write each histogram individually, such as

hnJpsi->Write();

b. running the job now creates the output file:

[~/Work/tutorials/root26]: ls -l histAnalysis.root
-rw-r--r-- 1 hearty staff 3966 Oct 20 19:21 histAnalysis.root

c. Read the file into root to access it. Here is a sample session.

root [0] TFile f("histAnalysis.root");
root [1] .ls
TFile** histAnalysis.root
TFile* histAnalysis.root
KEY: TH1F hnJpsi;1 Number of Jpsi
KEY: TH1F hmassJpsi;1 Raw Jpsi Mass
root [2] TCanvas MyC("MyC");
root [3] MyC.Divide(2,1);
root [4] MyC.cd(1)
root [5] hnJpsi->Draw()
root [6] MyC.cd(2)
root [7] hmassJpsi->Draw()
root [8] .q

d. This version of the code is

See also

Special for analysis-26 on yakut

Use #include <iostream>  instead of <iostream.h>

Use a macro to run the code

a. It is convenient to write a short macro, runAnalysis.C, to run the code and generate the output histogram file:

[~/Work/tutorials/root26]: cat runAnalysis.C
#include "TChain.h"

void runAnalysis () {
TChain chain("h3");
#include "SP-989-Run1-Chain.C"
chain.Process("histAnalysis.C+");
}

Note that I include the files to be chained in an include file:

[~/Work/tutorials/root26]: cat SP-989-Run1-Chain.C
chain.Add("data/SP-989-Run1-1.root");
chain.Add("data/SP-989-Run1-2.root");

This is a convenient way to deal with multiple data types - just create a similar include file for each (on-peak data, off-peak data, BB MC, continuum MC and so on). List them all in your macro and comment out the ones to skip.

root [1] .x runAnalysis.C+
Info in <TUnixSystem::ACLiC>: creating shared library /Users/hearty/Work/tutorials/root26/./runAnalysis_C.so
Info in <TUnixSystem::ACLiC>: creating shared library /Users/hearty/Work/tutorials/root26/./histAnalysis_C.so
In file included from /Users/hearty/Work/tutorials/root26/tmp_8_UjiUzK.h:29,
from /Users/hearty/Work/tutorials/root26/tmp_8_UjiUzK.cxx:13:
/Users/hearty/Work/tutorials/root26/histAnalysis.C: In member function `virtual
void histAnalysis::Begin(TTree*)':
/Users/hearty/Work/tutorials/root26/histAnalysis.C:30: warning: unused
parameter `TTree*tree'
Output file written

Note that the include file only works when compiling. Here are versions that work in interpreted mode, although they lack the flexibility of modifying datasets by adding or subtracting include files. Note that the analysis code itself is still compiled in this example. This macro can also be used in batch mode (next step):


Run in batch/background mode

a. If you execute the macro in background/batch mode, you can be sure that there are no problems with memory leaks or stale temporary items.
[~/Work/tutorials/root26]: root -b -q runAnalysis.C+ >& runAnalysis.log &
[1] 11608
[~/Work/tutorials/root26]:
[1] Done root -b -q runAnalysis.C+ >& runAnalysis.log
The "-b" runs in batch mode, "-q" exits root after running the macro. Here is the log: runAnalysis-3.log.

You can just skip the log file if you prefer; it gets annoying if you are running the job many times, since you have to delete it every time. 

b. You can now view the histograms by reading histAnalysis.root. It is convenient to leave an interactive root session running for this purpose. Just close and reopen the file when you remake it:

root [0] TFile f("histAnalysis.root");
root [1] hnJpsi->Draw()
<TCanvas::MakeDefCanvas>: created default TCanvas with name c1
root [2] f.Close()
root [3] hnJpsi->Draw()
Error: Symbol hnJpsi is not defined in current scope FILE:(tmpfile) LINE:1
Error: Failed to evaluate hnJpsi->Draw()Possible candidates are...
filename line:size busy function type and name
*** Interpreter error recovered ***
root [4] TFile f("histAnalysis.root");
root [5] hnJpsi->Draw()
<TCanvas::MakeDefCanvas<: created default TCanvas with name c1

A particular application of this technique is to run the background job on a remote Tier A site - IN2P3, for example - then to view the histograms on your local machine using AFS. This way, you don't have you run an X-window over the network, nor do you have to copy your large ntuple sets to your local machine. 

Special for analysis-26 on yakut

Use bbrroot instead of root when running in background mode:

  bbrroot -b -q runAnalysis.C+ >& runAnalysis.log &

Add some CLHEP to your analysis

You will probably want to use TLorentzVectors and other CLHEP-type classes. To do so, you need to load the libPhysics library in runAnalysis.C. Note the TSystem.h header as well.
[~/Work/tutorials/root26]: cat runAnalysis.C 
#include "TChain.h"
#include "TSystem.h"

void runAnalysis () {
gSystem->Load("libPhysics.so");
TChain chain("h3");
#include "SP-989-Run1Chain.C"
chain.Process("histAnalysis.C+");
}
We can use TLorentzVector to create a 4-vector of the center of mass, from which we can get the center of mass energy. First, #include "TLorentzVector.h" in histAnalysis.C. Then, in Process:
  TLorentzVector mom4Ups(eepx, eepy, eepz, eee);
Float_t sqrts = mom4Ups.M();
See the "Physics Vectors" chapter of the root users manual for more details on this class.

Add a function to your analysis class

It may be convenient to add other functions to your histAnalysis class. Here we create a function called CheckMC that uses the MC truth block and the center of mass energy to categorize the event as on-peak data, off-peak data, signal MC, inclusive Jpsi MC, other BB MC, or continuum MC. (You could further subdivide the continuum and BB MC if desired).

a. declare the function in histAnalysis.h, right after the Terminate declaration:

   void    Terminate();
Int_t CheckMC(Int_t mclund[200], Int_t mothidx[200], Int_t daulen[200],
Int_t dauidx[200], Int_t mclen, Float_t sqrts);
ClassDef(histAnalysis,0);

(Note that the second line above is broken only for formatting purposes.) Here is the full file: histAnalysis-CheckMC.h

b. Write the function. I put it in a separate file, CheckMC.C. Here are the first few lines:

// Value of CheckMC tells what type of events this is:
// 0 = on peak data, 1 = off peak, 2 = Jpsi K+, 3 = Other B-->Jpsi
// 4 = Other BB, 5 = continuum

Int_t histAnalysis::CheckMC(Int_t mclund[200], Int_t mothidx[200], Int_t daulen[200],
Int_t dauidx[200], Int_t mclen, Float_t sqrts) {

(Note that the line above is broken only for formatting purposes.) Note the "histAnalysis::CheckMC". Here is the full file: CheckMC.C

c. Include the new file into your code with #include "CheckMC.C":

//-----------------------------------------------------------------------------
#include "CheckMC.C"

d. Perhaps add a new histogram, hdtype, and fill it with the value returned by CheckMC.

  //..Categorize the event
TLorentzVector mom4Ups(eepx, eepy, eepz, eee);
Float_t sqrts = mom4Ups.M();
Int_t dtype = histAnalysis::CheckMC(mclund, mothidx, daulen, dauidx, mclen, sqrts);
hdtype->Fill(dtype);

Note that you include the class histAnalysis when using the function. Here is the full code. Remember to declare hdtype in dec.C as well: histAnalysis-CheckMC.C


Add some functions outside your analysis class

You may want to write functions that are not part of the histAnalysis class. Perhaps they are more general than this particular analysis. There is also the advantage that such functions are not recompiled when you modify your analysis code.

In this example, we will use a single class, MyF. Other classes can be similarly created as needed.

a. Create the header file MyF.h. This should be put in your Macros directory defined in .rootrc.

[~/Work/tutorials/root26]: cat ~/Work/paw/root/Macros/MyF.h
#include "TLorentzVector.h"

class MyF {

public:

//--------------------------------------------------------------------------
//..FourMomentum returns four vector from p, theta, phi and mass

static TLorentzVector FourMomentum(Float_t mom, Float_t theta, Float_t phi,
Float_t mass);

};

This first function makes a TLorentzVector from the p,theta, phi and mass of the particle. (There is no such standard constructor). The key features:

  • the function must be public
  • the "static" declaration means that the function can be used without first creating a "MyF" object. This is the same as "cosine", for example, which you can use without creating a "TMath" object.
b. Write the function in MyF.C in the same directory:
[~/Work/tutorials/root26]: cat ~/Work/paw/root/Macros/MyF.C
#include "MyF.h"

//--------------------------------------------------------------------------
//..FourMomentum returns four vector from p, Cos(theta), phi and mass

TLorentzVector MyF::FourMomentum(Float_t mom, Float_t costheta, Float_t phi, Float_t mass)
{
TLorentzVector temp(1.0,1.0,1.0,1.0);
Float_t energy = sqrt(mom*mom + mass*mass);
temp.SetRho(mom);
temp.SetTheta(acos(costheta));
temp.SetPhi(phi);
temp.SetE(energy);

return temp;
}

You could also put the code into a file FourMomentum.C and just include it in MyF.C using #include "FourMomentum.C"

c. Compile the code and load the library to make the code accessible.

To use the code, we need to compile and load it before running histAnalysis. We do this in runAnalysis.C, right after loading libPhysics.so:

  gSystem->Load("libPhysics.so");
gROOT->LoadMacro("MyF.C+");
Recall that the ".C+" extension means that MyF.C is compiled if changed; otherwise the existing library is loaded.

d. Create a soft link to your Macros directory:

[~/Work/tutorials/root26]: ln -s ~/Work/paw/root/Macros/ Macros

e. Use the function in your analysis.

First, you need to include the header: #include "Macros/MyF.h"

Here is a snippet of code to calculate the four vector and corresponding missing mass for every B candidate. Actually, a proper calculation of this quantity using a kinematic fit is available in the ntuple as Bpostfitmmiss[ib]. You might find it interesting to compare this quantity to Mmiss:

  //..Missing mass
for(Int_t ib=0; ib<nb; ib++) {
TLorentzVector mom4B =
MyF::FourMomentum(Bp3[ib], Bcosth[ib], Bphi[ib], Bmass[ib]);
Float_t Mmiss = (mom4Ups - mom4B).M();
hmyBmiss->Fill(Mmiss);
hntpBmiss->Fill(Bpostfitmmiss[ib]);
hCompMiss->Fill(Bpostfitmmiss[ib],Mmiss);
}

Remember to declare the histograms in dec.C and to create them in "Begin".  Here are the complete files.

and the resulting plot:

Dump some MC truth events

a. It is often convenient to write out the MC truth block in an event.  Unfortunately, this section of the workbook is currently broken. 

Handle multiple data types

Many analyses compare on peak, off peak and various MC data types. One method of dealing with these different data starts with the CheckMC function defined earlier. We use the resulting index dtype with arrays of histograms, and weight each data type by its relative luminosity so that all resulting plots are normalized to the on-peak luminosity.

a. Declare the relevant histograms to be arrays of length 6 in dec.C:

TH1F *hnJpsi[6], *hmassJpsi[6], *hdtype, *hmyBmiss[6], *hntpBmiss[6];
TH2F *hCompMiss[6];


TFile *fHistFile;

Note that hdtype is still only a single histogram.

b. Before defining the histograms in the Begin method of histAnalysis, create a vector of names and use them to customize each histogram:

 //..Some quantities to handle multiple data types
TString htit[6] = {"_on","_off","_sig","_Jpsi","_BB","_cont"};

//..Define histograms (declared in dec.C)
hdtype = new TH1F("hdtype", "Event Type", 10, -1.5, 8.5);
for( Int_t ih=0; ih<6; ih++ ) {
hnJpsi[ih] = new TH1F("hnJpsi"+htit[ih], "Number of Jpsi"+htit[ih],
20, -0.5, 19.5);
hmassJpsi[ih] = new TH1F("hmassJpsi"+htit[ih], "Raw Jpsi Mass"+htit[ih],
60, 2.9, 3.3);
hmyBmiss[ih] = new TH1F("hmyBmiss"+htit[ih], "My Missing Mass"+htit[ih],
50, 5.20, 5.30);
hntpBmiss[ih] = new TH1F("hntpBmiss"+htit[ih],
"Ntp Missing Mass"+htit[ih],
50, 5.20, 5.30);
hCompMiss[ih] = new TH2F("hCompMiss"+htit[ih],
"My Mmiss vs Ntp Mmiss"+htit[ih],
50, 5.20, 5.30, 50, 5.20, 5.30);
}

c. Now create an array of weights corresponding to each data type. The weight = on-peak-luminosity/sample-luminosity. Put this in dec.C, since it will probably be needed in more than one function of histAnalysis.  (Of course, you will need to calculate these for your own analysis!)

Float_t hwt[6] = {1., 8.55, 1., 0.241, 0.283, 1.098};

d. Now fill the histograms according to the event type and with the appropriate weight.  Note that dtype enters both in the histogram identifier and in the weight. 

  hnJpsi[dtype]->Fill(njpsi,hwt[dtype]);

and so forth for hmassJpsi and the others.

e. To test this out, you can try some B+B- MC (SP mode  1235): SP-1235-Jpsitoll-Run1-R16a-1.root, SP-1235-Jpsitoll-Run1-R16a-2.root

Put these in your data directory and create a file SP-1235-Run1-Chain.C: 

chain.Add("data/SP-1235-Jpsitoll-Run1-R16a-1.root");
chain.Add("data/SP-1235-Jpsitoll-Run1-R16a-2.root");
Include this in runAnalysis.C using #include "SP-1235-Run1-Chain.C". Run the job using root -q -b runAnalysis.C+ as normal.

f. Take a look at the resulting histograms in your interactive root, starting with the histogram of the event type, hdtype->Draw(). Note that most of the events are actually B+ --> Jpsi K+ signal events. This is not surprising, since we are requiring a reconstructed Jpsi K+ to write the ntuple.  Here is the plot.  Take a look at the Jpsi masses for each data type as well: 

root [4] TCanvas MyC("MyC");
root [5] MyC.Divide(3,2)
root [6] MyC.cd(1)
root [7] hmassJpsi_on->Draw()
root [8] MyC.cd(2)
root [9] hmassJpsi_off->Draw()
root [10] MyC.cd(3)
root [11] hmassJpsi_sig->Draw()
root [12] MyC.cd(4)
root [13] hmassJpsi_Jpsi->Draw()
root [14] MyC.cd(5)
root [15] hmassJpsi_BB->Draw()
root [16] MyC.cd(6)
root [17] hmassJpsi_cont->Draw()
root [18] Info in <TCanvas::Print>: GIF file /Users/hearty/Work/tutorials/root26/Jpsi-mass-SP1235.gif
has been created
Here is resulting plot.  Note that the on-peak, off-peak and continuum plots are empty, since we didn't run on those data, and that the Signal and Inclusive Jpsi samples give nice Jpsi peaks, while the "Other BB" sample does not. 

Also note that for the signal plot "Entries" (which is the number of times that Fill was called for this histogram) is equal to "underflow" + "overflow" + "integral", which are the sum of weights below, above and in the plot respectively. This is in contrast to the Jpsi plot, where the two values differ by the ratio of 0.241 - the Inclusive Jpsi data weight.

When doing an analysis, you often find yourself making the same set of plots over and over. In this case, it is worth writing a macro to make it.  To execute it, type .x plotMass.C in an interactive root session.

Here are the final versions of various files:


Producing a publication-quality plot

At some point you may want to produce a nice version of a plot for a talk or publication. As discussed in the previous section, it is often convenient to use a macro when manipulating histograms. In this section, we will use a macro to produce a nice version of a Jpsi mass distribution. This is based on a style package developed by David Kirkby, which is available in RooLogon.C, located in the workdir package.

a. Add the BABAR style to your rootlogon.C

Insert this code into your rootlogon.C (see "Some basics"), which defines a style called BABAR.

Put it before your normal commands, to be sure that you end up in your normal style. Here is my resulting rootlogon.C.

You then invoke this style by the command

     gROOT->SetStyle("BABAR");
            

b. Pick up code to write BaBar on plots

For conference use, you will generally want to write BaBar in an official-looking way on your plots. Sasha Telnov wrote a macro to do this, which I have copied from workdir/RooAlias.C. Add this to your macros directory: BABARSmartLabel.C

Note that there is no header file; it is assumed that this macro will not be used in compiled macros. You will need to load the macro either using .L BABARSmartLabel.C interactively, or gROOT->LoadMacro("BABARSmartLabel.C"); in the histogramming macro. (You don't need to specify the path to BABARSmartLabel.C if it's in your macros directory as defined in Some Basics). After loading the macro, the command

BABARSmartLabel(-1,-1,-1,"-1",-1);
will put "BaBar" in the upper right-hand corner;

BABARSmartLabel(-1,-1,-1,"~1",-1,-1);
will add "Preliminary" underneath. Check the comments in the code for the full usage.

c. A macro to produce a nice plot

It is often easier to manipulate histograms in a macro than interactively, unless you are confident that you will only have to do it once, and will do it right the first time. When making publication-quality plots, it is easiest to have one macro per plot.

In this macro, we will make a nice version of the Jpsi mass plot produced above. Here is the root file containing the produced histograms, in case you don't have your own: histAnalysis.root.

Here is the macro: DrawsighmassJpsi.C

This macro also includes a couple of lines with commands for drawing lines on figures in ROOT.

A key point for manipulating histograms in a macro is that under many circumstances (in particular, if you want to work with more than one in the macro), you need to explicitly create a pointer to each histogram:

TFile f("histAnalysis.root");
TH1* sighmassJpsi = (TH1*) f.Get("sighmassJpsi");
In addition to invoking the BABAR style, this macro does some typical modifications, like adjusting the marker size and moving the axis labels. Note that the BABAR style turns off the default titles, so you will need to add titles yourself. It then writes the plot to an eps file.

d. Run the macro

[~/Work/tutorials/root26]: root
*******************************************
* *
* W E L C O M E to R O O T *
* *
* Version 3.10/02 14 March 2004 *
* *
* You are welcome to visit our Web site *
* http://root.cern.ch *
* *
*******************************************

FreeType Engine v2.1.3 used to render TrueType fonts.
Compiled for macosx with thread support.

CINT/ROOT C/C++ Interpreter version 5.15.115, Dec 9 2003
Type ? for help. Commands must be C++ statements.
Enclose multiple statements between { }.

Welcome to my rootlogon.C
For approved plots use: gROOT->SetStyle("BABAR");

root [0] .x DrawsighmassJpsi.C
Info in <TCanvas::Print>: PostScript file JpsiMass.eps has been created

If you make changes to DrawsighmassJpsi.C, you don't need to quit and restart root; just rerun the macro. Here is the resulting plot: JpsiMass.eps

e. Special for analysis-26 on yakut

RooLogon.C already contains the BABAR style and loads the command BABARSmartLabel, so you do not need to add anything to your RooLogon.C or to your Macros directory. However, you do need to delete the following command in DrawsighJpsi.C, which loads BABARSmartLabel:

gROOT->LoadMacro("BABARSmartLabel.C");

Conclusion

In completing this tutorial, you have covered the features needed to perform an analysis on a set of ROOtuples. You have generated the code structure using MakeSelector, added histograms, code to deal with multiple MC types, and external functions, and developed a macro to load the required libraries and execute the code. These tools are adequate for a cut-and-count type analysis.

The next step in sophistication would be fitting. Basic fits are discussed in the ROOT II tutorial. The package RooFit provides many convenient and advanced tools for this purpose.


Back to Workbook Front Page

Author: Chris Hearty

Last modified: 7 March 2004
Last significant update: 3 February 2004
Updated to analysis-26: 16-Oct-2005