コード例 #1
0
def test_multiple_tiles_of_different_kind():
    with pytest.raises(TypeError):
        ImageStack.synthetic_stack(
            NUM_ROUND, NUM_CH, NUM_Z,
            HEIGHT, WIDTH,
            tile_fetcher=CornerDifferentDtype(np.uint32, np.float32),
        )
コード例 #2
0
    def run(
            self, stack: ImageStack,
            in_place: bool=False,
            verbose=False,
            n_processes: Optional[int]=None,
            *args,
    ) -> ImageStack:
        """Perform filtering of an image stack

        Parameters
        ----------
        stack : ImageStack
            Stack to be filtered.
        in_place : bool
            if True, process ImageStack in-place, otherwise return a new stack
        verbose : bool
            if True, report on the percentage completed during processing (default = False)
        n_processes : Optional[int]: None
            Not implemented. Number of processes to use when applying filter.

        Returns
        -------
        ImageStack :
            If in-place is False, return the results of filter as a new stack.  Otherwise return the
            original stack.

        """
        # The default is False, so even if code requests True require config to be True as well
        verbose = verbose and StarfishConfig().verbose
        channels_per_round = stack._data.groupby(Axes.ROUND.value)
        channels_per_round = tqdm(channels_per_round) if verbose else channels_per_round

        if not in_place:
            new_stack = deepcopy(stack)
            return self.run(new_stack, in_place=True)

        # compute channel magnitude mask
        for r, dat in channels_per_round:
            # nervous about how xarray orders dimensions so i put this here explicitly ....
            dat = dat.transpose(Axes.CH.value,
                                Axes.ZPLANE.value,
                                Axes.Y.value,
                                Axes.X.value
                                )
            # ... to account for this line taking the norm across axis 0, or the channel axis
            ch_magnitude = np.linalg.norm(dat, ord=2, axis=0)
            magnitude_mask = ch_magnitude >= self.thresh

            # apply mask and optionally, normalize by channel magnitude
            for c in stack.axis_labels(Axes.CH):
                ind = {Axes.ROUND.value: r, Axes.CH.value: c}
                stack._data[ind] = stack._data[ind] * magnitude_mask

                if self.normalize:
                    stack._data[ind] = np.divide(stack._data[ind],
                                                 ch_magnitude,
                                                 where=magnitude_mask
                                                 )
        return stack
コード例 #3
0
def test_synthetic_spot_creation_raises_error_with_coords_too_small(
        synthetic_intensity_table):
    num_z = 0
    height = 40
    width = 50
    with pytest.raises(ValueError):
        ImageStack.synthetic_spots(synthetic_intensity_table, num_z, height,
                                   width)
コード例 #4
0
ファイル: __init__.py プロジェクト: neuromusic/starfish
 def _cli(ctx, primary_images, nuclei, output):
     print('Segmenting ...')
     ctx.obj = dict(
         component=Segmentation,
         output=output,
         primary_images=ImageStack.from_path_or_url(primary_images),
         nuclei=ImageStack.from_path_or_url(nuclei),
     )
コード例 #5
0
 def _cli(ctx, primary_images, nuclei, output):
     """define polygons for cell boundaries and assign spots"""
     print('Segmenting ...')
     ctx.obj = dict(
         component=Segmentation,
         output=output,
         primary_images=ImageStack.from_path_or_url(primary_images),
         nuclei=ImageStack.from_path_or_url(nuclei),
     )
コード例 #6
0
def test_imagestack_export(tmpdir, format, count, recwarn):
    """
    Save a synthetic stack to files and check the results
    """
    stack = ImageStack.synthetic_stack()
    stack_json = tmpdir / "output.json"
    stack.export(str(stack_json), tile_format=format)
    files = list([x for x in tmpdir.listdir() if str(x).endswith(format.file_ext)])
    assert ImageStack.from_path_or_url(str(stack_json))
    assert count == len(files)
    with open(files[0], "rb") as fh:
        format.reader_func(fh)
コード例 #7
0
def test_fov_order():
    data = SyntheticData()
    codebook = data.codebook()
    stack1 = ImageStack.synthetic_stack()
    stack2 = ImageStack.synthetic_stack()
    fovs = [
        FieldOfView("stack2", {"primary": stack2}),
        FieldOfView("stack1", {"primary": stack1})
    ]
    extras = {"synthetic": True}
    experiment = Experiment(fovs, codebook, extras)
    assert "stack1" == experiment.fov().name
    assert ["stack1", "stack2"] == [x.name for x in experiment.fovs()]
