-- JuanCastillo - 30 Dec 2009

An easy to read, cut-and-copy collection of code shortcuts.

CONVENTIONS: The C++ or ROOT necessary headers are not displayed.
Just put the function in Google and you will know which library to include.
The errors are displayed in red (my professor did it in that way).

Basic links

You can refresh wink the basic pieces of the ROOT framework in this link

The ROOT course given at GSI you find here
If you want to be the best in ROOT, plot with style
Pieces of code to add latex, generate a ps, fit, gStyle options, etc Root Tips and Tricks
All the color codes, marker styles, line styles and so on in a useful screenshot at Home- ROOT

Working modes

ROOT prompt

The ROOT prompt you get after typing root if your installation is properly done big grin
It looks like:
This is the typical working mode if you want to do something fast, only once, like plotting a function or displaying the content of a file, but it is not nice if you develop a library, for example.


In this way, you call ROOT without log into it. And you save time.
$root -q .x MDvalidator.cxx++
is equivalent to:
root[0].x MDvalidator.cxx++
And you have your class compiled wink in only one step


From the root prompt or a shell, you can load an run a macro.
You can find examples in this link: Discovering ROOT: Working with macros

Stand alone program

For making a stand alone (SA) program, you need a makefile for your code.
If you don't know how to write it, there are several ways of finding it out big grin but I recommend you to begin with one of the simple examples you find elsewhere, for example here.

If you want to have a ROOT-based SA program, you need to link your code on the makefile with the ROOT libraries.

TH1D Problems

ALERT! NOTE: The tips for TH1D are valid for all the histos.

Recording in a file

Let's say you have a lot of histos, or simply you don't know how.
Declare a file, and force the histo to be recorded there:
Source:Root Forum

Copying it in memory

Let's call Original to the TH1D we want to copy.
In Clon at all the effects, we store the copy of Original writting this:
Clon = (TH1D*)Original->Clone("Clon");

Updating, renaming or deleting a TH1D in a file

Example: let's change the name of the histo h1 stored in the file myfile.root, and delete the original
You must open the file in a UPDATE mode:

ALERT! NOTE: each time you open the file in an UPDATE mode, the creation date will change.

  TFile *f = new TFile("myfile.root","UPDATE");
  TH1D  *hnew;   //pointer for a new TH1
  f->GetObject("h1;1",hnew); //pointer pointing to old histo
  hnew->SetName("NewName"); //new name of the old histo
  hnew->Write("NewName");  //write the new histo
  f->Delete("h1;1"); //delete the old histo

See the ROOT forum solution

Reusing a TH1D in memory

When an histogram is created, a reference to it is automatically added to the list of in-memory objects.
This is the reasong of the "Warning: replacing existing histogram" message.
Even if you have not defined a directory, you get rid of the message changing this default behaviour.
If you want to make it general, write:


If you want to do it only for one histo -a temp histo inside a function, for example-, write


just after your TH1 declaration. If you want to draw copys of the histo (because you are filling it in different ways) and you want to distinguish histo "p" from "p+1", you can try:


  • In this cases it's better to DrawCopy() of the histo, not Draw() .
  • To clean the bin content, to have like a "new" histogram, use Reset(). Don't try with Clear(), it's also a TH member function but it's not clearing the bins!

Rebinning a TH1D

Once you have the histo plotted, press right button, then choose DrawPanel and there go to Binning tab. Change the binning there, moving the slider.
Don't try right button, Rebin except if you know exactly which binning you're looking for.
If you Rebin to 2, for example, the original histo will be destroyed and the new one will have the half of bins. It's irreversible big grin

Example: Source ROOT talks

   TH1F *h1 = new TH1F("h1","h1",256,0,12.5);
   //do something with h1
   TH1F *hnew = (TH1F*)h1->Rebin(8,"hnew");  //hnew is h1 but each 8 bins merged in one

Another interesting example: function to rebin your histo safely

ALERT! NOTE: Since you can always "bin down", use a big binning in your annalysis.

Dealing wit a lot of TH1D: TClonesArray, TObjArray and TList

