Пример #1
0
def decoded_intensity_table_factory() -> Tuple[IntensityTable, np.ndarray]:
    """
    Create an IntensityTable that has gene labels, including null labels. The data doesn't matter,
    so will use np.zeros
    """
    data = np.zeros((1, 1, 2, 3, 3), dtype=np.float32)
    labels = np.array(
        [[[0, 1, 1],
          [0, 2, 2],
          [1, 1, 1]],
         [[0, 1, 1],
          [1, 1, 1],
          [0, 1, 2]]],
        dtype='<U3'
    )
    labels_with_nan = labels.copy()
    labels_with_nan[labels == '0'] = 'nan'

    # create an intensity table and add the labels
    image_stack = ImageStack.from_numpy(data)
    intensities = IntensityTable.from_image_stack(image_stack)
    intensities[Features.TARGET] = (Features.AXIS, np.ravel(labels_with_nan))

    # label the third column of this data as failing filters
    passes_filters = np.ones(data.shape, dtype=bool)
    passes_filters[:, :, :, :, -1] = 0
    intensities[Features.PASSES_THRESHOLDS] = (Features.AXIS, np.ravel(passes_filters))

    return intensities, labels_with_nan
def labeled_intensities_factory(
) -> Tuple[IntensityTable, np.ndarray, np.ndarray]:
    """
    Create a decoded IntensityTable with distance scores, and a corresponding label_image and
    decoded_image.
    """
    data = np.array(
        [
            [
                [[0., 0.], [.1, .1]],  # ch 1
                [[.5, .5], [.2, .3]]
            ],
            [
                [[.1, .1], [0, 0]],  # ch 2, x & y are reversed
                [[.2, .3], [.5, .5]]
            ]
        ],
        dtype=np.float32)
    image_stack = ImageStack.from_numpy(data.reshape(1, 2, 2, 2, 2))
    intensity_table = IntensityTable.from_image_stack(image_stack)
    intensity_table[Features.DISTANCE] = (Features.AXIS,
                                          np.zeros(intensity_table.shape[0]))
    label_image = np.array([[[1, 2], [3, 4]], [[1, 2], [3, 4]]])
    decoded_image = np.array([[[5, 4], [3, 2]], [[5, 4], [3, 2]]])

    # verify that the listed label image is what would be created by the function we use in the
    # code
    assert np.array_equal(label(decoded_image), label_image)

    return intensity_table, label_image, decoded_image
Пример #3
0
def compute_magnitudes(stack, norm_order=2):

    pixel_intensities = IntensityTable.from_image_stack(stack)
    feature_traces = pixel_intensities.stack(traces=(Axes.CH.value, Axes.ROUND.value))
    norm = np.linalg.norm(feature_traces.values, ord=norm_order, axis=1)

    return norm
Пример #4
0
def test_intensity_table_concatenation():
    """create two IntensityTables and assert that they are being concatenated properly."""

    r, c, z, y, x = 3, 3, 2, 2, 5
    data = np.zeros(180, dtype=np.float32).reshape(r, c, z, y, x)
    image_stack = ImageStack.from_numpy_array(data)
    intensities = IntensityTable.from_image_stack(image_stack)

    intensities2 = intensities.copy()

    original_shape = intensities.shape

    expected_shape = list(original_shape)
    expected_shape[0] *= 2  # only features is concatenated
    assert np.array_equal(
        concatenate([intensities, intensities2]).shape, expected_shape)

    # slice out a single channel and round from both experiments, such that the data no longer match
    # across all dimensions but the concatenation dimension. The resulting structure should be
    # 2 (r) * 2 (c) * 5 (z), 2, 2 = 40, 2, 2
    i1 = intensities.where(np.logical_and(intensities.r == 0,
                                          intensities.c == 0),
                           drop=True)
    i2 = intensities.where(np.logical_and(intensities.r == 1,
                                          intensities.c == 1),
                           drop=True)
    expected_shape = (i1.shape[0] + i2.shape[0], 2, 2)
    result = concatenate([i1, i2])

    assert expected_shape == result.shape

    # slice a larger r value for second array, however, there are still only two values, so
    # shape should be 40, 2, 2
    i3 = intensities.where(np.logical_and(intensities.r == 2,
                                          intensities.c == 1),
                           drop=True)
    expected_shape = (i1.shape[0] + i3.shape[0], 2, 2)
    result = concatenate([i1, i3])

    assert expected_shape == result.shape

    # slice out z in addition to reduce the total feature number by 1/2
    i4 = intensities.where(np.logical_and(intensities.r == 0,
                                          intensities.z == 1),
                           drop=True)
    expected_shape = (i1.shape[0] + i4.shape[0], 3, 1)
    result = concatenate([i1, i4])

    assert expected_shape == result.shape
