GSI ROOT Tutorial home page

Hands on session to use ROOT for First analysis.

I do assume here that you already want trough the ROOT basics tutorial.

The code for this tutorial can be retrieved via
svn co https://subversion.gsi.de/first/rec/trunk/macro/TutorialRoot 

Some basics instructions: making plots

A very basic and first use of ROOT is to display the reconstruction or analysis results. This can be done in two ways: by looking at PRE filled histograms or by creating histograms out of a tree.

Retrieving histograms from ROOT files

  • To display the content of a ROOT file use the command:
gDirectory->ls()
  • You can pick your favorite histogram and make a pointer to it grabbing it by its name:
TH1D* myh = ((TH1D*)gDirectory->Get("myhistoname"));
please CHECK that the object called "myhistoname" is actually a TH1D histo in order to get meaningful results.
  • Once you hold the pointer in your hands you can start the fun.
myh->SetTitle("");
myh->SetLineColor(2);
myh->SetTitleOffset(1.2);
myh->Draw("pe");
you can navigate the ROOT TH1D page in order to get an idea of what you can do to your pointer!
  • Superimposing plots is easy (just use histo->Draw("same")) BUT pay attention to when you want to Scale or alter a given histo and after that plot it... What you do to your pointer is actually propagated to the histo, so if you want to PRESERVE the first histo (the original one) you have to Clone the histogram into a new one.
TH1D *mynewh = myh->Clone("mynewh");

Exercise: take the myexample.C macro, run it and modify it in order to display the Momentum superposition instead of the Mass one.

Retrieving trees from ROOT files

DISCLAIMER . Most of you are now familiar with the "TBrowser" approach to root: open a file and then click it to death. This can be done IF you have a clear understanding of what you are clicking onto! ROOT is "so powerful" to allow us to store inside the tuples (trees) complex objects (like TAVTvertex(es)!) that are no longer "clickable". The same holds when you try to "access" the Tuple info using, for example, the MakeClass() method to build your "Loop" code. Int, Doubles, Bools and vectors can be handled. For the rest you have to pre-load proper dictionaries and libraries in order to allow ROOT to "understand" the stored data.
  • For the first use case (doubles/ints :)...) please proceed below.
  • For the second use case (how to access TAVTvertex stuff) jump to the paragraph below (devoted to analysis macros)

Once you have identified the tree name you want to access inside a file, you can get your hands on it, exactly as we did for the histos:
 TTree* mytree = ((TTree*)gDirectory->Get("tree"));
Then you can play with it either "interactively" trough the TBrowser interface (click click click) or trough a macro that Loop over all the events. ROOT has defined a method that will help you writing your first "data analysis macro": it is called MakeClass() and it is used as follows:
mytree->MakeClass("anatest")

Exercise: build the anatest.C and anatest.h files trough MakeClass on the tree "tree" of the file HlReco_carb_v41.root, and then alter the anatest.C file in order to book/fill an histo with the fToff and fTofr variables. the solution is find in sol_anatest.* files.

A more challenging example: writing an analysis macro

What is a macro and how to write it is explained elsewhere. Here we focus on the example related to FIRST macros. Before starting a general advice: you are encouraged, EVEN if you are using macros because you do not want the complication of an executable, to COMPILE it using ROOT itself! This is reducing the chances of BAD programming, "stupid" mistakes and is actually SPEEDING up significantly the macro run time.

How to compile a macro using root

  • If you have to compile the macro "myexample.C" here are some quick instructions on how to compile it within ROOT istelf and run it.
root
.L myexample.C++
myexample()
Please be aware than if you COMPILE it and you are not INTERPRETING the code anymore, you have to provide the include for ALL the root objects, otherwise you'll see a lot of error messages complaining about TSystem, TTree, TH1D, TCanvas that are not known!!!
/home/asarti/first/rec/trunk/hlreco/./myexample.C:3:3: error: ‘TFile’ was not declared in this scope
So please to fix that just add at the very beginning the proper include trough, for example
#include "TTree.h"
#include "TCanvas.h"
etc etc

Exercise : modify myexample.C in order to have it compiled trough ROOT!

