def add_image(image: omero.gateway.ImageWrapper, parent: Group, cache_dir: Optional[str] = None) -> int: """ Adds the image pixel data as array to the given parent zarr group. Optionally caches the pixel data in the given cache_dir directory. Returns the number of resolution levels generated for the image. """ if cache_dir is not None: cache = True os.makedirs(os.path.join(cache_dir, str(image.id)), mode=511, exist_ok=True) else: cache = False cache_dir = "" size_c = image.getSizeC() size_z = image.getSizeZ() size_x = image.getSizeX() size_y = image.getSizeY() size_t = image.getSizeT() d_type = image.getPixelsType() zct_list = [] for t in range(size_t): for c in range(size_c): for z in range(size_z): if cache: # We only want to load from server if not cached locally filename = os.path.join( cache_dir, str(image.id), f"{z:03d}-{c:03d}-{t:03d}.npy", ) if not os.path.exists(filename): zct_list.append((z, c, t)) else: zct_list.append((z, c, t)) pixels = image.getPrimaryPixels() def planeGen() -> np.ndarray: planes = pixels.getPlanes(zct_list) yield from planes planes = planeGen() # Target size for smallest multiresolution TARGET_SIZE = 96 level_count = 1 longest = max(size_x, size_y) while longest > TARGET_SIZE: longest = longest // 2 level_count += 1 field_groups = [] for t in range(size_t): for c in range(size_c): for z in range(size_z): if cache: filename = os.path.join( cache_dir, str(image.id), f"{z:03d}-{c:03d}-{t:03d}.npy", ) if os.path.exists(filename): plane = numpy.load(filename) else: plane = next(planes) numpy.save(filename, plane) else: plane = next(planes) for level in range(level_count): size_y = plane.shape[0] size_x = plane.shape[1] # If on first plane, create a new group for this resolution level if t == 0 and c == 0 and z == 0: field_groups.append( parent.create( str(level), shape=(size_t, size_c, size_z, size_y, size_x), chunks=(1, 1, 1, size_y, size_x), dtype=d_type, )) # field_group = field_groups[level] field_groups[level][t, c, z, :, :] = plane if (level + 1) < level_count: # resize for next level... plane = cv2.resize( plane, dsize=(size_x // 2, size_y // 2), interpolation=cv2.INTER_NEAREST, ) return level_count
def add_raw_image( *, planes: Iterator[np.ndarray], size_z: int, size_c: int, size_t: int, d_type: np.dtype, parent: Group, level_count: int, cache_dir: Optional[str] = None, cache_file_name_func: Callable[[int, int, int], str] = None, ) -> Tuple[int, List[str]]: """Adds the raw image pixel data as array to the given parent zarr group. Optionally caches the pixel data in the given cache_dir directory. Returns the number of resolution levels generated for the image. planes: Generator returning planes in order of zct (whatever order OMERO returns in its plane generator). Each plane must be a numpy array with shape (size_y, sizex), or None to skip the plane. """ if cache_dir is not None: cache = True else: cache = False cache_dir = "" dims = [dim for dim in [size_t, size_c, size_z] if dim != 1] axes = [] if size_t > 1: axes.append("t") if size_c > 1: axes.append("c") if size_z > 1: axes.append("z") field_groups: List[Array] = [] for t in range(size_t): for c in range(size_c): for z in range(size_z): if cache: assert cache_file_name_func filename = cache_file_name_func(z, c, t) if os.path.exists(filename): plane = numpy.load(filename) else: plane = next(planes) os.makedirs(os.path.dirname(filename), mode=511, exist_ok=True) numpy.save(filename, plane) else: plane = next(planes) if plane is None: continue for level in range(level_count): size_y = plane.shape[0] size_x = plane.shape[1] # If on first plane, create a new group for this resolution level if len(field_groups) <= level: field_groups.append( parent.create( str(level), shape=tuple(dims + [size_y, size_x]), chunks=tuple([1] * len(dims) + [size_y, size_x]), dtype=d_type, )) indices = [] if size_t > 1: indices.append(t) if size_c > 1: indices.append(c) if size_z > 1: indices.append(z) field_groups[level][tuple(indices)] = plane if (level + 1) < level_count: # resize for next level... plane = cv2.resize( plane, dsize=(size_x // 2, size_y // 2), interpolation=cv2.INTER_NEAREST, ) return (level_count, axes + ["y", "x"])