User data - so called n-tuples - are very similar to event data. Of course, the scope may be different: a row of an n-tuple may correspond to a track, an event or complete runs. Nevertheless, user data must be accessible by interactive tools such as PAW or Root.
Gaudi n-tuples allow to freely format structures. Later during the running phase of the program data are accumulated and written to disk.
The transient image of an n-tuple is stored in a Gaudi data store which is connected to the n-tuple service. Its purpose is to store user created objects that have a lifetime of more than a single event.
As with the other data stores, all access to data is via a service interface. In this case it is via the INTupleSvc interface which extends the IDataProviderSvc interface. In addition the interface to the n-tuple service provides methods for creating n-tuples, saving the current row of an n-tuple or retrieving n-tuples from a file. The n-tuples are derived from DataObject in order to be storable, and are stored in the same type of tree structure as the event data. This inheritance allows to load and locate n-tuples on the store with the same smart pointer mechanism as is availible for event data items (c.f. Chapter 6 ).
The Algorithm base class defines a member function
INTupleSvc* ntupleService() |
which returns a pointer to the INTupleSvc interface.
The n-tuple service provides methods for the creation and manipulation of n-tuples and the location of n-tuples within the database. The database reflects the tree structure of the n-tuple data store. Please refer to the online documentation for a description of this interface.
The top level directory of the n-tuple data store is called "/NTUPLES". The next directory layer is connected to the different output streams: e.g. "/NTuples/FILE1", where FILE1 is the logical name of the requested output file for a given stream. There can be several output streams connected to the service. In case of Persistency using HBOOK "FILE1" corresponds to the top level RZ Directory of the file (...the name given to HROPEN). From then on the tree structure is reflected with normal RZ directories.
When defining an n-tuple the following steps must be performed:
In the following an attempt is made to explain the different steps. Please note that the n-tuple number must be unique and, in particular, that it must be different from any histogram number. This is a limitation imposed by the fact that Gaudi is currently using HBOOK for histogram and n-tuple persistency.
When creating an n-tuple it is necessary to first define the tags to be filled in the n-tuple. Typically the tags belong to the filling algorithm and hence should be provided in the Algorithm's header file. Currently the following data types are supported: bool, long, float and double. double types (Fortran REAL*8) need special attention: the n-tuple structure must be defined in a way that aligns double types to 8 byte boundaries. In addition PAW cannot understand double types. The code fragment below illustrates how to define n-tuple items:
When booking the n-tuple, the previously defined tags must be declared to the the n-tuple. Before booking, the proper output stream (file) must be accessed and the target directory defined.
Tags which are not declared to the n-tuple are invalid and will cause an access violation at run-time. Later these tags can be used like ordinary numbers, arrays or matrices. However, there is one caveat: double numbers must be 8-byte aligned, otherwise HBOOK complains.
The tags should be usable just like normal data items, where
There is no implicit bounds checking possible without a rather big overhead at run-time. Hence it is up to the user to ensure the arrays do not overflow.
When all entries are filled, the row must be committed, ie. the record of the n-tuple must be written.
A conversion service exists which can convert NTuple objects into a form suitable for storage in a standard HBOOK file. In order to use this facility it is necessary to add the following line in the job options file:
NTupleSvc.Output = { "FILE1#<tuples.hbook>" }; // Perstency type of the N tuple service: 6=HBOOK NTupleSvc.Type = 6; |
where <tuples.hbook> should be replaced by the name of the file to which you wish to write the n-tuple. FILE1 one is the logical name of the output file - it could be any other string (Caveat: HBOOK only accepts directory names with less than 8 characters!).
The handling of row wise n-tuples does not differ. However, only individual items (class NTuple::Item) can be filled, no arrays and no matrices. Since the persistent representation of row wise n-tuples is done by floats only, the first row of each row wise n-tuple contains the type information - when looking at a row wise n-tuple with PAW make sure to start at the second event!