pymmcore_plus.mda
¶
Running multi-dimensional acquisitions: the runner, the default engine, and signals.
MDARunner (available as core.mda) runs an
acquisition, and MDAEngine (core.mda.engine)
drives the hardware for each event. See The Acquisition
Engine for a guide.
Submodules
| Name | Description |
|---|---|
events |
Signals emitted by the MDA runner (core.mda.events) during an acquisition. |
handlers |
Deprecated data handlers (writers) for MDA acquisitions. |
Classes
| Name | Description |
|---|---|
FinishReason |
Reason why an MDA sequence finished. |
MDAEngine |
The default MDAEngine that ships with pymmcore-plus. |
MDARunner |
Object that executes a multi-dimensional experiment using an MDAEngine. |
PMDAEngine |
Protocol that all MDA engines must implement. |
PMDASignaler |
Declares the protocol for all signals that will be emitted from pymmcore_plus.mda.MDARunner. |
RunState |
State of the MDA acquisition runner. |
RunnerStatus |
Snapshot of the MDA runner's current state. |
SkipEvent |
Raised by an engine's setup_event to skip the current event. |
Functions
| Name | Description |
|---|---|
mda_listeners_connected |
Context in which MDA events are connected to listeners, in a thread by default. |
Attributes
| Name | Description |
|---|---|
SupportsFrameReady |
Classes¶
MDAEngine
¶
MDAEngine(
mmc: CMMCorePlus,
*,
use_hardware_sequencing: bool = True,
force_set_xy_position: bool = True,
restore_initial_state: bool | None = None,
timeout_base: float = 5.0,
timeout_multiplier: float = 5.0,
timeout_first_frame: float | None = 20.0,
timeout_action: Literal["raise", "warn"] = "raise",
)
Bases: PMDAEngine
The default MDAEngine that ships with pymmcore-plus.
This implements the PMDAEngine protocol, and
uses a CMMCorePlus instance to control the hardware.
For each event, it moves the stages, sets the channel preset, exposure, properties
and ROI, waits for the system, and snaps an image (see what the engine
does). Where the hardware allows it, consecutive events
are merged into hardware-triggered sequences.
It may be subclassed to provide custom behavior, or to override specific methods. See Custom Acquisition Engines.
Attributes:
| Name | Type | Description |
|---|---|---|
mmcore |
CMMCorePlus
|
The |
use_hardware_sequencing |
bool
|
Whether to use hardware sequencing if possible. If |
force_set_xy_position |
bool
|
Whether to always set the XY position, even if the target position is the same
as the last commanded position (this does not query the stage for the
current position). By default, this is |
restore_initial_state |
bool | None
|
Whether to restore the initial hardware state after the MDA sequence completes.
If |
timeout_base |
float
|
Minimum per-image timeout in seconds for sequenced acquisitions. The actual
timeout used is |
timeout_multiplier |
float
|
Multiplier applied to the camera exposure time (in seconds) to compute the
per-image timeout for sequenced acquisitions. By default, this is |
timeout_first_frame |
float | None
|
Separate timeout in seconds for waiting for the first frame of a
sequenced acquisition. This is useful when the camera is waiting for an
external trigger that may arrive much later than the exposure time would
suggest. If |
timeout_action |
Literal['raise', 'warn']
|
What to do when a sequenced acquisition times out. If |
- API Reference pymmcore-plus
-
User Guide
- Advanced Topics Pycro-Manager-Style API
- Applications pymmcore-gui What's inside
- Running Acquisitions
restore_initial_state
¶
restore_initial_state: bool | None = restore_initial_state
- User Guide Running Acquisitions The Acquisition Engine What the engine does
include_frame_position_metadata
property
writable
¶
setup_sequence
¶
setup_sequence(sequence: MDASequence) -> SummaryMetaV1 | None
Setup the hardware for the entire sequence.
- User Guide Running Acquisitions The Acquisition Engine What the engine does
get_summary_metadata
¶
get_summary_metadata(
mda_sequence: MDASequence | None, *, include_property_details: bool = False
) -> SummaryMetaV1
setup_event
¶
setup_event(event: MDAEvent) -> None
Set the system hardware (XY, Z, channel, exposure) as defined in the event.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
MDAEvent
|
The event to use for the Hardware config |
required |
- User Guide Running Acquisitions The Acquisition Engine What the engine does
exec_event
¶
Execute an individual event and return the image data.
- User Guide Running Acquisitions The Acquisition Engine What the engine does
event_iterator
¶
Event iterator that merges events for hardware sequencing if possible.
This wraps for event in events: ... inside MDARunner.run() and combines
sequenceable events into an instance of SequencedEvent if
self.use_hardware_sequencing is True.
setup_single_event
¶
setup_single_event(event: MDAEvent) -> None
Setup hardware for a single (non-sequenced) event.
This method is not part of the PMDAEngine protocol (it is called by
setup_event, which is part of the protocol), but it is made public
in case a user wants to subclass this engine and override this method.
- User Guide Running Acquisitions Custom Acquisition Engines The built-in MDAEngine
exec_single_event
¶
Execute a single (non-triggered) event and return the image data.
This method is not part of the PMDAEngine protocol (it is called by
exec_event, which is part of the protocol), but it is made public
in case a user wants to subclass this engine and override this method.
- User Guide Running Acquisitions Custom Acquisition Engines The built-in MDAEngine
get_frame_metadata
¶
get_frame_metadata(
event: MDAEvent,
prop_values: tuple[PropertyValue, ...] | None = None,
runner_time_ms: float = 0.0,
include_position: bool = True,
camera_device: str | None = None,
) -> FrameMetaV1
teardown_event
¶
teardown_event(event: MDAEvent) -> None
Teardown state of system (hardware, etc.) after event.
teardown_sequence
¶
teardown_sequence(sequence: MDASequence) -> None
Perform any teardown required after the sequence has been executed.
setup_sequenced_event
¶
setup_sequenced_event(event: SequencedEvent) -> None
Setup hardware for a sequenced (triggered) event.
This method is not part of the PMDAEngine protocol (it is called by
setup_event, which is part of the protocol), but it is made public
in case a user wants to subclass this engine and override this method.
- User Guide Running Acquisitions Custom Acquisition Engines The built-in MDAEngine
post_sequence_started
¶
post_sequence_started(event: SequencedEvent) -> None
Perform any actions after startSequenceAcquisition has been called.
This method is available to subclasses in case they need to perform any actions after a hardware-triggered sequence has been started (i.e. after core.startSequenceAcquisition has been called).
The default implementation does nothing.
exec_sequenced_event
¶
exec_sequenced_event(event: SequencedEvent) -> EventPayloadGenerator
Execute a sequenced (triggered) event and return the image data.
This method is not part of the PMDAEngine protocol (it is called by
exec_event, which is part of the protocol), but it is made public
in case a user wants to subclass this engine and override this method.
- User Guide Running Acquisitions Custom Acquisition Engines The built-in MDAEngine
PMDAEngine
¶
Bases: Protocol
Protocol that all MDA engines must implement.
-
API Reference
pymmcore-plus
pymmcore_plusmda Classes - User Guide Running Acquisitions Custom Acquisition Engines The MDAEngine protocol
setup_sequence
abstractmethod
¶
setup_sequence(sequence: MDASequence) -> SummaryMetaV1 | None
Setup state of system (hardware, etc.) before an MDA is run.
This method is called once at the beginning of a sequence.
- User Guide Running Acquisitions Custom Acquisition Engines The MDAEngine protocol
setup_event
abstractmethod
¶
setup_event(event: MDAEvent) -> None
Prepare state of system (hardware, etc.) for event.
This method is called before each event in the sequence. It is
responsible for preparing the state of the system for the event.
The engine should be in a state where it can call exec_event
without any additional preparation. (This means that the engine
should perform any waits or blocks required for system state
changes to complete.)
If the engine cannot set up the event (e.g. hardware failure), it may
raise SkipEvent(num_frames) to tell the runner to skip this event
and inform the data sink of the missing frames. If SkipEvent is raised,
exec_event will NOT be called for this event, but teardown_event will be.
- User Guide Running Acquisitions Custom Acquisition Engines The MDAEngine protocol
exec_event
abstractmethod
¶
Execute event.
This method is called after setup_event and is responsible for
executing the event. The default assumption is to acquire an image,
but more elaborate events will be possible.
Yields (image, event, metadata) tuples for each acquired frame.
May yield None for frames that could not be acquired (e.g. partial
hardware failure during a triggered sequence); the runner will call
sink.skip(frames=1) for each None.
- User Guide Running Acquisitions Custom Acquisition Engines The MDAEngine protocol
event_iterator
¶
Wrapper on the event iterator.
Optional.
This can be used to wrap the event iterator to perform any event merging
(e.g. if the engine supports HardwareSequencing) or event modification.
The default implementation is just iter(events).
Be careful when using this method. It is powerful and can result in unexpected event iteration if used incorrectly.
- User Guide Running Acquisitions Custom Acquisition Engines The MDAEngine protocol
teardown_event
¶
teardown_event(event: MDAEvent) -> None
Teardown state of system (hardware, etc.) after event.
Optional.
If the engine provides this function, it will be called after
exec_event to perform any cleanup or teardown required after
the event has been executed.
- User Guide Running Acquisitions Custom Acquisition Engines The MDAEngine protocol
teardown_sequence
¶
teardown_sequence(sequence: MDASequence) -> None
Perform any teardown required after the sequence has been executed.
Optional.
If the engine provides this function, it will be called after the last event in the sequence has been executed.
- User Guide Running Acquisitions Custom Acquisition Engines The MDAEngine protocol
MDARunner
¶
Object that executes a multi-dimensional experiment using an MDAEngine.
This object is available at CMMCorePlus.mda.
This is the main object that runs a multi-dimensional experiment (the "runner").
It iterates over the events, waits until each one is due (min_start_time),
handles pausing and cancelling, and sends the acquired frames to the output
(if any). The hardware itself is driven by an acquisition engine (the
engine, by default an
MDAEngine) that implements the
PMDAEngine protocol. It emits signals at specific
times during the experiment (see
PMDASignaler for details on the signals
that are available to connect to and when they are emitted). See The
Acquisition Engine for a guide.
The state machine modeled by this runner is as follows:
stateDiagram-v2
[*] --> IDLE
IDLE --> PREPARING : run()
PREPARING --> running : sequence ready
state running {
WAITING --> ACQUIRING : next event ready
ACQUIRING --> WAITING : event done
WAITING --> PAUSED : <code>set_paused(True)</code>
PAUSED --> WAITING : <code>set_paused(False)</code>
ACQUIRING --> PAUSED : <code>set_paused(True)</code></br>(after event done)
}
running --> FINISHING : <code>cancel()</code>
running --> FINISHING : all events exhausted
FINISHING --> IDLE : cleanup done
You can query the current state of the runner using the
status property, which returns a snapshot
of the runner's current state, including the current phase of the acquisition,
whether a cancel or pause has been requested, and the reason for finishing
(once the acquisition is finished).
- API Reference pymmcore-plus
- User Guide Running Acquisitions
engine
property
¶
engine: MDAEngine | None
The PMDAEngine that is currently being used.
events
property
¶
events: PMDASignaler
Signals that are emitted during the MDA run.
See PMDASignaler for details on the
signals that are available to connect to.
set_engine
¶
set_engine(engine: PMDAEngine) -> PMDAEngine | None
Set the PMDAEngine to use for the MDA run.
- User Guide Running Acquisitions Custom Acquisition Engines Customizing the MDAEngine
is_running
¶
is_running() -> bool
Return True if an acquisition is currently underway.
This will return True at any point between the emission of the
sequenceStarted and
sequenceFinished signals,
including when the acquisition is currently paused.
Returns:
| Type | Description |
|---|---|
bool
|
Whether an acquisition is underway. |
is_paused
¶
is_paused() -> bool
Return True if the acquisition is currently paused.
Use set_paused to change the paused state.
Returns:
| Type | Description |
|---|---|
bool
|
Whether the current acquisition is paused. |
cancel
¶
Cancel the currently running acquisition.
This is a no-op if no acquisition is currently running. If an acquisition is running then this will cancel the acquisition and a sequenceCanceled signal, followed by a sequenceFinished signal will be emitted.
- User Guide Running Acquisitions The Acquisition Engine Cancelling or pausing
toggle_pause
¶
Toggle the paused state of the current acquisition.
Deprecated
Use set_paused instead.
set_paused
¶
set_paused(paused: bool) -> None
Set the paused state of the current acquisition.
This is a no-op if the acquisition is already in the requested state, or if no acquisition is currently underway.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
paused
|
bool
|
Whether to pause (True) or unpause (False) the acquisition. |
required |
run
¶
run(
events: Iterable[MDAEvent],
*,
output: SingleOutput | Sequence[SingleOutput] | None = None,
overwrite: bool = False,
dimension_overrides: dict[str, DimensionOverride] | None = None,
) -> None
Run the multi-dimensional acquisition defined by sequence.
Most users should not use this directly as it will block further
execution. Instead, use the
CMMCorePlus.run_mda method which will
run on a thread.
Important
If output is a sequence, it may contain no more than one
str | Path | AcquisitionSettings.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
events
|
Iterable[MDAEvent]
|
An iterable of |
required |
output
|
SingleOutput | Sequence[SingleOutput] | None
|
The output handler(s) to use. If None, no output will be saved. The value may be either a single output or a sequence of outputs, where a "single output" can be any of the following:
During the course of the sequence, the The array shape is taken from |
None
|
overwrite
|
bool
|
Whether to overwrite existing files when output is a |
False
|
dimension_overrides
|
dict[str, DimensionOverride] | None
|
Per-dimension storage overrides, keyed by dimension name.
Values are dicts of Dimension fields ("chunk_size", "shard_size_chunks")
to apply on top of the sequence-derived dimensions. Example:
|
None
|
-
API Reference
pymmcore-plus
pymmcore_plus - User Guide Running Acquisitions
get_view
¶
Array-like view of the current data sink, if it exists.
get_output_handlers
¶
get_output_handlers() -> tuple[SupportsFrameReady, ...]
Return the data handlers that are currently connected.
Deprecated
There is no full replacement. To look at the data while it is being
acquired, use get_view.
Output handlers are connected by passing them to the output parameter of the
run method; the run method accepts objects with a frameReady method or
strings representing paths. If a string is passed, a handler will be created
internally.
This method returns a tuple of currently connected handlers, including those
that were explicitly passed to run(), as well as those that were created based
on file paths. Internally, handlers are held by weak references, so if you want
the handler to persist, you must keep a reference to it. The only guaranteed
API that the handler will have is the frameReady method, but it could be any
user-defined object that implements that method.
Handlers are cleared each time run() is called, (but not at the end
of the sequence).
Returns:
| Type | Description |
|---|---|
tuple[SupportsFrameReady, ...]
|
Tuple of objects that (minimally) support the |
RunnerStatus
dataclass
¶
RunnerStatus(
phase: RunState = IDLE,
finish_reason: FinishReason | None = None,
cancel_requested: bool = False,
pause_requested: bool = False,
)
Snapshot of the MDA runner's current state.
Attributes:
| Name | Type | Description |
|---|---|---|
phase |
RunState
|
|
finish_reason |
FinishReason | None
|
|
cancel_requested |
bool
|
|
pause_requested |
bool
|
|
SkipEvent
¶
Bases: Exception
Raised by an engine's setup_event to skip the current event.
The num_frames parameter tells the runner how many sink frames
to skip (e.g. len(sequenced_event.events) for a SequencedEvent).
- User Guide Running Acquisitions Custom Acquisition Engines Skipping an event
Functions¶
mda_listeners_connected
¶
mda_listeners_connected(
*listeners: Any,
mda_events: PMDASignaler | None = ...,
name_map: dict[str, str] | None = ...,
asynchronous: Literal[False],
wait_on_exit: bool = ...,
) -> AbstractContextManager[None]
mda_listeners_connected(
*listeners: Any,
mda_events: PMDASignaler | None = ...,
name_map: dict[str, str] | None = ...,
asynchronous: Literal[True] = ...,
wait_on_exit: bool = ...,
) -> AbstractContextManager[MDARelayThread]
mda_listeners_connected(
*listeners: Any,
mda_events: PMDASignaler | None = None,
name_map: dict[str, str] | None = None,
asynchronous: bool = True,
wait_on_exit: bool = True,
) -> Iterator
Context in which MDA events are connected to listeners, in a thread by default.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
listeners
|
Any
|
Object(s) that has methods matching the name of signals on |
()
|
mda_events
|
PMDASignaler | None
|
The MDA events to connect to. If not provided, the |
None
|
name_map
|
dict[str, str] | None
|
Optionally map signal names to different method names on |
None
|
asynchronous
|
bool
|
Whether to execute callbacks on |
True
|
wait_on_exit
|
bool
|
Whether to wait for all callbacks on listeners to finish before exiting the context, by default True. |
True
|