next up previous
Next: 6. Calibration objects Up: No Title Previous: 4. The emcCalibrator

   
5. The emcDataManager, the plugins and ... the databases

The calibrator, as described in section 4, needs to access some calibration data. Apart from the time-zero calibrations which are only available on file so far and are accessed via the Static package, all other calibration data are accessed through the DataManager.

The DataManager was developped during a period when we did not know yet exactly what the calibration data will be. In the same time we wanted to be able to access the available ones and not to be obliged to re-code everything when new ones come into the game. Thus we defined a unique interface to access calibration data, and this interface is reflected by the emcDataManager class.

The DataManager can only handle objects which are of a subclass of a emcManageable class. It's the object by itself who instructs the DataManager where to fetch/put it. The DataManager is in fact doing nothing by itself, but delegates actual work to some Object Managers or Plugins which know how to read/write calibration data from/to database (figure 4). Using some trick in the code of the plugins, those are automatically known by the DataManager as soon as you load the library(ies) containing them (trick originally found in pdbcal code[Mes]).


  
Figure 4: emcDataManager and related classes

The DataManager is a singleton, and its interface basically consists in 3 methods : Read, Write and Collect. Before explaining those, we must first explain how data are stored in the databases.

As stated in section 4, the EMCAL calibrator needs calibration data about Gains, Pedestals, HLRatios, and Tofs (Least-Count and Walk). We hereby call those different ones ``calibration flavours''. Each flavour is sitting in a different database, sitting in the very same Objectivity Federation. Each database consists in calibration banks, storing information about 1 FEM (144 channels). Each calibration bank has a header, which is sitting itself in a different database (the Tag one). This header contains a bank identifier, a validity period (2 PHTimeStamps) and an insertion time (1 PHTimeStamp). The bank themselves are vectors of calibration items (there might be one item or several items per channel, e.g. for Gains). Those items are objects of classes named PdbEmcXXX, indicating that they are PdbCal classes[Mes]. Table 1 indicates the relationship between calibration flavours, database names and PdbCal low-level class names. Those are given for the sake of completeness, but please note that, as a normal user, you are not supposed to deal directly with those classes.


 
Table 1: Databases and PdbCal names for each EMCAL calibration flavour
Flavour DB PdbCal class
Gains calib.emc.GainsCal PdbEmcTracedValue
  calib.emc.GainsTag PdbCalHeader
Pedestals calib.emc.PedestalsCal PdbEmcPedestal
  calib.emc.PedestalsTag PdbCalHeader
HLRatios calib.emc.HLRatiosCal PdbEmcHLRatioVector
  calib.emc.HLRatiosTag PdbCalHeader
LCTofs calib.emc.LCTofsCal PdbEmcLCTof
  calib.emc.LCTofsTag PdbCalHeader
WalkTofs calib.emc.WalkTofsCal PdbEmcWalkTof
  calib.emc.WalkTofsTag PdbCalHeader
 

We now return to the DataManager interface. The emcDataManager::Read method is used to fetch an object spanning one FEM (144 channels usually) only, i.e. one bank. The Write method can be given an object spanning any number of FEMs, the underlying plugin will take care of splitting it into the relevant number of FEMs (banks). The Collect method is used to recover an object spanning those FEMs which are described in the configuration file. For example, if you would like to recover calibration data about gains for all the FEMs described in configuration file FEM.conf, for date 27-Jun-2000 00:00:00, try this :

 1 int status ;
 2 char* config = ``FEM.conf'' ;
 3 emcRawDataAccessor* rda = emcRawDataAccessor::GetInstance(status,config) ;
 4 PHTimeStamp when(2000,6,27,0,0,0) ;

 5 emcDataManager* dm = emcDataManager::GetInstance() ;
 6 emcGains gainDriver ;
 7 emcGains* gains ;

 8 gain_driver.SetSource(emcManageable::kDB_Objy) ;
 9 gains = dynamic_cast<emcGains*>(dm->Collect(gainDriver,when)) ;
10 if (gains) { //play with it... }

The 4 first lines are described in section 3. The RDA is initialized here not for real data access, but just for reading the configuration file, which is needed for the Collect.

In line 5 we get an instance of the DataManager.

Then we create in line 6 an emcGains object (for more details on this class, see section 6) and in line 7 a pointer to an emcGains. The need to create 2 such objects might seems strange to you (after all, you just want one object with all the information, right ?). In fact, this design decision has to do with performance and responsability. Thanks to the gainDriver object, the DataManager will be able to locate the relevant plugin that can handle this object, and will be able to know where to fetch him (line 8). This gainDriver is only used as a type (i.e. you don't need to fill it or whatever). The Collect method will return you a pointer to the full object you wanted. Doing this that way, it's the plugin responsability to actually access the DB if (and only if, thus saving some time in many cases) needed. You are not the owner of the returned pointer, thus you don't care about memory management for this object.

Line 9 does the actual job of returning you the object you wanted. In case you are not familiar with the dynamic_cast, it is the new C++ way of casting things. You might be familiar with this syntax :

gains = (emcGains*)(dm->Collect(gainDriver,when)) ;

The dynamic_cast has the advantage to dynamically (i.e. at runtime) check that the cast you request is a valid one (otherwise it returns null), thus it is safer.

There are in fact some other methods of the DataManager you may be aware of :


next up previous
Next: 6. Calibration objects Up: No Title Previous: 4. The emcCalibrator
Laurent APHECETCHE - 2000-07-28