The runtime database

see class HRuntimeDb

Schematic overview

Rtdb

Features

The parameters are stored in parameter containers (see Parameter containers)
The runtime database (Rtdb) allows to create all parameter containers via the container factories (see HadesRtdbContainerFactoriesIlseKoenig).
Once a parameter container is created, it is added in the list of parameter containers and accessible in Hydra by all tasks, which need these parameters.
The Rtdb allows to specify one or two input sources and takes care, that the parameters are initialized at the beginning of each run with the appropriate version (see Parameter I/O).
The user may specify an output and the Rtdb takes care, that the data are automatically written to this output before the parameter container is initialized again or before it is deleted.
For each run it stores for each parameter container the input and output versions. This run catalog is, together with the detector setups, written to the ROOT file output to be used as a local database for initialization (see Parameter I/O). For Oracle as input it allows to create a parameter ROOT file for all run of a specifies beam time and time range (see Parameter file generator).

Flow chart for initialization

Rtdb flow chart

The building blocks for parameter initialization and output

Loading the HYDRA libraries

When the shared libraries are loaded in ROOT, the container factories are created and added to the list of container factories in the runtime database.

Create Hades

In the HADES constructor the Rtdb is instantiated and an objects of HSpectrometer is created.
  Hades* myHades=new Hades;
  HSpectrometer* spec=gHades->getSetup();
  HRuntimeDb* rtdb=gHades->getRuntimeDb();

Create detectors

In the analysis you must create all detectors and their appropriate setup you want to analyse.
In a simple initialization macros this is only not necessary if the parameter containers is derived from HParCond (condition style parameter container) and calls the base class interface HCondParIo in its init and write function (which is unfortunately not always the case).

Each detector has its own class (HMdcDetector, HWallDetector, ...). They are all derived from a common base class HDetector. Each detector consists of one or more modules placed in the different sectors or directly in the Cave.

The code snippets below create the Forward Wall detector (with sector = -1, because is sits in the cave) and a MDC detector with the setup for beamtime AUG04 (0 = module is absent, 1 = module in setup) and adds them to the list off detectors in the HSpectrometer object.
  HWallDetector* wall=new HWallDetector;
  Int_t wallMods[]={1};
  wall->setModules(-1,wallMods);
  spec->addDetector(wall);

  HMdcDetector* mdc=new HMdcDetector;
  Int_t mdcMods[6][4]={ {1,1,1,1},
                        {1,1,1,1},
                        {1,1,1,0},
                        {1,1,1,1},
                        {1,1,1,1},
                        {1,1,1,0} };
  for(Int_t i=0;i<6;i++) { mdc->setModules(i,mdcMods[i]); }
  spec->addDetector(mdc);

Create input and output for parameters

Here you create the data sources for the parameters and set it as first or second input in the Rtdb.
Additionally you may specify an output.
Possible I/O types are Oracle, ROOT files, ASCII files.

Typically you use two inputs
  • if you want to merge the data from two input sources into one ROOT file
  • you have some parameters in a file (set this as first input) not yet stored in Oracle, but the rest you want to read from Oracle (set as second input)

There is a simple rule:
If a parameter container can be initialized from the first input, the second input is never used for this container.

For a more detailed description of the parameter I/O classes and features see Parameter I/O.
Here only a small example, which read the data from Oracle and writes them to a ROOT file:
  HParOraIo* ora=new HParOraIo;
  ora->open();
  rtdb->setFirstInput(ora);

  HParRootFileIo* output=new HParRootFileIo;
  output->open("params.root","RECREATE");
  rtdb->setOutput(output);

Create parameter containers

Typically a parameter container is created via the parameter container factories.
If one wants to use a non-default context for a parameter container, one should set this before the parameter container is created.
  Bool_t HRuntimeDb::addParamContext(const char context)
Then one creates the containers.
  HParSet* HRuntimeDb::getContainer(Text_t containerName);
The function returns the base class type and it must be casted to the concrete type to use the functions not available in the base class, for example:
  HWallRefWinPar* pPar=(HWallRefWinPar*)(rtdb->getContainer("WallRefWinPar"));
