GAUDI User Guide

Chapter 9
Histogram facilities

9.1  Overview

The histogram data store is one of the data stores discussed in chapter 2 . Its purpose is to store statistics based data and user created objects that have a lifetime of more than a single event (e.g. histograms).

As with the other data stores, all access to data is via a service interface. In this case it is via the IHistogramSvc interface. This interface is derived from the IDataProviderSvc interface discussed in chapter 6 . Both interfaces IHistogram1D and IHistogram2D are derived from DataObject as they must be in order to be storable. Users can create their 1D or 2D histograms and register them in the histogram data store in the same type of tree structure as the event data.

9.2   Histograms.

The current usage style of histograms is very similar to the usage style of event data. Users have to create their histograms using the new statement, and may register them in the histogram data store using the function registerObject. An example of this is shown in the code fragment from the Histograms example, Listing 4 on See Example of creation of histograms .

Both 1D and 2D histograms are available. The parameters of the H1D constructor are the histogram name, title, and number, and number of bins, lower and upper limits. The H2D constuctor requires in addition the number of bins, lower and upper limits in the axis X. Please note that the histogram number must be unique and, in particular, that it must be different from any n-tuple number. This is a limitation imposed by the fact that Gaudi is currently using HBOOK for histogram and n-tuple persistency.

Two abstract interfaces IHistogram1D and IHistogram2D have been defined which are fully functional but not user friendly. This is a constraint imposed by the current implementation of histograms in LHC++, the so called Histogram Template Library (or HTL), which we use in Gaudi for the transient representation of histograms. In a future release we will adopt the histogram interfaces being defined for LHC++ group in the new AIDA project (Abstract Interfaces for Data Analysis, see http://wwwinfo.cern.ch/asd/lhc++/AIDA/index.html).

9.3  The Histogram service.

An instance of the histogram data service is created by the application manager. After the service has been initialised, the histogram data store will contain a root directory "/stat" in which users may store histograms and/or create sub-directories (for example, in the code fragment below, the histogram is stored in the subdirectory "/stat/simple").

The Algorithm base class defines a member function

 

 
IHistogramSvc* histogramDataService()

which returns a pointer to the IHistogramSvc interface of the standard histogram service (see section 5.2 ). Access to any other non-standard histogram service (if one exists) must be sought via the ISvcLocator interface of the application manager.

9.4  Using histograms and the histogram service.

An example code fragment illustrating how to register a 1D histogram and place it in a directory within the histogram data store, and a simple statement which fills that histogram is shown here:

 

 
// Registering in the histogram data store 
status = histogramDataService()-> 
           registerObject( "/stat/simple/"+m_hTrackCount->number(), 
                           m_hTrackCount ); 
 
SmartDataPtr<MCParticleVector> particles( eventDataService(), 
                                          EventModel::MC::Particles ) 
if (!particles) return 0; 
 
// Filling the track count histogram 
		m_hTrackCount->fill(particles->size(), 1.);

Note that the pointer returned by the call to the histogramDataService() method is guaranteed to be non-null. The algorithm would have failed the initialisation step if the histogram data service could not be found. On the contrary the variable particles may contain null (in case of absence of Monte Carlo particles), and the fill statement would fail - so the value of particles must be checked before using it.

Algorithms which create histograms will in general keep pointers to those histograms, which they may use for filling operations. However it may be that you wish to share histograms between different algorithms. Maybe one algorithm is responsible for filling the histogram and another algorithm is responsible for fitting it at the end of the job. In this case it may be necessary to look for histograms within the store. The mechanism for doing this is identical to the method for locating event data objects within the event data store, namely via the IDataProviderSvc interface.

 

 
	StatusCode sc; 
DataObject* obj; 
// Try and find the 1D histogram. 
sc = histogramDataService()->findObject( "/stat/simple/1", obj ); 
if ( sc.isSuccess() ) { 
  // Cast the base DataObject to a histogram 
  // An exception will be thrown if the cast is not good 
  try { 
    Histogram* h1d = dynamic_cast<Histogram*>( obj ); 
    log << MSG::INFO << "Found Histogram with title : " 
                     << h1d->getTitle() << endreq; 
  catch(...) { } 
}

9.5   Persistent storage of histograms.

A conversion service exists which can convert Histogram objects into a form suitable for storage in a standard HBOOK file. In order to be able to save the histograms to disk it is necessary to declare the name of the output file in the job options:

 
HistogramPersistencySvc.OutputFile  = "histo.hbook";

At the end of the job all the histograms in the transient histogram store will be written into this file.

On NT, you also need to declare in the job options file the DLL containing the HBOOK conversion service:

ApplicationMgr.DLLs = { "S:\LHCb\LHCBSoft\SicbCnv\v6\Win32Debug\SicbCnvshr"}

On Unix, where we don't yet use shareable libraries, you need to add the following lines in the main program (see details in Listing 1 on See The example main program. ).

extern void HbookCnv_load();

....

int main(int argc, char* argv) {

  HbookCnv_load();

....

}