Exemplo n.º 1
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)))
Exemplo n.º 2
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
Exemplo n.º 3
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)
Exemplo n.º 4
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
def test_reshaping_between_stack_and_intensities():
    """
    transform an pixels of an ImageStack into an IntensityTable and back again, then verify that
    the created Imagestack is the same as the original
    """
    np.random.seed(777)
    image = ImageStack.from_numpy_array(np.random.rand(1, 2, 3, 4, 5).astype(np.float32))
    pixel_intensities = IntensityTable.from_image_stack(image, 0, 0, 0)
    image_shape = (image.shape['z'], image.shape['y'], image.shape['x'])
    image_from_pixels = pixel_intensities_to_imagestack(pixel_intensities, image_shape)
    assert np.array_equal(image.numpy_array, image_from_pixels.numpy_array)
Exemplo n.º 6
0
def test_apply_clipping_methods():
    """test that apply properly clips the imagestack"""

    # create a half-valued float array
    data = np.full((2, 2, 2, 5, 5), fill_value=0.5, dtype=np.float32)
    # set one value to max
    data[1, 1, 1, 1, 1] = 1

    imagestack = ImageStack.from_numpy_array(data)

    # max value after multiplication == 2, all other values == 1
    def apply_function(x):
        return x * 2

    # clip_method 0
    # all data are clipped to 1, setting all values to 1 (np.unique(pre_scaled) == [1, 2])
    res = imagestack.apply(apply_function, clip_method=Clip.CLIP, in_place=False, n_processes=1)
    assert np.allclose(res.xarray.values, 1)

    # clip_method 1
    # all data are scaled, resulting in values being multiplied by 0.5, replicating the original
    # data
    res = imagestack.apply(
        apply_function, clip_method=Clip.SCALE_BY_IMAGE, in_place=False, n_processes=1
    )
    assert np.allclose(imagestack.xarray, res.xarray)

    # clip_method 2
    res = imagestack.apply(
        apply_function, clip_method=Clip.SCALE_BY_CHUNK, in_place=False, n_processes=1,
        group_by={Axes.CH, Axes.ROUND},
    )
    # any (round, ch) combination that was all 0.5 should now be all 1.
    assert np.allclose(res.sel({Axes.ROUND: 0, Axes.CH: 0}).xarray, 1)
    assert np.allclose(res.sel({Axes.ROUND: 1, Axes.CH: 0}).xarray, 1)
    assert np.allclose(res.sel({Axes.ROUND: 0, Axes.CH: 1}).xarray, 1)

    # the specific (round, ch) combination with the single "1" value should be scaled, and due to
    # construction, look like the original data.
    assert np.allclose(
        res.sel({Axes.ROUND: 1, Axes.CH: 1}).xarray,
        imagestack.sel({Axes.ROUND: 1, Axes.CH: 1}).xarray
    )
Exemplo n.º 7
0
def synthetic_two_spot_3d_2round_2ch() -> ImageStack:
    """produce a 2-round 2-channel ImageStack

    Notes
    -----
    - After Gaussian filtering, all max intensities are 7
    - Two spots are located at (4, 10, 90) and (6, 90, 10)
    - Both spots are 1-hot, and decode to:
        - spot 1: (round 0, ch 0), (round 1, ch 1)
        - spot 2: (round 0, ch 1), (round 1, ch 0)

    Returns
    -------
    ImageStack :
        noiseless ImageStack containing two spots

    """

    # blank data_image
    data = np.zeros((2, 2, 10, 100, 100), dtype=np.float32)

    # round 0 channel 0
    data[0, 0, 4, 10, 90] = 1
    data[0, 0, 5, 90, 10] = 0

    # round 0 channel 1
    data[0, 1, 4, 10, 90] = 0
    data[0, 1, 5, 90, 10] = 1

    # round 1 channel 0
    data[1, 0, 4, 10, 90] = 0
    data[1, 0, 5, 90, 10] = 1

    # round 1 channel 1
    data[1, 1, 4, 10, 90] = 1
    data[1, 1, 5, 90, 10] = 0

    data = gaussian_filter(data, sigma=(0, 0, 2, 2, 2))
    return ImageStack.from_numpy_array(data)
Exemplo n.º 8
0
def test_from_numpy_array_automatically_handles_float_conversions():
    x = np.zeros((1, 1, 1, 20, 20), dtype=np.uint16)
    stack = ImageStack.from_numpy_array(x)
    assert stack.numpy_array.dtype == np.float32
Exemplo n.º 9
0
from starfish.spots._detector.local_max_peak_finder import LocalMaxPeakFinder
from starfish.spots._detector.trackpy_local_max_peak_finder import TrackpyLocalMaxPeakFinder
from starfish.test.factories import (
    two_spot_informative_blank_coded_data_factory,
    two_spot_one_hot_coded_data_factory,
    two_spot_sparse_coded_data_factory,
)
from starfish.types import Axes, Features

# verify all spot finders handle different coding types
_, ONE_HOT_IMAGESTACK, ONE_HOT_MAX_INTENSITY = two_spot_one_hot_coded_data_factory()
_, SPARSE_IMAGESTACK, SPARSE_MAX_INTENSITY = two_spot_sparse_coded_data_factory()
_, BLANK_IMAGESTACK, BLANK_MAX_INTENSITY = two_spot_informative_blank_coded_data_factory()

# make sure that all spot finders handle empty arrays
EMPTY_IMAGESTACK = ImageStack.from_numpy_array(np.zeros((4, 2, 10, 100, 100), dtype=np.float32))


def simple_gaussian_spot_detector() -> BlobDetector:
    """create a basic gaussian spot detector"""
    return BlobDetector(min_sigma=1, max_sigma=4, num_sigma=5, threshold=0, measurement_type='max')


def simple_trackpy_local_max_spot_detector() -> TrackpyLocalMaxPeakFinder:
    """create a basic local max peak finder"""
    return TrackpyLocalMaxPeakFinder(
        spot_diameter=3,
        min_mass=0.01,
        max_size=10,
        separation=2,
    )
Exemplo n.º 10
0
def random_data_image_stack_factory():
    data = np.random.uniform(0, 1, 100).reshape(1, 1, 1, 10, 10).astype(np.float32)
    return ImageStack.from_numpy_array(data)
Exemplo n.º 11
0
def synthetic_two_spot_imagestack_3d(synthetic_two_spot_3d):
    data = synthetic_two_spot_3d
    return ImageStack.from_numpy_array(data.reshape(1, 1, *data.shape))
Exemplo n.º 12
0
def synthetic_single_spot_imagestack_2d(synthetic_single_spot_2d):
    data = synthetic_single_spot_2d
    return ImageStack.from_numpy_array(data.reshape(1, 1, 1, *data.shape))