TClonesArray is used for "static" objects, that is, objects of the same size that are not modified.
So once you create it, you don't touch it! big grin
Example of something you can do:

TClonesArray CAHisto("TH1F",n);
  char hnameA[50];
  char htitleA[50];
  TH1F *ChA[n];
  for (int i=1 ; i< n ; i++){
    new(ChA[i]) TH1F(hnameA,htitleA,100,-4,4);

Now you have n different histos in a clonesarray that you can't use.
But if you create a... MC particle instead of an histo, it's fine.

ALERT! NOTE: You can CAHisto.Add(ChA[i]) above, but the code will complain, since it's a TObjArray feature

This is the right way of doing it:

 TObjArray OAHisto(n);
  char hnameA[50];
  char htitleA[50];
  for (int i=1 ; i< n ; i++){
    TH1F *ChA = new TH1F(hnameA,htitleA,100,-4,4); 

There is a third way: create a TList.
The advantage is that you can work with it like with an array, with the additional feature or "clean" removing and adding of elements.

  TList *LHisto = new TList();
  char hnameA[50];
  char htitleA[50];
  for (int i=1 ; i< n ; i++){
    TH1F *ChA = new TH1F(hnameA,htitleA,100,-4,4); 
  Int_t entries = LHisto->GetEntries();  
  cout << " number of TH1F stored: " << entries << endl;

ALERT! TIP: Decide where you want to create the object array. Original thread ROOT forum

Axis Formatting

Adding a Label

To eliminate one field, just don't write it or leave it empty.

    TH2D *T2 = new TH2D("Title",";xaxislabel;yaxislabel",binsx,xlow,xup,binsy,ylow,yup); 

Another way of changing the labels (from ROOT THistPainter Paint function) giving titles to the X, Y and Z axis:

    h->GetXaxis()->SetTitle("X axis title");
    h->GetYaxis()->SetTitle("Y axis title"); 

The histogram title and the axis titles can be any TLatex string.
The titles are part of the persistent histogram.

Scientific notation

The general axis object TGaxis is controlling this issue.
Try writting for example:
The default value is 5.
Now you will have 100000 instead of 1x10e6.

Axis in Time Format

This is tricky. You divide the axis onto time partitions (from your label to time) using TDatime objects.

   // Define the time offset
   TDatime T0(2005,10,13,10,27,00);
   int X0 = T0.Convert();
   // Define the lowest histogram limit
   TDatime T1(2005,10,12,10,27,00);
   int X1 = T1.Convert()-X0;
   // Define the highest histogram limit 
   TDatime T2(2005,10,19,15,10,00);
   int X2 = T2.Convert(1)-X0;

Now you need to set the axis onto time mode BEFORE drawing the histos.
For TH1 and TH2 (both with the time axis in X) you can do it like this:

   TH2D * h2 = new TH2D("h2","test",100,X1,X2,100,300,500);

In the case of a TGraph, it is enough with defining one TDatime as an offset, or an offset directly.
Being wmin and wmax two time values in seconds (from your time data), the time axis will be spread around the time offset value.
Set them with gStyle->SetTimeOffset() from TimeOffset+wmin to TimeOffset+wmax
Taken from ROOT documentation.
To solve the problem with the axis, you should use TAxis::SetNdivisions.
It's having 2 number "mixed" onto one (default 510). Try to change it (1010, 1005, etc) and see how the tics of your axis are changing. Also you should play with SetTimeFormat

Plotting in Polar Coordinates

Use the strange object TGraphPolar
To format the axis, you'll need also maybe TGraphPolargram

   TGraphPolar *grP1 = new TGraphPolar(size,theta,r);
   TGraphPolargram *gpgram = grP1->GetPolargram();

Axis Maximum on X and Y

The precision of that will depend on your binning. If you want to avoid using TSpectrum you can:

  1. Find the maximum bin. int maxbin = h->GetMaximumBin();
  2. Displays its content (Y maximum) .==double maxbincont = h->GetBinContent(maxbin);==
  3. Find its edge (X maximum). double maxbinXedge = h->GetBinLowEdge(maxbin);

Axis details

To retrieve axis limits and axis binning:

  Float_t xmin = fE->GetXaxis()->GetXmin();
  Float_t xmax = fE->GetXaxis()->GetXmax();
  Int_t xbin   = fE->GetNbinsX();


TCanvas, a canva for your plot

Prototype of TCanvas:
TCanvas *C3 = new TCanvas("C3Plots","My Plots L to R",200,10,900,450);
Sometimes it's nice to get rid of some things.
If you "compile", for making modifications on the global gROOT and gStyle pointers you need to:

     #include "TStyle.h"
     #include "TROOT.h"

If you're dealing with macros, I think it's not necessary big grin
So these are the settings for the ROOT global pointers controlling the aspect of your canvas:

     gROOT->SetStyle("Plain");   // the 'grey' background dissapears and it's chaged for a white one.
     gStyle->SetOptStat(000000); // the stat box dissapears 
     gStyle->SetOptFit(0000);   //the fit box dissapears completely

In this case, SetOptFit(pcev = 0000). In general:

  • p = 1; print Probability
  • c = 1; print Chisquare/Number of degress of freedom
  • e = 1; print errors (if e=1, v must be 1)
  • v = 1; print name/values of parameters

The same for the statistic box, SetOptStat(ourmen), being the default 001111,

  • o = overflow
  • u = underflow
  • r = rms
  • m = mean value
  • e = entries
  • n = name

TF1, the functions

Documentation: ROOT TF1 There are several different constructors.
A very fast how-to big grin

    • Define a gaussian. TF1 *mia    = new TF1("mia","gaus")
    • Define a polynom G.1 TF1 *rpol    = new TF1("rpol","pol1")
    • Give the 1st function parameter! function->GetParameter(1)
    • Paint it in blue! function->SetLineColor(kBlue) (or kRed, kGreen, etc)
    • This line is so thick ! function->SetLineWidth(1)
    • Fit only this peak! function->SetRange(up,down)
    • The fit does not work frown So, change its parameters! See below:

         function->SetParameter(1,value); // now parameter 1 = value
         function->SetParameters(a,b,c,d); //four first parameters to new values a, b, c, d 
         function->SetParameters(valarray); //set array "valarray" of parameters (up to 10 values) 

TH1, the histograms

Documentation: ROOT TH1
There is at least one constructor per histogram type
Different way of setting axis characteristics:


Usual (for me) drawing options ( see THistPainter::Paint for more details)
Usage: Put the option between quotes (in capitol letters or not) inside the parethesis of Draw().

  • "SAME" : Superimpose on previous picture in the same pad (for TH1D).
  • "SURF" : Draw a surface plot with hidden line removal (for TH2D).
  • "colz" : Cloud with density color bar to the right (for TH2D).
  • "E" : Draw error bars (only TH1D).
  • "L" : Draw a line througth the bin contents (including empty bins) (only TH1D).
  • "P" : Draw current marker at each bin except empty bins (only TH1D).
  • "LP" : Draw the current markers AND a line BUT including empty bins.
  • "P*" : Draw "star" marker at each bin except empty bins (only TH1D).
  • "AC*" : Draw "star" marker for each graph point connected with a "Curve" (TGraph).

TLegends, TPaveLabel and TPaveText, adding information to your plot

TLegends example

It draws a box over your pad/canva. Documentation: ROOT TLegend Prototype of TLegend:
TLegend *leg = new TLegend(0.4,0.6,0.89,0.89);

If we have defined one curve (fun1), one filled curve (fun3) and data from a graph(gr), the lines:

    leg = new TLegend(0.4,0.6,0.89,0.89);
    leg->AddEntry(fun1,"Theory 1","l");
    leg->AddEntry(fun3,"Theory 3","f");
    leg->AddEntry(gr,"The Data","p");

will draw a box in the current pad, identifying fun1, fun3 and gr. If one graph is defined and not plotted, it can appear also in the legend.

TPaveLabel example

   fCanva->cd(5);  //pad number
   string message;    //message
   char buffer[20]; //message buffer
   message += " R = ";
   double resol = fun->GetParameter(1); //one numerical value
   message += gcvt(resol,5,buffer);  //add the value as a string
   message += " %";
   TPaveLabel *fLabel   = new TPaveLabel(0.14,0.70,0.36,0.80,message.c_str(),"NDC");
   fLabel->Draw();  //This order!

TPaveText example

   fCanva->cd(5);  //pad number
   string msg;    //message
   char msgbuf[20]; //message buffer
   msg += "Slope = ";
   msg += gcvt(fit->GetParameter(1),5,msgbuf); //add fit parameter 1 as a character to msg
   TPaveText *fPave = new TPaveText(0.5,0.5,0.9,0.9,"NDC");
   fPave->AddText(msg.c_str());     //first line
   fPave->AddText("fit parameter");  //second line
   //equivalent to above code
   //TText *t1 = fPave->AddText(msg.c_str()); 
   //TText *t2 = fPave->AddText("fit parameter");

Formatting TPaveText and TPaveLabel

Once you have the plot, to remove the shadow on the borders and to eliminate the borders at all:
  • 1. Select the object. Right click on it, then left click.
  • 2. Go to SetFillAtributes
  • 3. Change Line and Fill menus to white.
To do the same from a command line:


ALERT! NOTE: the order is important. If you draw the pave before the histo, for example, the histo will appear OVER the pave.

File Handling

Recording objets in a file

Using a ROOT interactive session:

  • 1. Declare the object (it can be an empty pointer, pointing to a non-empty one). Plot it, add whatever you want. Ex:

root [] TH1D *p5_24 = HMdistP6[24]
root [] p5_24->Draw()

  • 2. Create a file for storing the objet and store it. Ex:

root [] TFile *s6 =new TFile("stack_P6.root","UPDATE")
root [] p5_24->Write()

Original source: ROOT how tow write objets to a file

Recovering objects from a ROOT file

Using a ROOT interactive session:

See this link: File Handling

root [] TFile *myfile=new TFile ('hsimple.root');
root [] myfile->ls()
TFile**         hsimple.root
 TFile*         hsimple.root
  KEY: TH1F     hpx;1   This is the px distribution
  KEY: TH2F     hpxpy;1 py vs px
root [] TH1F     *hpx   =(TH1F*)    myfile->Get("hpx");

Now you have TH1F !!! smile
The other way is, of course, use the TBrowser

Merging 2 ROOT files

Use the command hadd:

hadd filemerged.root file1.root file2.root

Some examples: Example 1 and Example 2

This is not working for TList, so, avoid then.

Trees and Branches

I hope you read before continuing the ROOT TTree documentation
This is a "quick guide, maybe it's not giving you what you expect.


TTree and TBranch instances for storing an object "Obj"

    Obj     *storageobj    = new Obj();
    TString Fileout;
    TFile   *outfile   = new TFile(Fileout,"RECREATE","Data from pack files");
    TTree   *storagetree   = new TTree("ObjTree","Obj data tree");
    TBranch *storagebranch = NULL;
    storagetree->SetAutoSave(1000000000);  // autosave when 1 Gbyte written
    int bufsize = 64000;
    storagebranch = storagetree->Branch("Obj","Obj",&storageobj,bufsize,2);

The object we want to store is a Obj named storageobj.
The file for storing must be called Fileout big grin

TTree and TBranch instances for reading an object "Obj"

    Obj     *readobj    = new Obj();
    TTree   *readtree   = new TTree("ObjTree","Obj data tree");
    TString  Filein;
    TFile   *readfile   = new TFile(Filein);
    TTree   *readtree   = (TTree*)readfile->Get("ObjTree");
    readtree->SetBranchAddress("Obj",&readobj); //pointing to in

This should work for reading the data tree we created above.
The file with the data must have a name Filein, of course.

ALERT! NOTE: The "brach address" MUST have the same name that in the file you created ("Obj" in our case), but the "tree" you MUST give another name.
If not, ROOT can complain giving you a * Break * segmentation violation*

Reading and Storing

Suppose we have 2 trees declared:
  • one for reading, intree, linked with an object inobj.
  • one for storing outtree, linked with an object outobj.
We will read 100 objects inobj (only big grin ) of intree, we take something private from them and we will store it in a public member of outobj.

   for (int j = 0; j < 100; j++){
       if (intree->GetEvent(j)<0){
            cout << "you're done, man  !" << endl;
       outobj->member = inobj->getsomething();
       outtree->Fill();  // fill the out tree with an "outobj"
  outtree->Print();       // print all the info about "outtree" once it is filled

Useful hints

Fitting with Predefined TF1

ALERT! NOTE: If you fit without the quiet (Q) option, the fitting parameters printed onto screen are beginning from ONE, while the stored parameters are beginning from ZERO.

Example: Gaussian. Once you fit, you want to recover the printed values. On the screen you see something like:

                     EDM=9.76255e-09    STRATEGY= 1      ERROR MATRIX ACCURATE
  EXT PARAMETER                                   STEP         FIRST
  NO.   NAME      VALUE            ERROR          SIZE      DERIVATIVE
   1  Constant     1.78750e+01   1.97072e+00   4.64448e-03  -1.11265e-05
   2  Mean         3.32415e+03   1.25239e+01   3.95934e-02  -1.10509e-05
   3  Sigma        1.39294e+02   1.22984e+01   5.76112e-05  -5.85423e-04

But if you try to recover the parameter NO.2, you will obtain "sigma", not "mean." :P
The proper way is :

      ...// some fit
      double mean  = gauss->GetParameter(1); // not 2
      double sigma = gauss->GetParameter(2); // not 3

Including ROOT user-defined TF1 in your class

For fitting with something different from a gaussian, for example.

  • First: Define your TF1 member.

In the header (*.h) write :

      class TF1;
      TF1 *pk;

  • Second: Define your TF1 function.

In the code (*.cpp) write (EX):

      Double_t g4(double* x, double* par) {
           double val  = 0.0;
           if(x[0] > par[1])
              val = par[0]*exp(4.0)* pow((x[0]-par[1])/par[2],4)*exp(-4.0*(x[0]-par[1])/par[2])+ par[3];
              val = 0;
           return val;
      pk =  new TF1("pk",g4, 0, 500, 4);

Executable generation under ROOT

Dictionary generation

ALERT! TIP:More information about CINT, the ROOT Dictionary generator here

ROOT needs a dictionary of your class if you want to work with it.
Otherwise you can obtain a GetActualClass segmentation violation
This line of code generates a dictionary MyDict.* for the class 'Class' :

rootcint -f MyDict.cpp -c Class.h LinkDef.h

ALERT! NOTE: MyDict.* files are removed if an error occurs. That is, if you had it you can loose it.

The file LinkDef is noting but a list of your classes in this way:

      #ifdef __CINT__

      #pragma link off all globals;
      #pragma link off all classes;
      #pragma link off all functions;
      #pragma link C++ class Class+;
      #pragma link C++ class OtherClass+;


You need to link ROOT libs if you want to use the ROOT stuff, like a TH1.
This is done in the line before the '-o' compilation flag of this line of code:
g++ 'root -config --cflags -glibs' -o myexecutable code.cpp classes.cpp dictionary.cpp

Run time ROOT errors or misbehaviors


Warning in <TClassTable::Add>: class TRootGuiFactory already in TClassTable

Non-fatal message when you have a problem while loading your ROOT eviroment variables. Check you didn't run the logon script unproperly, or something like this big grin Do you have more than one ROOT installed?

Warning: replacing existing histogram

See Array of Histos in this page and this thread of ROOT talk

TCanvas not plotted.

If you are expecting a TCanva with a TGraph or some THistos and it is not appearing, check:

  • That you are not running by default in a batch mode (see the corresponding section).
  • That you're including the corresponding files ( #include "TCanvas.h").
  • That you're defining in your main a TApplication object. Like this:

      #include "TApplication.h"
      int main(int argc, char **argv) {
        TApplication *myApp = new TApplication("myApp",&argc,argv);
        return 0;
      }// end of main

A simple check about that you can draw canvas is to draw an "empty canva".

TPad not accesible

A canva that you created, is already displayed but you want to modify the content of one of the pads.
  • Go to the canva, and find the name of the pad, right-clicking on it. Ex: your pad is called TPad::tres_2
  • Write: tres_2->cd() . Now you're in that pad! big grin

ALERT! TIP: To change the margins of the pads, you should use pad->SetTopMargin(topmargin).
See this Root Talk for more info about.

TGraph not plotted.

You are expecting a TCanva with a TGraph. The TCanva appears but without the TGraph. Don't loose your time to print the values big grin . Try:

  • To fill it in another way. Instead of in the constructor MyGraph = new TGraph(size,x,y) try after creating it.

    MyGraph = new TGraph(); 
    MyGraph->SetPoint(i,x[i],y[i]); //inside a loop 

  • To set another Draw option. The good one is MyGraph->DrawClone("AC*");

Histos not plotted

You are filling 3 TH and after that plotting them in a TCanva 2 of them are "simply" not appearing at all. Don't try ( it doesn't work! frown )

  • To change its positions on the canva (from up to down or so)
  • To change the range of the axis (smaller/bigger)
  • To print on the screen the values wich you're fillin it.

Try :

  • To fill the histogram in another way. For example, instead of using Fill(a,b), use SetBinContent(a,b)
  • To plot the histo with another function. (DrawClone(), DrawCopy() ...)

If you have the error message:

  Error in <TPad::Range>: illegal world coordinates range: (one point)
  Error in <TPad::RangeAxis>: illegal axis coordinates range: (your axis limits)

You have a problem with the definition of the axis ranges.
Try fixing these numbers directly while constructing the axis, or fix them in another place.
This is happening sometimes when you're defining something inside a function. Once the function finishes his duties, the variables are destroyed big grin

Loading Shared libraries

   myexecutable: error while loading shared libraries: 
   cannot open shared object file: No such file or directory

OK, this is a ROOT library. Just try to start root and try again.
But if the library is "external", you have 3 ways:

Load an user library in your system

In the prompt write
Check that the path is in that variable. If not, in the prompt write
>export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/of/my/lib/
Now it should run big grin

Load an user library in your code


I donno if it will work if you load it in your ROOT prompt and then rerun your program confused
It should work if you have a macro. ROOT is displaying after loading the next values:

  • 0 = library loaded sucessfully.
  • 1 = library loaded before this attempt (that is, your error is not there)
  • -1 = error or the library doesn't exist.

If you dont have the path of your library defined in LD_LIBARY_PATH (see above), you will not load it sucessfully (-1). Try writting the whole path inside Load.
In principle the gSystem is a general ROOT system pointer. If you add this line to your main.cpp or equivalent, ROOT will load it for you.

Load an user library with your makefile

In your makefile, you need to include somethin similar to:

EXT_DIR = /complete/path/
$(COMP) -o $@ $(COMP_FLAGS) $(ALL_INC) $^ $(ALL_LIB)

That is, a path to the library and the files to include, and link all while generating the executable.

Load an user header on your macro

root [0] .x Macro.C
Error: Symbol MyClass is not defined in current scope Macro.C:18:

Source: ROOT forum Headers of your class(es) need to be loaded onto ROOT
To make it work do:

root [] .include <path>/test/include

Or directly include the path onto your macro before it begins:

#include "<path>/test/include/MyClass.h"

Running in a batch mode

  • No histos are drawn, but you still use them. There are 2 ways:

  1. Setting ROOT to run "once" in a batch mode. Just add -b after your program/macro.
  2. Setting permanently the batch mode. Include these lines in your "main":

      #include "TROOT.h"   //for a batch mode
      gROOT->SetBatch(kTRUE);  //activate batch mode

GUI objects

  • TGLabel(a,b). a = frame, b = new TGString("message")
  • TGTextEntry(a,b). a = frame, b = new TGTextBuffer(39), b->AddText("message")

Topic attachments
I Attachment Action Size Date Who Comment
RClasses_2.pptppt RClasses_2.ppt manage 295.5 K 2007-02-23 - 15:44 JuanCastillo Cpp curse slides -commented
event_reconstruction.pngpng event_reconstruction.png manage 21.7 K 2007-02-23 - 14:57 JuanCastillo one event with the proper labels
Topic revision: r103 - 2010-03-09, JuanCastillo
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)