Skip to content

feat(ome-tiff): opt-in per-timepoint split for offloadable OME-TIFF acquisitions - #650

Draft
hongquanli wants to merge 3 commits into
feat/large-acquisitions-manifestfrom
feat/large-acquisitions-ome-split
Draft

hongquanli wants to merge 3 commits into
feat/large-acquisitions-manifestfrom
feat/large-acquisitions-ome-split

Conversation

@hongquanli

@hongquanli hongquanli commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Third of three stacked PRs for large acquisitions (stacks on #649; design: AI-docs Squid/to-do/2026-09-14-large-acquisitions-offload-and-pause-design.md). OME-TIFF acquisitions can now be split per timepoint, so finished timepoints become movable during the run like every other format.

Strictly opt-in. OME_TIFF_SPLIT_TIMEPOINTS (default off) or a per-run choice. With it off, the OME-TIFF writer, layout and metadata are byte-identical to today (one ome_tiff/<region>_<fov>.ome.tiff per FOV holding all timepoints, listed in the manifest only when the last timepoint finalizes it).

When on

  • Layout: <t>/ome_tiff/<region>_<fov>.ome.tiff per timepoint (timepoint folder named with FILE_ID_PADDING, like the individual-images format), each a valid standalone OME-TIFF with SizeT=1, plane TheT=0, DeltaT relative to the acquisition start (so times stay comparable across files), TimeIncrement retained.
  • The writer's existing on-disk progress accounting is scoped per timepoint (expected planes Z×C, progress file keyed by timepoint), so an aborted timepoint never contaminates the next, and each file finalizes as soon as its planes are written; the transfer manifest lists it then (writer-authoritative completion).
  • Where it is chosen: Settings › Acquisition › Large Acquisitions › "Split OME-TIFF by timepoint", or the pre-flight "Not Enough Disk Space" dialog, which for a multi-timepoint OME-TIFF run offers "Split OME-TIFF by timepoint and continue" (enables large acquisition mode for the run as well). Headless YAML runs use acquisition.ome_tiff_split_timepoints (absent = unchanged). The effective flag is recorded in acquisition.yaml.
  • tools/upload_acquisition.py verify understands both layouts.
  • NDViewer: browsing split runs needs the companion viewer change, Cephla-Lab/ndviewer_light#41 (verified against a real split run from this branch); the submodule pointer will be bumped once that merges. Until then the split option's tooltip says so.

Tests

Writer round trips (split and unsplit, DeltaT continuity, per-timepoint progress files, abort of one timepoint not affecting the next, simulation mode), settings/YAML/controller plumbing, the pre-flight decision matrix and dialog wiring, Preferences persistence, and simulated runs (test_ome_split_integration.py): unsplit layout unchanged and listed once at the end; split run writes one SizeT=1 file per timepoint, lists each before its timepoint_done, records the flag in acquisition.yaml; the upload tool moves and verifies a split run.

🤖 Generated with Claude Code

https://claude.ai/code/session_01F7SDD9fYF47FUoL8M1dfvF

…cquisitions

Third of three stacked PRs for large acquisitions. OME-TIFF wrote one
pre-allocated file per FOV holding every timepoint, so nothing could be
offloaded before the last timepoint. With the new opt-in split each
timepoint gets its own <t>/ome_tiff/<region>_<fov>.ome.tiff (SizeT=1,
TheT=0, DeltaT relative to the acquisition start, TimeIncrement kept),
which finalizes after Z x C planes and is then listed in the transfer
manifest like every other format.

Strictly opt-in: OME_TIFF_SPLIT_TIMEPOINTS (default off) or a per-run
choice; with it off the writer, layout and OME-XML are byte-identical
(verified against the previous module versions, UUIDs aside).

- utils_ome_tiff_writer / SaveOMETiffJob: when AcquisitionInfo.
  split_timepoints, the output folder is the timepoint folder's ome_tiff/,
  the on-disk progress file is keyed per timepoint (an aborted timepoint
  never contaminates the next), shape and expected count are per
  timepoint, plane indices are local (t=0) while DeltaT stays global, and
  the OME Description names the global timepoint.
- AcquisitionInfo gains split_timepoints and acquisition_start_time; the
  worker passes the run's effective flag and start time.
- Setting + per-run flag: AcquisitionParameters.split_ome_timepoints,
  MultiPointController.set_split_ome_timepoints, folded with the global
  setting in build_params, recorded as acquisition.ome_tiff_split_timepoints
  in acquisition.yaml and read back (absent = unchanged), reset after the
  run. Preferences: "Split OME-TIFF by timepoint" in Large Acquisitions.
- Pre-flight "Not Enough Disk Space" dialog: for a multi-timepoint
  OME-TIFF run offers "Split OME-TIFF by timepoint and continue", which
  also enables large acquisition mode for the run.

Tests: writer round trips (split/unsplit, DeltaT continuity, per-timepoint
progress files, abort isolation, simulation), plumbing and pre-flight
matrix, Preferences, and simulated runs: unsplit layout unchanged and
listed once at the end; split run writes one SizeT=1 file per timepoint,
lists each before its timepoint_done, records the flag; the upload tool
moves and verifies a split run.

Browsing split runs in the NDViewer needs the companion ndviewer_light
change (separate PR, submodule bump to follow).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F7SDD9fYF47FUoL8M1dfvF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant