Esempio n. 1
0
 def test_resize_to_larger(self):
     image = mi.MibiImage(np.random.rand(5, 5, 3), STRING_LABELS)
     expected = mi.MibiImage(
         transform.resize(image.data, (6, 6, 3), order=3, mode='edge'),
         STRING_LABELS)
     image.resize(6)
     self.assertTrue(image == expected)
Esempio n. 2
0
 def test_non_unique_channels(self):
     with self.assertRaises(ValueError):
         mi.MibiImage(TEST_DATA, ['1', '2', '1'])
     with self.assertRaises(ValueError):
         mi.MibiImage(TEST_DATA, [('1', 'A'), ('2', 'B'), ('3', 'A')])
     with self.assertRaises(ValueError):
         mi.MibiImage(TEST_DATA, [('1', 'A'), ('2', 'B'), ('2', 'C')])
Esempio n. 3
0
 def test_resize_integer_with_copy(self):
     image = mi.MibiImage(np.random.rand(5, 5, 3), STRING_LABELS)
     image_copy = mi.MibiImage(image.data.copy(), STRING_LABELS)
     resized = image.resize(3, copy=True)
     expected = transform.resize(image.data, (3, 3, 3), order=3, mode='edge')
     self.assertTrue(resized == mi.MibiImage(expected, STRING_LABELS))
     self.assertTrue(image == image_copy)
Esempio n. 4
0
 def test_resize_preserve_float_dtype(self):
     image = mi.MibiImage(np.random.rand(5, 5, 3), STRING_LABELS)
     data = image.data
     image.resize(3, preserve_type=True)
     # The return value should not be affected by whether the
     # dtype is preserved if the input data are floats in the unit interval.
     expected = transform.resize(data, (3, 3, 3), order=3, mode='edge')
     self.assertTrue(image == mi.MibiImage(expected, STRING_LABELS))
Esempio n. 5
0
 def test_resize_tuple_without_copy(self):
     image = mi.MibiImage(np.random.rand(5, 5, 3), STRING_LABELS)
     data = image.data
     image.resize((3, 3))
     expected = transform.resize(data, (3, 3, 3),
                                 order=3,
                                 mode='edge',
                                 anti_aliasing=False)
     self.assertTrue(image == mi.MibiImage(expected, STRING_LABELS))
Esempio n. 6
0
 def test_append(self):
     first_image = mi.MibiImage(TEST_DATA[:, :, :2], ['1', '2'], **METADATA)
     second_image = mi.MibiImage(TEST_DATA[:, :, 1:3], ['3', '4'])
     first_image.append(second_image)
     expected = mi.MibiImage(TEST_DATA[:, :, [0, 1, 1, 2]],
                             ['1', '2', '3', '4'], **METADATA)
     self.assertEqual(first_image, expected)
     np.testing.assert_array_equal(first_image.slice_data('4'),
                                   second_image.slice_data('4'))
Esempio n. 7
0
 def test_resize_preserve_uint_dtype(self):
     image = mi.MibiImage(
         np.random.randint(0, 255, (5, 5, 3)).astype(np.uint8),
         STRING_LABELS)
     data = image.data
     image.resize(3, preserve_type=True)
     expected = transform.resize(data, (3, 3, 3), order=3, mode='edge',
                                 preserve_range=True).astype(np.uint8)
     self.assertTrue(image == mi.MibiImage(expected, STRING_LABELS))
Esempio n. 8
0
    def test_slice_image(self):
        image = mi.MibiImage(TEST_DATA, STRING_LABELS)
        image_slice = image.slice_image(['1', '3'])
        self.assertEqual(
            image_slice, mi.MibiImage(image.slice_data(['1', '3']),
                                      ['1', '3']))

        single_slice = image.slice_image('2')
        self.assertEqual(single_slice,
                         mi.MibiImage(image.slice_data(['2']), ['2']))
