Class Design
The class design for I/O was developed according to the following requirements:
- Provide interfaces to Oracle, ROOT files and ASCII files
- To avoid dependencies, each detector has its own classes implementing the concrete read and write functions
- The actually used I/O is specified in the macro.
- The interface to Oracle is a shared library completely separated from the other analysis. (To compile this libraries one needs the Oracle client.)
The base class
HParIo defines the virtual functions each type of I/O must implement, for example to close the I/O or to check, if is the I/O is open.
The derived classes implement the open function (different arguments for the different types). This class is instantiated in the macro and then set as input or output in the runtime database.
It inherits from the base class the data member detParIoList. This list contains the detector I/O classes (with the read and write functions). When the I/O is opened, these detector I/Os are automatically created for all detectors in the actual setup.
This is the reason, why the detectors must be created in the macro before an I/O is opened.
The interface for parameter containers in the base library and for condition style parameter containers are always created for
HParOraIo,
HParRootFileIo and
HParAsciiFileIo, even if no detector is created in the macro (for example
HSpecParOraIo,
HCondParOraIo).
Each detector I/O has a name, which is identical for each source type, for example
HCondParIo. This name is used in the init function for a parameter container to find the corresponding detector I/O. The init function does not know, which type of I/O is actually used.
To minimize the code in the specific detector I/O classes, common functionality and utility functions are implemented in the base classes
HDetParOraIo,
HDetParRootFileIo,
HDetParAsciiFileIo,
HDetParHadAsciiFileIo.
The Oracle interface HParOraIo
All interfaces are implemented in the shared library ora. To compile this library, you need the Oracle client. The code used the Oracle precompiler ProC/C++.
The interface allows to read actual and historic data for all parameter containers and to write parameter containers to Oracle.
For a detailed description and the version management see
The Oracle analysis interface. Shown here are only typical examples to be used in macros.
The following lines open a connection for the default analysis user HADES_ANA (only privilege to read data) and sets it as first input in the runtime database.
HParOraIo* ora=new HParOraIo;
ora->open();
rtdb->setFirstInput(ora);
When the function initContainers() in the runtime database will be called with a certain run id (or reference run id), the parameter containers will be initialized with the data valid for the last parameter release for the corresponding beam time (or simulation project). If no parameter release exist yet, the actual valid data for this run will be read.
You may force to read the data valid for this run at a certain point in time by setting the
history date.
To read always the last version of the data:
ora->setHistoryDate("now");
To read the data valid in the past (the default for the time is 00:00:00):
ora->setHistoryDate(01-JAN-2007 12:00:00");
To read the data of a certain parameter release (here parameter release for DST production AUG04 generation 2):
ora->setHistoryDate(AUG04_v5 ");
The read of historic data might fail for some parameter containers derived from
HParCond, if the data are stored in Oracle in binary format and the code changed meanwhile without a properly implementation of the custom streamer. In this case one has to use old code to read the data.
If you want to store data in Oracle you must connect as a user which has the privilege for this parameter container.
It prompts for the password.
HParOraIo* ora=new HParOraIo;
Bool_t rc=ora->open("wall_oper");
if (rc) {
rtdb->setOutput(ora);
...
}
Some utility functions in HOraInfo (data member of HParOraIo):
If you only know the hld filename you may get the corresponding run id:
Int_t runId = ora->getOraInfo()->getRunId(be07141081019.hld );
To get the filename for a run id:
TString filename;
Bool_t found = ora->getOraInfo()->getDaqFilename(1347612441,filename);
To get the run id for the last run in a specified bamtime (useful for testing):
Int_t runId = ora->getOraInfo()->getLastRun(APR07);
To get a list of runs for a specified beam time (mandatory) and time range (optional):
TString* listOfRuns = ora->getOraInfo()->getListOfRuns(APR07,
13-APR-2007 ,13-APR-2007 23:59:59 );
This list contains objects of type
HRunInfo with data elements filename, run id, run start, run stop, number of events.
In the ROOT file parameter containers are stored as objects. The file can hold different versions of the same object (the variable fCycle in TKey).
Every time an object is written it gets automatically a new version incrementing the former version by 1, starting with 1 in each newly created file. The information which run corresponds to which version of each parameter container is stored in the ROOT file together with the data.
By default the Read() or Find() functions provided by ROOT read the object with the highest version. A retrieval of another version is possible by adding ";version number" to the name of the parameter container. When initializing from a parameter ROOT file, the first step is to get the version for this run from the version table and then to read this version.
If the run id is not found in the ROOT file, the parameter containers cannot be initialized for this run. But you may use an other run in the file as a reference run.
To write to a ROOT file, put in the macro (standard ROOT file options RECREATE, NEW, ...):
HParRootFileIo* output=new HParRootFileIo;
output->open("wallParams.root","RECREATE");
rtdb->setOutput(output);
To read from a ROOT file (the default option is READ):
HParRootFileIo* input=new HParRootFileIo;
input->open("wallParams.root");
rtdb->setFirstInput(input);
The ASCII interface does not implement a version management.
The reading starts always at be beginnig of the file. It read the first data it finds for the parameter container. A second version also in the file would never be read.
The structure in the parameter file is always the same:
- The name of the parameter container in [] brackets
- The data (different formats)
- At the end a line starting with a #
Any comment lines starting with // or # (not in the data block!) are ignored.
To write to a ASCII file, put in the macro:
HParAsciiFileIo* output=new HParAsciiFileIo;
output->open("wallParams.txt","out");
rtdb->setOutput(output);
To read from an ASCII file:
HParAsciiFileIo* input=new HParAsciiFileIo;
input->open("wallParams.txt");
rtdb->setFirstInput(input);
This interface is only used for RICH, SHOWER and TOFINO parameter containers.
See
hadascii documentation by W. Przygoda.
--
IlseKoenig - 25 Jun 2007