コード例 #8
0
def test_from_numpy_array_raises_error_when_incorrect_dims_passed():
    array = np.ones((2, 2), dtype=np.float32)
    # verify this method works with the correct shape
    image = ImageStack.from_numpy_array(array.reshape((1, 1, 1, 2, 2)))
    assert isinstance(image, ImageStack)

    with pytest.raises(ValueError):
        ImageStack.from_numpy_array(array.reshape((1, 1, 2, 2)))
        ImageStack.from_numpy_array(array.reshape((1, 2, 2)))
        ImageStack.from_numpy_array(array)
        ImageStack.from_numpy_array(array.reshape((1, 1, 1, 1, 2, 2)))
コード例 #9
0
    def run(self,
            image: ImageStack,
            in_place: bool = False) -> Optional[ImageStack]:
        """Register an ImageStack against a reference image.

        Parameters
        ----------
        image : ImageStack
            The stack to be registered
        in_place : bool
            If false, return a new registered stack. Else, register in-place (default False)

        Returns
        -------


        """

        if not in_place:
            image = deepcopy(image)

        # TODO: (ambrosejcarr) is this the appropriate way of dealing with Z in registration?
        mp = image.max_proj(Indices.CH, Indices.Z)
        reference_image = self.reference_stack.max_proj(
            Indices.ROUND, Indices.CH, Indices.Z)

        for r in range(image.num_rounds):
            # compute shift between maximum projection (across channels) and dots, for each round
            # TODO: make the max projection array ignorant of axes ordering.
            shift, error = compute_shift(mp[r, :, :], reference_image,
                                         self.upsampling)
            print(f"For round: {r}, Shift: {shift}, Error: {error}")

            for c in range(image.num_chs):
                for z in range(image.num_zlayers):
                    # apply shift to all zlayers, channels, and imaging rounds
                    indices = {Indices.ROUND: r, Indices.CH: c, Indices.Z: z}
                    data, axes = image.get_slice(indices=indices)
                    assert len(axes) == 0

                    result = shift_im(data, shift)
                    result = preserve_float_range(result)

                    image.set_slice(indices=indices, data=result)

        if not in_place:
            return image
        return None
コード例 #10
0
def test_apply_3d():
    """test that apply correctly applies a simple function across 3d volumes of a Stack"""
    stack = ImageStack.synthetic_stack()
    assert np.all(stack.xarray == 1)
    stack.apply(divide, in_place=True, value=4,
                group_by={Axes.ROUND, Axes.CH})
    assert (stack.xarray == 0.25).all()
コード例 #11
0
def test_spot_detection_with_reference_image(
    data_stack: ImageStack,
    spot_detector: SpotFinderAlgorithmBase,
    radius_is_gyration: bool,
):
    """
    This testing method uses a reference image to identify spot locations. Thus, it should detect
    two spots, each with max intensity 7. Because the channels and rounds are aggregated, this
    method should recognize the 1-hot code used in the testing data, and see one channel "on" per
    round. Thus, the total intensity across all channels and round for each spot should be 14.

    """
    reference_image = data_stack.max_proj(Indices.CH, Indices.ROUND)

    intensity_table = detect_spots(
        data_stack=data_stack,
        spot_finding_method=spot_detector.image_to_spots,
        reference_image=reference_image,
        measurement_function=np.max,
        radius_is_gyration=radius_is_gyration,
    )
    assert intensity_table.shape == (2, 2, 2), "wrong number of spots detected"
    expected = [0.01587425, 0.01587425]
    assert np.allclose(intensity_table.sum((Indices.ROUND, Indices.CH)).values, expected), \
        "wrong spot intensities detected"
コード例 #12
0
def test_imagestack_export(tmpdir, format, count, recwarn):
    """
    Save a synthetic stack to files and check the results
    """
    stack_shape = OrderedDict([(Axes.ROUND, 3), (Axes.CH, 2), (Axes.ZPLANE, 1),
                               (Axes.Y, 50), (Axes.X, 40)])

    physical_coords = OrderedDict([
        (PhysicalCoordinateTypes.X_MIN, X_COORDS[0]),
        (PhysicalCoordinateTypes.X_MAX, X_COORDS[1]),
        (PhysicalCoordinateTypes.Y_MIN, Y_COORDS[0]),
        (PhysicalCoordinateTypes.Y_MAX, Y_COORDS[1]),
        (PhysicalCoordinateTypes.Z_MIN, Z_COORDS[0]),
        (PhysicalCoordinateTypes.Z_MAX, Z_COORDS[1])
    ])

    stack = test_utils.imagestack_with_coords_factory(stack_shape,
                                                      physical_coords)

    stack_json = tmpdir / "output.json"
    stack.export(str(stack_json), tile_format=format)
    files = list(
        [x for x in tmpdir.listdir() if str(x).endswith(format.file_ext)])
    loaded_stack = ImageStack.from_path_or_url(str(stack_json))
    verify_physical_coordinates(
        loaded_stack,
        X_COORDS,
        Y_COORDS,
        get_physical_coordinates_of_z_plane(Z_COORDS),
    )
    assert count == len(files)
    with open(files[0], "rb") as fh:
        format.reader_func(fh)
