Skip to content

Commit 0e043bc

Browse files
committed
refering issue #72, implementing region
1 parent b9502ec commit 0e043bc

File tree

2 files changed

+141
-53
lines changed

2 files changed

+141
-53
lines changed

fractal_tasks_core/yokogawa_to_zarr.py

Lines changed: 138 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,48 @@
2121
from typing import Optional
2222

2323
import dask.array as da
24+
import zarr
2425
from anndata import read_zarr
25-
from skimage.io import imread
26+
from dask.array.image import imread
2627

27-
from fractal_tasks_core.lib_pyramid_creation import write_pyramid
2828
from fractal_tasks_core.lib_regions_of_interest import (
2929
convert_ROI_table_to_indices,
3030
)
3131
from fractal_tasks_core.lib_zattrs_utils import extract_zyx_pixel_sizes
3232

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
65+
3366

3467
def sort_fun(s):
3568
"""
@@ -71,15 +104,15 @@ def yokogawa_to_zarr(
71104
original_path_list = metadata["original_paths"]
72105
in_path = Path(original_path_list[0]).parent
73106
ext = Path(original_path_list[0]).name
74-
num_levels = metadata["num_levels"]
75-
coarsening_xy = metadata["coarsening_xy"]
107+
# num_levels = metadata["num_levels"]
108+
# coarsening_xy = metadata["coarsening_xy"]
76109

77110
# Hard-coded values (by now) of chunk sizes to be passed to rechunk,
78111
# both at level 0 (before coarsening) and at levels 1,2,.. (after
79112
# repeated coarsening).
80113
# Note that balance=True may override these values.
81-
chunk_size_x = 2560
82-
chunk_size_y = 2160
114+
# chunk_size_x = 2560
115+
# chunk_size_y = 2160
83116

84117
# Define well
85118
component_split = component.split("/")
@@ -89,11 +122,45 @@ def yokogawa_to_zarr(
89122
well_ID = well_row + well_column
90123

91124
# delayed_imread = delayed(imread)
125+
# from devtools import debug
126+
# debug(f"Channels: {chl_list}")
127+
128+
zarrurl = input_paths[0].parent.as_posix() + f"/{component}"
129+
adata = read_zarr(f"{zarrurl}/tables/FOV_ROI_table")
130+
pxl_size = extract_zyx_pixel_sizes(f"{zarrurl}/.zattrs")
131+
fov_indices = convert_ROI_table_to_indices(
132+
adata, full_res_pxl_sizes_zyx=pxl_size
133+
)
92134

93-
print(f"Channels: {chl_list}")
94-
95-
list_channels = []
96-
for chl in chl_list:
135+
max_x, max_y, max_z = get_ROIs_bounding_box(adata, pxl_size)
136+
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+
150+
sample = imread(glob(f"{in_path}/*_{well_ID}_*{ext}")[0])
151+
from devtools import debug
152+
153+
debug(f"{sample.shape=}, {sample.shape[1]=}")
154+
canvas_zarr = zarr.create(
155+
shape=(len(chl_list), max_z, max_y, max_x),
156+
chunks=(1, 1, sample.shape[1], sample.shape[2]),
157+
dtype=sample.dtype,
158+
store=da.core.get_mapper(zarrurl + "/0"),
159+
overwrite=False,
160+
dimension_separator="/",
161+
)
162+
# list_channels = []
163+
for i_c, chl in enumerate(chl_list):
97164
A, C = chl.split("_")
98165

99166
glob_path = f"{in_path}/*_{well_ID}_*{A}*{C}{ext}"
@@ -109,40 +176,58 @@ def yokogawa_to_zarr(
109176
f" glob_path: {glob_path}"
110177
)
111178

112-
sample = imread(filenames[0])
113-
114-
zarrurl = input_paths[0].parent.as_posix() + f"/{component}"
115-
adata = read_zarr(f"{zarrurl}/tables/FOV_ROI_table")
116-
pxl_size = extract_zyx_pixel_sizes(f"{zarrurl}/.zattrs")
117-
fov_position = convert_ROI_table_to_indices(
118-
adata, full_res_pxl_sizes_zyx=pxl_size
119-
)
120-
121-
max_x = max(roi[5] for roi in fov_position)
122-
max_y = max(roi[3] for roi in fov_position)
123-
max_z = max(roi[1] for roi in fov_position)
124-
125-
img_position = []
126-
for fov in fov_position:
127-
for z in range(fov[1]):
128-
img = [z, z + 1, fov[2], fov[3], fov[4], fov[5]]
129-
img_position.append(img)
130-
131-
canvas = da.zeros(
132-
(max_z, max_y, max_x),
133-
dtype=sample.dtype,
134-
chunks=(1, chunk_size_y, chunk_size_x),
135-
)
136-
137-
for indexes, image_file in zip(*(img_position, filenames)):
138-
canvas[
139-
indexes[0] : indexes[1], # noqa: 203
140-
indexes[2] : indexes[3], # noqa: 203
141-
indexes[4] : indexes[5], # noqa: 203
142-
] = imread(image_file)
143-
144-
list_channels.append(canvas)
145-
data_czyx = da.stack(list_channels, axis=0)
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):
191+
for indices in fov_indices:
192+
s_z, e_z, s_y, e_y, s_x, e_x = indices[:]
193+
# for i_z in range(s_z, e_z):
194+
region = (
195+
slice(i_c, i_c + 1),
196+
slice(s_z, e_z),
197+
slice(s_y, e_y),
198+
slice(s_x, e_x),
199+
)
200+
201+
# assert s_z == 0
202+
203+
FOV = da.concatenate(
204+
[imread(img) for img in filenames[:e_z]],
205+
)
206+
FOV_4D = da.expand_dims(FOV, axis=0)
207+
debug(FOV_4D)
208+
filenames = filenames[e_z:]
209+
210+
da.array(FOV_4D).to_zarr(
211+
url=canvas_zarr,
212+
region=region,
213+
compute=True,
214+
)
215+
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)
146231

147232
if delete_input:
148233
for f in filenames:
@@ -152,15 +237,15 @@ def yokogawa_to_zarr(
152237
print("Error: %s : %s" % (f, e.strerror))
153238

154239
# Construct resolution pyramid
155-
write_pyramid(
156-
data_czyx,
157-
newzarrurl=output_path.parent.as_posix() + f"/{component}",
158-
overwrite=False,
159-
coarsening_xy=coarsening_xy,
160-
num_levels=num_levels,
161-
chunk_size_x=chunk_size_x,
162-
chunk_size_y=chunk_size_y,
163-
)
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+
# )
164249

165250

166251
if __name__ == "__main__":

tests/test_unit_yokogawa_to_zarr.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ def test_yokogawa_to_zarr(
118118
mocker.patch(
119119
"fractal_tasks_core.yokogawa_to_zarr.sorted", return_value=images
120120
)
121+
mocker.patch(
122+
"fractal_tasks_core.yokogawa_to_zarr.glob", return_value=images
123+
)
121124

122125
# Patch correct() function, to keep track of the number of calls
123126
logfile = (tmp_path / "log_function_correct.txt").resolve().as_posix()

0 commit comments

Comments
 (0)