Skip to content

Single-scale image writes are serialized as multiscale pyramids with ome-zarr==0.14.0 #1091

@ArneDefauw

Description

@ArneDefauw

Writing a single-scale xarray.DataArray image with SpatialData.write() produces a multiscale OME-Zarr pyramid on disk when using ome-zarr 0.14.0, even though the input is not multiscale.

Expected behavior

A single-scale image should remain single-scale on disk unless pyramid generation was explicitly requested.

Roundtrip expectation:

input: xarray.DataArray
output after read_zarr(): xarray.DataArray
Actual behavior
The image is written as a pyramid (s0, s1, s2, ...), and read_zarr() returns a multiscale object on roundtrip.

Minimal reproducible example

import tempfile
from pathlib import Path
from numpy.random import default_rng

import dask.array as da

from spatialdata import SpatialData, read_zarr
from spatialdata.models import Image2DModel

RNG = default_rng(0)

data = da.from_array(
    RNG.random((3, 800, 1000)),
    chunks=((3,), (300, 200, 300), (512, 488)),
)

image = Image2DModel.parse(data, dims=("c", "y", "x"))
print(type(image))  # xarray.DataArray

sdata = SpatialData(images={"image": image})

tmpdir = Path(tempfile.mkdtemp())
path = tmpdir / "data.zarr"

sdata.write(path)
sdata2 = read_zarr(path)

print(type(sdata2["image"]))

On-disk result
The written image group contains multiple scales:

data.zarr/images/image/
s0/
s1/
s2/
s3/
s4/

Suspected cause

spatialdata writes single-scale images through ome_zarr.writer.write_image().

In current ome_zarr, write_image() defaults to building a pyramid via:

scale_factors=(2, 4, 8, 16)
So calling it without overriding scale_factors writes a multiscale pyramid even for a single-scale input.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions