diff --git a/src/calng/corrections/Gotthard2Correction.py b/src/calng/corrections/Gotthard2Correction.py index 63517b062af762b5261e649c29dbbf33c548c9c9..e35c4b59c08a0ff7b05fe5644acc5786d6eabd89 100644 --- a/src/calng/corrections/Gotthard2Correction.py +++ b/src/calng/corrections/Gotthard2Correction.py @@ -28,6 +28,12 @@ class Constants(enum.Enum): BadPixelsFFGotthard2 = enum.auto() +bp_constant_types = { + Constants.BadPixelsDarkGotthard2, + Constants.BadPixelsFFGotthard2, +} + + class CorrectionFlags(enum.IntFlag): NONE = 0 LUT = 1 @@ -46,6 +52,7 @@ class Gotthard2CpuRunner(base_kernel_runner.BaseKernelRunner): input_data_dtype=np.uint16, output_data_dtype=np.float32, bad_pixel_mask_value=np.nan, + bad_pixel_subset=None, ): super().__init__( pixels_x, @@ -71,6 +78,7 @@ class Gotthard2CpuRunner(base_kernel_runner.BaseKernelRunner): self.bad_pixel_map = np.empty(self.map_shape, dtype=np.uint32) self.bad_pixel_mask_value = bad_pixel_mask_value self.flush_buffers() + self._bad_pixel_subset = bad_pixel_subset self.input_data = None # will just point to data coming in self.input_gain_stage = None # will just point to data coming in @@ -87,15 +95,20 @@ class Gotthard2CpuRunner(base_kernel_runner.BaseKernelRunner): 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)) - elif constant_type in { - Constants.BadPixelsDarkGotthard2, - Constants.BadPixelsFFGotthard2, - }: + elif constant_type in bp_constant_types: # TODO: add the regular bad pixel subset configuration - self.bad_pixel_map |= np.transpose(data.astype(np.uint32, copy=False)) + data = data.astype(np.uint32, copy=False) + if self._bad_pixel_subset is not None: + data = data & self._bad_pixel_subset + self.bad_pixel_map |= np.transpose(data) else: raise ValueError(f"What is this constant '{constant_type}'?") + def set_bad_pixel_subset(self, subset, apply_now=True): + self._bad_pixel_subset = subset + if apply_now: + self.bad_pixel_map &= self._bad_pixel_subset + 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) @@ -318,6 +331,9 @@ class Gotthard2Correction(base_correction.BaseCorrection): Gotthard2Correction._managed_keys, Gotthard2Correction._correction_steps, ) + base_correction.add_bad_pixel_config_node( + expected, Gotthard2Correction._managed_keys + ) # mandatory: manager needs this in schema ( @@ -344,12 +360,50 @@ class Gotthard2Correction(base_correction.BaseCorrection): @property def _kernel_runner_init_args(self): - return {"bad_pixel_mask_value": self.bad_pixel_mask_value} + return { + "bad_pixel_mask_value": self._bad_pixel_mask_value, + "bad_pixel_subset": self._bad_pixel_subset, + } @property - def bad_pixel_mask_value(self): + def _bad_pixel_mask_value(self): return np.float32(self.unsafe_get("corrections.badPixels.maskingValue")) + _bad_pixel_subset = property(base_correction.get_bad_pixel_field_selection) + + def postReconfigure(self): + super().postReconfigure() + update = self._prereconfigure_update_hash + if update.has("corrections.badPixels.subsetToUse"): + if any( + update.get( + f"corrections.badPixels.subsetToUse.{field.name}", default=False + ) + for field in utils.BadPixelValues + ): + self.log_status_info( + "Some fields reenabled, reloading cached bad pixel constants" + ) + self.kernel_runner.set_bad_pixel_subset( + self._bad_pixel_subset, apply_now=False + ) + with self.calcat_friend.cached_constants_lock: + self.kernel_runner.flush_buffers(bp_constant_types) + for constant_type in ( + bp_constant_types & self.calcat_friend.cached_constants.keys() + ): + self._load_constant_to_runner( + constant_type, + self.calcat_friend.cached_constants[constant_type], + ) + else: + # just narrowing the subset - no reload, just AND + self.kernel_runner.set_bad_pixel_subset( + self._bad_pixel_subset, apply_now=True + ) + if update.has("corrections.badPixels.maskingvalue"): + self.kernel_runner.bad_pixel_mask_value = self._bad_pixel_mask_value + def __init__(self, config): super().__init__(config) try: