An implementation agnostic schema for describing a sequence of events during a multi-dimensional imaging acquisition.
Documentation: https://pymmcore-plus.github.io/useq-schema/
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. The hope is that this will encourage interoperability between various efforts to drive automated image acquisition.
The schema tries to remain agnostic to the specific acquisition engine, though it was designed around the needs of Micro-Manager. One hope is to solicit 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 is welcome! Please get in touch if you have any thoughts.
The primary "event" object is useq.MDAEvent
. This represents a single event
that a microscope should perform, including preparation of the hardware, and
execution of the event (such as an image acquisition). This is the simpler,
but more important of the two objects. Downstream libraries that aim to support
useq schema should support driving hardware based on an Iterable[MDAEvent]
.
- For micro-manager, this
object is most similar (though not that similar) to the events generated by
generate-acq-sequence
in the clojure acquisition engine. - For pycro-manager, this
object is similar to an individual acquisition event
dict
generated bymulti_d_acquisition_events
, (and,useq
provides ato_pycromanager()
method that converts anMDAEvent
into a single pycro-manager event dict) - your object here?...
See useq.MDAEvent
documentation
for more details.
Note:
useq-schema
usespydantic
to define models, so you can retrieve the json schema for theMDAEvent
object withMDAEvent.model_json_schema()
useq.MDASequence
is a declarative representation of an entire experiment. It
represents a sequence of events (as might be generated by the multidimensional
acquisition GUI in most microscope software). It is composed of "plans" for
each axis in the
experiment (such as a
Time Plan, a Z Plan, a list of channels and positions, etc.). A
useq.MDASequence
object is itself iterable, and yields MDAEvent
objects.
- For micro-manager, this
object is most similar to
org.micromanager.acquisition.SequenceSettings
, (generated by clicking the "Acquire!" button in the Multi-D Acquisition GUI) - For pycro-manager, this
object is similar to the
multi_d_acquisition_events
convenience function, (anduseq
provides ato_pycromanager()
method that converts anMDASequence
to a list of pycro-manager events) - your object here?...
See useq.MDASequence
documentation
for more details.
from useq import MDASequence
mda_seq = MDASequence(
stage_positions=[(100, 100, 30), (200, 150, 35)],
channels=["DAPI", "FITC"],
time_plan={'interval': 1, 'loops': 20},
z_plan={"range": 4, "step": 0.5},
axis_order='tpcz',
)
events = list(mda_seq)
print(len(events)) # 720
print(events[:3])
# [MDAEvent(
# channel=Channel(config='DAPI'),
# index=mappingproxy({'t': 0, 'p': 0, 'c': 0, 'z': 0}),
# min_start_time=0.0,
# x_pos=100.0,
# y_pos=100.0,
# z_pos=28.0,
# ),
# MDAEvent(
# channel=Channel(config='DAPI'),
# index=mappingproxy({'t': 0, 'p': 0, 'c': 0, 'z': 1}),
# min_start_time=0.0,
# x_pos=100.0,
# y_pos=100.0,
# z_pos=28.5,
# ),
# MDAEvent(
# channel=Channel(config='DAPI'),
# index=mappingproxy({'t': 0, 'p': 0, 'c': 0, 'z': 2}),
# min_start_time=0.0,
# x_pos=100.0,
# y_pos=100.0,
# z_pos=29.0,
# )]
serialize to yaml or json
print(mda_seq.yaml())
axis_order: tpcz
channels:
- config: DAPI
- config: FITC
stage_positions:
- x: 100.0
y: 100.0
z: 30.0
- x: 200.0
y: 150.0
z: 35.0
time_plan:
interval: 0:00:01
loops: 20
z_plan:
range: 4.0
step: 0.5
pymmcore-plus implements an
acquisition engine that can execute an MDASequence
using
micro-manager in a pure python environment (no Java required).
from pymmcore_plus import CMMCorePlus
core = CMMCorePlus()
core.loadSystemConfiguration() # loads demo by default
core.mda.run(mda_seq) # run the experiment
# or, construct a sequence of MDAEvents anyway you like
events = [MDAEvent(...), MDAEvent(...), ...]
core.mda.run(events)
See pymmcore-plus documentation for details