コード例 #13
0
def test_missing_extras():
    """
    If the extras are not present on some of the tiles, it should still work.
    """
    class OnesTilesWithExtrasMostly(OnesTile):
        def __init__(self, fov, r, ch, z, extras: dict) -> None:
            super().__init__((10, 10))
            self.fov = fov
            self._extras = extras

        @property
        def extras(self):
            if self.fov == 0:
                return None
            return self._extras

    tile_fetcher = tile_fetcher_factory(OnesTilesWithExtrasMostly, True,
                                        {'random_key': {
                                            'hello': "world",
                                        }})

    stack = ImageStack.synthetic_stack(
        num_round=NUM_ROUND,
        num_ch=NUM_CH,
        num_z=NUM_Z,
        tile_fetcher=tile_fetcher,
    )
    table = stack.tile_metadata
    assert len(table) == NUM_ROUND * NUM_CH * NUM_Z
コード例 #14
0
    def _find_spots(
        self,
        data_stack: ImageStack,
        verbose: bool = False,
        n_processes: Optional[int] = None
    ) -> Dict[Tuple[int, int], np.ndarray]:
        """Find spots in all (z, y, x) volumes of an ImageStack.

        Parameters
        ----------
        data_stack : ImageStack
            Stack containing spots to find.

        Returns
        -------
        Dict[Tuple[int, int], np.ndarray]
            Dictionary mapping (round, channel) pairs to a spot table generated by skimage blob_log
            or blob_dog.

        """
        # find spots in each (r, c) volume
        transform_results = data_stack.transform(
            self._spot_finder,
            group_by=determine_axes_to_group_by(self.is_volume),
            n_processes=n_processes,
        )

        # create output dictionary
        spot_results = {}
        for spot_calls, axes_dict in transform_results:
            r = axes_dict[Axes.ROUND]
            c = axes_dict[Axes.CH]
            spot_results[r, c] = spot_calls

        return spot_results
コード例 #15
0
def test_coordinates():
    """Set up an ImageStack with tiles that are offset based on round.  Verify that the coordinates
    retrieved match.
    """
    stack = ImageStack.synthetic_stack(NUM_ROUND,
                                       NUM_CH,
                                       NUM_Z,
                                       HEIGHT,
                                       WIDTH,
                                       tile_fetcher=tile_fetcher_factory(
                                           OffsettedTiles,
                                           True,
                                       ))

    for _round in range(NUM_ROUND):
        for ch in range(NUM_CH):
            for z in range(NUM_Z):
                indices = {Indices.ROUND: _round, Indices.CH: ch, Indices.Z: z}

                xmin, xmax = stack.tile_coordinates(indices, Coordinates.X)
                ymin, ymax = stack.tile_coordinates(indices, Coordinates.Y)
                zmin, zmax = stack.tile_coordinates(indices, Coordinates.Z)

                expected_xmin, expected_xmax = round_to_x(_round)
                expected_ymin, expected_ymax = round_to_y(_round)
                expected_zmin, expected_zmax = round_to_z(_round)

                assert np.isclose(xmin, expected_xmin)
                assert np.isclose(xmax, expected_xmax)
                assert np.isclose(ymin, expected_ymin)
                assert np.isclose(ymax, expected_ymax)
                assert np.isclose(zmin, expected_zmin)
                assert np.isclose(zmax, expected_zmax)