Пример #5
0
def test_intensity_table_serialization():
    """
    Test that an IntensityTable can be saved to disk, and that when it is reloaded, the data is
    unchanged
    """

    # create an IntensityTable
    data = np.zeros(100, dtype=np.float32).reshape(1, 5, 2, 2, 5)
    image_stack = ImageStack.from_numpy_array(data)
    intensities = IntensityTable.from_image_stack(image_stack)

    # dump it to disk
    tempdir = tempfile.mkdtemp()
    filename = os.path.join(tempdir, 'test.nc')
    intensities.save(filename)

    # verify the data has not changed
    loaded = intensities.load(filename)
    assert intensities.equals(loaded)
Пример #6
0
def test_to_mermaid_dataframe():
    """
    Creates a basic IntensityTable from an ImageStack and verifies that it can be dumped to disk
    as a DataFrame which MERmaid can load. Does not explicitly load the DataFrame in MERmaid.

    Verifies that the save function throws an error when target assignments are not present, which
    are required by MERmaid.
    """
    r, c, z, y, x = 1, 5, 2, 2, 5
    data = np.zeros(100, dtype=np.float32).reshape(r, c, z, y, x)
    image_stack = ImageStack.from_numpy_array(data)
    intensities = IntensityTable.from_image_stack(image_stack)

    # without a target assignment, should raise RuntimeError.
    with pytest.raises(RuntimeError):
        with TemporaryDirectory() as dir_:
            intensities.save_mermaid(os.path.join(dir_, 'test.csv.gz'))

    # assign targets
    intensities[Features.TARGET] = (Features.AXIS, np.random.choice(list('ABCD'), size=20))
    intensities[Features.DISTANCE] = (Features.AXIS, np.random.rand(20))
    with TemporaryDirectory() as dir_:
        intensities.save_mermaid(os.path.join(dir_, 'test.csv.gz'))
Пример #7
0
def test_intensity_table_can_be_constructed_from_an_imagestack():
    """
    ImageStack has enough information to create an IntensityTable without additional SpotAttributes.
    Each feature is a pixel, and therefore the SpotAttributes can be extracted from the relative
    locations.
    """
    r, c, z, y, x = 1, 5, 2, 2, 5
    data = np.zeros(100, dtype=np.float32).reshape(r, c, z, y, x)
    image_stack = ImageStack.from_numpy_array(data)
    intensities = IntensityTable.from_image_stack(image_stack)

    # there should be 100 features
    assert np.product(intensities.shape) == 100

    # the max features should be equal to the array extent (2, 2, 5) minus one, since indices
    # are being compared and python is zero based
    # import pdb; pdb.set_trace()
    assert np.max(intensities[Axes.ZPLANE.value].values) == z - 1
    assert np.max(intensities[Axes.Y.value].values) == y - 1
    assert np.max(intensities[Axes.X.value].values) == x - 1

    # the number of channels and rounds should match the ImageStack
    assert intensities.sizes[Axes.CH.value] == c
    assert intensities.sizes[Axes.ROUND.value] == r