next up previous contents
Next: Data Model and I/O Up: The MINOS Off-line Software Previous: Raw Data and Rotorooter   Contents



First version 07/2004 Nathaniel Tagg. This version describes the 'new calibrator' framework put forward to replace the older DigitCalibrator/StripCalibrator classes and their attendant machinery.


The Calibrator's purpose it to provide a framework for calibrating raw data. Generation of calibration constants is NOT part of it's use, although the database row classes used by the constants generators are defined in the Calibrator package.

A secondary use of the Calibrator is to provide decalibration constants for the detector simulation Monte-Carlo. Often the needs of the MC are slightly different, but in principle every calibration step should have a decalibration partner that can be used.


The Calibrator object is a singleton object that is used to handle all calibration calls. All calls for calibration are made to this object, and this object is the gateway for configuration and context changing.

The Calibrator holds pointers to ``sub-calibrator'' objects that do the actual work. The ``sub-calibrators'' all inherit from CalScheme, which holds prototypes for all the available calls. These sub-calibrators are responsible for holding any database tables, constants, and decision-making about the calibration steps.

The database tables held by the sub-calibrators will typically be DbiResultPtr<> objects, which hold rows of data. Each row typically corresponds to a channel (a strip end, a pixel spot, or a raw channel ID) and is a descendent of DbiTableRow. (For more information, please see the chapter on DatabaseInterface.) The row objects hold a few words of information each, and typically are little mini-calibrators.

The calibrator is invoked by several other pieces of the reconstruction framework. The time, photoelectron, drift, linearization, and strip-to-strip corrections are all done by AlgDigit, which use the Calibrator indirectly. The Calibrator handle is passed to the Plex when the AltStripEndIdList is made. The Plex calls the Calibrator with CalibStripEnd() for each strip end alternative. The Calibrator in turn calls it's own member functions: GetTime(), GetPhotoElectrons(), GetDriftCorrected(), GetLinearized() and GetStriptoStripCorrected() to apply the calibrations. These in turn call the sub-calibrators.

Attenuation correction (i.e. correction for position along the strip) and MIP calibration (i.e. conversion from pseudo-ADC to meaningful energy units) are done by Tracker, Shower-finder, and Event algorithms, which call Calibrator::GetSigMapped() and GetMIP(), which in turn call the Calibrator methods GetAttenCorrected() and GetMIP(), which call the sub-calibrators.

As an example, let us consider the application of Mapper data with the SigMappedCalScheme:

Figure 12.1: Diagram of the Calibrator

Configuring the Calibrator

The Calibrator object is a singleton object that can always be accessed with Calibrator::Instance(). There are two ways in which the Calibrator can be configured:

Choosing Schemes

There are eight different sub-calibrators that can be set. To set sub-calibrators, simply put a line like this in your job control script:

   Calibrator::Instance().Set("PeCalibrator=PEGainCalScheme "
                              "TimeCalibrator=TimeCalScheme ");

The default calibrators are defined in Calibrator.cxx. Usually, the defaults will be what you want; other schemes are used to test new calibration algorithms or tables.

Turning Calibration Off

A general-purpose scheme has been provided that can be used in place of the defaults to provide very fast execution of code by using a set of constants instead of loading database tables. This Scheme is the SimpleCalScheme 12.1To turn this on for all calibration modes, include the following line in your macro:

   Calibrator::Instance().Set("TimeCalibrator=SimpleCalScheme "
                              "PeCalibrator=SimpleCalScheme "
                              "VALinCalibrator=SimpleCalScheme "
                              "DriftCalibrator=SimpleCalScheme "
                              "LinCalibrator=SimpleCalScheme "
                              "StripCalibrator=SimpleCalScheme "
                              "AttenCalibrator=SimpleCalScheme "
                              "MIPCalibrator=SimpleCalScheme " );

This setting may be useful in cases where calibration is not important, e.g. event viewers, code testing, when the database is not available, etc.

Configuring the Sub-Calibrators

After the sub-calibrators have been chosen, you can configure them by getting a handle to them, then calling their Set() methods. You can get the handle to a sub-calibrator with the following functions:


or, more simply:


