Skip to content

pymmcore_plus.experimental.unicore

Pure-Python device adapters, used alongside C++ devices with UniMMCore.

Classes

Name Description
CameraDevice
Device ABC for all Devices.
GenericDevice Generic device API, e.g. for devices that don't fit into other categories.
HubDevice ABC for Hub devices that can have peripheral devices attached.
PropertyInfo State of a property of a device.
SLMDevice ABC for Spatial Light Modulator (SLM) devices.
ShutterDevice Shutter device API, e.g. for physical shutters or electronic shutter control.
SimpleCameraDevice A convenience subclass of CameraDevice for simple/simulated cameras.
StageDevice ABC for Stage devices.
StateDevice State device API, e.g. filter wheel, objective turret, etc.
UniMMCore Unified Core object that first checks for python, then C++ devices.
XYStageDevice ABC for XYStage devices.
XYStepperStageDevice ABC for XYStage devices that support stepper motors.

Functions

Name Description
pymm_property Decorates a (getter) method to create a device property.

Classes

UniMMCore

UniMMCore(*args: Any, **kwargs: Any)

Bases: CMMCorePlus

Unified Core object that first checks for python, then C++ devices.

load_py_device

load_py_device = loadPyDevice

loadSystemConfiguration

loadSystemConfiguration(fileName: str | Path = 'MMConfig_demo.cfg') -> None

Load a system config file conforming to the MM .cfg format.

This is a Python implementation that supports both C++ and Python devices. Lines prefixed with #py are processed as Python device commands but are ignored by upstream C++/pymmcore implementations.

Format example:

# C++ devices
Device,Camera,DemoCamera,DCam
Property,Core,Initialize,1

# Python devices (hidden from upstream via comment prefix)
#py pyDevice,PyCamera,mypackage.cameras,MyCameraClass
#py Property,PyCamera,Exposure,50.0

See https://micro-manager.org/Micro-Manager_Configuration_Guide#configuration-file-syntax

For relative paths, the current working directory is first checked, then the device adapter path is checked.

Parameters:

Name Type Description Default
fileName str | Path

Path to the configuration file. Defaults to "MMConfig_demo.cfg".

'MMConfig_demo.cfg'

saveSystemConfiguration

saveSystemConfiguration(
    filename: str | Path, *, prefix_py_devices: bool = True
) -> None

Save the current system configuration to a text file.

This saves both C++ and Python devices. Python device lines are prefixed with #py by default so they are ignored by upstream C++/pymmcore.

Parameters:

Name Type Description Default
filename str | Path

Path to save the configuration file.

required
prefix_py_devices bool

If True (default), Python device lines are prefixed with #py so they are ignored by upstream C++/pymmcore implementations, allowing config files to work with regular pymmcore. If False, Python device lines are saved without the prefix (config will only be loadable by UniMMCore).

True

loadDevice

loadDevice(
    label: str, moduleName: AdapterName | str, deviceName: DeviceName | str
) -> None

Loads a device from the plugin library, or python module.

In the standard MM case, this will load a device from the plugin library:

core.loadDevice("cam", "DemoCamera", "DCam")

For python devices, this will load a device from a python module:

core.loadDevice("pydev", "package.module", "DeviceClass")

loadPyDevice

loadPyDevice(label: str, device: Device) -> None

Load a unicore.Device as a python device.

This API allows you to create python-side Device objects that can be used in tandem with the C++ devices. Whenever a method is called that would normally interact with a C++ device, this class will first check if a python device with the same label exists, and if so, use that instead.

Parameters:

Name Type Description Default
label str

The label to assign to the device.

required
device Device

The device object to load. Use the appropriate subclass of Device for the type of device you are creating.

required

isPyDevice

isPyDevice(label: DeviceLabel | str) -> bool

Returns True if the specified device label corresponds to a Python device.

unloadDevice

unloadDevice(label: DeviceLabel | str) -> None

unloadAllDevices

unloadAllDevices() -> None

reset

reset() -> None

initializeDevice

initializeDevice(label: DeviceLabel | str) -> None

initializeAllDevices

initializeAllDevices() -> None

getDeviceInitializationState

getDeviceInitializationState(label: str) -> DeviceInitializationState

getLoadedDevices

getLoadedDevices() -> tuple[DeviceLabel, ...]

getLoadedDevicesOfType

getLoadedDevicesOfType(devType: int) -> tuple[DeviceLabel, ...]

getDeviceType

getDeviceType(label: str) -> DeviceType

getDeviceLibrary

getDeviceLibrary(label: DeviceLabel | str) -> AdapterName

getDeviceName

getDeviceName(label: DeviceLabel | str) -> DeviceName

getDeviceDescription

getDeviceDescription(label: DeviceLabel | str) -> str

getParentLabel

getParentLabel(peripheralLabel: DeviceLabel | str) -> DeviceLabel | Literal['']

setParentLabel

setParentLabel(
    deviceLabel: DeviceLabel | str, parentHubLabel: DeviceLabel | str
) -> None

getInstalledDevices

getInstalledDevices(hubLabel: DeviceLabel | str) -> tuple[DeviceName, ...]

getLoadedPeripheralDevices

getLoadedPeripheralDevices(
    hubLabel: DeviceLabel | str,
) -> tuple[DeviceLabel, ...]

getInstalledDeviceDescription

getInstalledDeviceDescription(
    hubLabel: DeviceLabel | str, peripheralLabel: DeviceName | str
) -> str

getDevicePropertyNames

getDevicePropertyNames(label: DeviceLabel | str) -> tuple[PropertyName, ...]

hasProperty

hasProperty(label: DeviceLabel | str, propName: PropertyName | str) -> bool

getProperty

getProperty(label: DeviceLabel | str, propName: PropertyName | str) -> Any

getPropertyFromCache

getPropertyFromCache(
    deviceLabel: DeviceLabel | str, propName: PropertyName | str
) -> Any

setProperty

setProperty(
    label: str, propName: str, propValue: bool | float | int | str
) -> None

getPropertyType

getPropertyType(label: str, propName: str) -> PropertyType

hasPropertyLimits

hasPropertyLimits(
    label: DeviceLabel | str, propName: PropertyName | str
) -> bool

getPropertyLowerLimit

getPropertyLowerLimit(
    label: DeviceLabel | str, propName: PropertyName | str
) -> float

getPropertyUpperLimit