A macro for First data analysis

  • First of all in order to access First stuff (TA* objects) you need to pre-load all the libraries and the includes. Beware ROOT is order sensitive: this means that in your "loadlibs.C" macro you have to specify the libraries in the correct order. A wrong example is given below:
{

  gSystem->Load("libEve.so");

gSystem->Load("$CTBREF/lib/libCTBbase.so");
gSystem->Load("$CTBREF/lib/libCTBmath.so");
gSystem->Load("$ASOFTREF/lib/libTAGbase.so");
gSystem->Load("$ASOFTREF/lib/libTAGmbs.so"); 
gSystem->Load("$ASOFTREF/lib/libTAGfirst.so"); 
gSystem->Load("$ASOFTREF/lib/libTAVTbase.so");
gSystem->Load("$ASOFTREF/lib/libTAIRbase.so");
gSystem->Load("$ASOFTREF/lib/libTABMbase.so");
gSystem->Load("$ASOFTREF/lib/libTATbase.so");
gSystem->Load("$ASOFTREF/lib/libTAKEbase.so");
gSystem->Load("$ASOFTREF/lib/libTAFadc.so");
gSystem->Load("$ASOFTREF/lib/libTAMbase.so");
 
gSystem->SetIncludePath(" -I$ASOFTREF/src/TAGbase"
         " -I$ASOFTREF/src/TAGmbs"
         " -I$ASOFTREF/src/TAGfirst"
         " -I$ASOFTREF/src/TAIRbase"
         " -I$ASOFTREF/src/TAVTbase"
         " -I$ASOFTREF/src/TABMbase"
         " -I$ASOFTREF/src/TATbase"
         " -I$ASOFTREF/src/TAKEbase"
         " -I$ASOFTREF/src/TAFadc"
         " -I$ASOFTREF/src/TAMbase");
}
The correct ordering is the following
{

  gSystem->Load("libEve.so");

gSystem->Load("$CTBREF/lib/libCTBbase.so");
gSystem->Load("$CTBREF/lib/libCTBmath.so");
gSystem->Load("$ASOFTREF/lib/libTAGbase.so");
gSystem->Load("$ASOFTREF/lib/libTAGmbs.so"); 
gSystem->Load("$ASOFTREF/lib/libTAVTbase.so");
gSystem->Load("$ASOFTREF/lib/libTAKEbase.so");
gSystem->Load("$ASOFTREF/lib/libTAIRbase.so");
gSystem->Load("$ASOFTREF/lib/libTAGfirst.so"); 
gSystem->Load("$ASOFTREF/lib/libTABMbase.so");
gSystem->Load("$ASOFTREF/lib/libTATbase.so");
gSystem->Load("$ASOFTREF/lib/libTAFadc.so");
gSystem->Load("$ASOFTREF/lib/libTAMbase.so");
 
gSystem->SetIncludePath(" -I$ASOFTREF/src/TAGbase"
         " -I$ASOFTREF/src/TAGmbs"
         " -I$ASOFTREF/src/TAGfirst"
         " -I$ASOFTREF/src/TAIRbase"
         " -I$ASOFTREF/src/TAVTbase"
         " -I$ASOFTREF/src/TABMbase"
         " -I$ASOFTREF/src/TATbase"
         " -I$ASOFTREF/src/TAKEbase"
         " -I$ASOFTREF/src/TAFadc"
         " -I$ASOFTREF/src/TAMbase");
}
otherwise you'll end up with several:
dlopen error: /u/asarti/first/rec/trunk/macro/startcounter/./../../libs//lib/libTAIRbase.so: undefined symbol: _ZN10TAKEparGeo18fgkDefaultModColOnE
Load Error: Failed to load Dynamic link library /u/asarti/first/rec/trunk/macro/startcounter/./../../libs//lib/libTAIRbase.so
  • Once you have setup ROOT, loaded the libraries, you can have some fun! To start you need to Load the file and setup the "looping" in the WM framework (that is a re-styled ROOT framework)
  TApplication::CreateApplication();

  //Here you specify the data you want to READ
  TAGdataDsc* myn_irraw   = new TAGdataDsc("myn_irraw", new TAIRdatRaw());
  TAGdataDsc* myn_trraw   = new TAGdataDsc("myn_trraw", new TATRdatRaw());

  TAGactTreeReader * myp_reader  = new TAGactTreeReader();

  myp_reader->SetupBranch(myn_irraw,  "irrd.");
  myp_reader->SetupBranch(myn_trraw,  "trrd.");

  tagr.AddRequiredItem(myn_irraw);
  //Then you open the file and start the loop
  myp_reader->Open("myfile.root");
  tagr.BeginEventLoop();
    
  while(tagr.NextEvent()) { 


  //Here you get your hands on the trigger data for each event
   TATRdatRaw* p_trraw  =
     (TATRdatRaw*) myn_trraw->GenerateObject();
   //    cout<<"New event  "<<endl;
   Int_t i_ntrhit = p_trraw->ntrhit;
   for (Int_t i = 0; i < i_ntrhit; i++) {
     const TATRrawHit* atrHi = p_trraw->Hit(i);
     for(int i=0; i<11; i++) {
       trType[i] = atrHi->Pattern() >> i & 0x1;
       //   cout<<trType[i];
     }
     //      cout<<endl;
   }
  }//Close the loop

