From 3da01c9e157a952c656e957c154ca9a1b7cd403a Mon Sep 17 00:00:00 2001 From: Daniel Cox Date: Fri, 8 Nov 2024 14:17:40 +0100 Subject: [PATCH] Add SLM set_phases_8bit --- openwfs/devices/slm/slm.py | 7 +++++++ tests/test_slm.py | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/openwfs/devices/slm/slm.py b/openwfs/devices/slm/slm.py index e7bdb62..98cb8db 100644 --- a/openwfs/devices/slm/slm.py +++ b/openwfs/devices/slm/slm.py @@ -555,6 +555,13 @@ def lookup_table(self, value: Sequence[int]): def set_phases(self, values: ArrayLike, update=True): self.primary_patch.set_phases(values, update) + def set_phases_8bit(self, values: ArrayLike, **kwargs): + """ + Pass 8bit unsigned integers [0, 255] as linearly mapped to phase, such that 0 -> 0, 256 -> 2π. Any other + keyword arguments will be passed to set_phases. + """ + self.set_phases(values * 2 * np.pi / 256, **kwargs) + @property def pixels(self) -> Detector: """Returns a 'camera' to monitor the current value of the pixels displayed on the SLM.""" diff --git a/tests/test_slm.py b/tests/test_slm.py index 85ec3c8..953f7ce 100644 --- a/tests/test_slm.py +++ b/tests/test_slm.py @@ -281,3 +281,24 @@ def test_circular_geometry(slm): np.repeat(np.flip(np.arange(30, 70)), 1).reshape((-1, 1)), atol=1, ) + + +def test_slm_lut(slm): + """ + Test the lookup table + """ + # === Test default lookup table === + # Includes edge cases like rounding/wrapping: -0.501 -> 255, -0.499 -> 0 + input_phase_a_256 = np.zeros(slm.shape) + input_phase_a_256[0:13, 0] = np.asarray([-1, -0.501, -0.499, 0, 1, 64, 255, 255.499, 255.501, 256, 257, 511, 512]) + input_phases_a = input_phase_a_256 * 2 * np.pi / 256 + + expected_output_phases_a = np.zeros(slm.shape) + expected_output_phases_a_256 = np.asarray([255, 255, 0, 0, 1, 64, 255, 255, 0, 0, 1, 255, 0]) + expected_output_phases_a[0:13, 0] = expected_output_phases_a_256 * 2 * np.pi / 256 + + slm.set_phases(input_phases_a) + assert np.all(np.abs(slm.pixels.read() - expected_output_phases_a_256) < 1e-6) + + slm.set_phases_8bit(input_phase_a_256) + assert np.all(np.abs(slm.pixels.read() - expected_output_phases_a_256) < 1e-6)