def imagestack_factory( fetched_tile_cls: Type[LocationAwareFetchedTile], round_labels: Sequence[int], ch_labels: Sequence[int], zplane_labels: Sequence[int], tile_height: int, tile_width: int, xrange: Tuple[Number, Number], yrange: Tuple[Number, Number], zrange: Tuple[Number, Number], crop_parameters: Optional[CropParameters] = None) -> ImageStack: """Given a type that implements the :py:class:`LocationAwareFetchedTile` contract, produce an imagestack with those tiles, and apply coordinates such that the 5D tensor has coordinates that range from `xrange[0]:xrange[1]`, `yrange[0]:yrange[1]`, `zrange[0]:zrange[1]`. Parameters ---------- fetched_tile_cls : Type[LocationAwareFetchedTile] The class of the FetchedTile. round_labels : Sequence[int] Labels for the rounds. ch_labels : Sequence[int] Labels for the channels. zplane_labels : Sequence[int] Labels for the zplanes. tile_height : int Height of each tile, in pixels. tile_width : int Width of each tile, in pixels. xrange : Tuple[Number, Number] The starting and ending x physical coordinates for the tile. yrange : Tuple[Number, Number] The starting and ending y physical coordinates for the tile. zrange : Tuple[Number, Number] The starting and ending z physical coordinates for the tile. crop_parameters : Optional[CropParameters] The crop parameters to apply during ImageStack construction. """ original_tile_fetcher = tile_fetcher_factory( fetched_tile_cls, True, round_labels, ch_labels, zplane_labels, tile_height, tile_width, ) modified_tile_fetcher = _apply_coords_range_fetcher( original_tile_fetcher, zplane_labels, xrange, yrange, zrange) collection = build_image( range(1), round_labels, ch_labels, zplane_labels, modified_tile_fetcher, ) tileset = list(collection.all_tilesets())[0][1] return ImageStack.from_tileset(tileset, crop_parameters)
def unique_tiles_imagestack( round_labels: Sequence[int], ch_labels: Sequence[int], z_labels: Sequence[int], tile_height: int, tile_width: int, crop_parameters: Optional[CropParameters] = None) -> ImageStack: """Build an imagestack with unique values per tile. """ collection = build_image( range(1), round_labels, ch_labels, z_labels, tile_fetcher_factory( UniqueTiles, True, len(round_labels), len(ch_labels), len(z_labels), tile_height, tile_width, ), ) tileset = list(collection.all_tilesets())[0][1] return ImageStack.from_tileset(tileset, crop_parameters)
def collection_factory( fetched_tile_cls: Type[LocationAwareFetchedTile], tile_identifiers: Collection[TileIdentifier], tile_coordinates_callback: Callable[[TileIdentifier], Mapping[Coordinates, CoordinateValue]], tile_height: int, tile_width: int, ) -> slicedimage.Collection: """Given a type that implements the :py:class:`LocationAwareFetchedTile` contract, produce a slicedimage Collection with the tiles in `tile_identifiers`. For a given tile_identifier, retrieve the coordinates by invoking the callback `tile_coordinates_callback`. Parameters ---------- fetched_tile_cls : Type[LocationAwareFetchedTile] The class of the FetchedTile. tile_identifiers : Collection[TileIdentifier] TileIdentifiers for each of the tiles in the collection. tile_coordinates_callback : Callable[[TileIdentifier], Mapping[Coordinates, CoordinatesValue]] A callable that returns the coordinates for a given tile's TileIdentifier. tile_height : int Height of each tile, in pixels. tile_width : int Width of each tile, in pixels. """ all_fov_ids = sorted( set(tile_identifier.fov_id for tile_identifier in tile_identifiers)) all_round_labels = sorted( set(tile_identifier.round_label for tile_identifier in tile_identifiers)) all_ch_labels = sorted( set(tile_identifier.ch_label for tile_identifier in tile_identifiers)) all_zplane_labels = sorted( set(tile_identifier.zplane_label for tile_identifier in tile_identifiers)) original_tile_fetcher = tile_fetcher_factory( fetched_tile_cls, True, all_fov_ids, all_round_labels, all_ch_labels, all_zplane_labels, tile_height, tile_width, ) modified_tile_fetcher = _apply_coords_range_fetcher( original_tile_fetcher, tile_coordinates_callback) return build_irregular_image(tile_identifiers, modified_tile_fetcher, default_shape={ Axes.Y: tile_height, Axes.X: tile_width })
def test_unaligned_tiles(): """Test that imagestack error is thrown when constructed with unaligned tiles""" try: synthetic_stack( NUM_ROUND, NUM_CH, NUM_Z, HEIGHT, WIDTH, tile_fetcher=tile_fetcher_factory( OffsettedTiles, True, ) ) except ValueError as e: # Assert value error is thrown with right message assert e.args[0] == "Tiles must be aligned"
def test_coordinates(): """Set up an ImageStack with tiles that are aligned. Verify that the coordinates retrieved match. """ stack = synthetic_stack( NUM_ROUND, NUM_CH, NUM_Z, HEIGHT, WIDTH, tile_fetcher=tile_fetcher_factory( AlignedTiles, True, ) ) for selectors in stack._iter_axes({Axes.ZPLANE}): verify_physical_coordinates(stack, X_COORDS, Y_COORDS, get_physical_coordinates_of_z_plane( zplane_to_z(selectors[Axes.ZPLANE])), selectors[Axes.ZPLANE])
def test_scalar_coordinates(): """Set up an ImageStack where only a single scalar physical coordinate is provided per axis. Internally, this should be converted to a range where the two endpoints are identical to the physical coordinate provided. """ stack = synthetic_stack( NUM_ROUND, NUM_CH, NUM_Z, HEIGHT, WIDTH, tile_fetcher=tile_fetcher_factory( ScalarTiles, True, ) ) expected_x = X_COORDS[0] expected_y = Y_COORDS[0] for selectors in stack._iter_axes({Axes.ZPLANE}): expected_z = zplane_to_z(selectors[Axes.ZPLANE])[0] verify_physical_coordinates(stack, (expected_x, expected_x), (expected_y, expected_y), get_physical_coordinates_of_z_plane((expected_z, expected_z)), selectors[Axes.ZPLANE])