Walkthrough: Using a C++ selector to analyze a Tree
(10 minutes)
Note
The first step is to have ROOT
write the skeleton of an analysis class for your n-tuple. This is done
with the MakeSelector
command.
Let’s start with a clean slate: quit ROOT if it’s running and start it up again. Open the ROOT tree again:
[] TFile myFile("experiment.root")
Now create an analysis macro for tree1
with MakeSelector
. I’m going
to use the name “Analyze” for this macro, but you can use any name you
want; just remember to use your name instead of “Analyze” in all the
examples below.
[] tree1->MakeSelector("Analyze")
Switch to the UNIX window and examine the files that were created:
> less Analyze.h
> less Analyze.C
A mass of code
Unless you’re familiar with C++, this probably looks like gobbledy-gook to you. (I know C++, and it looked like gobbledy-gook to me… at first.) We can simplify this by understanding the approach of most analysis tasks:
Definition – define the variables we’re going to use.
Initialization - open files, create histograms, etc.
Loop - for each event in the n-tuple or Tree, perform some tasks: calculate values, apply cuts, fill histograms, etc.
Wrap-up - display results, save histograms, etc.
You’ve probably already guessed that the lines beginning with // are comments. They describe more than we’re going to use, so I’ll narrow things down below.1
Here’s a simplified version of the C++ code from Analyze.C
. I’ve removed
the automatically generated comments created by ROOT, and minimized the
routines SlaveBegin
and SlaveTerminate
which we won’t use for
this tutorial. I also marked the places in the code where you’d place
your own commands for Definition, Initialization, Loop, and Wrap-up.
Compare the code you see in Analyze.C
with what I’ve put below. If you
wish, you can edit the contents of your Analyze.C
to match what I’ve
done; it will give you practice using emacs
or whatever text editor
you choose.2
#define Analyze_cxx
#include "Analyze.h"
#include <TH2.h>
#include <TStyle.h>
//******** Definition section *********
void Analyze::Begin(TTree * /*tree*/)
{
TString option = GetOption();
//******** Initialization section *********
}
void Analyze::SlaveBegin(TTree* tree) {}
Bool_t Analyze::Process(Long64_t entry)
{
// Don't delete this line! Without it the program will crash.
fReader.SetEntry(entry);
//******** Loop section *********
// You probably want GetEntry(entry) here.
return kTRUE;
}
void Analyze::SlaveTerminate() {}
void Analyze::Terminate()
{
//******** Wrap-up section *********
}
Compare this with the Python code in Listing 39.
- 1
Many of the comments, as well as the routines
SlaveBegin
andSlaveTerminate
refer to something called PROOF. This is a method of breaking up your n-tuple into sections and analyzing each section on a separate CPU core of your computer.PROOF is now deprecated by the ROOT developers. If, by some rare chance, you do use PROOF, note that
SlaveBegin
andSlaveTerminate
are where you put your initialization and wrap-up code, respectively, andBegin
andTerminate
should be “stubs.”By the way, PROOF has nothing directly to do with batch processing, which I describe in one of the optional appendices of this course.
There’s another ROOT class that can speed up n-tuple analysis on machines with multiple cores; see The RDataframe Path.
- 2
You can copy the “reduced” file from my area if (A) you’re pressed for time, or (B) just feeling lazy today.
> cp ~seligman/root-class/Analyze.C $PWD