コード例 #16
0
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 = ImageStack.synthetic_stack(NUM_ROUND,
                                       NUM_CH,
                                       NUM_Z,
                                       HEIGHT,
                                       WIDTH,
                                       tile_fetcher=tile_fetcher_factory(
                                           OffsettedScalarTiles,
                                           True,
                                       ))

    for _round in range(NUM_ROUND):
        for ch in range(NUM_CH):
            for z in range(NUM_Z):
                indices = {Indices.ROUND: _round, Indices.CH: ch, Indices.Z: z}

                xmin, xmax = stack.tile_coordinates(indices, Coordinates.X)
                ymin, ymax = stack.tile_coordinates(indices, Coordinates.Y)
                zmin, zmax = stack.tile_coordinates(indices, Coordinates.Z)

                expected_x = round_to_x(_round)[0]
                expected_y = round_to_y(_round)[0]
                expected_z = round_to_z(_round)[0]

                assert np.isclose(xmin, expected_x)
                assert np.isclose(xmax, expected_x)
                assert np.isclose(ymin, expected_y)
                assert np.isclose(ymax, expected_y)
                assert np.isclose(zmin, expected_z)
                assert np.isclose(zmax, expected_z)
コード例 #17
0
ファイル: clip.py プロジェクト: nicopierson/starfish
    def run(self,
            stack: ImageStack,
            in_place: bool = False,
            verbose: bool = False,
            n_processes: Optional[int] = None) -> ImageStack:
        """Perform filtering of an image stack

        Parameters
        ----------
        stack : ImageStack
            Stack to be filtered.
        in_place : bool
            if True, process ImageStack in-place, otherwise return a new stack
        verbose : bool
            If True, report on the percentage completed (default = False) during processing
        n_processes : Optional[int]
            Number of parallel processes to devote to calculating the filter

        Returns
        -------
        ImageStack :
            If in-place is False, return the results of filter as a new stack.  Otherwise return the
            original stack.

        """
        group_by = determine_axes_to_group_by(self.is_volume)
        clip = partial(self._clip, p_min=self.p_min, p_max=self.p_max)
        result = stack.apply(clip,
                             group_by=group_by,
                             verbose=verbose,
                             in_place=in_place,
                             n_processes=n_processes)
        return result
コード例 #18
0
    def run(
            self, stack: ImageStack, in_place: bool=False, verbose=False,
            n_processes: Optional[int]=None
    ) -> ImageStack:
        """Perform filtering of an image stack

        Parameters
        ----------
        stack : ImageStack
            Stack to be filtered.
        in_place : bool
            if True, process ImageStack in-place, otherwise return a new stack
        verbose : bool
            if True, report on the percentage completed during processing (default = False)
        n_processes : Optional[int]
            Number of parallel processes to devote to calculating the filter

        Returns
        -------
        ImageStack :
            If in-place is False, return the results of filter as a new stack.  Otherwise return the
            original stack.

        """
        func = partial(
            self._richardson_lucy_deconv,
            iterations=self.num_iter, psf=self.psf, clip=self.clip
        )
        result = stack.apply(
            func,
            in_place=in_place, verbose=verbose, n_processes=n_processes
        )
        return result
コード例 #19
0
    def run(self,
            stack: ImageStack,
            in_place: bool = False,
            verbose: bool = False,
            n_processes: Optional[int] = None) -> ImageStack:
        """Perform filtering of an image stack

        Parameters
        ----------
        stack : ImageStack
            Stack to be filtered.
        in_place : bool
            if True, process ImageStack in-place, otherwise return a new stack
        verbose : bool
            If True, report on the percentage completed (default = False) during processing
        n_processes : Optional[int]
            Number of parallel processes to devote to calculating the filter

        Returns
        -------
        ImageStack :
            If in-place is False, return the results of filter as a new stack.  Otherwise return the
            original stack.

        """
        group_by = {Axes.ROUND, Axes.ZPLANE}
        unmix = partial(self._unmix, coeff_mat=self.coeff_mat)
        result = stack.apply(unmix,
                             group_by=group_by,
                             verbose=verbose,
                             in_place=in_place,
                             n_processes=n_processes)
        return result
コード例 #20
0
ファイル: experiment.py プロジェクト: ttung/starfish
    def get_image(
        self,
        item: str,
        aligned_group: int = 0,
        x_slice: Optional[Union[int, slice]] = None,
        y_slice: Optional[Union[int, slice]] = None,
    ) -> ImageStack:
        """
        Parameters
        ----------

        item: str
            The name of the tileset ex. 'primary' or 'nuclei'
        aligned_group: int
            The aligned subgroup, default 0
        x_slice: int or slice
            The cropping parameters for the x axis
        y_slice:
            The cropping parameters for the y axis

        Returns
        -------
        The instantiated ImageStack
        """
        crop_params = copy.copy(
            (self.aligned_coordinate_groups[item][aligned_group]))
        crop_params._x_slice = x_slice
        crop_params._y_slice = y_slice
        return ImageStack.from_tileset(self._images[item],
                                       crop_parameters=crop_params)
