pymmcore_plus.mda.handlers
¶
Deprecated data handlers (writers) for MDA acquisitions.
Deprecated
This module is deprecated, and importing it emits a FutureWarning. To save
data, pass a path ending in .ome.zarr or .ome.tiff (or an
ome_writers.AcquisitionSettings) as the output of
MDARunner.run, which writes with
ome-writers (see
Saving Data). These handlers will be removed in a future version;
if you depend on one, please copy it into your own code.
Classes
| Name | Description |
|---|---|
ImageSequenceWriter |
Write each frame of an MDA to a directory as individual image files. |
OMETiffWriter |
MDA handler that writes to a 5D OME-TIFF file. |
OMEZarrWriter |
MDA handler that writes to a zarr file following the ome-ngff spec. |
TensorStoreHandler |
Tensorstore handler for writing MDA sequences. |
Functions
| Name | Description |
|---|---|
handler_for_path |
Convert a string or Path into a handler object. |
Classes¶
ImageSequenceWriter
¶
ImageSequenceWriter(
directory: Path | str,
extension: str = ".tif",
prefix: str = "",
*,
imwrite: ImgWriter | None = None,
overwrite: bool = False,
include_frame_count: bool = True,
imwrite_kwargs: dict | None = None,
)
Write each frame of an MDA to a directory as individual image files.
This writer assumes very little about the sequence, and simply writes each frame to a file in the specified directory. It is a good option for ragged or sparse sequences, or where the exact number of frames is not known in advance.
The default output format is TIFF, backed by tifffile.imwrite, but many other
common extensions can be used if imageio is installed. Or, you can pass a
custom writer function to the imwrite argument.
The metadata for each frame is stored in a JSON file in the directory (by default, named "_frame_metadata.json"). The metadata is stored as a dict, with the key being the index string for the frame (see index_template), and the value being the metadata dict for that frame.
The metadata for the entire MDA sequence is stored in a JSON file in the directory (by default, named "_useq_MDASequence.json").
Note
This writer outputs a format that is easily consumed by tifffile.imread
using the pattern="axes" option.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
directory
|
Path | str
|
The directory to write the files to. |
required |
extension
|
str
|
The file extension to use. By default, ".tif". |
'.tif'
|
prefix
|
str
|
A prefix to add to the file names. By default, no prefix is added. |
''
|
imwrite
|
ImgWriter | None
|
A function to write the image data to disk. The function should take a filename
and image data as positional arguments. If None, a writer will be selected based
on the extension. For the default extension |
None
|
overwrite
|
bool
|
Whether to overwrite the directory if it already exists. If False, a FileExistsError will be raised if the directory already exists. |
False
|
include_frame_count
|
bool
|
Whether to include a frame count item in the template ( |
True
|
imwrite_kwargs
|
dict | None
|
Extra keyword arguments to pass to the |
None
|
sequenceStarted
¶
sequenceStarted(seq: MDASequence) -> None
Store the sequence metadata and reset the frame counter.
frameReady
¶
frameReady(frame: ndarray, event: MDAEvent, meta: FrameMetaV1) -> None
Write a frame to disk.
fname_template
staticmethod
¶
fname_template(
axes: Mapping[str, int] | Sequence[str],
prefix: str = "",
extension: str = ".tif",
delimiter: str = "_",
include_frame_count: bool = True,
) -> str
Generate a string template for file names.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
axes
|
Mapping[str, int] | Sequence[str]
|
The axes to include in the template. If a mapping, the values are the number of digits to use for each axis. If a sequence, the number of digits is determined automatically. |
required |
prefix
|
str
|
A prefix to add to the template, by default "" |
''
|
extension
|
str
|
The file extension to use, by default ".tif" |
'.tif'
|
delimiter
|
str
|
The delimiter to use between items in the template, by default "_" |
'_'
|
include_frame_count
|
bool
|
Whether to include a frame count item in the template ( |
True
|
Examples:
OMETiffWriter
¶
MDA handler that writes to a 5D OME-TIFF file.
Positions will be split into different files.
Data is memory-mapped to disk using numpy.memmap via tifffile. Tifffile handles the OME-TIFF format.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filename
|
Path | str
|
The filename to write to. Must end with '.ome.tiff' or '.ome.tif'. |
required |
write_frame
¶
Write a frame to the file.
OMEZarrWriter
¶
OMEZarrWriter(
store: MutableMapping | str | PathLike | FSMap | None = None,
*,
overwrite: bool = False,
synchronizer: ZarrSynchronizer | None = None,
zarr_version: Literal[2, 3, None] = None,
array_kwargs: ArrayCreationKwargs | None = None,
minify_attrs_metadata: bool = False,
)
MDA handler that writes to a zarr file following the ome-ngff spec.
This implements v0.4 https://ngff.openmicroscopy.org/0.4/index.html
It also aims to be compatible with the xarray Zarr spec: https://docs.xarray.dev/en/latest/internals/zarr-encoding-spec.html
Note: this does not currently calculate any additional pyramid levels. But it would be easy to do so after acquisition. Chunk size is currently 1 XY plane.
Zarr directory structure will be:
root.zarr/
├── .zgroup # group metadata
├── .zattrs # contains ome-multiscales metadata
│
├── p0 # each position is a separate <=5D array
│ ├── .zarray
│ ├── .zattrs
│ └── t # nested directories for each dimension
│ └── c # (only collected dimensions will be present)
│ └── z
│ └── y
│ └── x # chunks will be each XY plane
├── ...
├── p<n>
│ ├── .zarray
│ ├── .zattrs
│ └── t...
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
store
|
MutableMapping | str | PathLike | FSMap | None
|
Zarr store or path to directory in file system to write to.
Semantics are the same as for |
None
|
overwrite
|
bool
|
If True, delete any pre-existing data in |
False
|
synchronizer
|
ZarrSynchronizer | None
|
Array synchronizer passed to |
None
|
zarr_version
|
(2, 3, None)
|
Zarr version passed to |
2
|
array_kwargs
|
dict
|
Keyword arguments passed to |
None
|
minify_attrs_metadata
|
bool
|
If True, zattrs metadata will be read from disk, minified, and written back to disk at the end of a successful acquisition (to save space). Default is False. |
False
|
in_tmpdir
classmethod
¶
in_tmpdir(
suffix: str | None = ".zarr",
prefix: str | None = "pymmcore_zarr_",
dir: str | PathLike[str] | None = None,
cleanup_atexit: bool = True,
**kwargs: Any,
) -> OMEZarrWriter
Create OMEZarrHandler that writes to a temporary directory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
suffix
|
str
|
If suffix is specified, the file name will end with that suffix, otherwise there will be no suffix. |
'.zarr'
|
prefix
|
str
|
If prefix is specified, the file name will begin with that prefix, otherwise a default prefix is used. |
'pymmcore_zarr_'
|
dir
|
str or PathLike
|
If dir is specified, the file will be created in that directory, otherwise a default directory is used (tempfile.gettempdir()) |
None
|
cleanup_atexit
|
bool
|
Whether to automatically cleanup the temporary directory when the python process exits. Default is True. |
True
|
**kwargs
|
Any
|
Remaining kwargs are passed to |
{}
|
finalize_metadata
¶
Called by superclass in sequenceFinished. Flush metadata to disk.
new_array
¶
Create a new array in the group, under key.
TensorStoreHandler
¶
TensorStoreHandler(
*,
driver: TsDriver = "zarr",
kvstore: str | dict | None = "memory://",
path: str | PathLike | None = None,
delete_existing: bool = False,
spec: Mapping | None = None,
)
Tensorstore handler for writing MDA sequences.
This is a performant and shape-agnostic handler for writing MDA sequences to chunked storages like zarr, n5, backed by tensorstore: https://google.github.io/tensorstore/
By default, the handler will store frames in a zarr array, with a shape of
(nframes, *frame_shape) and a chunk size of (1, *frame_shape), i.e. each frame
is stored in a separate chunk. To customize shape or chunking, override the
get_full_shape, get_chunk_layout, and get_index_domain methods (these
may change in the future as we learn to use tensorstore better).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
driver
|
TsDriver
|
The driver to use for the tensorstore, by default "zarr". Must be one of "zarr", "zarr3", "n5", or "neuroglancer_precomputed". |
'zarr'
|
kvstore
|
str | dict | None
|
The key-value store to use for the tensorstore, by default "memory://". A dict might look like {'driver': 'file', 'path': '/path/to/dataset.zarr'} see https://google.github.io/tensorstore/kvstore/index.html#json-KvStore for all options. If path is provided, the kvstore will be set to file://path |
'memory://'
|
path
|
str | Path | None
|
Convenience for specifying a local filepath. If provided, overrides the
kvstore option, to be |
None
|
delete_existing
|
bool
|
Whether to delete the existing dataset if it exists, by default False. |
False
|
spec
|
Mapping
|
A spec to use when opening the tensorstore, by default None. Values provided in this object will override the default values provided by the handler. This is a complex object that can completely define the tensorstore, see https://google.github.io/tensorstore/spec.html for more information. |
None
|
Examples:
from pymmcore_plus import CMMCorePlus
from pymmcore_plus.mda.handlers import TensorStoreHandler
from useq import MDASequence
core = CMMCorePlus.instance()
core.loadSystemConfiguration()
sequence = MDASequence(
channels=["DAPI", {"config": "FITC", "exposure": 1}],
stage_positions=[{"x": 1, "y": 1, "name": "some position"}, {"x": 0, "y": 0}],
time_plan={"interval": 2, "loops": 3},
z_plan={"range": 4, "step": 0.5},
axis_order="tpcz",
)
writer = TensorStoreHandler(path="example_ts.zarr", delete_existing=True)
core.mda.run(sequence, output=writer)
current_sequence
property
¶
current_sequence: MDASequence | None
Return current sequence, or none.
Use .reset() to initialize the handler for a new sequence.
in_tmpdir
classmethod
¶
in_tmpdir(
suffix: str | None = "",
prefix: str | None = "pymmcore_zarr_",
dir: str | PathLike[str] | None = None,
cleanup_atexit: bool = True,
**kwargs: Any,
) -> Self
Create TensorStoreHandler that writes to a temporary directory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
suffix
|
str
|
If suffix is specified, the file name will end with that suffix, otherwise there will be no suffix. |
''
|
prefix
|
str
|
If prefix is specified, the file name will begin with that prefix, otherwise a default prefix is used. |
'pymmcore_zarr_'
|
dir
|
str or PathLike
|
If dir is specified, the file will be created in that directory, otherwise a default directory is used (tempfile.gettempdir()) |
None
|
cleanup_atexit
|
bool
|
Whether to automatically cleanup the temporary directory when the python process exits. Default is True. |
True
|
**kwargs
|
Any
|
Remaining kwargs are passed to |
{}
|
sequenceStarted
¶
sequenceStarted(seq: MDASequence, meta: SummaryMetaV1) -> None
On sequence started, simply store the sequence.
sequenceFinished
¶
sequenceFinished(seq: MDASequence) -> None
On sequence finished, clear the current sequence.
frameReady
¶
frameReady(frame: ndarray, event: MDAEvent, meta: FrameMetaV1) -> None
Write frame to the zarr array for the appropriate position.
isel
¶
isel(
indexers: Mapping[str, int | slice] | None = None,
**indexers_kwargs: int | slice,
) -> ndarray
Select data from the array.
new_store
¶
new_store(
frame: ndarray, seq: MDASequence | None, meta: FrameMetaV1
) -> Future[TensorStore]