Skip to content

Commit

Permalink
Merge pull request #209 from tcompa/master
Browse files Browse the repository at this point in the history
Read multi-resolution pyramids in Well class (closes #208)
  • Loading branch information
sbesson authored Jul 1, 2022
2 parents 313e126 + 35cdce0 commit fe811a6
Showing 1 changed file with 22 additions and 13 deletions.
35 changes: 22 additions & 13 deletions ome_zarr/reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -405,23 +405,24 @@ def __init__(self, node: Node) -> None:
LOGGER.info("well_data: %s", self.well_data)

image_paths = [image["path"] for image in self.well_data.get("images")]

# Construct a 2D almost-square grid
field_count = len(image_paths)
column_count = math.ceil(math.sqrt(field_count))
row_count = math.ceil(field_count / column_count)

# Use first Field for rendering settings, shape etc.
# Use first Field and highest-resolution level for rendering settings,
# shapes etc.
image_zarr = self.zarr.create(image_paths[0])
image_node = Node(image_zarr, node)
x_index = len(image_node.metadata["axes"]) - 1
y_index = len(image_node.metadata["axes"]) - 2
level = 0 # load full resolution image
self.numpy_type = image_node.data[level].dtype
self.numpy_type = image_node.data[0].dtype
self.img_shape = image_node.data[0].shape
self.img_metadata = image_node.metadata
self.img_shape = image_node.data[level].shape
self.img_pyramid_shapes = [d.shape for d in image_node.data]

# stitch full-resolution images into a grid
def get_field(tile_name: str) -> np.ndarray:
def get_field(tile_name: str, level: int) -> np.ndarray:
"""tile_name is 'row,col'"""
row, col = (int(n) for n in tile_name.split(","))
field_index = (column_count * row) + col
Expand All @@ -431,29 +432,37 @@ def get_field(tile_name: str) -> np.ndarray:
data = self.zarr.load(path)
except ValueError:
LOGGER.error(f"Failed to load {path}")
data = np.zeros(self.img_shape, dtype=self.numpy_type)
data = np.zeros(self.img_pyramid_shapes[level], dtype=self.numpy_type)
return data

lazy_reader = delayed(get_field)

def get_lazy_well() -> da.Array:
def get_lazy_well(level: int, tile_shape: tuple) -> da.Array:
lazy_rows = []
# For level 0, return whole image for each tile
for row in range(row_count):
lazy_row: List[da.Array] = []
for col in range(column_count):
tile_name = f"{row},{col}"
LOGGER.debug(f"creating lazy_reader. row:{row} col:{col}")
LOGGER.debug(
f"creating lazy_reader. row:{row} col:{col} level:{level}"
)
lazy_tile = da.from_delayed(
lazy_reader(tile_name),
shape=self.img_shape,
lazy_reader(tile_name, level),
shape=tile_shape,
dtype=self.numpy_type,
)
lazy_row.append(lazy_tile)
lazy_rows.append(da.concatenate(lazy_row, axis=x_index))
return da.concatenate(lazy_rows, axis=y_index)

node.data = [get_lazy_well()]
# Create a pyramid of layers at different resolutions
pyramid = []
for level, tile_shape in enumerate(self.img_pyramid_shapes):
lazy_well = get_lazy_well(level, tile_shape)
pyramid.append(lazy_well)

# Set the node.data to be pyramid view of the plate
node.data = pyramid
node.metadata = image_node.metadata


Expand Down

0 comments on commit fe811a6

Please sign in to comment.