import inspect
import sys
from textwrap import dedent
from .calibration_constant import CalibrationConstant
from .detectors import DetectorTypes
[docs]class Offset(CalibrationConstant):
"""
Detector offset/pedestal
"""
def __init__(self):
super(Offset, self).__init__()
self._datadict["calibration_name"] = "Offset"
desc = "Per-pixel (per-memory cell) offset"
self._datadict["description"] = desc
[docs]class Noise(CalibrationConstant):
"""
Detector noise
"""
def __init__(self):
super(Noise, self).__init__()
self._datadict["calibration_name"] = "Noise"
desc = "Per-pixel (per-memory cell) noise"
self._datadict["description"] = desc
[docs]class RelativeGain(CalibrationConstant):
"""
Detector relative gain
"""
def __init__(self):
super(RelativeGain, self).__init__()
self._datadict["calibration_name"] = "RelativeGain"
desc = "Per-pixel (per-memory cell) relative gain"
self._datadict["description"] = desc
[docs]class BadPixels(CalibrationConstant):
"""
Detector bad pixel map
"""
def __init__(self):
super(BadPixels, self).__init__()
self._datadict["calibration_name"] = "BadPixels"
desc = "Per-pixel (per-memory cell) bad pixels"
self._datadict["description"] = desc
_BASE_CONSTANTS = [Offset, Noise, RelativeGain, BadPixels]
[docs]class Constants:
"""
Predefined constants are provided in this class.
They are organized by detector type, and then constant name. This
class is filled automatically at module load time. It is thus
statically empty on purpose.
Special contants for a given detector are defined explicitly
"""
[docs] class AGIPD:
[docs] class ThresholdsDark(CalibrationConstant):
"""
Gain thresholds derived from dark images
"""
def __init__(self):
super(Constants.AGIPD.ThresholdsDark, self).__init__()
self._datadict["detector_type_name"] = DetectorTypes.AGIPD.value
self._datadict["calibration_name"] = "ThresholdsDark"
desc = "Per-pixel (per-memory cell) thresholds from dark runs"
self._datadict["description"] = desc
[docs] class ThresholdsPC(CalibrationConstant):
"""
Gain thresholds derived from PC runs
"""
def __init__(self):
super(Constants.AGIPD.ThresholdsPC, self).__init__()
self._datadict["detector_type_name"] = DetectorTypes.AGIPD.value
self._datadict["calibration_name"] = "ThresholdsPC"
desc = "Per-pixel (per-memory cell) thresholds from PC runs"
self._datadict["description"] = desc
[docs] class ThresholdsCI(CalibrationConstant):
"""
Gain thresholds derived from CI run
"""
def __init__(self):
super(Constants.AGIPD.ThresholdsCI, self).__init__()
self._datadict["detector_type_name"] = DetectorTypes.AGIPD.value
self._datadict["calibration_name"] = "ThresholdsCI"
desc = "Per-pixel (per-memory cell) thresholds from CI runs"
self._datadict["description"] = desc
[docs] class BadPixelsDark(CalibrationConstant):
"""
Bad pixels derived from dark runs
"""
def __init__(self):
super(Constants.AGIPD.BadPixelsDark, self).__init__()
self._datadict["detector_type_name"] = DetectorTypes.AGIPD.value
self._datadict["calibration_name"] = "BadPixelsDark"
desc = "Per-pixel (per-memory cell) bad pixels from dark runs"
self._datadict["description"] = desc
[docs] class BadPixelsPC(CalibrationConstant):
"""
Bad pixels derived from PC runs
"""
def __init__(self):
super(Constants.AGIPD.BadPixelsPC, self).__init__()
self._datadict["detector_type_name"] = DetectorTypes.AGIPD.value
self._datadict["calibration_name"] = "BadPixelsPC"
desc = "Per-pixel (per-memory cell) bad pixels from PC runs"
self._datadict["description"] = desc
[docs] class BadPixelsCI(CalibrationConstant):
"""
Bad pixels derived from CI runs
"""
def __init__(self):
super(Constants.AGIPD.BadPixelsCI, self).__init__()
self._datadict["detector_type_name"] = DetectorTypes.AGIPD.value
self._datadict["calibration_name"] = "BadPixelsCI"
desc = "Per-pixel (per-memory cell) bad pixels from CI runs"
self._datadict["description"] = desc
[docs] class BadPixelsFF(CalibrationConstant):
"""
Bad pixels derived from FF runs
"""
def __init__(self):
super(Constants.AGIPD.BadPixelsFF, self).__init__()
self._datadict["detector_type_name"] = DetectorTypes.AGIPD.value
self._datadict["calibration_name"] = "BadPixelsFF"
desc = "Per-pixel (per-memory cell) bad pixels from FF runs"
self._datadict["description"] = desc
[docs] class SlopesPC(CalibrationConstant):
"""
Gain slopes derived from PC runs
"""
def __init__(self):
super(Constants.AGIPD.SlopesPC, self).__init__()
self._datadict["detector_type_name"] = DetectorTypes.AGIPD.value
self._datadict["calibration_name"] = "SlopesPC"
desc = """ Results of slope fitting from PC runs values are
distinguished on axis 0 by index:
0: linear slope - m value
1: linear slope - b value
2: linear slope - deviation
3: hook function - m value
4: hook function - b value
5: hook function - o value
6: hook function - c value
7: hook function - a value
8: hook function - deviation
"""
self._datadict["description"] = dedent(desc)
[docs] class SlopesCI(CalibrationConstant):
"""
Gain slopes derived from CI runs
"""
def __init__(self):
super(Constants.AGIPD.SlopesCI, self).__init__()
self._datadict["detector_type_name"] = DetectorTypes.AGIPD.value
self._datadict["calibration_name"] = "SlopesCI"
desc = "Per-pixel (per-memory cell) slopes from CI runs"
self._datadict["description"] = desc
[docs] class SlopesFF(CalibrationConstant):
"""
Gain slopes derived from FF runs
"""
def __init__(self):
super(Constants.AGIPD.SlopesFF, self).__init__()
self._datadict["detector_type_name"] = DetectorTypes.AGIPD.value
self._datadict["calibration_name"] = "SlopesFF"
desc = "Per-pixel (per-memory cell) slopes from FF runs"
self._datadict["description"] = desc
[docs] class LPD:
[docs] class BadPixelsDark(CalibrationConstant):
"""
Bad pixels derived from dark runs
"""
def __init__(self):
super(Constants.LPD.BadPixelsDark, self).__init__()
self._datadict["detector_type_name"] = DetectorTypes.LPD.value
self._datadict["calibration_name"] = "BadPixelsDark"
desc = "Per-pixel (per-memory cell) bad pixels from dark runs"
self._datadict["description"] = desc
[docs] class BadPixelsCI(CalibrationConstant):
"""
Bad pixels derived from CI runs
"""
def __init__(self):
super(Constants.LPD.BadPixelsCI, self).__init__()
self._datadict["detector_type_name"] = DetectorTypes.LPD.value
self._datadict["calibration_name"] = "BadPixelsCI"
desc = "Per-pixel (per-memory cell) bad pixels from CI runs"
self._datadict["description"] = desc
[docs] class BadPixelsFF(CalibrationConstant):
"""
Bad pixels derived from FF runs
"""
def __init__(self):
super(Constants.LPD.BadPixelsFF, self).__init__()
self._datadict["detector_type_name"] = DetectorTypes.LPD.value
self._datadict["calibration_name"] = "BadPixelsFF"
desc = "Per-pixel (per-memory cell) bad pixels from FF runs"
self._datadict["description"] = desc
[docs] class SlopesCI(CalibrationConstant):
"""
Gain slopes derived from CI runs
"""
def __init__(self):
super(Constants.LPD.SlopesCI, self).__init__()
self._datadict["detector_type_name"] = DetectorTypes.LPD.value
self._datadict["calibration_name"] = "SlopesCI"
desc = "Per-pixel (per-memory cell) slopes from CI runs"
self._datadict["description"] = desc
[docs] class SlopesFF(CalibrationConstant):
"""
Gain slopes derived from FF runs
"""
def __init__(self):
super(Constants.LPD.SlopesFF, self).__init__()
self._datadict["detector_type_name"] = DetectorTypes.LPD.value
self._datadict["calibration_name"] = "SlopesFF"
desc = "Per-pixel (per-memory cell) slopes from FF runs"
self._datadict["description"] = desc
[docs] class FFMap(CalibrationConstant):
"""Flatfield map"""
def __init__(self):
super(Constants.LPD.FFMap, self).__init__()
self._datadict["detector_type_name"] = DetectorTypes.LPD.value
self._datadict["calibration_name"] = "FFMap"
desc = "Per-pixel (per-memory cell) flatfield map"
self._datadict["description"] = desc
[docs] class RelativeGain(CalibrationConstant):
"""Detector relative gain."""
def __init__(self):
super(Constants.LPD.RelativeGain, self).__init__()
self._datadict["detector_type_name"] = DetectorTypes.LPD.value
self._datadict["calibration_name"] = "RelativeGain"
desc = "Per-pixel (per-memory cell) relative gain map"
self._datadict["description"] = desc
[docs] class GainAmpMap(CalibrationConstant):
"""Gain amplification factor map"""
def __init__(self):
super(Constants.LPD.GainAmpMap, self).__init__()
self._datadict["detector_type_name"] = DetectorTypes.LPD.value
self._datadict["calibration_name"] = "GainAmpMap"
desc = "Per-pixel (per-memory cell) gain amplification factor map"
self._datadict["description"] = desc
[docs] class jungfrau:
[docs] class BadPixelsDark(CalibrationConstant):
"""
Detector Bad pixels
"""
def __init__(self):
super(Constants.jungfrau.BadPixelsDark, self).__init__()
self._datadict["calibration_name"] = "BadPixelsDark10Hz"
self._datadict["detector_type_name"] = DetectorTypes.jungfrau.value
desc = "Per-pixel (per-memory cell) dark pixels"
self._datadict["description"] = desc
[docs] class Offset(CalibrationConstant):
"""
Detector offset/pedestal
"""
def __init__(self):
super(Constants.jungfrau.Offset, self).__init__()
self._datadict["calibration_name"] = "Offset10Hz"
desc = "Per-pixel (per-memory cell) offset"
self._datadict["description"] = desc
[docs] class Noise(CalibrationConstant):
"""
Detector noise
"""
def __init__(self):
super(Constants.jungfrau.Noise, self).__init__()
self._datadict["calibration_name"] = "Noise10Hz"
desc = "Per-pixel (per-memory cell) noise"
self._datadict["description"] = desc
[docs] class RelativeGain(CalibrationConstant):
"""
Detector relative gain
"""
def __init__(self):
super(Constants.jungfrau.RelativeGain, self).__init__()
self._datadict["calibration_name"] = "RelativeGain10Hz"
desc = "Per-pixel (per-memory cell) relative gain"
self._datadict["description"] = desc
[docs] class BadPixelsFF(CalibrationConstant):
"""
Bad pixels derived from FF runs
"""
def __init__(self):
super(Constants.jungfrau.BadPixelsFF, self).__init__()
self._datadict["detector_type_name"] = DetectorTypes.jungfrau.value
self._datadict["calibration_name"] = "BadPixelsFF10Hz"
desc = "Per-pixel (per-memory cell) bad pixels from FF runs"
self._datadict["description"] = desc
[docs] class ePix100:
[docs] class BadPixelsDark(CalibrationConstant):
"""
Detector Bad pixels
"""
def __init__(self):
super(Constants.ePix100.BadPixelsDark, self).__init__()
self._datadict["calibration_name"] = "BadPixelsDarkEPix100"
self._datadict["detector_type_name"] = DetectorTypes.ePix100.value
desc = "Per-pixel mask of dark bad pixels"
self._datadict["description"] = desc
[docs] class Offset(CalibrationConstant):
"""
Detector offset/pedestal
"""
def __init__(self):
super(Constants.ePix100.Offset, self).__init__()
self._datadict["calibration_name"] = "OffsetEPix100"
self._datadict["detector_type_name"] = DetectorTypes.ePix100.value
desc = "Per-pixel offset"
self._datadict["description"] = desc
[docs] class Noise(CalibrationConstant):
"""
Detector noise
"""
def __init__(self):
super(Constants.ePix100.Noise, self).__init__()
self._datadict["calibration_name"] = "NoiseEPix100"
self._datadict["detector_type_name"] = DetectorTypes.ePix100.value
desc = "Per-pixel noise"
self._datadict["description"] = desc
[docs] class RelativeGain(CalibrationConstant):
"""
Detector relative gain
"""
def __init__(self):
super(Constants.ePix100.RelativeGain, self).__init__()
self._datadict["calibration_name"] = "RelativeGainEPix100"
desc = "Per-pixel relative gain"
self._datadict["description"] = desc
[docs] class BadPixelsIlluminated(CalibrationConstant):
"""
Detector Bad pixels Illuminated
"""
def __init__(self):
super(Constants.ePix100.BadPixelsIlluminated, self).__init__()
self._datadict["calibration_name"] = "BadPixelsIlluminatedEPix"
desc = "Per-pixel mask of ill. bad pixels"
self._datadict["description"] = desc
[docs] class ePix10K:
[docs] class BadPixelsDark(CalibrationConstant):
"""
Detector Bad pixels
"""
def __init__(self):
super(Constants.ePix10K.BadPixelsDark, self).__init__()
self._datadict["calibration_name"] = "BadPixelsDarkEPix10K"
self._datadict["detector_type_name"] = DetectorTypes.ePix10K.value
desc = "Per-pixel mask of dark bad pixels"
self._datadict["description"] = desc
[docs] class Offset(CalibrationConstant):
"""
Detector offset/pedestal
"""
def __init__(self):
super(Constants.ePix10K.Offset, self).__init__()
self._datadict["calibration_name"] = "OffsetEPix10K"
self._datadict["detector_type_name"] = DetectorTypes.ePix10K.value
desc = "Per-pixel offset"
self._datadict["description"] = desc
[docs] class Noise(CalibrationConstant):
"""
Detector noise
"""
def __init__(self):
super(Constants.ePix10K.Noise, self).__init__()
self._datadict["calibration_name"] = "NoiseEPix10K"
self._datadict["detector_type_name"] = DetectorTypes.ePix10K.value
desc = "Per-pixel noise"
self._datadict["description"] = desc
[docs] class RelativeGain(CalibrationConstant):
"""
Detector relative gain
"""
def __init__(self):
super(Constants.ePix10K.RelativeGain, self).__init__()
self._datadict["calibration_name"] = "RelativeGainEPix10K"
desc = "Per-pixel relative gain"
self._datadict["description"] = desc
[docs] class BadPixelsIlluminated(CalibrationConstant):
"""
Detector Bad pixels Illuminated
"""
def __init__(self):
super(Constants.ePix10K.BadPixelsIlluminated, self).__init__()
self._datadict["calibration_name"] = "BadPixelsIlluminatedEPix10K"
desc = "Per-pixel mask of ill. bad pixels"
self._datadict["description"] = desc
[docs] def CCD(ccd_type):
# Most offline calibration notebooks pass the actual enum member
# here, while online calibration passes its name. Attempt
# conversion of any non-member to the corresponding member.
if not isinstance(ccd_type, DetectorTypes):
ccd_type = DetectorTypes[ccd_type]
class _InnerCCD:
class BadPixelsDark(CalibrationConstant):
"""
Detector Bad pixels
"""
def __init__(self):
super().__init__()
self._datadict["calibration_name"] = "BadPixelsDarkCCD"
self._datadict[
"detector_type_name"] = ccd_type.value
desc = "Per-pixel (per-memory cell) dark pixels"
self._datadict["description"] = desc
class StaticBadPixels(CalibrationConstant):
"""
Detector Static Bad Pixels (frequency map of Bad pixels)
"""
def __init__(self):
super().__init__()
self._datadict["calibration_name"] = "StaticBadPixelsCCD"
self._datadict[
"detector_type_name"] = ccd_type.value
desc = "Per-pixel (per-memory cell) bad pixels frequency"
self._datadict["description"] = desc
class Offset(CalibrationConstant):
"""
Detector offset/pedestal
"""
def __init__(self):
super().__init__()
self._datadict["calibration_name"] = "OffsetCCD"
self._datadict[
"detector_type_name"] = ccd_type.value
desc = "Per-pixel (per-memory cell) offset"
self._datadict["description"] = desc
class Noise(CalibrationConstant):
"""
Detector noise
"""
def __init__(self):
super().__init__()
self._datadict["calibration_name"] = "NoiseCCD"
self._datadict[
"detector_type_name"] = ccd_type.value
desc = "Per-pixel (per-memory cell) noise"
self._datadict["description"] = desc
class RelativeGain(CalibrationConstant):
"""
Detector relative gain
"""
def __init__(self):
super().__init__()
self._datadict["calibration_name"] = "RelativeGainCCD"
self._datadict[
"detector_type_name"] = ccd_type.value
desc = "Per-pixel (per-memory cell) relative gain"
self._datadict["description"] = desc
class CTI(CalibrationConstant):
"""
Detector CTI
"""
def __init__(self):
super().__init__()
self._datadict["calibration_name"] = "CTICCD"
self._datadict[
"detector_type_name"] = ccd_type.value
desc = "Per-pixel (per-memory cell) relative gain"
self._datadict["description"] = desc
class CTE(CalibrationConstant):
"""
Detector CTE
"""
def __init__(self):
super().__init__()
self._datadict["calibration_name"] = "CTECCD"
self._datadict[
"detector_type_name"] = ccd_type.value
desc = "Per-pixel (per-memory cell) relative gain"
self._datadict["description"] = desc
class BadPixelsIlluminated(CalibrationConstant):
"""
Detector Bad pixels Illuminated
"""
def __init__(self):
super().__init__()
self._datadict["calibration_name"] = "BadPixelsIlluminatedCCD"
self._datadict[
"detector_type_name"] = ccd_type.value
desc = "Per-pixel (per-memory cell) relative gain"
self._datadict["description"] = desc
return _InnerCCD
# add these classes for all detectors to the Constants class
for detector in DetectorTypes:
dcls_name = detector.name
dcls = getattr(Constants, dcls_name, None)
if not dcls:
dcls = type(dcls_name, (object,), {})
for constant in _BASE_CONSTANTS:
if inspect.isclass(constant):
cls_name = constant.__name__
if hasattr(dcls, cls_name):
cls = getattr(dcls, cls_name)
orig_init = getattr(cls, "__init__")
else:
cls = type(cls_name, (constant,), {})
orig_init = None
setattr(cls, "__init__", meta_init(cls, detector, orig_init))
if orig_init is None:
setattr(dcls, cls_name, cls)
setattr(Constants, dcls_name, dcls)