diff --git a/src/calng/corrections/Gotthard2Correction.py b/src/calng/corrections/Gotthard2Correction.py index 0dd5a591b78398059b1d496b63824cdd08b15c93..0c38094186e5191ca5e638c0124fa2bb22644f65 100644 --- a/src/calng/corrections/Gotthard2Correction.py +++ b/src/calng/corrections/Gotthard2Correction.py @@ -2,6 +2,7 @@ import enum import numpy as np from karabo.bound import ( + DOUBLE_ELEMENT, FLOAT_ELEMENT, KARABO_CLASSINFO, OUTPUT_CHANNEL, @@ -19,10 +20,12 @@ from .._version import version as deviceVersion _pretend_pulse_table = np.arange(2720, dtype=np.uint8) -class Gotthard2Constants(enum.Enum): - Lut = enum.auto() - Offset = enum.auto() - Gain = enum.auto() +class Constants(enum.Enum): + LUTGotthard2 = enum.auto() + OffsetGotthard2 = enum.auto() + RelativeGainGotthard2 = enum.auto() + BadPixelsDarkGotthard2 = enum.auto() + BadPixelsFFGotthard2 = enum.auto() class CorrectionFlags(enum.IntFlag): @@ -30,6 +33,7 @@ class CorrectionFlags(enum.IntFlag): LUT = 1 OFFSET = 2 GAIN = 4 + BPMASK = 8 class Gotthard2CpuRunner(base_kernel_runner.BaseKernelRunner): @@ -64,6 +68,7 @@ class Gotthard2CpuRunner(base_kernel_runner.BaseKernelRunner): self.lut = np.empty(self.lut_shape, dtype=np.uint16) self.offset_map = np.empty(self.map_shape, dtype=np.float32) self.rel_gain_map = np.empty(self.map_shape, dtype=np.float32) + self.bad_pixel_map = np.empty(self.map_shape, dtype=np.uint32) self.flush_buffers() self.input_data = None # will just point to data coming in @@ -71,9 +76,19 @@ class Gotthard2CpuRunner(base_kernel_runner.BaseKernelRunner): self.processed_data = None # will just point to buffer we're given @property - def input_data_views(self): + def preview_data_views(self): return (self.input_data, self.processed_data) + def load_constant(self, constant_type, data): + if constant_type is Constants.LUTGotthard2: + self.lut[:] = np.transpose(data.astype(np.uint16, copy=False), (1, 2, 0)) + elif constant_type is Constants.OffsetGotthard2: + self.offset_map[:] = np.transpose(data.astype(np.float32, copy=False)) + elif constant_type is Constants.RelativeGainGotthard2: + self.rel_gain_map[:] = np.transpose(data.astype(np.float32, copy=False)) + else: + print(f"Not ready for {constant_type}") + def load_data(self, image_data, input_gain_stage): """Experiment: loading both in one function as they are tied""" self.input_data = image_data.astype(np.uint16, copy=False) @@ -87,6 +102,7 @@ class Gotthard2CpuRunner(base_kernel_runner.BaseKernelRunner): self.lut[:] = np.stack([np.stack([default_lut] * 2)] * self.pixels_x, axis=2) self.offset_map.fill(0) self.rel_gain_map.fill(1) + self.bad_pixel_map.fill(0) def correct(self, flags, out=None): if out is None: @@ -106,16 +122,35 @@ class Gotthard2CpuRunner(base_kernel_runner.BaseKernelRunner): class Gotthard2CalcatFriend(base_calcat.BaseCalcatFriend): - _constant_enum_class = Gotthard2Constants + _constant_enum_class = Constants def __init__(self, device, *args, **kwargs): super().__init__(device, *args, **kwargs) - self._constants_need_conditions = {} # TODO + self._constants_need_conditions = { + Constants.LUTGotthard2: self.condition_2, + Constants.OffsetGotthard2: self.condition_1, + Constants.RelativeGainGotthard2: self.condition_2, + Constants.BadPixelsDarkGotthard2: self.condition_1, + Constants.BadPixelsFFGotthard2: self.condition_2, + } + + def condition_1(self): + res = base_calcat.OperatingConditions() + res["Exposure time"] = self._get_param("exposureTime") + res["Exposure period"] = self._get_param("exposurePeriod") + res["Sensor Bias Voltage"] = self._get_param("biasVoltage") + res["Single photon"] = self._get_param("singlePhoton") + return res + + def condition_2(self): + res = self.condition_1() + res["Acquisition rate"] = self._get_param("acquisitionRate") + return res @staticmethod def add_schema(schema, managed_keys): super(Gotthard2CalcatFriend, Gotthard2CalcatFriend).add_schema( - schema, managed_keys, "gotthard-Type" + schema, managed_keys, "Gotthard2-Type" ) # set some defaults for common parameters @@ -134,10 +169,45 @@ class Gotthard2CalcatFriend(base_calcat.BaseCalcatFriend): .key("constantParameters.memoryCells") .setNewDefaultValue(2) .commit(), + + OVERWRITE_ELEMENT(schema) + .key("constantParameters.biasVoltage") + .setNewDefaultValue(200) + .commit() + ) + + ( + DOUBLE_ELEMENT(schema) + .key("constantParameters.exposureTime") + .assignmentOptional() + .defaultValue(0) + .reconfigurable() + .commit(), + + DOUBLE_ELEMENT(schema) + .key("constantParameters.exposurePeriod") + .assignmentOptional() + .defaultValue(0) + .reconfigurable() + .commit(), + + DOUBLE_ELEMENT(schema) + .key("constantParameters.singlePhoton") + .assignmentOptional() + .defaultValue(0) + .reconfigurable() + .commit(), + + DOUBLE_ELEMENT(schema) + .key("constantParameters.acquisitionRate") + .assignmentOptional() + .defaultValue(1.1) + .reconfigurable() + .commit(), ) base_calcat.add_status_schema_from_enum( - schema, Gotthard2Constants + schema, Constants ) @@ -148,22 +218,30 @@ class Gotthard2Correction(base_correction.BaseCorrection): ( "lut", CorrectionFlags.LUT, - {Gotthard2Constants.Lut}, + {Constants.LUTGotthard2}, ), ( "offset", CorrectionFlags.OFFSET, - {Gotthard2Constants.Offset}, + {Constants.OffsetGotthard2}, ), ( "gain", CorrectionFlags.GAIN, - {Gotthard2Constants.Gain}, + {Constants.RelativeGainGotthard2}, + ), + ( + "badPixels", + CorrectionFlags.BPMASK, + { + Constants.BadPixelsDarkGotthard2, + Constants.BadPixelsFFGotthard2, + } ), ) _kernel_runner_class = Gotthard2CpuRunner _calcat_friend_class = Gotthard2CalcatFriend - _constant_enum_class = Gotthard2Constants + _constant_enum_class = Constants _managed_keys = base_correction.BaseCorrection._managed_keys.copy() _image_data_path = "data.adc" _cell_table_path = "data.memoryCell" @@ -345,13 +423,4 @@ class Gotthard2Correction(base_correction.BaseCorrection): ) def _load_constant_to_runner(self, constant, constant_data): - if constant is Gotthard2Constants.Lut: - self.kernel_runner.lut[:] = constant_data.astype(np.uint16, copy=False) - elif constant is Gotthard2Constants.Offset: - self.kernel_runner.offset_map[:] = constant_data.astype( - np.float32, copy=False - ) - elif constant is Gotthard2Constants.Gain: - self.kernel_runner.rel_gain_map[:] = constant_data.astype( - np.float32, copy=False - ) + self.kernel_runner.load_constant(constant, constant_data)