pytweezer.drivers.slm module¶
Meadowlark Blink Plus SLM driver.
Wraps the Blink C-wrapper SDK (a ctypes DLL) as a single-target device backend,
so a Spatial Light Modulator is a first-class device: get_device("Rb SLM").
This replaces the old standalone ZMQ SLMServer.py — the point of making it a
device is that a coordinator sharing its process (e.g. rearrangement) can call
slm.update_mask(frame) directly, with no socket between the GPU-computed
phasemask and the hardware.
The Blink DLL and LUT paths are Windows-only and specific to the SLM PC; they are
loaded lazily in _connect(), so importing this module never requires the SDK
to be present. Use SimulatedSLM (simulate: True) anywhere else.
Masks are uint8 arrays of shape (height, width) (or a flat
height*width buffer) already mapped through the phase LUT by the caller; the
hardware applies its own voltage LUT on top.
- pytweezer.drivers.slm.DEFAULT_SDK_DLL = 'C:\\Program Files\\Meadowlark Optics\\Blink Plus\\SDK\\Blink_C_wrapper'¶
Defaults matching the lab’s Blink Plus install; overridable via config.
- pytweezer.drivers.slm.MAX_PRELOAD_FRAMES = 752¶
Frames the 1024x1024 board’s on-board memory holds (manual S4.3.9).
- class pytweezer.drivers.slm.SLM(sdk_dll='C:\\Program Files\\Meadowlark Optics\\Blink Plus\\SDK\\Blink_C_wrapper', lut_file='C:\\Program Files\\Meadowlark Optics\\Blink Plus\\LUT Files\\slm40_at852.LUT', board_number=1, timeout_ms=5000, wait_for_trigger=False, flip_immediate=False, output_pulse=False)[source]¶
Bases:
objectBlink Plus SLM over its ctypes C-wrapper SDK.
The live hardware handle (the loaded DLL) lives on
_lib;Nonemeans disconnected. One board only (board number defaults to 1).- Parameters:
- preload_image(mask_array, frame)[source]¶
Upload one mask into on-board frame slot
frame.Same destination as
preload_sequence(), one frame at a time, so frames can be uploaded as they are generated instead of after the whole sequence exists. Does not display anything. Raises on failure.
- preload_sequence(mask_sequence)[source]¶
Upload a whole
(n, H, W)sequence into the SLM’s on-board memory.Does not display anything by itself (1024x1024 board only, up to 752 frames); the upload time is logged. Raises on failure.
- Parameters:
mask_sequence (ndarray)
- Return type:
None
- run_sequence(mask_sequence, fps=1.0)[source]¶
Display each frame of a
(n, H, W)sequence atfps(software timed).Software-timed writes; for hardware-triggered playback use
preload_sequence(),start_auto_increment(), and drive the SLM’s external trigger.
- set_wait_for_trigger(enabled)[source]¶
Turn external-trigger gating on or off at runtime.
With it on, an image is not displayed until a trigger falling edge arrives, and calls that load images (
update_mask,preload_sequence) block until one does ortimeout_msexpires. Preloading therefore has to happen with it off; turn it on only to clock a preloaded sequence out withstart_auto_increment().- Parameters:
enabled (bool)
- Return type:
None
- start_auto_increment(list_length)[source]¶
Arm hardware auto-increment over a preloaded sequence.
After
preload_sequence(), this makes the SLM listen for external triggers: frame 0 is live once armed, then each trigger advances to the next preloaded frame, looping back to frame 0 after the last one, untilstop_auto_increment(). So ann-frame sequence needsn-1triggers to end on the final frame; ann-th trigger wraps to frame 0.1024x1024 board with firmware rev >= 2.4 only. Raises on failure.
- Parameters:
list_length (int)
- Return type:
None
- stop_auto_increment()[source]¶
Stop hardware auto-increment (see
start_auto_increment()).Leaves whichever frame was last triggered live on the SLM. Raises on failure.
- Return type:
None
- class pytweezer.drivers.slm.SimulatedSLM(width=1024, height=1024, depth=8, **_ignored)[source]¶
Bases:
objectSynthetic SLM: remembers the last mask written and counts frames.
Interface-complete with
SLMviasimulate(), so anything the real driver adds is auto-stubbed. Fixed 1024x1024 8-bit geometry, matching the lab’s board.