getPropertyUpperLimit(
    label: DeviceLabel | str, propName: PropertyName | str
) -> float

getAllowedPropertyValues

getAllowedPropertyValues(
    label: DeviceLabel | str, propName: PropertyName | str
) -> tuple[str, ...]

isPropertyPreInit

isPropertyPreInit(
    label: DeviceLabel | str, propName: PropertyName | str
) -> bool

isPropertyReadOnly

isPropertyReadOnly(
    label: DeviceLabel | str, propName: PropertyName | str
) -> bool

isPropertySequenceable

isPropertySequenceable(
    label: DeviceLabel | str, propName: PropertyName | str
) -> bool

getPropertySequenceMaxLength

getPropertySequenceMaxLength(
    label: DeviceLabel | str, propName: PropertyName | str
) -> int

loadPropertySequence

loadPropertySequence(
    label: DeviceLabel | str,
    propName: PropertyName | str,
    eventSequence: Sequence[Any],
) -> None

startPropertySequence

startPropertySequence(
    label: DeviceLabel | str, propName: PropertyName | str
) -> None

stopPropertySequence

stopPropertySequence(
    label: DeviceLabel | str, propName: PropertyName | str
) -> None

deviceBusy

deviceBusy(label: DeviceLabel | str) -> bool

waitForDevice

waitForDevice(label: DeviceLabel | str) -> None

waitForConfig

waitForConfig(group: str, configName: str) -> None

systemBusy

systemBusy() -> bool

waitForSystem

waitForSystem() -> None

waitForDeviceType

waitForDeviceType(devType: int) -> None

deviceTypeBusy

deviceTypeBusy(devType: int) -> bool

getDeviceDelayMs

getDeviceDelayMs(label: DeviceLabel | str) -> float

setDeviceDelayMs

setDeviceDelayMs(label: DeviceLabel | str, delayMs: float) -> None

usesDeviceDelay

usesDeviceDelay(label: DeviceLabel | str) -> bool

setXYStageDevice

setXYStageDevice(xyStageLabel: DeviceLabel | str) -> None

getXYStageDevice

getXYStageDevice() -> DeviceLabel | Literal['']

Returns the label of the currently selected XYStage device.

Returns empty string if no XYStage device is selected.

setXYPosition

setXYPosition(x: float, y: float) -> None
setXYPosition(xyStageLabel: DeviceLabel | str, x: float, y: float) -> None
setXYPosition(*args: Any) -> None

Sets the position of the XY stage in microns.

getXYPosition

getXYPosition() -> tuple[float, float]
getXYPosition(xyStageLabel: DeviceLabel | str) -> tuple[float, float]
getXYPosition(xyStageLabel: DeviceLabel | str = '') -> tuple[float, float]

Obtains the current position of the XY stage in microns.

getXPosition

getXPosition() -> float
getXPosition(xyStageLabel: DeviceLabel | str) -> float
getXPosition(xyStageLabel: DeviceLabel | str = '') -> float

Obtains the current position of the X axis of the XY stage in microns.

getYPosition

getYPosition() -> float
getYPosition(xyStageLabel: DeviceLabel | str) -> float
getYPosition(xyStageLabel: DeviceLabel | str = '') -> float

Obtains the current position of the Y axis of the XY stage in microns.

getXYStageSequenceMaxLength

getXYStageSequenceMaxLength(xyStageLabel: DeviceLabel | str) -> int

Gets the maximum length of an XY stage's position sequence.

isXYStageSequenceable

isXYStageSequenceable(xyStageLabel: DeviceLabel | str) -> bool

Queries XY stage if it can be used in a sequence.

loadXYStageSequence

loadXYStageSequence(
    xyStageLabel: DeviceLabel | str,
    xSequence: Sequence[float],
    ySequence: Sequence[float],
) -> None

Transfer a sequence of stage positions to the xy stage.

xSequence and ySequence must have the same length. This should only be called for XY stages that are sequenceable

setOriginX

setOriginX() -> None
setOriginX(xyStageLabel: DeviceLabel | str) -> None
setOriginX(xyStageLabel: DeviceLabel | str = '') -> None

Zero the given XY stage's X coordinate at the current position.

setOriginY

setOriginY() -> None
setOriginY(xyStageLabel: DeviceLabel | str) -> None
setOriginY(xyStageLabel: DeviceLabel | str = '') -> None

Zero the given XY stage's Y coordinate at the current position.

setOriginXY

setOriginXY() -> None
setOriginXY(xyStageLabel: DeviceLabel | str) -> None
setOriginXY(xyStageLabel: DeviceLabel | str = '') -> None

Zero the given XY stage's coordinates at the current position.

setAdapterOriginXY

setAdapterOriginXY(newXUm: float, newYUm: float) -> None
setAdapterOriginXY(
    xyStageLabel: DeviceLabel | str, newXUm: float, newYUm: float
) -> None
setAdapterOriginXY(*args: Any) -> None

Enable software translation of coordinates for the current XY stage.

The current position of the stage becomes (newXUm, newYUm). It is recommended that setOriginXY() be used instead where available.

setRelativeXYPosition

setRelativeXYPosition(dx: float, dy: float) -> None
setRelativeXYPosition(
    xyStageLabel: DeviceLabel | str, dx: float, dy: float
) -> None
setRelativeXYPosition(*args: Any) -> None

Sets the relative position of the XY stage in microns.

startXYStageSequence

startXYStageSequence(xyStageLabel: DeviceLabel | str) -> None

Starts an ongoing sequence of triggered events in an XY stage.

This should only be called for stages that are sequenceable

stopXYStageSequence

stopXYStageSequence(xyStageLabel: DeviceLabel | str) -> None

Stops an ongoing sequence of triggered events in an XY stage.

This should only be called for stages that are sequenceable

getFocusDevice

getFocusDevice() -> DeviceLabel | Literal['']

Return the current Focus Device.

setFocusDevice

setFocusDevice(focusLabel: str) -> None

Set new current Focus Device.

getPosition

getPosition() -> float
getPosition(stageLabel: str) -> float
getPosition(stageLabel: str | None = None) -> float

setPosition

setPosition(position: float) -> None
setPosition(stageLabel: DeviceLabel | str, position: float) -> None
setPosition(*args: Any) -> None

setFocusDirection

setFocusDirection(stageLabel: DeviceLabel | str, sign: int) -> None

getFocusDirection

