Skip to content

About

Python pipeline engine for scientific image analysis recipes, built for real-time adaptive feedback microscopy

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

ZMART Analysis

tests python license status

ZMART Analysis

ZMART Analysis is an image analysis engine built for smart microscopy. It analyses images as the microscope acquires them, so the results can decide what to image next. Tools with conflicting dependencies work together in one pipeline, and every pipeline is reproducible. Any interface, AI agent or acquisition workflow can drive it.

It is part of ZMART (ZMB's Microscopy-Agnostic Research Toolkit), the tools we use for smart microscopy at the Center for Microscopy and Image Analysis (ZMB), University of Zurich.

The Problem

When building smart microscopy workflows, you are likely to run into the following four problems.

  1. Dependency conflicts. Analysis pipelines consist of multiple steps. Each step needs the right environment with the right dependencies, and often there is no single environment in which all steps can run.

  2. Reproducibility. Image analysis pipelines can be complex and are often fitted to one use case. They chain many algorithms, each with their own parameters. Making sure that these pipelines are reproducible, properly documented and easy to share is a challenge on its own.

  3. Time. The analysis is often time sensitive. The microscope waits for the answer, so images must be analysed as soon as they come in.

  4. Analysis over scopes. Depending on the experiment, analysis needs to be done over single images, a group of images, a compartment, a carrier, or a whole experiment. However, the data does not come in all at once. A step over a larger scope can only start once the right set of images is in. Keeping track of all these analysis requirements calls for a higher degree of orchestration.

The Solution

The ZMART Analysis pipeline engine addresses all four of them.

  1. Every step can be executed in its own environment. Each step says which conda environment it needs. The pipeline engine runs each step in that environment and pieces the steps together into one pipeline. In this way, steps can share an environment or be separated to neutralise dependency conflicts.

  2. Pipelines are constructed in YAML files. Which steps are pieced together, in which order, with which parameters, is defined in a YAML file: the recipe. An analysis is always started from this file, so it is reproducible and easy to share and document. Every result also records the environment, Python version and package versions each step actually ran with.

  3. Environments stay active, and several can run at once. During a run, the analysis environments (workers) are started once and stay active, so each image is processed the moment it comes in. For one step, several workers can be spawned to analyse images concurrently. A queue routes incoming work to the right worker and lets urgent jobs go first.

  4. Steps declare a scope. Each step says over which scope its analysis needs to run: a single image, a group, a compartment, a carrier, or the experiment. When all the data for a scope is in, the step starts. Steps within one pipeline can differ in scope, so per-image steps run as each image comes in while a per-carrier step waits for the whole carrier, is told what failed beneath it, and carries the lineage of every image it was built from.

Want to give it a try?

from engine import Engine

engine = Engine()
engine.register("focus", "workflows/focus/pipelines/focus.yaml")
engine.submit("focus", {"image_path": "stack.tiff", "z_um": [0, 2, 4, 6, 8]})
print(engine.results("focus"))
engine.shutdown()
  1. Use the engine. Every call, the recipe format, scopes, workers, and what comes back. Tutorial: notebook.
  2. Implement an analysis step. The one function a step needs, its own environment, and where everything lives. Tutorial: notebook.
  3. The workflows we use. Focus, object analysis and driver configuration: what each does and where to start.

Install it

Python 3.11 or newer and conda are needed. The engine itself needs only PyYAML; each workflow's setup_env.py makes the conda environment its steps run in.

git clone https://github.com/thomdehoog/ZMART-analysis.git
cd ZMART-analysis
pip install -e .
python workflows/focus/environments/setup_env.py   # once for each workflow you use

The package installs as engine: from engine import Engine. The tutorials are notebooks; pip install jupyter to run them.

Status

This is a release candidate. The step format, the recipe layout and the Engine calls are settled in spirit, and small changes may still happen before 1.0. If you build a workflow on it, please open an issue so we can keep the contract honest together.

Testing

pip install -e ".[test]"
pytest -m "not cellpose and not conda_env and not pooch"

This is what the continuous integration runs on every change, on Linux, macOS and Windows with Python 3.11 to 3.13, after ruff check . and ruff format --check .. Without the -m filter the suite also runs the tests that need the per-step conda environments, Cellpose with its model, and public sample images downloaded on first use. tests/ holds the engine's tests and those of workflows/shared/; each workflow's steps are tested in its own workflows/<name>/tests/.

Author

Thom de Hoog, Center for Microscopy and Image Analysis (ZMB), University of Zurich (thom.dehoog@zmb.uzh.ch, thomdehoog@gmail.com).

License

MIT License. See LICENSE for details, and CITATION.cff for how to cite ZMART Analysis.

Links

About

Python pipeline engine for scientific image analysis recipes, built for real-time adaptive feedback microscopy

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages