Overview#
useq-schema
is an implementation agnostic schema for describing a
sequence of events during a multi-dimensional imaging acquisition.
The goal of this repo is to provide a specification (and some python utilities) for generating event objects that can be consumed by microscope acquisition engines. A hope is that this will encourage inter-operability between various efforts to drive automated image acquisition.
The schema tries to remain agnostic to the specific acquisition engine (though it was designed based on the capabilities Micro-Manager). We welcome feedback from interested parties regarding limitations and/or potential extensions to the schema! Similarly, while the "ideal" schema will support arbitrary dimensions (i.e. more than the conventional position, time, channel, z, ...), it also hard to avoid hard-coding some assumptions about dimensionality in certain places. Any and all feedback (even minor stuff, such as parameter naming, etc...) is welcome! Please open an issue.
Core Schema#
MDAEvent
#
The primary "event" object is useq.MDAEvent
. This describes a single event
that a microscope should perform, including preparation of the hardware, and
execution of the event (such as an image acquisition).
- For micro-manager, this
object is most similar (though not identical) to the events generated by
generate-acq-sequence
in the clojure acquisition engine that drives Micro-Managers multi-dimensional acquisitions. - For Pycro-manager, this
object is similar to an individual acquisition event
dict
generated bymulti_d_acquisition_events
, (and,useq.pycromanager
provides ato_pycromanager
method that returns a dict following the pycro-manager event spec) - your object here?...
MDASequence
#
useq.MDASequence
represents a sequence of events – as might be
generated by the multidimensional acquisition GUI in most microscope software.
The Python MDASequence
object is itself
iterable, and yields
useq.MDAEvent
objects.
- For micro-manager, this
object is most similar to
org.micromanager.acquisition.SequenceSettings
, (generated by clicking theAcquire!
button in the Multi-D Acquisition GUI) - For Pycro-manager, this
object is similar to the
multi_d_acquisition_events
convenience function, (anduseq.pycromanager
provides ato_pycromanager
method that returns a list of pycro-manager event dicts) - your object here?...
Executing an MDASequence#
This library is just a schema, and does not provide any built-in functionality
for executing an MDASequence
. However,
pymmcore-plus
implements an
acquisition engine that can execute an MDASequence
object with
micro-manager (via the
pymmcore
python wrapper around
the C++ MMCore). See the pymmcore-plus documentation for
details.
napari-micromanager
also creates a useq.MDASequence
object from user input
and passes it to pymmcore-plus
for execution.
hi!
Have you implemented an acquisition engine that can execute a useq.MDASequence
?
Let us know so we can add it here!
Serialization and Deserialization#
MDASequence
and MDAEvent
objects are designed to be serialized and deserialized,
allowing you to define an entire multi-dimensional acquisition in human-readable
YAML (or JSON) file, and then load that file into your acquisition engine.
For example, the following file defines an experiment with:
- 3 channels (
DAPI
,FITC
, andCy5
), specifying exposure times in ms for each channel - a two-phase time-lapse: 3 frames in the first phase, followed by a frame every 10 seconds for 40 minutes
- a Z-stack at each timepoint, with a range of 4 microns and a step size of 0.5 micron
- two stage positions, specifying a unique Z-stack for the second position
Example
axis_order: tpcz
channels:
- config: Cy5
exposure: 50.0
- config: FITC
exposure: 100.0
- config: DAPI
acquire_every: 3
do_stack: false
time_plan:
phases:
- interval: 0:00:03
loops: 3
- duration: 0:40:00
interval: 0:00:10
z_plan:
range: 4.0
step: 0.5
stage_positions:
- x: 10.0
y: 20.0
- name: Cell 1
x: 10.0
y: 20.0
z: 50.0
z_plan:
above: 10.0
below: 0.0
step: 1.0
metadata:
some info: about my experiment
{
"axis_order": "tpcz",
"channels": [
{
"config": "Cy5",
"exposure": 50.0
},
{
"config": "FITC",
"exposure": 100.0
},
{
"config": "DAPI",
"acquire_every": 3,
"do_stack": false
}
],
"time_plan": {
"phases": [
{
"interval": "0:00:03",
"loops": 3
},
{
"duration": "0:40:00",
"interval": "0:00:10"
}
]
},
"z_plan": {
"range": 4.0,
"step": 0.5
},
"stage_positions": [
{
"x": 10.0,
"y": 20.0
},
{
"name": "Cell 1",
"x": 10.0,
"y": 20.0,
"z": 50.0,
"z_plan": {
"above": 10.0,
"below": 0.0,
"step": 1.0
}
}
],
"metadata": {
"some info": "about my experiment"
}
}