From fd7e092f1121dd230dddba79ac4e94e6afaa96ad Mon Sep 17 00:00:00 2001 From: Kaidong Chai Date: Fri, 15 Nov 2024 16:21:52 -0500 Subject: [PATCH] refactor: write_ome_metadata --- .../modalities/psoct/single_volume.py | 91 ++++++++++--------- linc_convert/modalities/psoct/utils.py | 26 ++---- 2 files changed, 57 insertions(+), 60 deletions(-) diff --git a/linc_convert/modalities/psoct/single_volume.py b/linc_convert/modalities/psoct/single_volume.py index a1e545f..0d1a1b9 100644 --- a/linc_convert/modalities/psoct/single_volume.py +++ b/linc_convert/modalities/psoct/single_volume.py @@ -21,7 +21,7 @@ from linc_convert.modalities.psoct.cli import psoct from linc_convert.modalities.psoct.utils import make_json, generate_pyramid, \ - niftizarr_write_header + niftizarr_write_header, write_ome_metadata from linc_convert.utils.math import ceildiv from linc_convert.utils.orientation import orientation_to_affine, center_affine from linc_convert.utils.unit import to_ome_unit, to_nifti_unit @@ -179,49 +179,7 @@ def convert( print("Write metadata") print(unit) ome_unit = to_ome_unit(unit) - multiscales = [ - { - "version": "0.4", - "axes": [ - {"name": "z", "type": "space", "unit": ome_unit}, - {"name": "y", "type": "space", "unit": ome_unit}, - {"name": "x", "type": "space", "unit": ome_unit}, - ], - "datasets": [], - "type": ("2x2x2" if no_pool is None else "2x2") + "mean window", - "name": "", - } - ] - - for n in range(nblevels): - multiscales[0]["datasets"].append({}) - level = multiscales[0]["datasets"][-1] - level["path"] = str(n) - - # With a moving window, the scaling factor is exactly 2, and - # the edges of the top-left voxel are aligned - level["coordinateTransformations"] = [ - { - "type": "scale", - "scale": [ - (1 if no_pool == 0 else 2 ** n) * vx[0], - (1 if no_pool == 1 else 2 ** n) * vx[1], - (1 if no_pool == 2 else 2 ** n) * vx[2], - ], - }, - { - "type": "translation", - "translation": [ - (0 if no_pool == 0 else (2 ** n - 1)) * vx[0] * 0.5, - (0 if no_pool == 1 else (2 ** n - 1)) * vx[1] * 0.5, - (0 if no_pool == 2 else (2 ** n - 1)) * vx[2] * 0.5, - ], - }, - ] - multiscales[0]["coordinateTransformations"] = [ - {"scale": [1.0] * 3, "type": "scale"} - ] - omz.attrs["multiscales"] = multiscales + write_ome_metadata(omz, no_pool=no_pool, space_unit=ome_unit, space_scale=vx, multiscales_type=("2x2x2" if no_pool is None else "2x2") + "mean window") if not nii: print("done.") @@ -256,6 +214,51 @@ def convert( # print("done.") +# def write_ome_metadata(nblevels, no_pool, ome_unit, omz, vx): +# multiscales = [ +# { +# "version": "0.4", +# "axes": [ +# {"name": "z", "type": "space", "unit": ome_unit}, +# {"name": "y", "type": "space", "unit": ome_unit}, +# {"name": "x", "type": "space", "unit": ome_unit}, +# ], +# "datasets": [], +# "type": ("2x2x2" if no_pool is None else "2x2") + "mean window", +# "name": "", +# } +# ] +# for n in range(nblevels): +# multiscales[0]["datasets"].append({}) +# level = multiscales[0]["datasets"][-1] +# level["path"] = str(n) +# +# # With a moving window, the scaling factor is exactly 2, and +# # the edges of the top-left voxel are aligned +# level["coordinateTransformations"] = [ +# { +# "type": "scale", +# "scale": [ +# (1 if no_pool == 0 else 2 ** n) * vx[0], +# (1 if no_pool == 1 else 2 ** n) * vx[1], +# (1 if no_pool == 2 else 2 ** n) * vx[2], +# ], +# }, +# { +# "type": "translation", +# "translation": [ +# (0 if no_pool == 0 else (2 ** n - 1)) * vx[0] * 0.5, +# (0 if no_pool == 1 else (2 ** n - 1)) * vx[1] * 0.5, +# (0 if no_pool == 2 else (2 ** n - 1)) * vx[2] * 0.5, +# ], +# }, +# ] +# multiscales[0]["coordinateTransformations"] = [ +# {"scale": [1.0] * 3, "type": "scale"} +# ] +# omz.attrs["multiscales"] = multiscales + + @contextmanager def mapmat(fname, key=None): """Load or memory-map an array stored in a .mat file""" diff --git a/linc_convert/modalities/psoct/utils.py b/linc_convert/modalities/psoct/utils.py index 7a5daff..9d0f742 100644 --- a/linc_convert/modalities/psoct/utils.py +++ b/linc_convert/modalities/psoct/utils.py @@ -258,7 +258,7 @@ def generate_pyramid( def write_ome_metadata( - path: str | os.PathLike, + omz, axes: list[str], space_scale: float | list[float] = 1, time_scale: float = 1, @@ -267,6 +267,8 @@ def write_ome_metadata( name: str = "", pyramid_aligns: str | int | list[str | int] = 2, levels: int | None = None, + no_pool: int | None = None, + multiscales_type : str = "" ) -> None: """ Write OME metadata into Zarr. @@ -298,25 +300,19 @@ def write_ome_metadata( """ - # Detect zarr version - # Read shape at each pyramid level - zname = ".zarray" shapes = [] level = 0 while True: if levels is not None and level > levels: break - zpath = path / str(level) / zname - if not zpath.exists(): + if str(level) not in omz.keys(): levels = level break level += 1 - with zpath.open("rb") as f: - zarray = json.load(f) - shapes += [zarray["shape"]] + shapes += omz[str(level)].shape axis_to_type = { "x": "space", @@ -370,7 +366,7 @@ def write_ome_metadata( for axis in axes ], "datasets": [], - "type": "median window " + "x".join(["2"] * sdim), + "type": "median window " + "x".join(["2"] * sdim) if not multiscales_type else multiscales_type, "name": name, } ] @@ -391,6 +387,7 @@ def write_ome_metadata( else ((shape0[bdim + i] - 1) / (shape[bdim + i] - 1)) ) * space_scale[i] + if i != no_pool else space_scale[i] for i in range(sdim) ] translation = [0] * bdim + [ @@ -403,6 +400,7 @@ def write_ome_metadata( ) * 0.5 * space_scale[i] + if i != no_pool else 0 for i in range(sdim) ] @@ -417,18 +415,14 @@ def write_ome_metadata( }, ] - scale = [1] * ndim + scale = [1.0] * ndim if "t" in axes: scale[axes.index("t")] = time_scale multiscales[0]["coordinateTransformations"] = [{"scale": scale, "type": "scale"}] multiscales[0]["version"] = "0.4" - with (path / ".zgroup").open("wt") as f: - json.dump({"zarr_format": 2}, f, indent=4) - with (path / ".zattrs").open("wt") as f: - json.dump({"multiscales": multiscales}, f, indent=4) - + omz.attrs["multiscales"] = multiscales def niftizarr_write_header( omz,