The individual parameters that may be set for each sub-calibrator can be found by looking at the configuration with PrintConfig() or by looking at the current configuration with GetConfig(). The parameters may be set with a variety of Set functions granted by CfgPromptConfigurable, for example:

// .. shows the current config...
Calibrator::PeCalibrator().Set("defaultGainFD",60.);    // ok
Calibrator::PeCalibrator().Set("defaultGainFD=,60.");   // ok
Calibrator::PeCalibrator().Set("defaultGainFD",60);     // will fail.. wrong type

The Set() commands are all safe, so any mistyped key or wrong value type will generate an error from CfgPromptConfigurable.

Configuration, Statistics, Errors

The current configuration of the Calibrator may be printed out at any time with Calibrator::Instance().PrintConfig().

The current configuration may be saved by getting a Registry that contains the entire configuration for the Calibrator and all sub-calibrators by calling GetCompleteConfiguration(). This returned registry can later be applied by using Calibrator::Instance().Set(registry) to re-apply it. This use is intended to be used to log the configuration during batch processing.

By convention, all bad calibrations will be reported as Warnings, so turning the log level on the ``Calib'' stream up to Error will stop all non-critical calibration warnings.

Errors that occur during calibration are tracked. To see the current error status, you may call Calibrator::PrintErrorStats(), and they may be cleared with ResetStatistics(). The error printout contains a summary of the number of types of errors seen by each sub-calibrator, and a partial list of channels that saw problems, listed by frequency. For example:

          Calibrator      Calls ||   General|Miss Table|  Miss Row|  FP Error|Insuf.Data
             Unknown          0 ||        0 |        0 |        0 |        0 |        0
      TimeCalibrator      15680 ||        0 |        5 |        0 |        0 |        0
        PeCalibrator      15680 ||        0 |        0 |      680 |        0 |        0
     VALinCalibrator          0 ||        0 |        0 |        0 |        0 |        0
     DriftCalibrator      15680 ||        0 |       60 |        0 |        0 |        0
       LinCalibrator      15680 ||        0 |       10 |        0 |        0 |        0
     StripCalibrator      15680 ||        0 |        0 |        0 |        0 |        0
     AttenCalibrator       2404 ||        0 |        0 |        0 |        0 |        0
       MIPCalibrator       1202 ||        0 |        5 |        0 |        0 |        0
Channels with the most errors:
Errors:       40  [   Far|   1 Vt|  2|*E]
Errors:       40  [   Far|   1 Vt| 20|*W]
Errors:       40  [   Far|   1 Vt| 25|*E]
Errors:       40  [   Far|   1 Vt| 44|*W]
Errors:       40  [   Far|   1 Vt| 48|*E]
Errors:       40  [   Far|   1 Vt| 68|*W]
Errors:       40  [   Far|   1 Vt| 92|*W]
Errors:       40  [   Far|   1 Vt| 95|*E]
Errors:       40  [   Far|   1 Vt|116|*W]
Errors:       40  [   Far|   1 Vt|118|*E]
In this example, five events were run. The TimeCalibrator was unable to find any data at all for all 5 events, nor was the MIP calibrator The Drift and Lin calibrators also had problems (they look for more than 1 table each, so each was recorded).

The PeCalibrator found the tables it needed, but 680 strip ends didn't have database rows (even though the table existed). The rows corresponded to the strip ends listed below, all in plane 1, with 40 missed calibrations each.

Note (NJT 07/04) This example is fudged; some of the error reporting in some modules isn't quite right, and I've never actually seen a missing row. However, this is a better example pedagogically.

Writing a New Sub-Calibrator

New calibration methods are easily created. Simply make a new class that inherits from CalScheme(), and implement the following functions:

The constructor should create a registry, and fill it with the default configuration for the scheme. The registry should be locked in with InitializeConfig(), which will call the ConfigModified() you define below. The constructor should not set any class members or initialize anything, although it should set pointers to zero and the like.

This function should get the current configuration registry with GetConfig() and parse all the members in the configuration. If a needed value is not in the configuration, it should complain. If something is changed that could affect the database queries (i.e. changing which Task is being used) then the function should call this->Reset(GetContext()); to force a reload of the DB tables.

This function is called by Reset() whenever there is a change of the current context. It should perform a NewQuery() on each database table it holds, or do other things that might change with detector or time.