Inside the loop you can do whatever you want (book histo, compute quantities, etc etc)
  • In order to run it you can load it and executing it directly in ROOT or you can try to compile it and run it as a standalone executable (see next exercise)

Exercise : modify loopexa.C in order to fill an histo with the mass info! Exercise II : modify loopexa.C in order to get the vertex and the attached tracks from the global track itself!

The final excercise: producing an executable

In order to produce reliable results you need to use reliable software.
  • macro are not the best tool to produce results. ROOT macro can be just fine if you want to re-style a plot, but if you need to compute numbers over large datasets I recommend to use COMPILED code (or at least compiled macros)
  • when compiling the code you get for free a lot of sanity checks and a considerable speedup.
Before we saw how to compile a macro and run it within root. Now we see how to compile an executable from a given code. We take as input the loopexa.C macro. How can we proceed if we want to compile it?
  • You have to modify the macro.. here I attach a modified version of loopexa.C
#include "TApplication.h"
#include "TString.h"
#include "TSystem.h"
#include "TCanvas.h"
#include "TROOT.h"

#include "TAGroot.hxx"
#include "TAGntuGlbTracks.hxx"
#include "TAGdataDsc.hxx"
#include "TAGactTreeReader.hxx"

int main (int argc, char *argv[]) {
  • Then you really need a makefile!!! Here's one:
ROOTCFLAGS    = $(shell $(ROOTSYS)/bin/root-config --cflags)
ROOTLIBS      = $(shell $(ROOTSYS)/bin/root-config --libs)
ROOTGLIBS     = $(shell $(ROOTSYS)/bin/root-config --glibs)
 
CXX           = g++

LD            = g++
LDFLAGS       = -g
SOFLAGS       = -shared

NGLIBB         = $(ROOTGLIBS) 
NGLIBB        += -lMinuit  -lGeom -lGeomPainter -lEve -lRGL -lGed -lEG -lTreePlayer
 
#TA* libs
NGLIBB        += ../../libs/lib/libTAGmbsApi.so 
NGLIBB        += ../../libs/lib/libTAGbase.so ../../libs/lib/libTAGmbs.so  
NGLIBB        += ../../libs/lib/libTATbase.so ../../libs/lib/libTAFadc.so
NGLIBB        += ../../libs/lib/libTAMbase.so ../../libs/lib/libTABMbase.so
NGLIBB        += ../../libs/lib/libTAVTbase.so ../../libs/lib/libTAKEbase.so
NGLIBB        += ../../libs/lib/libTAGfirst.so ../../libs/lib/libTAIRbase.so 
#CTB libs
#NGLIBB        += ../../libs/CTB/lib/libCTBbase.so ../../libs/CTB/lib/libCTBmath.so

NGLIBB        += ../../l0mcreco/libEvento.so 
NGLIBB        += ../../l0mcreco/libSegnale.so 
NGLIBB        += ../../l0mcreco/libGeometry.so 
NGLIBB        += ../../l0mcreco/libTrigger.so

GLIBB          = $(filter-out -lNew, $(NGLIBB))

TAINCL          = -I../../  -I../../libs/src/TAGmbsApi/ -I../../libs/src/TAGbase/ 
-I../../libs/src/TAFadc/ -I../../libs/src/TAGmbs/ -I../../libs/src/TAGprim/ 
-I../../libs/src/TAMbase/ -I../../libs/src/TATbase/ -I../../libs/src/TABMbase/ 
-I../../libs/src/TAVTbase/ -I../../libs/src/TAKEbase/  -I../../libs/src/TAGfirst/ 
 -I../../libs/src/TAIRbase/ -I../../../../../../sim/trunk

CXXFLAGS      = -g -Wall -fPIC
CXXFLAGS      += $(ROOTCFLAGS)
CXXFLAGS      += $(TAINCL)

LIBS           = $(ROOTLIBS) 

.SUFFIXES: .cc,.C

.cc.o:
   $(CXX) $(CXXFLAGS) -c $<

myexe:  loopexa_comp.o 
# -----------------------------------------------------------------------------
   $(LD) $(LDFLAGS) -o DoIt loopexa_comp.o $(GLIBB)


# ================================================================================
clean:
   rm -f *.o *Dict* DoIt

  • Remember to PRE configure ROOT and your env. variables (such as LD_LIBRARY_PATH) in order to have everything setup to compile and run. For this you have the myLogin.sh script (for bash)!
  • Then you compile and run
make myexe
./DoIt

-- AlessioSarti - 13 Dec 2012
Topic revision: r4 - 2012-12-14, AlessioSarti
 
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding GSI Wiki? Send feedback
Imprint (in German)
Privacy Policy (in German)