diff --git a/starfish/core/experiment/builder/__init__.py b/starfish/core/experiment/builder/__init__.py index 738714d1b..99e9b55cc 100644 --- a/starfish/core/experiment/builder/__init__.py +++ b/starfish/core/experiment/builder/__init__.py @@ -30,6 +30,7 @@ from starfish import FieldOfView from starfish.core.codebook.codebook import Codebook +from starfish.core.errors import DataFormatWarning from starfish.core.experiment.builder.orderediterator import join_axes_labels, ordered_iterator from starfish.core.experiment.version import CURRENT_VERSION from starfish.core.types import Axes, Coordinates @@ -116,6 +117,14 @@ def reducer_to_sets( current_ch, current_zplane ) + for axis in (Axes.X, Axes.Y): + if image.shape[axis] < max(len(rounds), len(chs), len(zplanes)): + warnings.warn( + f"{axis} axis appears to be smaller than rounds/chs/zplanes, which is " + "unusual", + DataFormatWarning + ) + tile = Tile( image.coordinates, { diff --git a/starfish/core/experiment/builder/test/test_small_axis.py b/starfish/core/experiment/builder/test/test_small_axis.py new file mode 100644 index 000000000..0cc39e849 --- /dev/null +++ b/starfish/core/experiment/builder/test/test_small_axis.py @@ -0,0 +1,66 @@ +import warnings +from typing import Callable, Collection, Mapping, Sequence + +import pytest + +from starfish.core.errors import DataFormatWarning +from starfish.core.types import Coordinates, CoordinateValue +from .factories.all_purpose import collection_factory +from .factories.unique_tiles import UniqueTiles +from .. import TileIdentifier + + +@pytest.mark.parametrize( + "num_round_labels, num_ch_labels, num_zplane_labels, tile_height, tile_width, has_warnings", + ( + (1, 1, 1, 100, 100, False), + (1, 1, 1000, 100, 100, True), + (1, 1000, 1, 100, 100, True), + (1000, 1, 1, 100, 100, True), + (1000, 1, 1, 10000, 100, True), + (1000, 1, 1, 100, 10000, True), + ) +) +def test_small_axis( + num_round_labels, + num_ch_labels, + num_zplane_labels, + tile_height, + tile_width, + has_warnings, +): + tile_identifiers: Collection[TileIdentifier] = [ + TileIdentifier(0, round_label, ch_label, zplane_label) + for round_label in range(num_round_labels) + for ch_label in range(num_ch_labels) + for zplane_label in range(num_zplane_labels) + ] + + def make_tile_coordinate_callback( + all_zplane_labels: Sequence[int] + ) -> Callable[[TileIdentifier], Mapping[Coordinates, CoordinateValue]]: + def tile_coordinate_callback( + tile_identifier: TileIdentifier + ) -> Mapping[Coordinates, CoordinateValue]: + zplane_offset = all_zplane_labels.index(tile_identifier.zplane_label) + return { + Coordinates.X: (0.0, 0.1), + Coordinates.Y: (0.0, 0.1), + Coordinates.Z: zplane_offset * 0.1, + } + + return tile_coordinate_callback + + with warnings.catch_warnings(record=True) as warnings_: + collection_factory( + UniqueTiles, + tile_identifiers, + make_tile_coordinate_callback( + sorted(set(tile_identifier.zplane_label for tile_identifier in tile_identifiers))), + tile_height, + tile_width, + ) + assert has_warnings == ( + 0 != len( + [warning for warning in warnings_ + if issubclass(warning.category, DataFormatWarning)]))