Esempio n. 9
0
 def setUp(self):
     self.float_image = mi.MibiImage(DATA, CHANNELS, **METADATA)
     self.int_image = mi.MibiImage(DATA.astype(np.uint16), CHANNELS,
                                   **METADATA)
     self.image_user_defined_metadata = mi.MibiImage(
         DATA, CHANNELS, **METADATA, **USER_DEFINED_METADATA)
     self.image_old_metadata = mi.MibiImage(DATA, CHANNELS, **OLD_METADATA)
     self.image_old_mibiscope_metadata = mi.MibiImage(
         DATA, CHANNELS, **OLD_MIBISCOPE_METADATA)
     self.folder = tempfile.mkdtemp()
     self.filename = os.path.join(self.folder, 'test.tiff')
     self.maxDiff = None
Esempio n. 10
0
 def test_append_channels_of_different_type(self):
     first_image = mi.MibiImage(TEST_DATA, TUPLE_LABELS, **METADATA)
     original_data = np.copy(first_image.data)
     second_image = mi.MibiImage(TEST_DATA, STRING_LABELS, **METADATA)
     with self.assertRaises(ValueError):
         first_image.append(second_image)
     self.assertEqual(first_image.channels, TUPLE_LABELS)
     np.testing.assert_array_equal(first_image.data, original_data)
     first_image = second_image.copy()
     second_image = mi.MibiImage(TEST_DATA, TUPLE_LABELS, **METADATA)
     with self.assertRaises(ValueError):
         first_image.append(second_image)
     self.assertEqual(first_image.channels, STRING_LABELS)
     np.testing.assert_array_equal(first_image.data, original_data)
Esempio n. 11
0
 def test_append(self):
     first_image = mi.MibiImage(TEST_DATA[:, :, :2], ['1', '2'], **METADATA)
     second_image = mi.MibiImage(TEST_DATA[:, :, 1:3], ['3', '4'])
     first_image.append(second_image)
     expected = mi.MibiImage(TEST_DATA[:, :, [0, 1, 1, 2]],
                             ['1', '2', '3', '4'], **METADATA)
     self.assertEqual(first_image, expected)
     np.testing.assert_array_equal(first_image.slice_data('4'),
                                   second_image.slice_data('4'))
     first_image = mi.MibiImage(TEST_DATA[:, :, :2], TUPLE_LABELS[:2],
                                **METADATA)
     second_image.channels = [('Mass3', 'Target3'), ('Mass4', 'Target4')]
     expected.channels = TUPLE_LABELS + (('Mass4', 'Target4'), )
     first_image.append(second_image)
     self.assertEqual(first_image, expected)
Esempio n. 12
0
 def test_write_float32_from_float64(self):
     float64_image = mi.MibiImage(DATA.astype(np.float64), CHANNELS,
                                  **METADATA)
     tiff.write(self.filename, float64_image, multichannel=True)
     image = tiff.read(self.filename)
     np.testing.assert_equal(image.data, DATA)
     self.assertEqual(image.data.dtype, np.float32)
Esempio n. 13
0
 def test_set_fov_dont_change_folder(self):
     image = mi.MibiImage(TEST_DATA,
                          TUPLE_LABELS,
                          folder='Point1/RowNumber0/Depth_Profile0')
     image.set_fov_id('Point1')
     self.assertEqual(image.fov_id, 'Point1')
     self.assertEqual(image.folder, 'Point1/RowNumber0/Depth_Profile0')
Esempio n. 14
0
 def test_backwards_compatibility_with_old_metadata(self):
     with self.assertWarns(UserWarning):
         image = mi.MibiImage(TEST_DATA, TUPLE_LABELS, **OLD_METADATA)
     self.assertEqual(image.fov_id, OLD_METADATA['folder'].split('/')[0])
     self.assertEqual(image.fov_name, OLD_METADATA['point_name'])
     self.assertEqual(image.point_name, OLD_METADATA['point_name'])
     self.assertEqual(image._user_defined_attributes, ['point_name'])
Esempio n. 15
0
 def test_convert_from_deprecated_aperture(self):
     with warnings.catch_warnings(record=True) as w:
         image = mi.MibiImage(TEST_DATA, TUPLE_LABELS,
                              aperture='300um')
     self.assertTrue(
         str(w[-1].message).startswith('Deprecated aperture code'))
     self.assertEqual(image.aperture, 'B')
