Skip to content

feat(cli): add iohub compute-pyramid command#412

Open
edyoshikun wants to merge 1 commit into
czbiohub-sf:mainfrom
edyoshikun:feat/cli-compute-pyramid
Open

feat(cli): add iohub compute-pyramid command#412
edyoshikun wants to merge 1 commit into
czbiohub-sf:mainfrom
edyoshikun:feat/cli-compute-pyramid

Conversation

@edyoshikun
Copy link
Copy Markdown
Collaborator

@edyoshikun edyoshikun commented May 1, 2026

Summary

  • Adds iohub compute-pyramid to the CLI, wrapping Position.compute_pyramid so users can build multiscale pyramid levels in place on existing OME-Zarr stores from the shell.
  • Modeled on iohub set-scale: uses @input_position_dirpaths() (so plates and globs like input.zarr/*/*/* Just Work), opens each position with mode=\"r+\", mutates in place.
  • No new dependencies. Logger-based progress messages.

Why

Position.compute_pyramid is already a public, tested method, but there is no shell-level entry point. Pipelines that produce a single-level zarr (e.g. biahub concatenate) currently need a custom Python script per project to add downsampled levels. Surfacing it as a CLI subcommand makes it a one-liner and matches the precedent set by set-scale.

Usage

# Build 4 total levels (level 0 + 3 extra), default mean downsampling
iohub compute-pyramid -i input.zarr/*/*/* --levels 4

# Median, YX-only (preserve Z)
iohub compute-pyramid -i input.zarr/*/*/* -l 3 -m median --dims y,x

# Pass the plate root — gets expanded into positions automatically
iohub compute-pyramid -i input.zarr -l 4

Options

Option
`-i / --input-position-dirpaths` required Position glob (or plate root)
`-l / --levels` required, int>=2 Total levels including level 0
`-m / --method` default `mean` One of mean/median/mode/min/max/stride
`-d / --dims` optional Comma list of axes to downsample, e.g. `y,x`. Defaults to z,y,x in iohub.

Tests

`tests/cli/test_cli.py` adds 5 new tests covering:

  • Happy path with explicit `--levels` and `--method`, asserting cascade halving on YX
  • Passing the plate root (verifies `_validate_and_process_paths` plate expansion)
  • `--dims y,x` (Z preserved)
  • `--help`
  • Invalid `--dims` value rejected with non-zero exit
$ uv run pytest tests/cli/
74 passed in 10.26s

`uvx prek run --files src/iohub/cli/cli.py tests/cli/test_cli.py` is clean.

Test plan

  • New CLI tests pass locally
  • Existing CLI suite still passes (`tests/cli/` 74/74)
  • `uvx prek run` clean (ruff check + ruff format + whitespace + EOF)
  • CI runs

🤖 Generated with Claude Code

Wraps `Position.compute_pyramid` so users can build multiscale
pyramid levels in place from the command line, mirroring the
ergonomics of `iohub set-scale` (per-position glob, plate
expansion, mode="r+").

  iohub compute-pyramid -i input.zarr/*/*/* --levels 4
  iohub compute-pyramid -i input.zarr/*/*/* -l 3 -m median --dims y,x

Tests cover:
- happy path with explicit levels and method
- plate-glob expansion (passing the plate root)
- partial-axis downsampling via --dims y,x (Z preserved)
- --help and invalid --dims rejection
@srivarra
Copy link
Copy Markdown
Collaborator

srivarra commented May 1, 2026

@edyoshikun We have the ability to create pyramids from cli over in biahub: https://github.com/czbiohub-sf/biahub/blob/main/biahub/pyramid.py

Is there a specific reason you want it in iohub too?

@edyoshikun
Copy link
Copy Markdown
Collaborator Author

IMO this is an iohub feature. you have all the code for multiscale here, so we should support the call here

@edyoshikun
Copy link
Copy Markdown
Collaborator Author

Also, that's the function I was looking for but you guys pointed me to the example in the website so I thought it didn't exist.

@ieivanov
Copy link
Copy Markdown
Contributor

ieivanov commented May 1, 2026

@edyoshikun as you said we currently have iohub API that computes a pyramid: Position.compute_pyramid and a biahub CLI: biahub pyramid which can distribute this computation over multiple SLURM nodes. Sorry that the biahub documentation is not easily accessible.

I don't mind adding a iohub CLI for computing pyramids too, as in this PR, the downside of that if that it will happen sequentially for multiple positions.

@srivarra
Copy link
Copy Markdown
Collaborator

srivarra commented May 1, 2026

@edyoshikun gotcha I see. Sure I think it'd be nice to have it here. Could be useful for just small one off things, and we would recommend users to go to biahub if they're working on larger datasets.

@edyoshikun
Copy link
Copy Markdown
Collaborator Author

For the 20GB dataset it was fairly fast ~ 5 min tops, so I think it's useful to have it here and independent to biahub. I could use some of this for the DL course as well.

@srivarra
Copy link
Copy Markdown
Collaborator

srivarra commented May 1, 2026

@edyoshikun Feel free to request a review whenever you think this is ready for one!

@ieivanov
Copy link
Copy Markdown
Contributor

ieivanov commented May 1, 2026

Agreed. We have a similar problem with convert. Currently iohub convert does only tif to zarr. For zarr v2 to zarr v3 we use biahub concatenate which is a bit odd. We discussed adding a biahub convert CLI: czbiohub-sf/biahub#178 and extending iohub convert to handle more than just tif to zarr: #408 (comment)

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.

3 participants