コード例 #21
0
    def run(
        self,
        stack: ImageStack,
        in_place: bool = False,
        verbose: bool = False,
        n_processes: Optional[int] = None,
        *args,
    ) -> ImageStack:
        """Perform filtering of an image stack

        Parameters
        ----------
        stack : ImageStack
            Stack to be filtered.
        in_place : bool
            if True, process ImageStack in-place, otherwise return a new stack
        verbose : bool
            if True, report on filtering progress (default = False)
        n_processes : Optional[int]
            Number of parallel processes to devote to calculating the filter

        Returns
        -------
        ImageStack :
            If in-place is False, return the results of filter as a new stack.  Otherwise return the
            original stack.

        """
        return stack.max_proj(*tuple(Axes(dim) for dim in self.dims))
コード例 #22
0
    def run(self,
            stack: ImageStack,
            in_place: bool = False,
            verbose: bool = True,
            n_processes: Optional[int] = None) -> ImageStack:
        """Perform filtering of an image stack

        Parameters
        ----------
        stack : ImageStack
            Stack to be filtered.
        in_place : bool
            if True, process ImageStack in-place, otherwise return a new stack
        verbose : bool
            if True, report on filtering progress (default = False)
        n_processes : Optional[int]
            Number of parallel processes to devote to calculating the filter

        Returns
        -------
        ImageStack :
            If in-place is False, return the results of filter as a new stack.  Otherwise return the
            original stack.

        """
        group_by = determine_axes_to_group_by(self.is_volume)
        high_pass: Callable = partial(self._high_pass, sigma=self.sigma)
        result = stack.apply(high_pass,
                             group_by=group_by,
                             verbose=verbose,
                             in_place=in_place,
                             n_processes=n_processes)
        return result
コード例 #23
0
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 = ImageStack.synthetic_stack(NUM_ROUND,
                                       NUM_CH,
                                       NUM_Z,
                                       HEIGHT,
                                       WIDTH,
                                       tile_fetcher=tile_fetcher_factory(
                                           OffsettedScalarTiles,
                                           True,
                                       ))

    assert stack.tiles_aligned is False

    for selectors in stack._iter_axes({Axes.ROUND, Axes.CH, Axes.ZPLANE}):
        expected_x = round_to_x(selectors[Axes.ROUND])[0]
        expected_y = round_to_y(selectors[Axes.ROUND])[0]
        expected_z = round_to_z(selectors[Axes.ROUND])[0]

        verify_physical_coordinates(
            stack,
            selectors,
            (expected_x, expected_x),
            (expected_y, expected_y),
            (expected_z, expected_z),
        )
コード例 #24
0
def test_unaligned_tiles():
    """Test that imagestack error is thrown when constructed with unaligned tiles"""

    try:
        ImageStack.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"
コード例 #25
0
def pixel_intensities_to_imagestack(
        intensities: IntensityTable, image_shape: Tuple[int, int,
                                                        int]) -> ImageStack:
    """Re-create the pixel intensities from an IntensityTable

    Parameters
    ----------
    intensities : IntensityTable
        intensities to transform into an ImageStack
    image_shape : Tuple[int, int, int]
        the dimensions of z, y, and x for the original image that the intensity table was generated
        from

    Returns
    -------
    ImageStack :
        ImageStack containing Intensity information

    """
    # reverses the process used to produce the intensity table in to_pixel_intensities
    data = intensities.values.reshape([
        *image_shape, intensities.sizes[Axes.CH], intensities.sizes[Axes.ROUND]
    ])
    data = data.transpose(4, 3, 0, 1, 2)
    return ImageStack.from_numpy_array(data)
コード例 #26
0
ファイル: laplace.py プロジェクト: Henley13/starfish
 def run(self,
         stack: ImageStack,
         in_place: bool = True,
         verbose: bool = True,
         n_processes: Optional[int] = None) -> ImageStack:
     """Perform filtering of an image stack
     Parameters
     ----------
     stack : ImageStack
         Stack to be filtered.
     in_place : bool
         if True, process ImageStack in-place, otherwise return a new stack
     verbose : bool
         if True, report on filtering progress (default = False)
     Returns
     -------
     ImageStack :
         if in-place is False, return the results of filter as a new stack
     """
     group_by = determine_axes_to_group_by(self.is_volume)
     apply_filtering: Callable = partial(self._gaussian_laplace,
                                         sigma=self.sigma)
     return stack.apply(
         apply_filtering,
         group_by=group_by,
         verbose=verbose,
         in_place=in_place,
         n_processes=n_processes,
     )
