Skip to content

Commit 5c1410e

Browse files
committed
Update yokogawa_to_zarr, with new build_pyramid function and by moving get_ROIs_bounding_box (ref #8) to lib_regions_of_interest
1 parent 91d2b11 commit 5c1410e

File tree

2 files changed

+69
-116
lines changed

2 files changed

+69
-116
lines changed

fractal_tasks_core/lib_regions_of_interest.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,3 +170,46 @@ def _inspect_ROI_table(
170170
for indices in list_indices:
171171
print(indices)
172172
print()
173+
174+
175+
def get_ROIs_bounding_box(
176+
adata,
177+
pxl_size: Iterable,
178+
x_start_label: str = "x_micrometer",
179+
y_start_label: str = "y_micrometer",
180+
z_start_label: str = "z_micrometer",
181+
len_x_label: str = "len_x_micrometer",
182+
len_y_label: str = "len_y_micrometer",
183+
len_z_label: str = "len_z_micrometer",
184+
):
185+
186+
x_start = adata[:, x_start_label].X
187+
y_start = adata[:, y_start_label].X
188+
z_start = adata[:, z_start_label].X
189+
len_x = adata[:, len_x_label].X
190+
len_y = adata[:, len_y_label].X
191+
len_z = adata[:, len_z_label].X
192+
193+
x_min_micrometer = min(x_start)
194+
y_min_micrometer = min(y_start)
195+
z_min_micrometer = min(z_start)
196+
197+
x_max_micrometer = max(x_start + len_x)
198+
y_max_micrometer = max(y_start + len_y)
199+
z_max_micrometer = max(z_start + len_z)
200+
201+
ind_x_min = x_min_micrometer / pxl_size[2]
202+
ind_y_min = y_min_micrometer / pxl_size[1]
203+
ind_z_min = z_min_micrometer / pxl_size[0]
204+
205+
ind_x_max = x_max_micrometer / pxl_size[2]
206+
ind_y_max = y_max_micrometer / pxl_size[1]
207+
ind_z_max = z_max_micrometer / pxl_size[0]
208+
209+
if max(ind_x_min, ind_y_min, ind_z_min) > 0:
210+
raise Exception(
211+
"We are assuming that ind_mu_min=0, but"
212+
f"{ind_x_min=}, {ind_y_min=}, {ind_z_min=}"
213+
)
214+
215+
return ind_x_max, ind_y_max, ind_z_max

fractal_tasks_core/yokogawa_to_zarr.py

Lines changed: 26 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -25,43 +25,10 @@
2525
from anndata import read_zarr
2626
from dask.array.image import imread
2727

28-
from fractal_tasks_core.lib_regions_of_interest import (
29-
convert_ROI_table_to_indices,
30-
)
31-
from fractal_tasks_core.lib_zattrs_utils import extract_zyx_pixel_sizes
32-
33-
# import numpy as np
34-
35-
# from fractal_tasks_core.lib_pyramid_creation import write_pyramid
36-
37-
# from skimage.io import imread
38-
39-
40-
def get_ROIs_bounding_box(adata, pxl_size):
41-
# x_min_micrometer = min(adata[:, "x_micrometer"].X)
42-
x_max_micrometer = max(
43-
adata[:, "x_micrometer"].X + adata[:, "len_x_micrometer"].X
44-
)
45-
# ind_x_min = x_min_micrometer / pxl_size[2]
46-
ind_x_max = x_max_micrometer / pxl_size[2]
47-
# y_min_micrometer = min(adata[:, "y_micrometer"].X)
48-
y_max_micrometer = max(
49-
adata[:, "y_micrometer"].X + adata[:, "len_y_micrometer"].X
50-
)
51-
# ind_y_min = y_min_micrometer / pxl_size[1]
52-
ind_y_max = y_max_micrometer / pxl_size[1]
53-
# z_min_micrometer = min(adata[:, "z_micrometer"].X)
54-
z_max_micrometer = max(
55-
adata[:, "z_micrometer"].X + adata[:, "len_z_micrometer"].X
56-
)
57-
# ind_z_min = z_min_micrometer / pxl_size[0]
58-
ind_z_max = z_max_micrometer / pxl_size[0]
59-
60-
# assert ind_x_min == 0
61-
# assert ind_y_min == 0
62-
# assert ind_z_min == 0
63-
64-
return ind_x_max, ind_y_max, ind_z_max
28+
from .lib_pyramid_creation import build_pyramid
29+
from .lib_regions_of_interest import convert_ROI_table_to_indices
30+
from .lib_regions_of_interest import get_ROIs_bounding_box
31+
from .lib_zattrs_utils import extract_zyx_pixel_sizes
6532

6633

6734
def sort_fun(s):
@@ -104,62 +71,39 @@ def yokogawa_to_zarr(
10471
original_path_list = metadata["original_paths"]
10572
in_path = Path(original_path_list[0]).parent
10673
ext = Path(original_path_list[0]).name
107-
# num_levels = metadata["num_levels"]
108-
# coarsening_xy = metadata["coarsening_xy"]
109-
110-
# Hard-coded values (by now) of chunk sizes to be passed to rechunk,
111-
# both at level 0 (before coarsening) and at levels 1,2,.. (after
112-
# repeated coarsening).
113-
# Note that balance=True may override these values.
114-
# chunk_size_x = 2560
115-
# chunk_size_y = 2160
74+
num_levels = metadata["num_levels"]
75+
coarsening_xy = metadata["coarsening_xy"]
11676

11777
# Define well
11878
component_split = component.split("/")
11979
well_row = component_split[1]
12080
well_column = component_split[2]
121-
12281
well_ID = well_row + well_column
12382

124-
# delayed_imread = delayed(imread)
125-
# from devtools import debug
126-
# debug(f"Channels: {chl_list}")
127-
83+
# Read useful information from ROI table and .zattrs
12884
zarrurl = input_paths[0].parent.as_posix() + f"/{component}"
12985
adata = read_zarr(f"{zarrurl}/tables/FOV_ROI_table")
13086
pxl_size = extract_zyx_pixel_sizes(f"{zarrurl}/.zattrs")
13187
fov_indices = convert_ROI_table_to_indices(
13288
adata, full_res_pxl_sizes_zyx=pxl_size
13389
)
134-
13590
max_x, max_y, max_z = get_ROIs_bounding_box(adata, pxl_size)
13691

137-
# ref_img_size = None
138-
# for indices in fov_indices:
139-
# img_size = (indices[3] - indices[2], indices[5] - indices[4])
140-
# if ref_img_size is None:
141-
# ref_img_size = img_size
142-
# else:
143-
# if img_size != ref_img_size:
144-
# raise Exception(
145-
# "ERROR: inconsistent image sizes in list_indices"
146-
# )
147-
148-
# img_size_y, img_size_x = img_size[:]
149-
92+
# Load a single image, to retrieve useful information
15093
sample = imread(glob(f"{in_path}/*_{well_ID}_*{ext}")[0])
151-
from devtools import debug
15294

153-
debug(f"{sample.shape=}, {sample.shape[1]=}")
95+
# Initialize zarr
96+
chunksize = (1, 1, sample.shape[1], sample.shape[2])
15497
canvas_zarr = zarr.create(
15598
shape=(len(chl_list), max_z, max_y, max_x),
156-
chunks=(1, 1, sample.shape[1], sample.shape[2]),
99+
chunks=chunksize,
157100
dtype=sample.dtype,
158101
store=da.core.get_mapper(zarrurl + "/0"),
159102
overwrite=False,
160103
dimension_separator="/",
161104
)
162-
# list_channels = []
105+
106+
# Loop over channels
163107
for i_c, chl in enumerate(chl_list):
164108
A, C = chl.split("_")
165109

@@ -175,78 +119,44 @@ def yokogawa_to_zarr(
175119
f" channel: {chl},\n"
176120
f" glob_path: {glob_path}"
177121
)
178-
179-
# max_x = max(roi[5] for roi in fov_position)
180-
# max_y = max(roi[3] for roi in fov_position)
181-
# max_z = max(roi[1] for roi in fov_position)
182-
183-
# img_position = []
184-
# for fov in fov_position:
185-
# for z in range(fov[1]):
186-
# img = [z, z + 1, fov[2], fov[3], fov[4], fov[5]]
187-
# img_position.append(img)
188-
189-
# regions = []
190-
# for i_c, channel in enumerate(chl_list):
122+
# Loop over 3D FOV ROIs
191123
for indices in fov_indices:
192124
s_z, e_z, s_y, e_y, s_x, e_x = indices[:]
193-
# for i_z in range(s_z, e_z):
194125
region = (
195126
slice(i_c, i_c + 1),
196127
slice(s_z, e_z),
197128
slice(s_y, e_y),
198129
slice(s_x, e_x),
199130
)
200-
201-
# assert s_z == 0
202-
203-
FOV = da.concatenate(
131+
FOV_3D = da.concatenate(
204132
[imread(img) for img in filenames[:e_z]],
205133
)
206-
FOV_4D = da.expand_dims(FOV, axis=0)
207-
debug(FOV_4D)
134+
FOV_4D = da.expand_dims(FOV_3D, axis=0)
208135
filenames = filenames[e_z:]
209-
210136
da.array(FOV_4D).to_zarr(
211137
url=canvas_zarr,
212138
region=region,
213139
compute=True,
214140
)
215141

216-
# canvas = da.zeros(
217-
# (max_z, max_y, max_x),
218-
# dtype=sample.dtype,
219-
# chunks=(1, chunk_size_y, chunk_size_x),
220-
# )
221-
222-
# for indexes, image_file in zip(*(img_position, filenames)):
223-
# canvas[
224-
# indexes[0] : indexes[1], # noqa: 203
225-
# indexes[2] : indexes[3], # noqa: 203
226-
# indexes[4] : indexes[5], # noqa: 203
227-
# ] = imread(image_file)
228-
229-
# list_channels.append(canvas)
230-
# data_czyx = da.stack(list_channels, axis=0)
142+
# Starting from on-disk highest-resolution data, build and write to disk a
143+
# pyramid of coarser levels
144+
build_pyramid(
145+
zarrurl=zarrurl,
146+
overwrite=False,
147+
num_levels=num_levels,
148+
coarsening_xy=coarsening_xy,
149+
chunksize=chunksize,
150+
)
231151

152+
# Delete images (optional)
232153
if delete_input:
233154
for f in filenames:
234155
try:
235156
os.remove(f)
236157
except OSError as e:
237158
print("Error: %s : %s" % (f, e.strerror))
238159

239-
# Construct resolution pyramid
240-
# write_pyramid(
241-
# data_czyx,
242-
# newzarrurl=output_path.parent.as_posix() + f"/{component}",
243-
# overwrite=False,
244-
# coarsening_xy=coarsening_xy,
245-
# num_levels=num_levels,
246-
# chunk_size_x=chunk_size_x,
247-
# chunk_size_y=chunk_size_y,
248-
# )
249-
250160

251161
if __name__ == "__main__":
252162
from argparse import ArgumentParser

0 commit comments

Comments
 (0)