Esempio n. 16
0
 def test_write_float32_as_uint16_fails(self):
     lossy_image = mi.MibiImage(DATA + 0.001, CHANNELS, **METADATA)
     with self.assertRaises(ValueError):
         tiff.write(self.filename,
                    lossy_image,
                    multichannel=True,
                    dtype=np.uint16)
Esempio n. 17
0
 def test_add_existing_metadata(self):
     image = mi.MibiImage(TEST_DATA, TUPLE_LABELS, **METADATA,
                          **USER_DEFINED_METADATA)
     metadata = METADATA.copy()
     metadata = {**metadata, **USER_DEFINED_METADATA}
     with self.assertRaises(ValueError):
         image.add_attr(**metadata)
Esempio n. 18
0
def replace_labeled_pixels(label_image, df, columns=None):
    """Replaces the pixels within each label with a value from a dataframe.

    Args:
        label_image: An NxM array where each pixel's nonnegative integer value
            corresponds to the label of an image region, such as a cell or
            other segment.
        df: A dataframe whose index corresponds to the integers in the
            label_array, and whose column values will replace the labels in the
            returned image.
        columns: An optional sequence of which columns from the dataframe to
            include in the returned image. Defaults to None, which uses all
            columns in the dataframe.

    Returns:
        A :class:`mibitof.mibi_image.MibiImage` instance where each channel
        corresponds to a dataframe column, and the data is a copy of the label
        image where each pixel has been replaced with the corresponding value
        from that label's row in the dataframe.
    """
    if columns is None:
        columns = df.columns
    label_array = np.zeros((label_image.max() + 1, len(columns)),
                           dtype=label_image.dtype)
    label_array[df.index, :] = df[columns]
    columns = [str(i) for i in columns]
    return mi.MibiImage(label_array[label_image], columns)
Esempio n. 19
0
 def test_append_single_channel(self):
     first_image = mi.MibiImage(TEST_DATA[:, :, :2], ['Target1', 'Target2'],
                                **METADATA)
     second_data = np.expand_dims(TEST_DATA[:, :, 2], -1)
     second_image = mi.MibiImage(second_data, ['Target3'], **METADATA)
     expected = mi.MibiImage(TEST_DATA, ['Target1', 'Target2', 'Target3'],
                             **METADATA)
     first_image.append(second_image)
     self.assertEqual(first_image, expected)
     first_image = mi.MibiImage(TEST_DATA[:, :, :2], TUPLE_LABELS[:2],
                                **METADATA)
     second_image.channels = [('Mass3', 'Target3')]
     expected.channels = TUPLE_LABELS
     first_image.append(second_image)
     np.testing.assert_array_equal(first_image.data, expected.data)
     self.assertEqual(first_image, expected)
 def test_mibi_image_string_labels(self):
     image = mi.MibiImage(TEST_DATA, STRING_LABELS)
     np.testing.assert_array_equal(image.data, TEST_DATA)
     self.assertEqual(image.channels, STRING_LABELS)
     self.assertEqual(image._index, {'1': 0, '2': 1, '3': 2})
     self.assertIsNone(image.masses)
     self.assertIsNone(image.targets)
