acia.segm.folder_source#

A folder of per-timepoint TIFFs exposed as one lazy time series.

Many acquisition setups (µManager, LabVIEW rigs, “save each frame” exports) write one folder per movie and one TIFF file per timepoint rather than a single stack. FolderSequenceSource reads that layout with the frame index being the file index: file i (natural-sorted) is frame i, decoded on demand, so peak memory stays at roughly one frame no matter how long the movie is.

resolve_layout() decides, from directory listings alone, whether a folder is a single movie (it holds the TIFFs itself) or a set of positions (its immediate subfolders hold them) – the same position axis that ND2 P and CZI S expose, so acia.segm.open.open_sequence() can serve all three identically.

acia.segm.folder_source.natural_key(name)[source]#

Digit-aware sort key so t2.tif sorts before t10.tif.

Lexicographic ordering of per-timepoint filenames is a silent frame-order corruption (it yields plausible-looking but wrong tracking), so ordering is always done through this key. re.split on a captured digit group always alternates text/number, so the tuples compare element-wise without ever mixing int and str at the same position.

img_1.tif and img_01.tif produce the same numeric key, so the raw basename is appended as a tie-break: without it their relative order would come from the filesystem’s listing order and could differ between machines.

Parameters:

name (str)

Return type:

tuple

acia.segm.folder_source.resolve_layout(folder, *, pattern=None, storage_options=None)[source]#

Resolve a folder into its position folders.

Parameters:
  • folder (str | PathLike) – directory holding either the frames themselves or one subfolder per position. A plain path or any fsspec URL.

  • pattern (str | None) – glob for the frame filenames; None means .tif/.tiff.

  • storage_options (dict | None) – extra fsspec options, resolved as everywhere else.

Returns:

(position_folders, nested). nested is False when folder holds the frames itself (one position, the folder itself), True when each matching immediate subfolder is a position (natural-sorted).

Raises:

ValueError – If neither the folder nor any immediate subfolder holds a matching file. Detection is exactly one level deep – a deeper tree raises rather than guessing which level is the position axis.

Return type:

tuple[list[str], bool]

class acia.segm.folder_source.FolderSequenceSource[source]#

Bases: ImageSequenceSource, JupyterVisualizationMixin

A folder of per-timepoint TIFFs as a lazy (T, H, W, C) time series.

Frame i is the i-th file in natural-sorted order and is decoded only when asked for, so a 3000-frame folder streams the same way ND2/CZI does. size_t costs a directory listing and no pixel decode at all.

The most recently read frame is cached (segmentation and property extraction ask for the same frame repeatedly), which keeps peak memory at ~one frame. Use materialize() to trade RAM for IO and hold the whole movie in memory.

Two consequences of that cache, shared with LocalSequenceSource: a returned frame’s raw array is the cached array, so do not modify it in place (copy first, or call close() to drop the cache); and an instance is not thread-safe – give each worker its own source rather than sharing one across threads.

Parameters:
  • folder – directory holding the per-timepoint files. A plain local path or any fsspec-supported URL (e.g. smb://).

  • pattern – glob for the frame filenames, matched case-insensitively against the basename. None (default) matches .tif/.tiff.

  • storage_options – extra fsspec storage options (e.g. credentials), merged on top of the acia config entry for the host (see acia.config).

  • normalize_image – normalize frames into uint8 RGB for display. Defaults to False, i.e. the file’s own dtype and intensities are preserved (the raw-frame convention of ND2SequenceSource/CZISequenceSource).

  • channel_axis – for 3-D files, which axis holds the channels: -1 (default) for (H, W, C), 0 for (C, H, W).

  • pixel_size – physical pixel size (pint length per pixel); overrides the first file’s own OME-XML/ImageJ metadata.

  • frame_interval – scalar time between frames (pint Quantity or a string like "5 min"). Per-timepoint files rarely carry timing, so this is usually the only source of it.

  • timepoints – explicit per-frame timepoints (pint Quantity array); same override-vs-auto-detect behavior as the other calibration args.

__init__(folder, *, pattern=None, storage_options=None, normalize_image=False, channel_axis=-1, pixel_size=None, frame_interval=None, timepoints=None)[source]#
Parameters:
Return type:

None

property files: tuple[str, ...]#

The resolved frame files, in frame order (frame i is files[i]).

Worth printing the first and last entry when opening an unfamiliar folder: wrong ordering is the one failure mode here that is otherwise silent.

get_frame(frame)[source]#

Return frame frame, decoding exactly the one file that backs it.

Parameters:

frame (int)

Return type:

BaseImage

property size_t: int#

Number of frames == number of matched files (listing only, no decode).

property size_h: int#
property size_w: int#
property size_c: int#
property num_channels: int#
property dtype: dtype#

dtype of the frames as stored in the files.

with_pixel_size(pixel_size)[source]#

Tag this source with a pixel size (pint length per pixel); returns self.

with_frame_interval(interval)[source]#

Tag this source with a scalar frame interval (pint); returns self.

with_timepoints(timepoints)[source]#

Tag this source with explicit per-frame timepoints (pint); returns self.

property pixel_size#

user override, else first file, else None.

Type:

Pint length per pixel

property timepoints#

user override, else first file, else None.

Type:

Per-frame pint timepoints

property calibration_source: str | None#

"ome", "imagej", or None (nothing detected, or every field was user-supplied).

Type:

Where auto-detected calibration came from

close()[source]#

Drop the cached frame (the source stays usable).

Return type:

None