Hi, I’ve been learning spatialdata
for a couple of days now and I’m trying to apply it to some MIBI data represented as a collection of n single channel tiffs.
Currently for each FOV we store it’s channels as individual TIFF files (512 \times 512), for example:
mibi_cohort/
└── fov0/
├── chan_0.tiff
├── chan_1.tiff
├── chan_2.tiff
├── ...
└── chan_n.tiff
When loading the data, I’m loading all the images together with tifffile
and reading / opening them as a Zarr
Store / Array. Then I convert it to an Xarray.DataArray
, and then I convert it to a SpatialData
object with Image2DModel
.
This all works, however the x and y coordinates are now floating points starting at 0.5 to 511.5 incrementing by 0.5.
Here is a minimum working example
# Imports
from pathlib import Path
import spatialdata as sd
from spatialdata.models import Image2DModel, C, Y, X
import tifffile
import numpy as np
import zarr
import xarray as xr
# Creating some example single channel TIFFS
ex_fov_path = Path("./data/fov_ex")
ex_fov_path.mkdir(exist_ok=True, parents=True)
rng = np.random.default_rng()
rng_data = rng.random(size=(3, 512, 512))
channels = ["chan_0", "chan_1", "chan_2"]
# Populate an array (Channels, Y, X) with random data and save as TIFFs
for data, channel in zip(rng_data, channels):
tifffile.imwrite(ex_fov_path / f"{channel}.tiff", data=data)
# 1. Load the tiffs
# 2. Convert to `Zarr` Store and the open `Zarr` Store,
# 3. Convert to `xr.DataArray`
# 4. Convert to `spatialdata.models.Image2DModel`
# 5. Convert to SpatialData Object
def load_folder_of_tiffs(p: Path):
tiff_paths = list(p.glob("*.tiff"))
channel_names: list[str] = [tp.stem for tp in tiff_paths]
zarr_store: tifffile.ZarrFileSequenceStore = tifffile.imread(
tiff_paths, aszarr=True
)
zarr_array = zarr.open(zarr_store)
fov = xr.DataArray(
data=zarr_array,
dims=(C, Y, X),
coords={
C: channel_names,
Y: np.arange(512, dtype=np.int16),
X: np.arange(512, dtype=np.int16),
},
)
fov_sd = sd.SpatialData(
images={"fov": Image2DModel.parse(data=fov, scale_factors=None)}
)
return fov_sd
Run the function with the example directory
fov = load_folder_of_tiffs(ex_fov_path)
fov.images["fov"]
Here is the html rendered output of the DataArray.
I expected the x and y coordinates to be integers covering [0,511].
Thank you!