Walkthrough: Using C++ to analyze a Tree (10 minutes)

Note

You can spend a lifetime learning all the in-and-outs of object-oriented programming in C++.1 Fortunately, you only need a small subset of this to perform analysis tasks with ROOT. 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.2

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

Note

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.3

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.4

Listing 1: Example C++ TSelector macro
#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 2.


1

That’s four lifetimes, five if you’re studying LaTeX. And you thought you only signed up for a ten-week project! Gosh, I wonder if it takes a lifetime to understand high-energy physics.

2

If you’re bolder or familiar with C++, you don’t have to use MakeSelector to write an analysis class (specifically, a TSelector class) for you; look up TTreeReader on the ROOT web site. I use MakeSelector in this tutorial to spare you from having to define a TTreeReaderValue for every branch in the TTree. If you’re willing to follow the directions for TTreeReader, you may get code that will be easier for you to revise in the long run. For an example, see ~seligman/root-class/AnalyzeReader.C.

3

Many of the comments, as well as the routines SlaveBegin and SlaveTerminate 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.

By the way, PROOF has nothing directly to do with batch processing, which I describe in one of the optional lectures of this course. If you do use PROOF, note that SlaveBegin and SlaveTerminate are where you put your initialization and wrap-up code, respectively, and Begin and Terminate should be “stubs.”

There’s another ROOT class that can speed up n-tuple analysis on machines with multiple cores: RDataFrame.

4

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