You may also create the parameter container via the constructor, but then you must also add it to the Rtdb to be later automatically initialized.
  HWallRefWinPar* pPar=new HWallRefWinPar();
  rtdb->addContainer(pPar);
In the analysis the parameter containers are created typically in the init functions of the tasks (called in Hades:init())
A few of them are also initialized, for example parameter containers needed to create other parameter containers or to create the data structure for the unpackers. But these are exceptions. Typically the data are the default values.
See also: Parameter container factories, Parameter containers

Initialize parameter containers

All parameter containers can be initialized with the function call
  Bool_t HRuntimeDb::initContainers(Int_t runId, Int_t refId, const Text_t fileName)
with the arguments
runId Number in the event header uniquely defining the hld file or simulation run
refId Reference run id (default value: -1). If not -1, all parameter containers are initialized with the versions valid for this run
fileName name of current file (default NULL)
This function is automatically called in the Hades event loop for the first event of each file.
In a macro it is called explicitly (eventually several times with different run ids).

In the analysis, the reference run id is set in the data source for events and always necessary, if data are not available for the file to be analyzed.
The best example for such a case are simulation runs, where each file has an individual run id in the event header, but Oracle does not know these runs, because they were never stored in Oracle (although actually still possible).
See Simulation projects for more details.

Delete HADES

Before you delete Hades and with it the Rtdb, you may want to see the content in the Rtdb (in principle you can do this everywhere in the macro, even multiple times)
  rtdb->saveOutput();
  rtdb->print();
The function saveOutput() loops over all parameter containers and writes them to the output if not yet done.
For a ROOT file as output, also the detector setups and the version table is written to the file.

The print function lists the parameter containers, the version table and information of input(s) and output. (see Example macros)
ALERT! If you call this function without calling before saveOutput, the version table might be misleading, because the input and output versions are stored in the version table when the write function is called and this might not yet been done for the current run.

Initialization in an analysis macro

ALERT! In the following only the parts relevant for initialization are described.

You create in the macro the detectors, the parameter input(s) and eventually a parameter output.

Then you define the data source(s) and add one or more files, eventually with a reference run (specified by filename) or a reference run id. The data source opens the first file and reads the run id in the header. If a reference run is defined by filename, it opens also this file and reads the run id.
For HLD files you also add the unpackers in the HLD source.

Then you define the tasks respectively task sets.

The parameter containers are created when Hades::init() is called:
  • Initializes all containeres already created.
  • Calls the init function of all detectors
    For the MDC the parameter containers HMdcRawStruct and MdcGeomStruct are created and initialized (needed to build other parameter containers and the data structures).
  • Calls the init functions of the data sources
    • The init function of an HLD source calls the init function of all unpackers, where the lookup tables are created.
  • Calls the init function of all tasks. Here all other parameter containers are created.

At this point all parameter container are in the runtime database, but besides a few exceptions, not yet initialized. This is done in the Hades event loop:
  1. Before analyzing the first event of a file all containers are initialized.
  2. The connection to Oracle is closed.
  3. The re-init of all tasks is called.
    Some tasks calculate private data from the parameter containers and use them in the execute function.
If several files are analyzed in a chain (or for a ROOT file as input generated from several input files) step 1 - 3 is repeated. The connection to Oracle is automatically re-opened and closed again after initialization.

TIP If you want to change a parameter in a parameter container on-the-fly in the macro without creating before a parameter file do this directly before the Hades event loop:
  • Get the pointer to the parameter container using the function
    HParSet* HRuntimeDB::findContainer(Text_t* containerName).
    It returns the pointer to an existing container (constructor not called).
  • Initialze the parameter container (call its init() function)
  • Change the parameter(s).
  • Set the parameter container static to avoid a re-initialization
    (call its function setStatic(Boot_t flag=kTRUE).

Example macros

-- IlseKoenig - 24 Jun 2007
Topic revision: r5 - 2007-07-01, IlseKoenig
Copyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Foswiki Send feedback | Imprint | Privacy Policy (in German)