コード例 #27
0
def test_match_histograms():
    linear_gradient = np.linspace(0, 0.5, 2000, dtype=np.float32)
    image = linear_gradient.reshape(2, 4, 5, 5, 10)

    # linear_gradient = np.linspace(0, 1, 10)[::-1]
    # grad = np.repeat(linear_gradient[np.newaxis, :], 10, axis=0)
    # image2 = np.tile(grad, (1, 2, 2, 10, 10))

    # because of how the image was structured, every volume should be the same after
    # quantile normalization
    stack = ImageStack.from_numpy_array(image)
    mh = MatchHistograms({Axes.CH, Axes.ROUND})
    results = mh.run(stack)
    assert len(np.unique(results.xarray.sum(("x", "y", "z")))) == 1

    # because here we are allowing variation to persist across rounds, each
    # round within each channel should be different
    mh = MatchHistograms({Axes.CH})
    results2 = mh.run(stack)
    assert len(np.unique(results2.xarray.sum(("x", "y", "z")))) == 2

    # same as above, but verifying this functions for a different data shape (2 rounds, 4 channels)
    mh = MatchHistograms({Axes.ROUND})
    results2 = mh.run(stack)
    assert len(np.unique(results2.xarray.sum(("x", "y", "z")))) == 4
コード例 #28
0
def test_max_projection_preserves_dtype():
    original_dtype = np.float32
    array = np.ones((2, 2, 2), dtype=original_dtype)
    image = ImageStack.from_numpy_array(array.reshape((1, 1, 2, 2, 2)))

    max_projection = image.max_proj(Indices.CH, Indices.ROUND, Indices.Z)
    assert max_projection.dtype == original_dtype
コード例 #29
0
ファイル: warp.py プロジェクト: ttung/starfish
    def run(self,
            stack: ImageStack,
            transforms_list: TransformsList,
            in_place: bool = False,
            verbose: bool = False,
            *args,
            **kwargs) -> ImageStack:
        """Applies a list of transformations to an ImageStack

        Parameters
        ----------
        stack : ImageStack
            Stack to be transformed.
        transforms_list: TransformsList
            The list of transform objects to apply to the ImageStack.
        in_place : bool
            if True, process ImageStack in-place, otherwise return a new stack
        verbose : bool
            if True, report on transformation progress (default = False)

        Returns
        -------
        ImageStack :
            If in-place is False, return the results of the transforms as a new stack.
            Otherwise return the original stack.
        """
        if not in_place:
            # create a copy of the ImageStack, call apply on that stack with in_place=True
            image_stack = deepcopy(stack)
            return self.run(image_stack,
                            transforms_list,
                            in_place=True,
                            **kwargs)
        if verbose and StarfishConfig().verbose:
            transforms_list.transforms = tqdm(transforms_list.transforms)
        all_axes = {Axes.ROUND, Axes.CH, Axes.ZPLANE}
        for selector, _, transformation_object in transforms_list.transforms:
            other_axes = all_axes - set(selector.keys())
            # iterate through remaining axes
            for axes in stack._iter_axes(other_axes):
                # combine all axes data to select one tile
                selector.update(axes)  # type: ignore
                selected_image, _ = stack.get_slice(selector)
                warped_image = warp(selected_image, transformation_object,
                                    **kwargs).astype(np.float32)
                stack.set_slice(selector, warped_image)
        return stack
コード例 #30
0
def verify_physical_coordinates(
        stack: ImageStack, selectors: Mapping[Axes, int],
        expected_x_coordinates: Tuple[float, float],
        expected_y_coordinates: Tuple[float, float],
        expected_z_coordinates: Tuple[float, float]) -> None:
    """Given an imagestack and a set of selectors, verify that the physical coordinates for the data
    referred to by the selectors match the expected physical coordinates.
    """
    assert np.all(
        np.isclose(stack.tile_coordinates(selectors, Coordinates.X),
                   expected_x_coordinates))
    assert np.all(
        np.isclose(stack.tile_coordinates(selectors, Coordinates.Y),
                   expected_y_coordinates))
    assert np.all(
        np.isclose(stack.tile_coordinates(selectors, Coordinates.Z),
                   expected_z_coordinates))