getFocusDirection(stageLabel: DeviceLabel | str) -> FocusDirection

Get the current focus direction of the Z stage.

setOrigin

setOrigin() -> None
setOrigin(stageLabel: DeviceLabel | str) -> None
setOrigin(stageLabel: DeviceLabel | str | None = None) -> None

Zero the current focus/Z stage's coordinates at the current position.

setRelativePosition

setRelativePosition(d: float) -> None
setRelativePosition(stageLabel: DeviceLabel | str, d: float) -> None
setRelativePosition(*args: Any) -> None

Sets the relative position of the stage in microns.

setAdapterOrigin

setAdapterOrigin(newZUm: float) -> None
setAdapterOrigin(stageLabel: DeviceLabel | str, newZUm: float) -> None
setAdapterOrigin(*args: Any) -> None

Enable software translation of coordinates for the current focus/Z stage.

The current position of the stage becomes Z = newZUm. Only some stages support this functionality; it is recommended that setOrigin() be used instead where available.

isStageSequenceable

isStageSequenceable(stageLabel: DeviceLabel | str) -> bool

Queries stage if it can be used in a sequence.

isStageLinearSequenceable

isStageLinearSequenceable(stageLabel: DeviceLabel | str) -> bool

Queries if the stage can be used in a linear sequence.

A linear sequence is defined by a step size and number of slices.

getStageSequenceMaxLength

getStageSequenceMaxLength(stageLabel: DeviceLabel | str) -> int

Gets the maximum length of a stage's position sequence.

loadStageSequence

loadStageSequence(
    stageLabel: DeviceLabel | str, positionSequence: Sequence[float]
) -> None

Transfer a sequence of stage positions to the stage.

This should only be called for stages that are sequenceable.

startStageSequence

startStageSequence(stageLabel: DeviceLabel | str) -> None

Starts an ongoing sequence of triggered events in a stage.

This should only be called for stages that are sequenceable.

stopStageSequence

stopStageSequence(stageLabel: DeviceLabel | str) -> None

Stops an ongoing sequence of triggered events in a stage.

This should only be called for stages that are sequenceable.

setStageLinearSequence

setStageLinearSequence(
    stageLabel: DeviceLabel | str, dZ_um: float, nSlices: int
) -> None

Loads a linear sequence (defined by step size and nr. of steps).

isContinuousFocusDrive

isContinuousFocusDrive(stageLabel: DeviceLabel | str) -> bool

Check if a stage has continuous focusing capability.

Returns True if positions can be set while continuous focus runs.

home

home(xyOrZStageLabel: DeviceLabel | str) -> None

Perform a hardware homing operation for an XY or focus/Z stage.

stop

stop(xyOrZStageLabel: DeviceLabel | str) -> None

Stop the XY or focus/Z stage.

setCameraDevice

setCameraDevice(cameraLabel: DeviceLabel | str) -> None

Set the camera device.

getCameraDevice

getCameraDevice() -> DeviceLabel | Literal['']

Returns the label of the currently selected camera device.

Returns empty string if no camera device is selected.

getImage

getImage(*, fix: bool = True) -> ndarray
getImage(numChannel: int, *, fix: bool = True) -> ndarray
getImage(numChannel: int | None = None, *, fix: bool = True) -> ndarray

isSequenceRunning

isSequenceRunning() -> bool
isSequenceRunning(cameraLabel: DeviceLabel | str) -> bool
isSequenceRunning(cameraLabel: DeviceLabel | str | None = None) -> bool

getRemainingImageCount

getRemainingImageCount() -> int

getLastImage

getLastImage(*, out: ndarray | None = None) -> ndarray

getLastImageMD

getLastImageMD(
    channel: int, slice: int, md: Metadata, /, *, out: ndarray | None = None
) -> ndarray
getLastImageMD(md: Metadata, /, *, out: ndarray | None = None) -> ndarray
getLastImageMD(*args: Any, out: ndarray | None = None) -> ndarray

getNBeforeLastImageMD

getNBeforeLastImageMD(
    n: int, md: Metadata, /, *, out: ndarray | None = None
) -> ndarray

popNextImage

popNextImage(*, fix: bool = True) -> ndarray

popNextImageMD

popNextImageMD(channel: int, slice: int, md: Metadata) -> ndarray
popNextImageMD(md: Metadata) -> ndarray
popNextImageMD(*args: Any) -> ndarray

setCircularBufferMemoryFootprint

setCircularBufferMemoryFootprint(sizeMB: int) -> None

Set the circular buffer memory footprint in MB.

initializeCircularBuffer

initializeCircularBuffer() -> None

Initialize the circular buffer.

getBufferFreeCapacity

getBufferFreeCapacity() -> int

Get the number of free slots in the circular buffer.

getBufferTotalCapacity

getBufferTotalCapacity() -> int

Get the total capacity of the circular buffer.

getCircularBufferMemoryFootprint

getCircularBufferMemoryFootprint() -> int

Get the circular buffer memory footprint in MB.

clearCircularBuffer

clearCircularBuffer() -> None

Clear all images from the circular buffer.

isBufferOverflowed

isBufferOverflowed() -> bool

Check if the circular buffer has overflowed.

getImageBitDepth

getImageBitDepth() -> int

getBytesPerPixel

getBytesPerPixel() -> int

getImageBufferSize

getImageBufferSize() -> int

getImageHeight

getImageHeight() -> int

getImageWidth

getImageWidth() -> int

getNumberOfComponents

getNumberOfComponents() -> int

getNumberOfCameraChannels

getNumberOfCameraChannels() -> int

getCameraChannelName

getCameraChannelName(channelNr: int) -> str

Get the name of the camera channel.

getExposure

getExposure() -> float
getExposure(cameraLabel: DeviceLabel | str) -> float
getExposure(cameraLabel: DeviceLabel | str | None = None) -> float

Get the exposure time in milliseconds.

setExposure

setExposure(exp: float) -> None
setExposure(cameraLabel: DeviceLabel | str, dExp: float) -> None
setExposure(*args: Any) -> None

Set the exposure time in milliseconds.

getROI

getROI() -> list[int]
getROI(label: DeviceLabel | str) -> list[int]
getROI(label: DeviceLabel | str = '') -> list[int]

Get the current region of interest (ROI) for the camera.

clearROI

clearROI() -> None

Clear the current region of interest (ROI) for the camera.

isExposureSequenceable