Esempio n. 21
0
    def test_circular_sectors(self):
        """Test circular sectors method in segmentation.
        """

        # create data for image 2 channels
        channels = ['ch0', 'ch1']
        data = np.stack(
            (
                # channel 0
                np.arange(36, dtype='float').reshape(6, 6),
                # this is the matrix:
                #np.array([[ 0,  1,  2,  3,  4,  5],
                #          [ 6,  7,  8,  9, 10, 11],
                #          [12, 13, 14, 15, 16, 17],
                #          [18, 19, 20, 21, 22, 23],
                #          [24, 25, 26, 27, 28, 29],
                #          [30, 31, 32, 33, 34, 35]], dtype='float')
                # channel 1
                np.array([[0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0],
                          [0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1],
                          [0, 1, 0, 0, 0, 0], [0, 0, 3, 0, 0, 2]],
                         dtype='float'),
            ),
            axis=2)
        # assume labels are for cell ID 1, such as with label image:
        # np.array([
        #     [1, 1, 1, 1, 1, 0],
        #     [1, 1, 1, 1, 1, 0],
        #     [1, 1, 1, 1, 1, 0],
        #     [1, 1, 1, 1, 1, 0],
        #     [1, 1, 1, 1, 1, 0],
        #     [0, 0, 0, 0, 0, 0]])
        # indices of the pixels of the cell
        x = np.arange(5)
        y = x
        x_inds, y_inds = np.meshgrid(x, y, indexing='ij')
        inds = (y_inds.flatten(), x_inds.flatten())
        # sum within sectors and calculate geometric mean for each channel
        secs = []
        for i in range(len(channels)):
            sec1 = data[2][2][i] + data[2][3][i] + data[2][4][i] + data[3][4][i]
            sec2 = data[3][3][i] + data[4][3][i] + data[4][4][i]
            sec3 = data[3][2][i] + data[4][2][i] + data[4][1][i]
            sec4 = data[3][1][i] + data[4][0][i] + data[3][0][i]
            sec5 = data[2][1][i] + data[2][0][i] + data[1][0][i]
            sec6 = data[1][1][i] + data[0][0][i] + data[0][1][i]
            sec7 = data[1][2][i] + data[0][2][i] + data[0][3][i]
            sec8 = data[1][3][i] + data[0][4][i] + data[1][4][i]
            secs_geom_mean = np.power(sec1 * sec2 * sec3 * sec4 * \
                                sec5 * sec6 * sec7 * sec8, 1/8)
            secs.append(secs_geom_mean)
        expected = np.array(secs)

        # test the function
        image = mi.MibiImage(data, channels)
        circ_secs = segmentation._circular_sectors_mean(inds,
                                                        image,
                                                        num_sectors=8)
        assert_array_equal(circ_secs, expected)
Esempio n. 22
0
 def test_set_channels_invalid_tuple(self):
     image = mi.MibiImage(TEST_DATA, TUPLE_LABELS)
     invalid_tuple_1 = [(c, ) for c in STRING_LABELS]
     invalid_tuple_3 = [(c, 'a', 'b') for c in STRING_LABELS]
     with self.assertRaises(ValueError):
         image.channels = invalid_tuple_1
     with self.assertRaises(ValueError):
         image.channels = invalid_tuple_3
Esempio n. 23
0
 def _test_export_image_helper(self, array, expected):
     channels = ['1', '2']
     im = mi.MibiImage(array, channels)
     im.export_pngs(self.test_dir)
     for i, label in enumerate(channels):
         roundtripped = skio.imread(
             f'{os.path.join(self.test_dir, label)}.png')
         np.testing.assert_array_equal(roundtripped, expected[:, :, i])
Esempio n. 24
0
 def test_metadata_with_user_defined_metadata_in_instantiation(self):
     image = mi.MibiImage(TEST_DATA, TUPLE_LABELS, **METADATA,
                          **USER_DEFINED_METADATA)
     metadata = METADATA.copy()
     metadata.update(USER_DEFINED_METADATA)
     metadata['date'] = datetime.datetime.strptime(metadata['date'],
                                                   mi._DATETIME_FORMAT)
     self.assertEqual(image.metadata(), metadata)
Esempio n. 25
0
 def test_write_uint16_from_uint8(self):
     uint8_image = mi.MibiImage(
         np.random.randint(0, 256, (32, 32, 5), dtype=np.uint8), CHANNELS,
         **METADATA)
     tiff.write(self.filename, uint8_image, multichannel=True)
     image = tiff.read(self.filename)
     np.testing.assert_equal(image.data, uint8_image.data.astype(np.uint16))
     self.assertEqual(image.data.dtype, np.uint16)
