Experimental UniMMCore#
pymmcore_plus.experimental.unicore
#
CameraDevice
#
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)})
class-attribute
#
dtype() -> DTypeLike
abstractmethod
#
Return the data type of the image buffer.
get_binning() -> int
#
Get the binning factor for the camera.
get_exposure() -> float
abstractmethod
#
Get the current exposure time in milliseconds.
register_standard_properties() -> None
#
Inspect the class for standard properties and register them.
set_exposure(exposure: float) -> None
abstractmethod
#
Set the exposure time in milliseconds.
shape() -> tuple[int, ...]
abstractmethod
#
Return the shape of the image buffer.
This is used when querying Width, Height, and number of components. If the camera is grayscale, it should return (width, height). If the camera is color, it should return (width, height, n_channels).
start_sequence(n: int | None, get_buffer: Callable[[Sequence[int], DTypeLike], np.ndarray]) -> Iterator[Mapping]
abstractmethod
#
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], np.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. |
Device
#
ABC for all Devices.
busy() -> bool
#
Return True
if the device is busy.
core() -> CMMCoreProxy
property
#
The device may use this to access a restricted subset of the Core API.
description() -> str
#
Return a description of the device.
get_label() -> str
#
get_property_info(prop_name: str) -> PropertyInfo
#
Return the property controller for a property.
get_property_names() -> KeysView[str]
#
Return the names of the properties.
get_property_value(prop_name: str) -> Any
#
Return the value of a property.
has_property(prop_name: str) -> bool
#
Return True
if the device has a property with the given name.
initialize() -> None
#
Initialize the device.
is_property_read_only(prop_name: str) -> bool
#
Return True
if the property is read-only.
is_property_sequenceable(prop_name: str) -> bool
#
Return True
if the property is sequenceable.
load_property_sequence(prop_name: str, sequence: Sequence[Any]) -> None
#
Load a sequence into a property.
name() -> str
classmethod
#
Return the name of the device.
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.
set_property_allowed_values(prop_name: str, allowed_values: Sequence[Any]) -> None
#
Set the allowed values of a property.
set_property_limits(prop_name: str, limits: tuple[float, float] | None) -> None
#
Set the limits of a property.
set_property_sequence_max_length(prop_name: str, max_length: int) -> None
#
Set the sequence max length of a property.
set_property_value(prop_name: str, value: Any) -> None
#
Set the value of a property.
shutdown() -> None
#
Shutdown the device.
start_property_sequence(prop_name: str) -> None
#
Start a sequence of a property.
stop_property_sequence(prop_name: str) -> None
#
Stop a sequence of a property.
type() -> DeviceType
classmethod
#
Return the type of the device.
GenericDevice
#
Generic device API, e.g. for devices that don't fit into other categories.
Generic Devices generally only use the device property interface.
PropertyInfo
dataclass
#
State of a property of a device.
Attributes:
Name | Type | Description |
---|---|---|
name |
str
|
The name of the property. |
default_value |
TProp, optional
|
The default value of the property, by default None. |
last_value |
TProp, optional
|
The last value seen from the device, by default None. |
limits |
tuple[int | float, int | float], optional
|
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, optional
|
A description of the property, by default None. |
type |
PropertyType
|
The type of the property. |
allowed_values |
Sequence[TProp], optional
|
The allowed values of the property, by default None. |
is_read_only |
bool
|
Whether the property is read-only. |
is_pre_init |
bool
|
Whether the property must be set before initialization. |
allowed_values: Sequence[TProp] | None = None
class-attribute
#
default_value: TProp | None = None
class-attribute
#
description: str | None = None
class-attribute
#
is_pre_init: bool = False
class-attribute
#
is_read_only: bool | None = None
class-attribute
#
last_value: TProp | None = None
class-attribute
#
limits: tuple[int | float, int | float] | None = None
class-attribute
#
name: str
class-attribute
#
sequence_max_length: int = 0
class-attribute
#
type: PropertyType = PropertyType.Undef
class-attribute
#
is_sequenceable() -> bool
property
#
Return True if the property is sequenceable.
number_of_allowed_values() -> int
property
#
Return the number of allowed values.
SLMDevice
#
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.
display_image() -> None
abstractmethod
#
Command the SLM to display the loaded image.
dtype() -> DTypeLike
abstractmethod
#
Return the data type of the image buffer.
get_exposure() -> float
abstractmethod
#
Find out the exposure interval of an SLM.
get_image() -> np.ndarray
#
Get the current image from the SLM device adapter.
This is useful for verifying that the image was set correctly.
get_sequence_max_length() -> int
#
Return the maximum length of an image sequence that can be uploaded.
send_sequence(sequence: Sequence[np.ndarray]) -> None
#
Load a sequence of images to the SLM.
set_exposure(interval_ms: float) -> None
abstractmethod
#
Command the SLM to turn off after a specified interval.
set_image(pixels: np.ndarray) -> None
abstractmethod
#
Load the image into the SLM device adapter.
shape() -> tuple[int, ...]
abstractmethod
#
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 (width, height). If the SLM is color, it should return (width, height, n_channels).
start_sequence() -> None
#
Start a sequence of images on the SLM.
stop_sequence() -> None
#
Stop a sequence of images on the SLM.
ShutterDevice
#
Shutter device API, e.g. for physical shutters or electronic shutter control.
Or any 2-state device that can be either open or closed.
StageDevice
#
StateDevice
#
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 |
assign_label_to_position(pos: int, label: str) -> None
#
Assign a User-defined label to a position.
from_count(count: int) -> Self
classmethod
#
Simplified constructor with just a number of states.
get_position_for_label(label: str) -> int
#
Return the position corresponding to the provided label.
get_state() -> int
abstractmethod
#
Get the current state of the device (integer index).
register_standard_properties() -> None
#
Inspect the class for standard properties and register them.
set_position_or_label(pos_or_label: int | str) -> None
#
Set the position of the device by index or label.
set_state(position: int) -> None
abstractmethod
#
Set the state of the device (integer index).
UniMMCore
#
Unified Core object that first checks for python, then C++ devices.
load_py_device = loadPyDevice
class-attribute
#
clearCircularBuffer() -> None
#
Clear all images from the circular buffer.
clearROI() -> None
#
Clear the current region of interest (ROI) for the camera.
defineStateLabel(stateDeviceLabel: DeviceLabel | str, state: int, label: str) -> None
#
Define a label for the specific state.
deviceBusy(label: DeviceLabel | str) -> bool
#
deviceTypeBusy(devType: int) -> bool
#
displaySLMImage(slmLabel: DeviceLabel | str | None = None) -> None
#
Command the SLM to display the loaded image.
getAllowedPropertyValues(label: DeviceLabel | str, propName: PropertyName | str) -> tuple[str, ...]
#
getBufferFreeCapacity() -> int
#
Get the number of free slots in the circular buffer.
getBufferTotalCapacity() -> int
#
Get the total capacity of the circular buffer.
getBytesPerPixel() -> int
#
getCameraChannelName(channelNr: int) -> str
#
Get the name of the camera channel.
getCameraDevice() -> DeviceLabel | Literal['']
#
Returns the label of the currently selected camera device.
Returns empty string if no camera device is selected.
getCircularBufferMemoryFootprint() -> int
#
Get the circular buffer memory footprint in MB.
getDeviceDelayMs(label: DeviceLabel | str) -> float
#
getDeviceDescription(label: DeviceLabel | str) -> str
#
getDeviceInitializationState(label: str) -> DeviceInitializationState
#
getDeviceLibrary(label: DeviceLabel | str) -> AdapterName
#
getDeviceName(label: DeviceLabel | str) -> DeviceName
#
getDevicePropertyNames(label: DeviceLabel | str) -> tuple[PropertyName, ...]
#
getDeviceType(label: str) -> DeviceType
#
getExposure(cameraLabel: DeviceLabel | str | None = None) -> float
#
Get the exposure time in milliseconds.
getExposureSequenceMaxLength(cameraLabel: DeviceLabel | str) -> int
#
Get the maximum length of the exposure sequence.
getImage(numChannel: int | None = None, *, fix: bool = True) -> np.ndarray
#
getImageBitDepth() -> int
#
getImageBufferSize() -> int
#
getImageHeight() -> int
#
getImageWidth() -> int
#
getLastImage(*, out: np.ndarray | None = None) -> np.ndarray
#
getLastImageMD(*args: Any, out: np.ndarray | None = None) -> np.ndarray
#
getLoadedDevices() -> tuple[DeviceLabel, ...]
#
getLoadedDevicesOfType(devType: int) -> tuple[DeviceLabel, ...]
#
getNBeforeLastImageMD(n: int, md: pymmcore.Metadata, /, *, out: np.ndarray | None = None) -> np.ndarray
#
getNumberOfCameraChannels() -> int
#
getNumberOfComponents() -> int
#
getNumberOfStates(stateDeviceLabel: DeviceLabel | str) -> int
#
Return the total number of available positions (states).
getPixelSizeAffine(cached: bool = False) -> AffineTuple
#
Get the pixel size affine transformation matrix.
getPixelSizeUm(cached: bool = False) -> float
#
Get the pixel size in micrometers.
getProperty(label: DeviceLabel | str, propName: PropertyName | str) -> Any
#
getPropertyFromCache(deviceLabel: DeviceLabel | str, propName: PropertyName | str) -> Any
#
getPropertyLowerLimit(label: DeviceLabel | str, propName: PropertyName | str) -> float
#
getPropertySequenceMaxLength(label: DeviceLabel | str, propName: PropertyName | str) -> int
#
getPropertyType(label: str, propName: str) -> PropertyType
#
getPropertyUpperLimit(label: DeviceLabel | str, propName: PropertyName | str) -> float
#
getROI(label: DeviceLabel | str = '') -> list[int]
#
Get the current region of interest (ROI) for the camera.
getRemainingImageCount() -> int
#
getSLMBytesPerPixel(slmLabel: DeviceLabel | str | None = None) -> int
#
Returns the number of bytes per pixel for the SLM.
getSLMDevice() -> DeviceLabel | Literal['']
#
Returns the label of the currently selected SLM device.
Returns empty string if no SLM device is selected.
getSLMExposure(slmLabel: DeviceLabel | str | None = None) -> float
#
Find out the exposure interval of an SLM.
getSLMHeight(slmLabel: DeviceLabel | str | None = None) -> int
#
Returns the height of the SLM in pixels.
getSLMImage(slmLabel: DeviceLabel | str | None = None) -> np.ndarray
#
Get the current image from the SLM device.
getSLMNumberOfComponents(slmLabel: DeviceLabel | str | None = None) -> int
#
Returns the number of color components (channels) in the SLM.
getSLMSequenceMaxLength(slmLabel: DeviceLabel | str) -> int
#
Get the maximum length of an image sequence that can be uploaded.
getSLMWidth(slmLabel: DeviceLabel | str | None = None) -> int
#
Returns the width of the SLM in pixels.
getShutterDevice() -> DeviceLabel | Literal['']
#
Returns the label of the currently selected Shutter device.
Returns empty string if no Shutter device is selected.
getShutterOpen(shutterLabel: DeviceLabel | str | None = None) -> bool
#
getState(stateDeviceLabel: DeviceLabel | str) -> int
#
Return the current state (position) on the specific device.
getStateFromLabel(stateDeviceLabel: DeviceLabel | str, stateLabel: str) -> int
#
Obtain the state for a given label.
getStateLabel(stateDeviceLabel: DeviceLabel | str) -> StateLabel
#
Return the current state as the label (string).
getStateLabels(stateDeviceLabel: DeviceLabel | str) -> tuple[StateLabel, ...]
#
Return labels for all states.
getXPosition(xyStageLabel: DeviceLabel | str = '') -> float
#
Obtains the current position of the X axis of the XY stage in microns.
getXYPosition(xyStageLabel: DeviceLabel | str = '') -> tuple[float, float]
#
Obtains the current position of the XY stage in microns.
getXYStageDevice() -> DeviceLabel | Literal['']
#
Returns the label of the currently selected XYStage device.
Returns empty string if no XYStage device is selected.
getXYStageSequenceMaxLength(xyStageLabel: DeviceLabel | str) -> int
#
Gets the maximum length of an XY stage's position sequence.
getYPosition(xyStageLabel: DeviceLabel | str = '') -> float
#
Obtains the current position of the Y axis of the XY stage in microns.
hasProperty(label: DeviceLabel | str, propName: PropertyName | str) -> bool
#
hasPropertyLimits(label: DeviceLabel | str, propName: PropertyName | str) -> bool
#
home(xyOrZStageLabel: DeviceLabel | str) -> None
#
Perform a hardware homing operation for an XY or focus/Z stage.
initializeAllDevices() -> None
#
initializeCircularBuffer() -> None
#
Initialize the circular buffer.
initializeDevice(label: DeviceLabel | str) -> None
#
isBufferOverflowed() -> bool
#
Check if the circular buffer has overflowed.
isExposureSequenceable(cameraLabel: DeviceLabel | str) -> bool
#
Check if the camera supports exposure sequences.
isPropertyPreInit(label: DeviceLabel | str, propName: PropertyName | str) -> bool
#
isPropertyReadOnly(label: DeviceLabel | str, propName: PropertyName | str) -> bool
#
isPropertySequenceable(label: DeviceLabel | str, propName: PropertyName | str) -> bool
#
isSequenceRunning(cameraLabel: DeviceLabel | str | None = None) -> bool
#
isXYStageSequenceable(xyStageLabel: DeviceLabel | str) -> bool
#
Queries XY stage if it can be used in a sequence.
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")
loadExposureSequence(cameraLabel: DeviceLabel | str, exposureSequence_ms: Sequence[float]) -> None
#
Transfer a sequence of exposure times to the camera.
loadPropertySequence(label: DeviceLabel | str, propName: PropertyName | str, eventSequence: Sequence[Any]) -> None
#
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 |
unicore.Device
|
The device object to load. Use the appropriate subclass of |
required |
loadSLMSequence(slmLabel: DeviceLabel | str, imageSequence: Sequence[bytes | np.ndarray]) -> None
#
Load a sequence of images to the SLM.
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
popNextImage(*, fix: bool = True) -> np.ndarray
#
popNextImageMD(*args: Any) -> np.ndarray
#
prepareSequenceAcquisition(cameraLabel: DeviceLabel | str) -> None
#
Prepare the camera for sequence acquisition.
reset() -> 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.
setCameraDevice(cameraLabel: DeviceLabel | str) -> None
#
Set the camera device.
setCircularBufferMemoryFootprint(sizeMB: int) -> None
#
Set the circular buffer memory footprint in MB.
setDeviceDelayMs(label: DeviceLabel | str, delayMs: float) -> None
#
setExposure(*args: Any) -> None
#
Set the exposure time in milliseconds.
setOriginX(xyStageLabel: DeviceLabel | str = '') -> None
#
Zero the given XY stage's X coordinate at the current position.
setOriginXY(xyStageLabel: DeviceLabel | str = '') -> None
#
Zero the given XY stage's coordinates at the current position.
setOriginY(xyStageLabel: DeviceLabel | str = '') -> None
#
Zero the given XY stage's Y coordinate at the current position.
setProperty(label: str, propName: str, propValue: bool | float | int | str) -> None
#
setRelativeXYPosition(*args: Any) -> None
#
Sets the relative position of the XY stage in microns.
setSLMDevice(slmLabel: DeviceLabel | str) -> None
#
Set the SLM device.
setSLMExposure(*args: Any) -> None
#
Command the SLM to turn off after a specified interval.
setSLMImage(*args: Any) -> None
#
Load the image into the SLM device adapter.
setSLMPixelsTo(*args: Any) -> None
#
Set all pixels of the SLM to a uniform intensity or RGB values.
setShutterDevice(shutterLabel: DeviceLabel | str) -> None
#
setState(stateDeviceLabel: DeviceLabel | str, state: int) -> None
#
Set state (position) on the specific device.
setStateLabel(stateDeviceLabel: DeviceLabel | str, stateLabel: str) -> None
#
Set device state using the previously assigned label (string).
setXYPosition(*args: Any) -> None
#
Sets the position of the XY stage in microns.
setXYStageDevice(xyStageLabel: DeviceLabel | str) -> None
#
startExposureSequence(cameraLabel: DeviceLabel | str) -> None
#
Start a sequence of exposures.
startPropertySequence(label: DeviceLabel | str, propName: PropertyName | str) -> None
#
startSLMSequence(slmLabel: DeviceLabel | str) -> None
#
Start a sequence of images on the SLM.
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
stop(xyOrZStageLabel: DeviceLabel | str) -> None
#
Stop the XY or focus/Z stage.
stopExposureSequence(cameraLabel: DeviceLabel | str) -> None
#
Stop a sequence of exposures.
stopPropertySequence(label: DeviceLabel | str, propName: PropertyName | str) -> None
#
stopSLMSequence(slmLabel: DeviceLabel | str) -> None
#
Stop a sequence of images on the SLM.
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
systemBusy() -> bool
#
unloadAllDevices() -> None
#
unloadDevice(label: DeviceLabel | str) -> None
#
usesDeviceDelay(label: DeviceLabel | str) -> bool
#
waitForDevice(label: DeviceLabel | str) -> None
#
waitForDeviceType(devType: int) -> None
#
waitForSystem() -> None
#
XYStageDevice
#
ABC for XYStage devices.
get_position_um() -> tuple[float, float]
abstractmethod
#
Returns the current position of the XY stage in microns.
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() -> 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.
set_origin_x() -> None
abstractmethod
#
Zero the stage's X coordinates at the current position.
set_origin_y() -> None
abstractmethod
#
Zero the stage's Y coordinates at the current position.
set_position_um(x: float, y: float) -> None
abstractmethod
#
Set the position of the XY stage in microns.
set_relative_position_um(dx: float, dy: float) -> None
#
Move the stage by a relative amount.
Can be overridden for more efficient implementations.
XYStepperStageDevice
#
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.
get_position_steps() -> tuple[int, int]
abstractmethod
#
Returns the current position of the XY stage in steps.
get_position_um() -> tuple[float, float]
#
Get the position of the XY stage in microns.
get_step_size_x_um() -> float
abstractmethod
#
Returns the step size of the X axis in microns.
get_step_size_y_um() -> float
abstractmethod
#
Returns the step size of the Y axis in microns.
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() -> None
#
Zero the stage's coordinates at the current position.
set_origin_x() -> None
#
Zero the stage's X coordinates at the current position.
set_origin_y() -> None
#
Zero the stage's Y coordinates at the current position.
set_position_steps(x: int, y: int) -> None
abstractmethod
#
Set the position of the XY stage in steps.
set_position_um(x: float, y: float) -> None
#
Set the position of the XY stage in microns.
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(dx: float, dy: float) -> None
#
Default implementation for relative motion.
Can be overridden for more efficient implementations.
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], optional
|
The getter method for the property, by default None. |
None
|
limits |
tuple[float, float], optional
|
The minimum and maximum values of the property, by default None. Cannot be
combined with |
None
|
sequence_max_length |
int, optional
|
The maximum length of a sequence of property values, by default 0. |
0
|
allowed_values |
Sequence[TProp], optional
|
The allowed values of the property, by default None. Cannot be combined with
|
None
|
is_read_only |
bool, optional
|
Whether the property is read-only, by default False. |
None
|
is_pre_init |
bool, optional
|
Whether the property must be set before initialization, by default False. |
False
|
name |
str, optional
|
The name of the property, by default, the name of the getter method is used. |
None
|
prop_type |
PropArg, optional
|
The type of the property, by default the return annotation of the getter method
is used (but must be one of |
required |
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}")