isExposureSequenceable(cameraLabel: DeviceLabel | str) -> bool

Check if the camera supports exposure sequences.

loadExposureSequence

loadExposureSequence(
    cameraLabel: DeviceLabel | str, exposureSequence_ms: Sequence[float]
) -> None

Transfer a sequence of exposure times to the camera.

getExposureSequenceMaxLength

getExposureSequenceMaxLength(cameraLabel: DeviceLabel | str) -> int

Get the maximum length of the exposure sequence.

startExposureSequence

startExposureSequence(cameraLabel: DeviceLabel | str) -> None

Start a sequence of exposures.

stopExposureSequence

stopExposureSequence(cameraLabel: DeviceLabel | str) -> None

Stop a sequence of exposures.

prepareSequenceAcquisition

prepareSequenceAcquisition(cameraLabel: DeviceLabel | str) -> None

Prepare the camera for sequence acquisition.

getPixelSizeAffine

getPixelSizeAffine() -> AffineTuple
getPixelSizeAffine(cached: bool) -> AffineTuple
getPixelSizeAffine(cached: bool = False) -> AffineTuple

Get the pixel size affine transformation matrix.

getPixelSizeUm

getPixelSizeUm() -> float
getPixelSizeUm(cached: bool) -> float
getPixelSizeUm(cached: bool = False) -> float

Get the pixel size in micrometers.

setSLMDevice

setSLMDevice(slmLabel: DeviceLabel | str) -> None

Set the SLM device.

getSLMDevice

getSLMDevice() -> DeviceLabel | Literal['']

Returns the label of the currently selected SLM device.

Returns empty string if no SLM device is selected.

setSLMImage

setSLMImage(pixels: ndarray) -> None
setSLMImage(slmLabel: DeviceLabel | str, pixels: ndarray) -> None
setSLMImage(*args: Any) -> None

Load the image into the SLM device adapter.

getSLMImage

getSLMImage(slmLabel: DeviceLabel | str | None = None) -> ndarray

Get the current image from the SLM device.

setSLMPixelsTo

setSLMPixelsTo(intensity: int) -> None
setSLMPixelsTo(red: int, green: int, blue: int) -> None
setSLMPixelsTo(slmLabel: DeviceLabel | str, intensity: int) -> None
setSLMPixelsTo(
    slmLabel: DeviceLabel | str, red: int, green: int, blue: int
) -> None
setSLMPixelsTo(*args: Any) -> None

Set all pixels of the SLM to a uniform intensity or RGB values.

displaySLMImage

displaySLMImage() -> None
displaySLMImage(slmLabel: DeviceLabel | str) -> None
displaySLMImage(slmLabel: DeviceLabel | str | None = None) -> None

Command the SLM to display the loaded image.

setSLMExposure

setSLMExposure(interval_ms: float) -> None
setSLMExposure(slmLabel: DeviceLabel | str, interval_ms: float) -> None
setSLMExposure(*args: Any) -> None

Command the SLM to turn off after a specified interval.

getSLMExposure

getSLMExposure() -> float
getSLMExposure(slmLabel: DeviceLabel | str) -> float
getSLMExposure(slmLabel: DeviceLabel | str | None = None) -> float

Find out the exposure interval of an SLM.

getSLMWidth

getSLMWidth() -> int
getSLMWidth(slmLabel: DeviceLabel | str) -> int
getSLMWidth(slmLabel: DeviceLabel | str | None = None) -> int

Returns the width of the SLM in pixels.

getSLMHeight

getSLMHeight() -> int
getSLMHeight(slmLabel: DeviceLabel | str) -> int
getSLMHeight(slmLabel: DeviceLabel | str | None = None) -> int

Returns the height of the SLM in pixels.

getSLMNumberOfComponents

getSLMNumberOfComponents() -> int
getSLMNumberOfComponents(slmLabel: DeviceLabel | str) -> int
getSLMNumberOfComponents(slmLabel: DeviceLabel | str | None = None) -> int

Returns the number of color components (channels) in the SLM.

getSLMBytesPerPixel

getSLMBytesPerPixel() -> int
getSLMBytesPerPixel(slmLabel: DeviceLabel | str) -> int
getSLMBytesPerPixel(slmLabel: DeviceLabel | str | None = None) -> int

Returns the number of bytes per pixel for the SLM.

getSLMSequenceMaxLength

getSLMSequenceMaxLength(slmLabel: DeviceLabel | str) -> int

Get the maximum length of an image sequence that can be uploaded.

loadSLMSequence

loadSLMSequence(
    slmLabel: DeviceLabel | str, imageSequence: Sequence[bytes | ndarray]
) -> None

Load a sequence of images to the SLM.

startSLMSequence

startSLMSequence(slmLabel: DeviceLabel | str) -> None

Start a sequence of images on the SLM.

stopSLMSequence

stopSLMSequence(slmLabel: DeviceLabel | str) -> None

Stop a sequence of images on the SLM.

setState

setState(stateDeviceLabel: DeviceLabel | str, state: int) -> None

Set state (position) on the specific device.

getState

getState(stateDeviceLabel: DeviceLabel | str) -> int

Return the current state (position) on the specific device.

getNumberOfStates

getNumberOfStates(stateDeviceLabel: DeviceLabel | str) -> int

Return the total number of available positions (states).

setStateLabel

setStateLabel(stateDeviceLabel: DeviceLabel | str, stateLabel: str) -> None

Set device state using the previously assigned label (string).

getStateLabel

getStateLabel(stateDeviceLabel: DeviceLabel | str) -> StateLabel

Return the current state as the label (string).

defineStateLabel

defineStateLabel(
    stateDeviceLabel: DeviceLabel | str, state: int, label: str
) -> None

Define a label for the specific state.

getStateLabels

getStateLabels(stateDeviceLabel: DeviceLabel | str) -> tuple[StateLabel, ...]

Return labels for all states.

getStateFromLabel

getStateFromLabel(stateDeviceLabel: DeviceLabel | str, stateLabel: str) -> int

Obtain the state for a given label.

setShutterDevice

setShutterDevice(shutterLabel: DeviceLabel | str) -> None

getShutterDevice

getShutterDevice() -> DeviceLabel | Literal['']

Returns the label of the currently selected Shutter device.

Returns empty string if no Shutter device is selected.

getShutterOpen

