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:
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:
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.
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.
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:
Calibrator::Instance().GetTimeCalibrator() Calibrator::Instance().GetPeCalibrator() Calibrator::Instance().GetVALinCalibrator() Calibrator::Instance().GetDriftCalibrator() Calibrator::Instance().GetLinCalibrator() Calibrator::Instance().GetStripCalibrator() Calibrator::Instance().GetAttenCalibrator() Calibrator::Instance().GetMIPCalibrator()
or, more simply:
Calibrator::TimeCalibrator() Calibrator::PeCalibrator() Calibrator::VALinCalibrator() Calibrator::DriftCalibrator() Calibrator::LinCalibrator() Calibrator::StripCalibrator() Calibrator::AttenCalibrator() Calibrator::MIPCalibrator()
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:
Calibrator::Instance().Set("PeCalibrator=SimpleCalScheme"); Calibrator::Instance().PrintConfig(); // .. 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.
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.
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.
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.
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:
jc->Path("path").Mod("DigitListModule").Set("CalPeMode=0"); jc->Path("path").Mod("TrackSRListModule").Set("CalMipMode=1");
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 |
Calibrator::Instance(). | ||
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) |
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 );