Esempio n. 26
0
 def test_remove_layers_with_copy(self):
     image = mi.MibiImage(TEST_DATA, STRING_LABELS)
     new_image = image.remove_channels(['1', '3'], copy=True)
     np.testing.assert_array_equal(new_image.data, TEST_DATA[:, :, [1]])
     self.assertEqual(new_image.channels, tuple('2'))
     # check have not altered original image
     np.testing.assert_array_equal(image.data, TEST_DATA)
     self.assertEqual(image.channels, STRING_LABELS)
Esempio n. 27
0
 def test_check_fov_id(self):
     image = mi.MibiImage(TEST_DATA, TUPLE_LABELS)
     image.fov_id = 'Point2'
     image.folder = 'Point2/RowNumber0/Depth_Profile0'
     image.fov_name = 'R1C3_Tonsil'
     with self.assertRaises(ValueError):
         image.fov_id = 'Point99'
     with self.assertRaises(ValueError):
         image.fov_id = None
Esempio n. 28
0
 def test_remove_layers_without_copy(self):
     image = mi.MibiImage(TEST_DATA, STRING_LABELS, **METADATA)
     image.remove_channels(['1', '3'])
     np.testing.assert_array_equal(image.data, TEST_DATA[:, :, [1]])
     self.assertEqual(image.channels, tuple('2'))
     metadata = METADATA.copy()
     metadata['date'] = datetime.datetime.strptime(metadata['date'],
                                                   mi._DATETIME_FORMAT)
     self.assertEqual(image.metadata(), metadata)
Esempio n. 29
0
 def test_slice_data(self):
     # Test slicing out single layer.
     im = mi.MibiImage(TEST_DATA, STRING_LABELS)
     np.testing.assert_array_equal(im.slice_data('2'), TEST_DATA[:, :, 1])
     np.testing.assert_array_equal(im.slice_data(['2']), TEST_DATA[:, :,
                                                                   [1]])
     # Test slicing out multiple layers.
     np.testing.assert_array_equal(im.slice_data(['3', '1']),
                                   TEST_DATA[:, :, [2, 0]])
Esempio n. 30
0
def read(filename, sims=True, sed=False, optical=False, label=False):
    """Reads MIBI data from an IonpathMIBI TIFF file.

    Args:
        filename: The path to the TIFF.
        sims: Boolean for whether to return the SIMS (MIBI) data. Defaults to
            True.
        sed: Boolean for whether to return the SED data. Defaults to False.
        optical: Boolean for whether to return the optical image. Defaults to
            False.
        label: Boolean for whether to return the slide label image. Defauls to
            False.

    Returns: A tuple of the image types set to True in the parameters, in the
        order SIMS, SED, Optical, Label (but including only those types
        specified). The SIMS data will be returned as a
        ``mibitof.mibi_image.MibiImage`` instance; the other image types will be
        returned as numpy arrays. If an image type is selected to be returned
        but is not present in the image, it will be returned as None.

    Raises:
        ValueError: Raised if the input file is not of the IonpathMIBI
            format, or if no image type selected to be returned.
    """
    return_types = collections.OrderedDict([('sims', sims), ('sed', sed),
                                            ('optical', optical),
                                            ('label', label)])
    if not any((val for val in return_types.values())):
        raise ValueError(
            'At least one image type must be specified to return.')
    to_return = {}
    metadata = {}
    sims_data = []
    channels = []
    with TiffFile(filename) as tif:
        _check_software(tif)
        for page in tif.pages:
            description = _page_description(page)
            image_type = description['image.type'].lower()
            if sims and image_type == 'sims':
                channels.append((description['channel.mass'],
                                 description['channel.target']))
                sims_data.append(page.asarray())
                #  Get metadata on first SIMS page only
                if not metadata:
                    metadata.update(_page_metadata(page, description))
            elif return_types.get(image_type):
                to_return[image_type] = page.asarray()
    if sims:
        to_return['sims'] = mi.MibiImage(np.stack(sims_data, axis=2), channels,
                                         **metadata)
    return_vals = tuple(
        to_return.get(key) for key, val in return_types.items() if val)
    if len(return_vals) == 1:
        return return_vals[0]
    return return_vals