getShutterOpen() -> bool
getShutterOpen(shutterLabel: DeviceLabel | str) -> bool
getShutterOpen(shutterLabel: DeviceLabel | str | None = None) -> bool

defineConfigGroup

defineConfigGroup(groupName: str) -> None

deleteConfigGroup

deleteConfigGroup(groupName: str) -> None

renameConfigGroup

renameConfigGroup(oldGroupName: str, newGroupName: str) -> None

defineConfig

defineConfig(groupName: str, configName: str) -> None
defineConfig(
    groupName: str, configName: str, deviceLabel: str, propName: str, value: Any
) -> None
defineConfig(
    groupName: str,
    configName: str,
    deviceLabel: str | None = None,
    propName: str | None = None,
    value: Any | None = None,
) -> None

deleteConfig

deleteConfig(groupName: str, configName: str) -> None
deleteConfig(
    groupName: str, configName: str, deviceLabel: str, propName: str
) -> None
deleteConfig(
    groupName: str,
    configName: str,
    deviceLabel: str | None = None,
    propName: str | None = None,
) -> None

renameConfig

renameConfig(groupName: str, oldConfigName: str, newConfigName: str) -> None

getConfigData

getConfigData(
    configGroup: str, configName: str, *, native: Literal[True]
) -> Configuration
getConfigData(
    configGroup: str, configName: str, *, native: Literal[False] = False
) -> Configuration
getConfigData(
    configGroup: str, configName: str, *, native: bool = False
) -> Configuration | Configuration

setConfig

setConfig(groupName: str, configName: str) -> None

getCurrentConfig

getCurrentConfig(groupName: str) -> ConfigPresetName | Literal['']

getCurrentConfigFromCache

getCurrentConfigFromCache(groupName: str) -> ConfigPresetName | Literal['']

getConfigState

getConfigState(
    group: str, config: str, *, native: bool = False
) -> Configuration | Configuration

getConfigGroupState

getConfigGroupState(group: str, *, native: Literal[True]) -> Configuration
getConfigGroupState(
    group: str, *, native: Literal[False] = False
) -> Configuration
getConfigGroupState(
    group: str, *, native: bool = False
) -> Configuration | Configuration

getConfigGroupStateFromCache

getConfigGroupStateFromCache(
    group: str, *, native: Literal[True]
) -> Configuration
getConfigGroupStateFromCache(
    group: str, *, native: Literal[False] = False
) -> Configuration
getConfigGroupStateFromCache(
    group: str, *, native: bool = False
) -> Configuration | Configuration

getSystemState

getSystemState(*, native: bool = False) -> Configuration | Configuration

Return the entire system state including Python device properties.

This method iterates through all devices (C++ and Python) and returns all property values. Following the C++ implementation pattern.

getSystemStateCache

getSystemStateCache(*, native: Literal[True]) -> Configuration
getSystemStateCache(*, native: Literal[False] = False) -> Configuration
getSystemStateCache(*, native: bool = False) -> Configuration | Configuration

updateSystemStateCache

updateSystemStateCache() -> None

Update the system state cache for all devices including Python devices.

This populates our Python-side cache with current values from all Python devices, then calls the C++ updateSystemStateCache.

CameraDevice

CameraDevice()

Bases: Device

STANDARD_PROPERTIES

STANDARD_PROPERTIES: ClassVar = MappingProxyType(
    {
        Keyword.ActualInterval_ms: ("actual_interval_ms", float),
        Keyword.Binning: ("binning", int),
        Keyword.CameraID: ("camera_id", str),
        Keyword.CameraName: ("camera_name", str),
        Keyword.CCDTemperature: ("ccd_temperature", float),
        Keyword.CCDTemperatureSetPoint: ("ccd_temperature_set_point", float),
        Keyword.EMGain: ("em_gain", float),
        Keyword.Exposure: ("exposure", float),
        Keyword.Gain: ("gain", float),
        Keyword.Interval_ms: ("interval_ms", float),
        Keyword.Offset: ("offset", float),
        "PixelFormat": ("pixel_format", PixelFormat),
        Keyword.ReadoutMode: ("readout_mode", str),
        Keyword.ReadoutTime: ("readout_time", float),
        Keyword.Metadata_ROI_X: ("roi_x", int),
        Keyword.Metadata_ROI_Y: ("roi_y", int),
    }
)

get_exposure abstractmethod

get_exposure() -> float

Get the current exposure time in milliseconds.

set_exposure abstractmethod

set_exposure(exposure: float) -> None

Set the exposure time in milliseconds.

shape abstractmethod

shape() -> tuple[int, int] | tuple[int, int, int]

Return the shape of the current image buffer.

This is used when querying Height, Width and number of components. If the camera is grayscale, it should return (height, width). If the camera is color, it should return (height, width, n_channels).

If the camera supports ROI, this should return the ROI dimensions.

dtype abstractmethod

dtype() -> DTypeLike

Return the data type of the image buffer.

start_sequence abstractmethod

start_sequence(
    n: int | None, get_buffer: Callable[[Sequence[int], DTypeLike], ndarray]
) -> Iterator[Mapping]

Start a sequence acquisition.

This method should be implemented by the camera device adapter and should yield metadata for each acquired image. The implementation should call get_buffer() to get a buffer, fill it with image data, then yield the metadata for that image.

The core will handle threading and synchronization. This function may block.

Parameters:

Name Type Description Default
n int | None

If an integer, this is the number of images to acquire. If None, the camera should acquire images indefinitely until stopped.

required
get_buffer Callable[[Sequence[int], DTypeLike], ndarray]

A callable that returns a buffer for the camera to fill with image data. You should call this with the shape of the image and the dtype of the image data. The core will produce a buffer of the requested shape and dtype, and you should fill it (in place) with the image data.

required

Yields:

Type Description
Mapping

Metadata for each acquired image. This should be yielded after the corresponding buffer has been filled with image data.

register_standard_properties

register_standard_properties() -> None

Inspect the class for standard properties and register them.

get_roi

get_roi() -> tuple[int, int, int, int]

Return the current ROI as (x, y, width, height).

The default implementation returns the full frame from shape(). Override in subclasses to support hardware ROI.

set_roi

set_roi(x: int, y: int, width: int, height: int) -> None

Set the ROI.

The default implementation raises NotImplementedError. Override in subclasses to support hardware ROI.

clear_roi

clear_roi() -> None

Reset the ROI to the full sensor frame.

