88"""Task to remove singleton T dimension from an OME-Zarr."""
99
1010import logging
11+ import os
12+ import shutil
1113from typing import Any
1214
1315import dask .array as da
14- import zarr
15- from fractal_tasks_core .ngff import load_NgffImageMeta
16- from fractal_tasks_core .pyramids import build_pyramid
16+ import ngio
1717from pydantic import validate_call
1818
1919logger = logging .getLogger (__name__ )
2020
2121
22- def get_attrs_without_t (zarr_url : str ):
23- """Generate zattrs without the t dimension.
24-
25- Args:
26- zarr_url: Path to the zarr image
27- """
28- image_group = zarr .open_group (zarr_url )
29- zattrs = image_group .attrs .asdict ()
30- # print(zattrs)
31- for multiscale in zattrs ["multiscales" ]:
32- # Update axes
33- multiscale ["axes" ] = multiscale ["axes" ][1 :]
34- # Update coordinate Transforms
35- for dataset in multiscale ["datasets" ]:
36- for transform in dataset ["coordinateTransformations" ]:
37- if transform ["type" ] == "scale" :
38- transform ["scale" ] = transform ["scale" ][1 :]
39- return zattrs
40-
41-
4222@validate_call
4323def drop_t_dimension (
4424 * ,
@@ -58,60 +38,49 @@ def drop_t_dimension(
5838 """
5939 # Normalize zarr_url
6040 zarr_url_old = zarr_url .rstrip ("/" )
61- if overwrite_input :
62- zarr_url_new = zarr_url_old
63- else :
64- zarr_url_new = f"{ zarr_url_old } _{ suffix } "
41+ zarr_url_new = f"{ zarr_url_old } _{ suffix } "
6542
6643 logger .info (f"{ zarr_url_old = } " )
6744 logger .info (f"{ zarr_url_new = } " )
6845
69- # Read some parameters from metadata
70- ngff_image = load_NgffImageMeta (zarr_url_old )
71-
72- # Check that T axis is the first axis:
73- if not ngff_image .multiscale .axes [0 ].name == "t" :
74- logger .warning (
75- f"The Zarr image { zarr_url_old } did not contain a T axis as its "
76- f"first axis. The axes were: { ngff_image .multiscale .axes } \n "
77- "The Drop T axis task is skipped"
46+ old_ome_zarr = ngio .open_ome_zarr_container (zarr_url_old )
47+ old_ome_zarr_img = old_ome_zarr .get_image ()
48+ if not old_ome_zarr_img .has_axis ("t" ):
49+ raise ValueError (
50+ f"The Zarr image { zarr_url_old } does not contain a T axis. "
51+ "Thus, the drop T dimension task can't be applied to it."
7852 )
79- return {}
80-
81- # Load 0-th level
82- data_tczyx = da .from_zarr (zarr_url_old + "/0" )
83- # TODO: Check that T dimension is actually a singleton.
84- new_data = data_tczyx [0 , ...]
53+ # TODO: Check if T dimension not singleton
54+ image = old_ome_zarr_img .get_array (mode = "dask" )
55+ t_index = old_ome_zarr_img .meta .axes_mapper .get_index ("t" )
56+ new_img = da .squeeze (image , axis = t_index )
57+ pixel_size = old_ome_zarr_img .pixel_size
58+ new_pixel_size = ngio .PixelSize (x = pixel_size .x , y = pixel_size .y , z = pixel_size .z )
59+ axes_names = old_ome_zarr_img .meta .axes_mapper .on_disk_axes_names
60+ del axes_names [t_index ]
61+ chunk_sizes = old_ome_zarr_img .chunks
62+ new_chunk_sizes = chunk_sizes [:t_index ] + chunk_sizes [t_index + 1 :]
63+ new_ome_zarr_container = old_ome_zarr .derive_image (
64+ store = zarr_url_new ,
65+ shape = new_img .shape ,
66+ chunks = new_chunk_sizes ,
67+ dtype = old_ome_zarr_img .dtype ,
68+ pixel_size = new_pixel_size ,
69+ axes_names = axes_names ,
70+ )
71+ new_image_container = new_ome_zarr_container .get_image ()
72+ new_image_container .set_array (new_img )
73+ new_image_container .consolidate ()
8574
8675 if overwrite_input :
8776 image_list_update = dict (zarr_url = zarr_url_old , types = dict (has_t = False ))
77+ os .rename (zarr_url_old , f"{ zarr_url_old } _tmp" )
78+ os .rename (zarr_url_new , zarr_url_old )
79+ shutil .rmtree (f"{ zarr_url } _tmp" )
8880 else :
89- # Generate attrs without the T dimension
90- new_attrs = get_attrs_without_t (zarr_url_old )
91- new_image_group = zarr .group (zarr_url_new )
92- new_image_group .attrs .put (new_attrs )
9381 image_list_update = dict (
9482 zarr_url = zarr_url_new , origin = zarr_url_old , types = dict (has_t = False )
9583 )
96- # TODO: Check if image contains labels & raise error (or even copy them)
97- # FIXME: Check if image contains ROI tables & copy them
98-
99- # Write to disk (triggering execution)
100- logger .debug (f"Writing Zarr without T dimension to { zarr_url_new } " )
101- new_data .to_zarr (
102- f"{ zarr_url_new } /0" ,
103- overwrite = True ,
104- dimension_separator = "/" ,
105- write_empty_chunks = False ,
106- )
107- logger .debug (f"Finished writing Zarr without T dimension to { zarr_url_new } " )
108- build_pyramid (
109- zarrurl = zarr_url_new ,
110- overwrite = True ,
111- num_levels = ngff_image .num_levels ,
112- coarsening_xy = ngff_image .coarsening_xy ,
113- chunksize = new_data .chunksize ,
114- )
11584
11685 return {"image_list_updates" : [image_list_update ]}
11786
0 commit comments