This function should print out the current configuration of your scheme. This is optional but recommended.

Calibration calls
One or more of the calibration calls from CalScheme should be implemented, e.g. GetPhotoElectrons() if your scheme is a p.e. calibration.

Decalibration calls
For every calibration call, you should also implement the complimentary decalibration call.

The CalScheme can implement multiple different sub-calibrator types in the same class (like SimpleCalScheme) but be warned that more than one instance of the class will be created by the Calibrator, and they may be calibrated differently.

Warnings and errors should be handled correctly. All message service strings should go to MSG(``Calib'',Msg::kWarning) for bad calibrations or missing tables. The use of the MAXMSG macro is advised for most of these cases.

In addition, an error-counting service is in place. If you fail to find any rows in a table during DoReset(), you should make a call to IncrementErrors(k<type>Calibrator,kMissingTable). If you can't find a row in a table that has rows, you should make a call to IncrementErrors(k<type>Calibrator,kMissingRow,<channel>), where <channel> is a PlexStripEndId, an LedId, a RawChannelId, or a PlexPixelSpotId. There are also kFPE to track floating-point errors, kDataInsuffcient to track places where there is insufficient calibration data to make a good calibration, and kGeneralErr as a catch-all category.

Migrating from the Old DigitCalibrator and StripCalibrator

The old calibration system used a simpler configuration interface, but it was typically used by the reconstruction Algorithms, rather than directly by the user. If you have old scripts that change the calibration modes from the defaults, then you will need to change them to the new configuration method.

Calls Via AlgConfig

Many macros will use the AlgDigit (via the DigitListModule) to change the digit calibration modes. A few also have lines to change the strip calibration modes (attenaution and MIP correction) via calls to the tracker or showerer. Examples:


These configuration methods are no longer used. Use the conversion table below to interpret these calls. In general, setting a mode to zero implied turning off that calibration. In the new system, that means changing the calibrator to the 'Simple' calibrator. Otherwise, the integer was a mode flag which could imply lots of different behaviours.

Old call Meaning New call
CalPeMode = 0 Turns off PE cal Set("PeCalibrator=SimpleCalScheme");
CalPeMode = 1 Turns on PE cal (default)
CalSigLinMode=0 Turns off LI cal Set("DriftCalibrator=SimpleCalScheme" "LinCalibrator=SimpleCalScheme");
CalSigLinMode=n Sets mods for LI cal GetDriftCalibrator().Set("CalMode=n");
CalSigCorrMode=0 Turns off muon cal Set("StripCalibrator=SimpleCalScheme");
CalSigCorrMode=1 Default muon cal (default)
CalSigCorrMode=2 Turn on temp correction GetStripCalibrator().Set("TemperatureCorrection=on");
CalSigCorrMode=3 Use PS muon calibration GetStripCalibrator().Set("MuonSource=PSMuons");
CalSigCorrMode=4 Use alternate PS muons GetStripCalibrator().Set("MuonSource=AltPS");
CalTimeMode=0 Turns off time calibration Set("TimeCalibrator=SimpleCalScheme");
CalTimeMode=1 Turns on time calibration (default)
CalSigMapMode=n Mode for Atten correction GetAttenCalibrator().Set("CalMode=n");
CalMipMode=0 Turn off MIP calibration Set("MIPCalibrator=SimpleCalScheme");
CalMipMode=1 Turn on MIP calibration (default)

Direct Calls

You may have lines such as these in your macro:

DigitCalibrator::Instance().SetCalModes( 1, 1, 1, 1 );
StripCalibrator::Instance().SetCalModes( 1, 1 );

These perform the same actions as above, but without the AlgConfig mechanism. These calls can be interpeted as in the table above:

DigitCalibrator::Instance().SetCalModes( 1, // CalPeMode
                                         1, // CalSigLinMode=1 
                                         1, // CalSigCorrMode=1
                                         1  // CalTimeMode=1
StripCalibrator::Instance().SetCalModes( 1, // CalSigMapMode=1
                                         1  // CalMipMode=1

next up previous contents
Next: Data Model and I/O Up: The MINOS Off-line Software Previous: Raw Data and Rotorooter   Contents
MINOS Software 2017-11-20