No-op by default (nothing was set, nothing to clear).

get_binning

get_binning() -> int

Get the binning factor for the camera.

SimpleCameraDevice

SimpleCameraDevice()

Bases: CameraDevice

A convenience subclass of CameraDevice for simple/simulated cameras.

Instead of implementing start_sequence() and shape() directly, subclasses only need to implement:

  • sensor_shape(): the full (height, width) of the sensor
  • snap(buffer): fill the provided full-frame buffer with image data and return metadata. The buffer is always sized to sensor_shape(). If a ROI is active, cropping is handled automatically by this base class.

Software ROI (set_roi / clear_roi) works out of the box.

.. warning:: This class is not recommended for real hardware cameras that need efficient ring-buffer or hardware-triggered acquisition. For those, use subclass CameraDevice directly and implement start_sequence().

sensor_shape abstractmethod

sensor_shape() -> tuple[int, int] | tuple[int, int, int]

Return the full sensor shape (height, width[, n_channels]).

snap abstractmethod

snap(buffer: ndarray) -> Mapping

Snap a single image into the provided full-frame buffer.

Parameters:

Name Type Description Default
buffer ndarray

Pre-allocated buffer shaped to sensor_shape(). Must be filled with full-frame image data every time.

required

Returns:

Type Description
Mapping

Metadata for the acquired image.

shape

shape() -> tuple[int, int] | tuple[int, int, int]

Return the current image shape, accounting for any active ROI.

get_roi

get_roi() -> tuple[int, int, int, int]

Return the current ROI as (x, y, width, height).

set_roi

set_roi(x: int, y: int, width: int, height: int) -> None

Set the software ROI, validating bounds against the sensor shape.

clear_roi

clear_roi() -> None

Reset the ROI to the full sensor frame.

start_sequence

start_sequence(
    n: int | None, get_buffer: Callable[[Sequence[int], DTypeLike], ndarray]
) -> Iterator[Mapping]

Loop over snap(), cropping to the active ROI if set.

Device

Device()

Bases: ABC

ABC for all Devices.

core property

core: CMMCoreProxy

The device may use this to access a restricted subset of the Core API.

register_property

register_property(
    name: str,
    *,
    default_value: TProp | None = None,
    getter: Callable[[TDev], TProp] | None = None,
    setter: Callable[[TDev, TProp], None] | None = None,
    limits: tuple[int | float, int | float] | None = None,
    sequence_max_length: int = 0,
    allowed_values: Sequence[TProp] | None = None,
    is_read_only: bool = False,
    is_pre_init: bool = False,
    property_type: PropArg = None,
    sequence_loader: Callable[[TDev, Sequence[TProp]], None] | None = None,
    sequence_starter: Callable[[TDev], None] | None = None,
    sequence_stopper: Callable[[TDev], None] | None = None,
) -> None

Manually register a property.

This is an alternative to using the @pymm_property decorator. It can be used to register properties that are not defined in the class body. This is useful for pure "user-side" properties that are not used by the adapter, but which the adapter may want to access (such as a preference or a configuration setting that doesn't affect the device's behavior, but which the adapter may want to read).

Properties defined this way are not accessible as class attributes.

initialize

initialize() -> None

Initialize the device.

shutdown

shutdown() -> None

Shutdown the device.

get_label

get_label() -> str

type classmethod

type() -> DeviceType

Return the type of the device.

name classmethod

name() -> str

Return the name of the device.

description

description() -> str

Return a description of the device.

busy

busy() -> bool

Return True if the device is busy.

has_property

has_property(prop_name: str) -> bool

Return True if the device has a property with the given name.

get_property_names

get_property_names() -> KeysView[str]

Return the names of the properties.

get_property_info

get_property_info(prop_name: str) -> PropertyInfo

Return the property controller for a property.

get_property_value

get_property_value(prop_name: str) -> Any

Return the value of a property.

set_property_value

set_property_value(prop_name: str, value: Any) -> None

Set the value of a property.

set_property_allowed_values

set_property_allowed_values(
    prop_name: str, allowed_values: Sequence[Any]
) -> None

Set the allowed values of a property.

set_property_limits

set_property_limits(prop_name: str, limits: tuple[float, float] | None) -> None

Set the limits of a property.

set_property_sequence_max_length

set_property_sequence_max_length(prop_name: str, max_length: int) -> None

Set the sequence max length of a property.

load_property_sequence

load_property_sequence(prop_name: str, sequence: Sequence[Any]) -> None

Load a sequence into a property.

start_property_sequence

start_property_sequence(prop_name: str) -> None

Start a sequence of a property.

stop_property_sequence

stop_property_sequence(prop_name: str) -> None

Stop a sequence of a property.

is_property_sequenceable

is_property_sequenceable(prop_name: str) -> bool

Return True if the property is sequenceable.

is_property_read_only

is_property_read_only(prop_name: str) -> bool

Return True if the property is read-only.

get_parent_label

get_parent_label() -> str

Return the label of the parent hub device, or empty string if none.

set_parent_label

set_parent_label(parent_label: str) -> None

Set the label of the parent hub device.

GenericDevice

GenericDevice()

Bases: Device

Generic device API, e.g. for devices that don't fit into other categories.

Generic Devices generally only use the device property interface.

HubDevice

HubDevice()

Bases: Device

ABC for Hub devices that can have peripheral devices attached.

Hub devices represent a central device (e.g., a controller) that can have multiple peripheral devices attached to it. Examples include multi-channel controllers, or devices that manage multiple sub-devices.

To implement a Hub device, simply override get_installed_peripherals():

class MyHub(HubDevice):
    def get_installed_peripherals(self) -> Sequence[tuple[str, str]]:
        return [
            ("Motor1", "First motor controller"),
            ("Motor2", "Second motor controller"),
        ]

If your hub needs to perform expensive detection (e.g., scanning a bus), implement caching inside your get_installed_peripherals() method.

get_installed_peripherals

get_installed_peripherals() -> Sequence[tuple[str, str]]

Return information about installed peripheral devices.

Override this method to return a sequence of tuple[str, str] objects describing all devices that can be loaded as peripherals of this hub.

Returns:

Type Description
Sequence[tuple[str, str]]

A sequence of (name, description) tuples for each available peripheral. The name MUST be the name of a class, importable from the same module as this hub.

PropertyInfo dataclass

