RootFAQ
Introduction
Most of your questions about ROOT can be answered using the documentation found at the ROOT website. This FAQ answers a few specfic questions that come up often and for which the answers are hard to find on the ROOT web site.
Porting root v5 scripts to root v6
TFile, TDirectory and the ROOT Current Working Directory
When one opens a ROOT file that holds, or will hold, histograms, ntuples etc, that file is seen inside the program as a TFile object. Inside an executing program, there may be zero, one or many TFiles open at any given time. Inside each of these TFiles there may be a hierarchy of many directories; each directory is represented inside ROOT as a TDirectory object. In addition there may be TDirectory objects that are only inside the memory of an executing program and are not associated with any disk file.
At any given time ROOT has the concept of the current working directory; this is available to the user as the global variable gDirectory, from the header TDirectory.h. When the user codes
TH1F* hist = new TH1F( "hist", "Title", nx, xlow, xhigh);
the following actions are implied:
- Upon instantiation, the object hist is appended to the list of objects inside the current working directory.
- If the current working directory is associated with a TFile, then, when the TFile is closed, a snapshot of hist at close-time will be written to the TFile.
This behaviour happens for objects of type TH* and TTree; the latter includes objects of type TNtuple. To be a little more specific, objects of type TTree are periodically written to the output file as their internal memory buffers fill; at close-time the buffers are flushed.
Objects of other types are not automatically written to the output file; for many other types, the user may take additional steps to cause selected objects to be written to the output file, see below.
Why is my TCanvas, TGraph etc not written to the ROOT output file?
While ROOT automatically writes histograms, ntuples and trees to output files, it does not do so for objects of other types, in particular for objects of type TGraph, TCanvas and TText. This FAQ item describes how to write these items to a ROOT output file; it presumes that the reader is already familiar with the FAQ item about TFile, TDirectory and the ROOT current working directory . This FAQ item discusses two methods:
Method 1: Using TDirectory::Append
One may add an object to the current working directory using Append(). For example,
TGraph* graph = new TGraph(); graph->SetName("myGraph"); graph->SetTitle("My Graph"); gDirectory->Append(graph); // ... code to fill the graph
In this example the unnamed, untitled object graph is given a name and a title and is added to the current working directory. If the current working directory is associated with a TFile, then, when the TFile is closed, a snapshot of graph will be written to the file. The call to Append may be made at any time after the object is created and before the TFile is closed ( of course gDirectory might change frequently during that time). Alternatively, one might have added graph to any other TDirectory by getting a pointer to that TDirectory and calling its Append method.
I am not sure what happens if the call to SetName is skipped; I think that the object appears in the output file with
a name automatically generated by ROOT. The call to SetTitle is optional.
Bug Report, Septemeber 2010:
This method does not work when one creates a TCanvas inside a framework job. For reasons that are not yet understood,
one must use the second method. We suspect that both the framework and the root are trying to delete the objects
that are posted to the TCanvas.
Method 2: Using TObject::Write
TGraph* graph = new TGraph(); graph->SetName("myGraph"); graph->SetTitle("My Graph"); // ... code to fill the graph graph->Write();
In this example, a snapshot of graph will be written to the directory that is current at the time of the call to Write(); so, normally, one would call Write in the endJob method. One may make multiple calls to Write throughout a job; each call will write a snapshot to the directory that is current at the time of the call; if there is already an object named "myGraph" in that directory, then ROOT will automatically generate a new name and both objects will be present in the directory; the automatic name is generated by by appending ";1" to the original name of the object; and so on, for versions ";2", ";3" etc ).
Bug Report, September 2010: The framework TFileSerivce creates a TDirectory with a unique name for each module in a framework job. It also does a cd to the correct TDirectory before calling most methods of each module. The exception is that it fails to do the cd for the endJob method. This will be fixed in a new release of the TFileService. One can work around this by saving the value of gDirectory in beginJob and doing a cd() to it during endJob.
Showing Full Histogram Statistics
We strongly recommend that when you make a histogram to show at a group meeting or in an internal report, that you tell root to show the underflows and overflows in the statistics box. While there will be reasonable exceptions to this, we strongly encourage it as the default practice.
To enable this behaviour by default, you can add a line like one of the following lines to your root script or to your .rootrc file.
gStyle->SetOptStat("emruoi"); // Pick one or the other. gStyle->SetOptStat(1111110);
Both of these lines tell root to do the same thing; the first uses mnemonic letters while the second uses the paw style bit map. In both cases the statistics box will contain the number of entries in the histogram (including underflows and overflow), the mean value, the rms, the number of underflows, the number of overflows and the sum of all entries inside the histogram limits. For a full description of the available options to SetOptStat, see the root documentation for the class TStyle and search for SetOptStat.