1414@validate_call
1515def convert_2D_segmentation_to_3D (
1616 zarr_url : str ,
17- label_name : str ,
17+ label_name : Optional [ str ] = None ,
1818 level : str = "0" ,
1919 tables_to_copy : Optional [list [str ]] = None ,
2020 new_label_name : Optional [str ] = None ,
@@ -96,10 +96,7 @@ def convert_2D_segmentation_to_3D(
9696 if image_suffix_3D_to_add :
9797 zarr_3D_url += image_suffix_3D_to_add
9898
99- if new_label_name is None :
100- new_label_name = label_name
101- if new_table_names is None :
102- new_table_names = tables_to_copy
99+ ome_zarr_container_2d = ngio .open_ome_zarr_container (zarr_url )
103100
104101 try :
105102 ome_zarr_container_3d = ngio .open_ome_zarr_container (zarr_3D_url )
@@ -109,71 +106,82 @@ def convert_2D_segmentation_to_3D(
109106 f"suffix (set to { plate_suffix } )."
110107 ) from e
111108
112- logger .info (
113- f"Copying { label_name } from { zarr_url } to { zarr_3D_url } as "
114- f"{ new_label_name } ."
115- )
116-
117- # 1) Load a 2D label image
118- ome_zarr_container_2d = ngio .open_ome_zarr_container (zarr_url )
119- label_img = ome_zarr_container_2d .get_label (label_name , path = level )
109+ if new_label_name is None :
110+ new_label_name = label_name
111+ if new_table_names is None :
112+ new_table_names = tables_to_copy
120113
121- if not label_img .is_2d :
122- raise ValueError (
123- f"Label image { label_name } is not 2D. It has a shape of "
124- f"{ label_img .shape } and the axes "
125- f"{ label_img .axes_mapper .on_disk_axes_names } ."
114+ if label_name :
115+ logger .info (
116+ f"Copying { label_name } from { zarr_url } to { zarr_3D_url } as "
117+ f"{ new_label_name } ."
126118 )
127119
128- chunks = list ( label_img . chunks )
129- label_dask = label_img . get_array ( mode = "dask" )
120+ # 1) Load a 2D label image
121+ label_img = ome_zarr_container_2d . get_label ( label_name , path = level )
130122
131- # 2) Set up the 3D label image
132- ref_image_3d = ome_zarr_container_3d .get_image (
133- pixel_size = label_img .pixel_size ,
134- )
135-
136- z_index = label_img .axes_mapper .get_index ("z" )
137- y_index = label_img .axes_mapper .get_index ("y" )
138- x_index = label_img .axes_mapper .get_index ("x" )
139- z_index_3d_reference = ref_image_3d .axes_mapper .get_index ("z" )
140- if z_chunks :
141- chunks [z_index ] = z_chunks
142- else :
143- chunks [z_index ] = ref_image_3d .chunks [z_index_3d_reference ]
144- chunks = tuple (chunks )
123+ if not label_img .is_2d :
124+ raise ValueError (
125+ f"Label image { label_name } is not 2D. It has a shape of "
126+ f"{ label_img .shape } and the axes "
127+ f"{ label_img .axes_mapper .on_disk_axes_names } ."
128+ )
145129
146- nb_z_planes = ref_image_3d .shape [z_index_3d_reference ]
130+ chunks = list (label_img .chunks )
131+ label_dask = label_img .get_array (mode = "dask" )
147132
148- shape_3d = (nb_z_planes , label_img .shape [y_index ], label_img .shape [x_index ])
133+ # 2) Set up the 3D label image
134+ ref_image_3d = ome_zarr_container_3d .get_image (
135+ pixel_size = label_img .pixel_size ,
136+ )
149137
150- pixel_size = label_img .pixel_size
151- pixel_size .z = ref_image_3d .pixel_size .z
152- axes_names = label_img .axes_mapper .on_disk_axes_names
138+ z_index = label_img .axes_mapper .get_index ("z" )
139+ y_index = label_img .axes_mapper .get_index ("y" )
140+ x_index = label_img .axes_mapper .get_index ("x" )
141+ z_index_3d_reference = ref_image_3d .axes_mapper .get_index ("z" )
142+ if z_chunks :
143+ chunks [z_index ] = z_chunks
144+ else :
145+ chunks [z_index ] = ref_image_3d .chunks [z_index_3d_reference ]
146+ chunks = tuple (chunks )
147+
148+ nb_z_planes = ref_image_3d .shape [z_index_3d_reference ]
149+
150+ shape_3d = (nb_z_planes , label_img .shape [y_index ], label_img .shape [x_index ])
151+
152+ pixel_size = label_img .pixel_size
153+ pixel_size .z = ref_image_3d .pixel_size .z
154+ axes_names = label_img .axes_mapper .on_disk_axes_names
155+
156+ z_extent = nb_z_planes * pixel_size .z
157+
158+ new_label_container = ome_zarr_container_3d .derive_label (
159+ name = new_label_name ,
160+ ref_image = ref_image_3d ,
161+ shape = shape_3d ,
162+ pixel_size = pixel_size ,
163+ axes_names = axes_names ,
164+ chunks = chunks ,
165+ dtype = label_img .dtype ,
166+ overwrite = overwrite ,
167+ )
153168
154- z_extent = nb_z_planes * pixel_size .z
169+ # 3) Create the 3D stack of the label image
170+ label_img_3D = da .stack ([label_dask .squeeze ()] * nb_z_planes )
155171
156- new_label_container = ome_zarr_container_3d .derive_label (
157- name = new_label_name ,
158- ref_image = ref_image_3d ,
159- shape = shape_3d ,
160- pixel_size = pixel_size ,
161- axes_names = axes_names ,
162- chunks = chunks ,
163- dtype = label_img .dtype ,
164- overwrite = overwrite ,
165- )
172+ # 4) Save changed label image to OME-Zarr
173+ new_label_container .set_array (label_img_3D , axes_order = "zyx" )
166174
167- # 3) Create the 3D stack of the label image
168- label_img_3D = da .stack ([label_dask .squeeze ()] * nb_z_planes )
175+ logger .info (f"Saved { new_label_name } to 3D Zarr at full resolution" )
176+ # 5) Build pyramids for label image
177+ new_label_container .consolidate ()
178+ logger .info (f"Built a pyramid for the { new_label_name } label image" )
169179
170- # 4) Save changed label image to OME-Zarr
171- new_label_container .set_array (label_img_3D , axes_order = "zyx" )
172-
173- logger .info (f"Saved { new_label_name } to 3D Zarr at full resolution" )
174- # 5) Build pyramids for label image
175- new_label_container .consolidate ()
176- logger .info (f"Built a pyramid for the { new_label_name } label image" )
180+ else :
181+ logger .info (
182+ "No label_name provided, skipping label image conversion. "
183+ "Only tables will be copied."
184+ )
177185
178186 # 6) Copy tables
179187 if tables_to_copy :
@@ -183,6 +191,7 @@ def convert_2D_segmentation_to_3D(
183191 f"Table { table_name } not found in 2D OME-Zarr { zarr_url } ."
184192 )
185193 table = ome_zarr_container_2d .get_table (table_name )
194+ print (table .type ())
186195 if table .type () == "roi_table" or table .type () == "masking_roi_table" :
187196 for roi in table .rois ():
188197 roi .z_length = z_extent
@@ -191,21 +200,15 @@ def convert_2D_segmentation_to_3D(
191200 table = table ,
192201 overwrite = overwrite ,
193202 )
194- elif table .type () == "feature_table" :
195- # For some reason, I need to load the table explicitly before
196- # I can write it again
197- # FIXME
203+ else :
204+ # Added to avoid an KeyError: 'obs' that occurs for some
205+ # AnnData tables otherwise
198206 table .dataframe # noqa #B018
199207 ome_zarr_container_3d .add_table (
200208 name = new_table_names [i ],
201209 table = table ,
202210 overwrite = overwrite ,
203211 )
204- else :
205- logger .warning (
206- f"Table { table_name } was not copied over. Tables of type "
207- f"{ table .type ()} are not supported by this task so far."
208- )
209212
210213 logger .info ("Finished 2D to 3D conversion" )
211214
0 commit comments