PropertyInfo(
    *,
    name: str,
    default_value: TProp | None = None,
    last_value: TProp | None = None,
    limits: tuple[int | float, int | float] | None = None,
    sequence_max_length: int = 0,
    description: str | None = None,
    type: PropertyType = Undef,
    allowed_values: Sequence[TProp] | None = None,
    is_read_only: bool | None = None,
    is_pre_init: bool = False,
)

Bases: Generic[TProp]

State of a property of a device.

Attributes:

Name Type Description
name str

The name of the property.

default_value TProp | None

The default value of the property, by default None.

last_value TProp | None

The last value seen from the device, by default None.

limits tuple[int | float, int | float] | None

The minimum and maximum values of the property, by default None.

sequence_max_length int

The maximum length of a sequence of property values.

description str | None

A description of the property, by default None.

type PropertyType

The type of the property.

allowed_values Sequence[TProp] | None

The allowed values of the property, by default None.

is_read_only bool | None

Whether the property is read-only.

is_pre_init bool

Whether the property must be set before initialization.

name

name: str

default_value

default_value: TProp | None = None

last_value

last_value: TProp | None = None

limits

limits: tuple[int | float, int | float] | None = None

sequence_max_length

sequence_max_length: int = 0

description

description: str | None = None

allowed_values

allowed_values: Sequence[TProp] | None = None

is_read_only

is_read_only: bool | None = None

is_pre_init

is_pre_init: bool = False

number_of_allowed_values property

number_of_allowed_values: int

Return the number of allowed values.

is_sequenceable property

is_sequenceable: bool

Return True if the property is sequenceable.

ShutterDevice

ShutterDevice()

Bases: Device

Shutter device API, e.g. for physical shutters or electronic shutter control.

Or any 2-state device that can be either open or closed.

get_open abstractmethod

get_open() -> bool

Return True if the shutter is open, False if it is closed.

set_open abstractmethod

set_open(open: bool) -> None

Set the shutter to open or closed.

Parameters:

Name Type Description Default
open bool

True to open the shutter, False to close it.

required

SLMDevice

SLMDevice(*args: Any, **kwargs: Any)

Bases: SequenceableDevice[ndarray]

ABC for Spatial Light Modulator (SLM) devices.

SLM devices are capable of displaying images. They are expected to represent a rectangular grid of pixels that can be either 8-bit or 32-bit. Illumination (light source on or off) is logically independent of displaying the image.

shape abstractmethod

shape() -> tuple[int, ...]

Return the shape of the SLM image buffer.

This is used when querying Width, Height, and number of components. If the SLM is grayscale, it should return (height, width). If the SLM is color, it should return (height, width, n_channels).

dtype abstractmethod

dtype() -> DTypeLike

Return the data type of the image buffer.

set_image abstractmethod

set_image(pixels: ndarray) -> None

Load the image into the SLM device adapter.

get_image

get_image() -> ndarray

Get the current image from the SLM device adapter.

This is useful for verifying that the image was set correctly.

display_image abstractmethod

display_image() -> None

Command the SLM to display the loaded image.

set_exposure abstractmethod

set_exposure(interval_ms: float) -> None

Command the SLM to turn off after a specified interval.

get_exposure abstractmethod

get_exposure() -> float

Find out the exposure interval of an SLM.

get_sequence_max_length

get_sequence_max_length() -> int

Return the maximum length of an image sequence that can be uploaded.

send_sequence

send_sequence(sequence: Sequence[ndarray]) -> None

Load a sequence of images to the SLM.

start_sequence

start_sequence() -> None

Start a sequence of images on the SLM.

stop_sequence

stop_sequence() -> None

Stop a sequence of images on the SLM.

StageDevice

StageDevice(*args: Any, **kwargs: Any)

ABC for Stage devices.

set_position_um abstractmethod

set_position_um(val: float) -> None

Set the position of the stage in microns.

get_position_um abstractmethod

get_position_um() -> float

Returns the current position of the stage in microns.

get_focus_direction

get_focus_direction() -> FocusDirection

Returns the focus direction of the stage.

set_focus_direction

set_focus_direction(sign: int) -> None

Sets the focus direction of the stage.

set_relative_position_um

set_relative_position_um(d: float) -> None

Move the stage by a relative amount.

Can be overridden for more efficient implementations.

set_adapter_origin_um

set_adapter_origin_um(newZUm: float) -> None

Enable software translation of coordinates.

The current position of the stage becomes Z = newZUm. Only some stages support this functionality; it is recommended that set_origin() be used instead where available.

is_linear_sequenceable

is_linear_sequenceable() -> bool

Return True if the stage supports linear sequences.

A linear sequence is defined by a step size and number of slices.

set_linear_sequence

set_linear_sequence(dZ_um: float, nSlices: int) -> None

Load a linear sequence defined by step size and number of slices.

is_continuous_focus_drive

is_continuous_focus_drive() -> bool

Return True if positions can be set while continuous focus runs.

XYStageDevice

XYStageDevice(*args: Any, **kwargs: Any)

ABC for XYStage devices.

set_position_um abstractmethod

set_position_um(x: float, y: float) -> None

Set the position of the XY stage in microns.

get_position_um abstractmethod

get_position_um() -> tuple[float, float]

Returns the current position of the XY stage in microns.

set_origin_x abstractmethod

set_origin_x() -> None

Zero the stage's X coordinates at the current position.

set_origin_y abstractmethod

set_origin_y() -> None

Zero the stage's Y coordinates at the current position.

set_relative_position_um

set_relative_position_um(dx: float, dy: float) -> None

Move the stage by a relative amount.

Can be overridden for more efficient implementations.

set_adapter_origin_um

set_adapter_origin_um(x: float, y: float) -> None

Alter the software coordinate translation between micrometers and steps.

... such that the current position becomes the given coordinates.

set_origin

set_origin() -> None

Zero the stage's coordinates at the current position.

This is a convenience method that calls set_origin_x and set_origin_y. Can be overridden for more efficient implementations.

XYStepperStageDevice

XYStepperStageDevice()

Bases: XYStageDevice

ABC for XYStage devices that support stepper motors.

In this variant, rather than providing set_position_um and get_position_um, you provide set_position_steps, get_position_steps, get_step_size_x_um, and get_step_size_y_um. A default implementation of set_position_um and get_position_um is then provided that uses these methods, taking into account the XY-mirroring properties of the device.

set_position_steps abstractmethod

