def _correct_image_data(self, sliced_assembled, slicer): gain = self._gain if self._correct_gain else None if self._correct_offset: offset = self._dark if self._dark_as_offset else self._offset else: offset = None if sliced_assembled.ndim == 3: if gain is not None: gain = gain[slicer] if offset is not None: offset = offset[slicer] if gain is not None and sliced_assembled.shape != gain.shape: raise ImageProcessingError( f"Assembled shape {sliced_assembled.shape} and " f"gain shape {gain.shape} are different!") if offset is not None and sliced_assembled.shape != offset.shape: raise ImageProcessingError( f"Assembled shape {sliced_assembled.shape} and " f"offset shape {offset.shape} are different!") correct_image_data(sliced_assembled, gain=gain, offset=offset)
def process(self, data): image_data = data['processed'].image assembled = data['assembled']['data'] catalog = data['catalog'] det = catalog.main_detector pulse_slicer = catalog.get_slicer(det) if assembled.ndim == 3: n_total = assembled.shape[0] sliced_assembled = assembled[pulse_slicer] sliced_indices = list(range(*(pulse_slicer.indices(n_total)))) n_sliced = len(sliced_indices) else: n_total = 1 sliced_assembled = assembled sliced_indices = [0] n_sliced = 1 if self._recording_dark: self._record_dark(assembled) sliced_gain, sliced_offset = self._update_gain_offset(assembled.shape) correct_image_data(sliced_assembled, gain=sliced_gain, offset=sliced_offset, slicer=pulse_slicer) # Note: This will be needed by the pump_probe_processor to calculate # the mean of assembled images. Also, the on/off indices are # based on the sliced data. data['assembled']['sliced'] = sliced_assembled image_shape = sliced_assembled.shape[-2:] self._update_image_mask(image_shape) self._update_reference(image_shape) # Avoid sending all images around image_data.images = [None] * n_sliced image_data.poi_indices = self._poi_indices self._update_pois(image_data, sliced_assembled) image_data.gain_mean = self._gain_mean image_data.offset_mean = self._offset_mean if self._dark is not None: # default is 0 image_data.n_dark_pulses = 1 if self._dark.ndim == 2 \ else len(self._dark) image_data.dark_count = self.__class__._dark.count image_data.image_mask = self._image_mask image_data.threshold_mask = self._threshold_mask image_data.reference = self._reference image_data.sliced_indices = sliced_indices
def _run_correct_image_array(data, data_type, gain, offset): gain = gain.astype(data_type) offset = offset.astype(data_type) data = data.astype(data_type) # offset only data_cpp = data.copy() t0 = time.perf_counter() correct_image_data(data_cpp, offset=offset) dt_cpp_offset = time.perf_counter() - t0 data_py = data.copy() t0 = time.perf_counter() data_py -= offset dt_py_offset = time.perf_counter() - t0 np.testing.assert_array_almost_equal(data_cpp, data_py) # gain only data_cpp = data.copy() t0 = time.perf_counter() correct_image_data(data_cpp, gain=gain) dt_cpp_gain = time.perf_counter() - t0 data_py = data.copy() t0 = time.perf_counter() data_py *= gain dt_py_gain = time.perf_counter() - t0 np.testing.assert_array_almost_equal(data_cpp, data_py) # gain and offset data_cpp = data.copy() t0 = time.perf_counter() correct_image_data(data_cpp, gain=gain, offset=offset) dt_cpp_both = time.perf_counter() - t0 data_py = data.copy() t0 = time.perf_counter() data_py = (data_py - offset) * gain dt_py_both = time.perf_counter() - t0 np.testing.assert_array_almost_equal(data_cpp, data_py) print(f"\ncorrect_image_data (offset) with {data_type} - \n" f"dt (cpp para) offset: {dt_cpp_offset:.4f}, " f"dt (numpy) offset: {dt_py_offset:.4f}, \n" f"dt (cpp para) gain: {dt_cpp_gain:.4f}, " f"dt (numpy) gain: {dt_py_gain:.4f}, \n" f"dt (cpp para) gain and offset: {dt_cpp_both:.4f}, " f"dt (numpy) gain and offset: {dt_py_both:.4f}")
def _run_correct_image_array(data_type, gain, offset): gain = gain.astype(data_type) offset = offset.astype(data_type) # offset only data = 2. * np.ones((64, 1024, 512), dtype=data_type) t0 = time.perf_counter() correct_image_data(data, offset=offset) dt_cpp_offset = time.perf_counter() - t0 data = 2. * np.ones((64, 1024, 512), dtype=data_type) t0 = time.perf_counter() data -= offset dt_py_offset = time.perf_counter() - t0 # gain only data = 2. * np.ones((64, 1024, 512), dtype=data_type) t0 = time.perf_counter() correct_image_data(data, gain=gain) dt_cpp_gain = time.perf_counter() - t0 data = 2. * np.ones((64, 1024, 512), dtype=data_type) t0 = time.perf_counter() data *= gain dt_py_gain = time.perf_counter() - t0 gain = gain.astype(data_type) offset = offset.astype(data_type) # gain and offset data = 2. * np.ones((64, 1024, 512), dtype=data_type) t0 = time.perf_counter() correct_image_data(data, gain=gain, offset=offset) dt_cpp_both = time.perf_counter() - t0 data = 2. * np.ones((64, 1024, 512), dtype=data_type) t0 = time.perf_counter() data -= offset data *= gain dt_py_both = time.perf_counter() - t0 print(f"\ncorrect_image_data (offset) with {data_type} - \n" f"dt (cpp para) offset: {dt_cpp_offset:.4f}, " f"dt (numpy) offset: {dt_py_offset:.4f}, \n" f"dt (cpp para) gain: {dt_cpp_gain:.4f}, " f"dt (numpy) gain: {dt_py_gain:.4f}, \n" f"dt (cpp para) gain and offset: {dt_cpp_both:.4f}, " f"dt (numpy) gain and offset: {dt_py_both:.4f}")
def testCorrectImageData(self): arr1d = np.ones(2, dtype=np.float32) arr2d = np.ones((2, 2), dtype=np.float32) arr3d = np.ones((2, 2, 2), dtype=np.float32) arr4d = np.ones((2, 2, 2, 2), dtype=np.float32) # test invalid input with self.assertRaises(TypeError): correct_image_data() with self.assertRaises(TypeError): correct_image_data(arr1d, offset=arr1d) with self.assertRaises(TypeError): correct_image_data(arr4d, gain=arr4d) # test incorrect shape with self.assertRaises(TypeError): correct_image_data(np.ones((2, 2, 2)), offset=arr2d) with self.assertRaises(TypeError): correct_image_data(np.ones((2, 2, 2)), gain=arr2d) with self.assertRaises(TypeError): correct_image_data(np.ones((2, 2)), offset=arr3d) with self.assertRaises(TypeError): correct_image_data(np.ones((2, 2)), gain=arr3d) with self.assertRaises(TypeError): correct_image_data(np.ones((2, 2)), gain=arr2d, offset=arr3d) # test incorrect dtype with self.assertRaises(TypeError): correct_image_data(arr3d, offset=np.ones((2, 2, 2), dtype=np.float64)) with self.assertRaises(TypeError): correct_image_data(arr3d, gain=arr3d, offset=np.ones((2, 2, 2), dtype=np.float64)) # test without gain and offset for img in [np.ones([2, 2]), np.ones([2, 2, 2])]: img_gt = img.copy() correct_image_data(img) np.testing.assert_array_equal(img_gt, img) # ------------ # single image # ------------ # offset only img = np.array([[1, 2, 3], [3, np.nan, np.nan]], dtype=np.float32) offset = np.array([[1, 2, 1], [2, np.nan, np.nan]], dtype=np.float32) correct_image_data(img, offset=offset) np.testing.assert_array_equal( np.array([[0, 0, 2], [1, np.nan, np.nan]], dtype=np.float32), img) # gain only gain = np.array([[1, 2, 1], [2, 2, 1]], dtype=np.float32) correct_image_data(img, gain=gain) np.testing.assert_array_equal( np.array([[0, 0, 2], [2, np.nan, np.nan]], dtype=np.float32), img) # both gain and offset img = np.array([[1, 2, 3], [3, np.nan, np.nan]], dtype=np.float32) correct_image_data(img, gain=gain, offset=offset) np.testing.assert_array_equal( np.array([[0, 0, 2], [2, np.nan, np.nan]], dtype=np.float32), img) # ------------ # train images # ------------ # offset only img = np.array([[[1, 2, 3], [3, np.nan, np.nan]], [[1, 2, 3], [3, np.nan, np.nan]]], dtype=np.float32) offset = np.array([[[1, 2, 1], [3, np.nan, np.nan]], [[2, 1, 2], [2, np.nan, np.nan]]], dtype=np.float32) correct_image_data(img, offset=offset) np.testing.assert_array_equal( np.array([[[0, 0, 2], [0, np.nan, np.nan]], [[-1, 1, 1], [1, np.nan, np.nan]]], dtype=np.float32), img) # gain only gain = np.array([[[1, 2, 1], [2, 2, 1]], [[2, 1, 2], [2, 1, 2]]], dtype=np.float32) correct_image_data(img, gain=gain) np.testing.assert_array_equal( np.array([[[0, 0, 2], [0, np.nan, np.nan]], [[-2, 1, 2], [2, np.nan, np.nan]]], dtype=np.float32), img) # both gain and offset img = np.array([[[1, 2, 3], [3, np.nan, np.nan]], [[1, 2, 3], [3, np.nan, np.nan]]], dtype=np.float32) correct_image_data(img, gain=gain, offset=offset) np.testing.assert_array_equal( np.array([[[0, 0, 2], [0, np.nan, np.nan]], [[-2, 1, 2], [2, np.nan, np.nan]]], dtype=np.float32), img)