Skip to content

Towards a First Acquisition

A complete acquisition workflow requires coordinating multiple hardware sub-systems in a defined sequence: selecting the correct optical path, opening the illumination shutter, snapping the image, and safely closing the shutter once the frame is captured. This example demonstrates how to orchestrate these steps programmatically using the Inscoper API.

Prerequisites

This example builds on the device exploration pattern introduced in Explore Devices. The device map constructed in that example is reused here to locate all relevant sub-devices by their functional type.

Overview

The acquisition sequence relies on six sub-device types:

Sub-device type Role
OBJECTIVE Selects the active objective on the turret
CUBE Selects the active filter cube on the turret
X_AXIS / Y_AXIS Hold the current stage position along each axis
MOVE_AXIS Triggers the physical stage movement
Transmission lamp intensity Sets the illumination intensity (as a percentage)
SHUTTER (TL) Opens and closes the transmitted-light illumination path

The example executes the following steps in order:

  1. Select the objective slot and filter cube slot.
  2. Set the lamp intensity and open the transmitted-light shutter.
  3. Snap a single image and retrieve the pixel data.
  4. Display the image in a viewer.
  5. Close the shutter and reduce the lamp intensity to zero.

Note

This example uses a configuration named camera_and_microscope and a camera named MyCamera. Replace these values with the names defined in your own hardware configuration file.

Proto-acquisition

# 1. Create the Napari viewer
viewer = napari.Viewer()

objective_slot = 0
cube_slot = 0
lamp_intensity_percent = 30

# To move the stage we need to interact with the X_AXIS, Y_AXIS, and MOVE_XY sub-devices.
x_axis_sub_device_id    = None
y_axis_sub_device_id    = None
move_xy_sub_device_id   = None
objective_turret_sub_device_id = None
cube_turret_sub_device_id = None
light_power_sub_device_id = None
shutter_tl_sub_device_id = None
for device_id, device in device_map.items():
    for sub_device_tag, sub_device in device.sub_device_map.items():
        if sub_device.inscoper_type == "X_AXIS":
            x_axis_sub_device_id    = inscoper_api.SubDeviceId(device.name, sub_device.name)
        elif sub_device.inscoper_type == "Y_AXIS":
            y_axis_sub_device_id    = inscoper_api.SubDeviceId(device.name, sub_device.name)
        elif sub_device.inscoper_type == "MOVE_AXIS":
            move_xy_sub_device_id   = inscoper_api.SubDeviceId(device.name, sub_device.name)
        elif sub_device.inscoper_type == "SHUTTER" and "TL" in sub_device.name:
            shutter_tl_sub_device_id = inscoper_api.SubDeviceId(device.name, sub_device.name)
        elif sub_device.inscoper_type == "OBJECTIVE":
            objective_turret_sub_device_id = inscoper_api.SubDeviceId(device.name, sub_device.name)
        elif sub_device.inscoper_type == "CUBE":
            cube_turret_sub_device_id = inscoper_api.SubDeviceId(device.name, sub_device.name)
        elif ("Intensity" in sub_device.name or "Power" in sub_device.name) and "TL" in sub_device.name:
            light_power_sub_device_id = inscoper_api.SubDeviceId(device.name, sub_device.name)

my_bridge.setValue(objective_turret_sub_device_id, objective_slot)
my_bridge.setValue(cube_turret_sub_device_id, cube_slot)
my_bridge.setValue(light_power_sub_device_id, lamp_intensity_percent)
my_bridge.setValue(shutter_tl_sub_device_id, 1)

my_camera = my_bridge.getCamera("MyCamera")
image = my_camera.snapImage(0)

image_data = image.getImageData()

image_width = image.getWidth()
image_height = image.getHeight()
pixel_size_bytes = image.getPixelSize()
bit_depth = image.getBitDepth()
bytes_per_value = bit_depth // 8

values_per_pixel = pixel_size_bytes // bytes_per_value
img = np.reshape(image_data, (image_height, image_width, values_per_pixel))

viewer.add_image(img[:, :, 0], name="Microscope Snap")

my_bridge.setValue(shutter_tl_sub_device_id, 0)
my_bridge.setValue(light_power_sub_device_id, 0)

napari.run()