set_position_steps(x: int, y: int) -> None

Set the position of the XY stage in steps.

get_position_steps abstractmethod

get_position_steps() -> tuple[int, int]

Returns the current position of the XY stage in steps.

get_step_size_x_um abstractmethod

get_step_size_x_um() -> float

Returns the step size of the X axis in microns.

get_step_size_y_um abstractmethod

get_step_size_y_um() -> float

Returns the step size of the Y axis in microns.

set_position_um

set_position_um(x: float, y: float) -> None

Set the position of the XY stage in microns.

get_position_um

get_position_um() -> tuple[float, float]

Get the position of the XY stage in microns.

set_relative_position_steps

set_relative_position_steps(dx: int, dy: int) -> None

Move the stage by a relative amount.

Can be overridden for more efficient implementations.

set_relative_position_um

set_relative_position_um(dx: float, dy: float) -> None

Default implementation for relative motion.

Can be overridden for more efficient implementations.

set_adapter_origin_um

set_adapter_origin_um(x: float = 0.0, y: float = 0.0) -> None

Alter the software coordinate translation between micrometers and steps.

... such that the current position becomes the given coordinates.

set_origin

set_origin() -> None

Zero the stage's coordinates at the current position.

set_origin_x

set_origin_x() -> None

Zero the stage's X coordinates at the current position.

set_origin_y

set_origin_y() -> None

Zero the stage's Y coordinates at the current position.

StateDevice

StateDevice(state_labels: Mapping[int, str] | Iterable[tuple[int, str]])

Bases: Device

State device API, e.g. filter wheel, objective turret, etc.

A state device is a device that at any point in time is in a single state out of a list of possible states, like a filter wheel, an objective turret, etc. The interface contains functions to get and set the state, to give states human readable labels, and functions to make it possible to treat the state device as a shutter.

In terms of implementation, this base class provides the basic functionality by presenting state and label as properties, which it keeps in sync with the underlying device.

Parameters:

Name Type Description Default
state_labels Mapping[int, str] | Iterable[tuple[int, str]]

A mapping (or iterable of 2-tuples) of integer state indices to string labels.

required

get_state abstractmethod

get_state() -> int

Get the current state of the device (integer index).

set_state abstractmethod

set_state(position: int) -> None

Set the state of the device (integer index).

from_count classmethod

from_count(count: int) -> Self

Simplified constructor with just a number of states.

register_standard_properties

register_standard_properties() -> None

Inspect the class for standard properties and register them.

set_position_or_label

set_position_or_label(pos_or_label: int | str) -> None

Set the position of the device by index or label.

assign_label_to_position

assign_label_to_position(pos: int, label: str) -> None

Assign a User-defined label to a position.

get_position_for_label

get_position_for_label(label: str) -> int

Return the position corresponding to the provided label.

Functions

pymm_property

pymm_property(fget: Callable[[TDev], TProp]) -> PropertyController[TDev, TProp]
pymm_property(
    *,
    allowed_values: Sequence[TProp] | None,
    sequence_max_length: int = ...,
    is_read_only: bool | None = ...,
    is_pre_init: bool = ...,
    name: str | None = ...,
    property_type: PropArg = ...,
) -> Callable[[Callable[[TDev], TProp]], PropertyController[TDev, TProp]]
pymm_property(
    *,
    limits: tuple[TLim, TLim] | None,
    sequence_max_length: int = ...,
    is_read_only: bool | None = ...,
    is_pre_init: bool = ...,
    name: str | None = ...,
    property_type: PropArg = ...,
) -> Callable[[Callable[[TDev], TLim]], PropertyController[TDev, TLim]]
pymm_property(
    *,
    sequence_max_length: int = ...,
    is_read_only: bool | None = ...,
    is_pre_init: bool = ...,
    name: str | None = ...,
    property_type: PropArg = ...,
) -> Callable[[Callable[[TDev], TProp]], PropertyController[TDev, TProp]]
pymm_property(
    fget: Callable[[TDev], TProp] | None = None,
    *,
    limits: tuple[TLim, TLim] | None = None,
    sequence_max_length: int = 0,
    allowed_values: Sequence[TProp] | None = None,
    is_read_only: bool | None = None,
    is_pre_init: bool = False,
    name: str | None = None,
    property_type: PropArg = None,
) -> (
    PropertyController[TDev, TProp]
    | Callable[[Callable[[TDev], TProp]], PropertyController[TDev, TProp]]
)

Decorates a (getter) method to create a device property.

The returned PropertyController instance can be additionally used (similar to @property) to decorate setter, sequence_loader, sequence_starter, and/or sequence_stopper methods.

Properties can have limits, allowed values, but may not have both.

Properties will only be considered "sequenceable" (i.e. they support hardware triggering) if they have a non-zero sequence_max_length AND have decorated sequence_loader and sequence_starter methods.

Parameters:

Name Type Description Default
fget Callable[[TDev], TProp]

The getter method for the property, by default None.

None
limits tuple[float, float]

The minimum and maximum values of the property, by default None. Cannot be combined with allowed_values.

None
sequence_max_length int

The maximum length of a sequence of property values, by default 0.

0
allowed_values Sequence[TProp]

The allowed values of the property, by default None. Cannot be combined with limits.

None
is_read_only bool

Whether the property is read-only, by default False.

None
is_pre_init bool

Whether the property must be set before initialization, by default False.

False
name str

The name of the property, by default, the name of the getter method is used.

None
property_type PropArg

The type of the property, by default the return annotation of the getter method is used (but must be one of float, int, or str).

None

Examples:

class MyDevice(Device):
    @pymm_property(limits=(0, 100), sequence_max_length=10)
    def position(self) -> float:
        # get position from device
        return 42.0

    @position.setter
    def position(self, value: float) -> None:
        print(f"Setting position to {value}")

    @position.sequence_loader
    def load_position_sequence(self, sequence: Sequence[float]) -> None:
        print(f"Loading position sequence: {sequence}")

    @position.sequence_starter
    def start_position_sequence(self) -> None:
        print("Starting position sequence")

    @pymm_property(is_read_only=True)
    def pressure(self) -> float:
        return 1.0

    @pymm_property(allowed_values=["low", "medium", "high"])
    def speed(self) -> str:
        # get speed from device
        return "medium"

    @speed.setter
    def speed(self, value: str) -> None:
        print(f"Setting speed to {value}")