Skip to content

Commit

Permalink
Update readme (#195)
Browse files Browse the repository at this point in the history
* docs: update readme

* bold
  • Loading branch information
tlambert03 authored Nov 1, 2024
1 parent 9162967 commit a706d80
Showing 1 changed file with 107 additions and 65 deletions.
172 changes: 107 additions & 65 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,53 @@
[![docs](https://github.com/pymmcore-plus/useq-schema/actions/workflows/docs.yml/badge.svg)](https://pymmcore-plus.github.io/useq-schema/)
[![codecov](https://codecov.io/gh/pymmcore-plus/useq-schema/branch/main/graph/badge.svg)](https://codecov.io/gh/pymmcore-plus/useq-schema)

*An implementation agnostic schema for describing a sequence of events during a
multi-dimensional imaging acquisition.*
*An open, implementation-agnostic schema for describing multi-dimensional
microscopy experiments.*

**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.
## Rationale

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.
The `useq-schema` library defines a structured schema to represent a sequence of
microscope acquisition events. By adopting this schema, various microscopy
software tools can facilitate interoperability, allowing end users to
potentially switch between different control backends with ease. The goal is to
encourage a shared standard, making it straightforward for developers to adopt
useq-schema and enhance compatibility across tools.

Any and all feedback is welcome! Please get in touch if you have any thoughts.
**We are particularly interested in feedback from developers of microscopy-control
software**. If you are interested in supporting the useq-schema in your software,
please open an issue or pull request to discuss how we can make that easier for
you, or to request additional features that would be necessary for your use case.

## `MDAEvent`
## `useq.MDAEvent`

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]`.
execution of the event (such as an image acquisition).

```python
from useq import MDAEvent

event = MDAEvent(
channel="DAPI",
exposure=100,
x_pos=100.0,
y_pos=100.0,
z_pos=30.0,
min_start_time=10.0,
... # multiple other fields
)
```

Downstream libraries that aim to support useq-schema should support driving
hardware based on an `Iterable[MDAEvent]`. See [`useq.MDAEvent`
documentation](https://pymmcore-plus.github.io/useq-schema/schema/event/) for
more details.

<details>

<summary>Similar objects in existing software packages</summary>

- For [micro-manager](https://github.com/micro-manager/micro-manager), this
object is most similar (though not *that* similar) to the events generated by
Expand All @@ -49,23 +69,25 @@ useq schema should support driving hardware based on an `Iterable[MDAEvent]`.
single pycro-manager event dict)
- *your object here?...*

See [`useq.MDAEvent` documentation](https://pymmcore-plus.github.io/useq-schema/schema/event/)
for more details.

> **Note:** `useq-schema` uses [`pydantic`](https://pydantic-docs.helpmanual.io/) to
> define models, so you can retrieve the [json schema](https://json-schema.org/)
> for the `MDAEvent` object with `MDAEvent.model_json_schema()`
</details>

## `MDASequence`
## `useq.MDASequence`

`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
`useq.MDASequence` is a declarative representation of an multi-dimensional
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](https://pymmcore-plus.github.io/useq-schema/schema/axes/) (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.

See [`useq.MDASequence` documentation](https://pymmcore-plus.github.io/useq-schema/schema/sequence/)
for more details.

<details>

<summary>Similar objects in existing software packages</summary>

- For [micro-manager](https://github.com/micro-manager/micro-manager), this
object is most similar to
[`org.micromanager.acquisition.SequenceSettings`](https://github.com/micro-manager/micro-manager/blob/2b0f51a2f916112d39c6135ad35a112065f8d58d/mmstudio/src/main/java/org/micromanager/acquisition/SequenceSettings.java#L39),
Expand All @@ -77,10 +99,9 @@ Time Plan, a Z Plan, a list of channels and positions, etc.). A
converts an `MDASequence` to a list of pycro-manager events)
- *your object here?...*

See [`useq.MDASequence` documentation](https://pymmcore-plus.github.io/useq-schema/schema/sequence/)
for more details.
</details>

### example `MDASequence` usage
### Example usage

```python
from useq import MDASequence
Expand All @@ -92,39 +113,46 @@ mda_seq = MDASequence(
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
The `MDASequence` object is iterable, yielding `MDAEvent` objects in the order
specified by the `axis_order` attribute.

```python
>>> 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,
)]
```

Both `MDAEvent` and `MDASequence` objects are pydantic models, so they can be
easily serialized to and from json or yaml.

```py
print(mda_seq.yaml())
Expand All @@ -150,10 +178,22 @@ z_plan:
step: 0.5
```
## Installation
```bash
pip install useq-schema
```

or, with conda:

```bash
conda install -c conda-forge useq-schema
```

## Executing useq-schema experiments with pymmcore-plus

[pymmcore-plus](https://github.com/pymmcore-plus/pymmcore-plus) implements an
acquisition engine that can execute an `MDASequence` using
acquisition engine that can execute an iterable of `MDAEvents` using
micro-manager in a pure python environment (no Java required).

```python
Expand All @@ -169,4 +209,6 @@ events = [MDAEvent(...), MDAEvent(...), ...]
core.mda.run(events)
```

See [pymmcore-plus documentation](https://pymmcore-plus.github.io/pymmcore-plus/examples/mda/) for details
This can be considered a "reference implementation" of an engine that supports useq-schema.

See [pymmcore-plus documentation](https://pymmcore-plus.github.io/pymmcore-plus/examples/mda/) for details.

0 comments on commit a706d80

Please sign in to comment.