CAF ROOT Macros and PyROOT (Releases prior to S13-04-09)

There are two popular interfaces for ROOT libraries: the ROOT interpreter (CINT) and PyROOT (a set of python bindings for ROOT classes). Both of these are exceptionally easy to use. This page will document both. As one digs deeper into the CAF, they may be interested in the tree structure. The structure is currently documented in doxygen, but eventually there will be documentation on this wiki.

The ROOT interpreter can be used either interactively at the prompt or by writing macros. The prompt acts as an interactive environment where commands can be executed one at a time. A ROOT macro is essentially a script which executes a set of commands one after another.

Getting Started

Before you start mucking around with CAF files, make sure that you have run the nova setup function, as described in Documentation FOR BEGINNERS. Running the setup function gives you access to the required dictionary libraries, ROOT, CAFE and PyROOT. Note that you must source the release under which the files were produced. For the MDC CAF production, this was S12-10-07, so for instance, you would type:

% setup_nova -r S12-10-07

Starting your ROOT macros

The following preamble will allow you to load CAF files without warnings and loop over trees. This should be placed inside your function, and you will not need any explicit #include statements.


Note that if you're making local changes to CAFMaker that you will need to load your version of and not
the version in $SRT_PUBLIC_CONTEXT:


Then you can load your file, as demonstrated with an mdc file :

TFile* file = new TFile("/nova/ana/caf/mdc/fd/mdc0/mdcCAF_fd_nhc_262_r159_0_mdc0_S12.06.17_20121023_162736_reco.root", "READ");
TTree* tree = (TTree*)file->Get("recTree");

Starting a ROOT interactive session manually

The first step is to enter the ROOT environment by entering the following command:

% root 

This should bring up the root prompt that looks like root [0]. The ROOT prompt interprets commands in C++ syntax. There is a magic incantation that must be executed prior to loading any ROOT trees, as follows:

root [0]  gSystem->Load("");
root [1]  Cintex::Enable();

Now you can load the CAF libraries:
root [2]  gSystem->Load("$SRT_PUBLIC_CONTEXT/lib/Linux2.6-GCC-debug/");

And then we can load a file. I have picked one of the MDC CAF files: /nova/ana/caf/mdc/fd/mdc0/mdcCAF_fd_nhc_262_r159_0_mdc0_S12.06.17_20121023_162736_reco.root.
We can load this file as a TFile and extract the CAF tree from it:
root [3] file = new TFile("/nova/ana/caf/mdc/fd/mdc0/mdcCAF_fd_nhc_262_r159_0_mdc0_S12.06.17_20121023_162736_reco.root", "READ");
root [4] tree = (TTree*)file->Get("recTree");

Easiest method: CAF Environment (CAFE)

The nova setup script creates an alias that loads the libraries automatically. You can use this to start an interactive session or run a macro without the steps above. On the command line, type:

% cafe 

Then you could immediately do these steps:
root [0] file = new TFile("/nova/ana/caf/mdc/fd/mdc0/mdcCAF_fd_nhc_262_r159_0_mdc0_S12.06.17_20121023_162736_reco.root", "READ");
root [1] tree = (TTree*)file->Get("recTree");

Alternatively, you can pass file paths as command line arguments:

% cafe /nova/ana/caf/mdc/fd/mdc0/mdcCAF_fd_nhc_262_r159_0_mdc0_S12.06.17_20121023_162736_reco.root

which produces the output:
root [0] 
Attaching file /nova/ana/caf/mdc/fd/mdc0/mdcCAF_fd_nhc_262_r159_0_mdc0_S12.06.17_20121023_162736_reco.root as _file0...

This indicates that we can access the tree using:

tree = (TTree*)_file0->Get("recTree")

Analysis Strategies

Histograms with TTree::Draw()

Now we can use the tree to make some histograms. Let's start with a simple one-dimensional dimensional histogram, for instance, the number of hits in each slice:

root [5] tree->Draw("rec.slc.nhit")

which should produce something like the following display:

We can also have make a two dimensional histogram using the colon syntax below. Also note that I am supplying "colz" as a display option, this makes a color plot and draws a z-axis.

root [6] tree->Draw("rec.slc.nhit:slc.nmiphit", "", "colz")

The 2D histogram should look like this:

Finally, we might want some cuts, for instance, we might want to have more than 20 contiguous planes. The second parameter in TTree::Draw() accepts cuts.

root [7] tree->Draw("rec.slc.nhit:slc.nmiphit", "slc.ncontplanes > 20", "colz")

which then produces the prettier histogram:

We can also do math in these strings, so we could do:

root [7] tree->Draw("rec.slc.nmiphit / slc.nhit", "slc.ncontplanes > 20")

to produce a 1D histogram of the fraction of hits that are MIP-like.

ROOT macros and looping over trees

If you'd rather not type your commands every time you want a plot, you can chain commands together in a ROOT macro. If you're not using the "cafe" environment,

Now you are free to do all of your favorite things, for instance, load a file:

TFile* file = new TFile("/nova/ana/caf/mdc/fd/mdc0/mdcCAF_fd_nhc_260_r184_0_mdc0_S12.06.17_20121023_162750_reco.root", "read");  

Get out the record tree:
  TTree* tree = file->Get("recTree");

Draw a histogram:

For more examples of how to exploit TTree::Draw(), look in the histograms section.

We can also loop over trees entry-by-entry to do more complicated stuff, but ROOT does this in a somewhat counterintuitive way. To begin this process, we must create a StandardRecord object and set the branch address using our tree:

  caf::StandardRecord* rec = new caf::StandardRecord(); 
  tree->SetBranchAddress("rec", &rec);

This means that the object rec is now tied to that branch. Note that we could have called SetBranchAddress() for a branch deeper in the tree, giving a performance boost upon looping.

Then, we loop over the tree. Each time we call tree->GetEntry(i), the data in the tree is copied to rec.

  for(int i = 0; i< tree->GetEntries(); ++i)
    cout << rec->slc.nhit << endl;    

Rather than simply cout << ... you could have done fancier things, for instance, make calculations and fill histograms.