Ejemplo n.º 1
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)
Ejemplo n.º 2
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)
Ejemplo n.º 3
0
    def test_write_float_tiff(self):

        tiff.write(self.filename, self.image,
                   multichannel=True, write_float=True)
        image = tiff.read(self.filename)
        self.assertEqual(image.data.dtype, np.float32)
        np.testing.assert_equal(image.data, self.image.data.astype(np.float32))
Ejemplo n.º 4
0
 def test_default_ranges(self):
     tiff.write(self.filename, self.image)
     with TiffFile(self.filename) as tif:
         for i, page in enumerate(tif.pages):
             self.assertEqual(page.tags['smin_sample_value'].value, 0)
             self.assertEqual(page.tags['smax_sample_value'].value,
                              self.image.data[:, :, i].max())
Ejemplo n.º 5
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)
Ejemplo n.º 6
0
 def test_sims_extra_masses(self):
     tiff.write(self.filename, self.float_image)
     with warnings.catch_warnings(record=True) as warns:
         image = tiff.read(self.filename, masses=[1, 2, 6])
     expected_image = tiff.read(self.filename).slice_image([1, 2])
     self.assertEqual(expected_image, image)
     messages = [str(w.message) for w in warns]
     self.assertTrue('Requested masses not found in file: [6]' in messages)
Ejemplo n.º 7
0
 def test_sims_and_sed_and_optical_and_label(self):
     tiff.write(self.filename, self.image, sed=SED, optical=CAROUSEL)
     image, sed, optical, label = tiff.read(self.filename, sed=True,
                                            optical=True, label=True)
     self.assertEqual(image, self.image)
     np.testing.assert_array_equal(sed, SED)
     np.testing.assert_array_equal(optical, CAROUSEL)
     np.testing.assert_array_equal(label, LABEL)
Ejemplo n.º 8
0
 def test_custom_ranges(self):
     ranges = list(zip([1]*5, range(2, 7)))
     tiff.write(self.filename, self.image, ranges=ranges)
     with TiffFile(self.filename) as tif:
         for i, page in enumerate(tif.pages):
             self.assertEqual(page.tags['smin_sample_value'].value,
                              ranges[i][0])
             self.assertEqual(page.tags['smax_sample_value'].value,
                              ranges[i][1])
Ejemplo n.º 9
0
 def test_write_uint16_from_float32_dtype_np_uint16(self):
     tiff.write(self.filename,
                self.float_image,
                multichannel=True,
                dtype=np.uint16)
     image = tiff.read(self.filename)
     self.assertEqual(image.data.dtype, np.uint16)
     np.testing.assert_equal(image.data,
                             self.float_image.data.astype(np.uint16))
Ejemplo n.º 10
0
 def test_page_names_non_ascii(self):
     tiff.write(self.filename,
                self.float_image_non_ascii,
                multichannel=True)
     with TiffFile(self.filename) as tif:
         for page_ind, page in enumerate(tif.pages):
             page_name_actual = page.tags['PageName'].value
             page_name_expected = CHANNELS_NON_ASCII[page_ind][1] + \
                 ' (' + str(CHANNELS_NON_ASCII[page_ind][0]) + ')'
             self.assertEqual(page_name_actual, page_name_expected)
Ejemplo n.º 11
0
 def test_write_float32_from_float32_tiff_dtype_none_non_ascii(self):
     tiff.write(self.filename,
                self.float_image_non_ascii,
                multichannel=True)
     image = tiff.read(self.filename)
     self.assertEqual(image.data.dtype, np.float32)
     np.testing.assert_equal(
         image.data, self.float_image_non_ascii.data.astype(np.float32))
     np.testing.assert_equal(image.channels,
                             self.float_image_non_ascii.channels)
Ejemplo n.º 12
0
 def test_sims_and_sed(self):
     tiff.write(self.filename, self.image, sed=SED)
     image = tiff.read(self.filename)
     self.assertEqual(image, self.image)
     sims, sed, optical, label = tiff.read(self.filename, sed=True,
                                           optical=True, label=True)
     self.assertEqual(sims, self.image)
     np.testing.assert_array_equal(sed, SED)
     self.assertIsNone(optical)
     self.assertIsNone(label)
Ejemplo n.º 13
0
 def test_read_metadata_only(self):
     tiff.write(self.filename, self.image)
     metadata = tiff.info(self.filename)
     expected = METADATA.copy()
     expected.update({
         'conjugates': list(CHANNELS),
         'date': datetime.datetime.strptime(expected['date'],
                                            '%Y-%m-%dT%H:%M:%S')
     })
     self.assertEqual(metadata, expected)
Ejemplo n.º 14
0
    def test_sims_extra_targets(self):
        tiff.write(self.filename, self.float_image)
        target = self.float_image.targets[1]

        with warnings.catch_warnings(record=True) as warns:
            image = tiff.read(self.filename, targets=['Target0', target])
        expected_image = tiff.read(self.filename).slice_image([target])
        self.assertEqual(expected_image, image)
        messages = [str(w.message) for w in warns]
        self.assertTrue(
            'Requested targets not found in file: [\'Target0\']' in messages)
Ejemplo n.º 15
0
 def test_sims_only(self):
     tiff.write(self.filename, self.image)
     image = tiff.read(self.filename)
     self.assertEqual(image, self.image)
     sims, sed, optical, label = tiff.read(self.filename, sed=True,
                                           optical=True, label=True)
     self.assertEqual(sims, self.image)
     self.assertIsNone(sed)
     self.assertIsNone(optical)
     self.assertIsNone(label)
     self.assertEqual(image.data.dtype, np.uint16)
Ejemplo n.º 16
0
    def test_read_optical_and_label_only(self):
        tiff.write(self.filename, self.image, optical=CAROUSEL)
        optical, label = tiff.read(self.filename, sims=False,
                                   optical=True, label=True)
        np.testing.assert_array_equal(optical, CAROUSEL)
        np.testing.assert_array_equal(label, LABEL)

        optical_only = tiff.read(self.filename, sims=False, optical=True)
        np.testing.assert_array_equal(optical_only, CAROUSEL)

        label_only = tiff.read(self.filename, sims=False, label=True)
        np.testing.assert_array_equal(label_only, LABEL)
Ejemplo n.º 17
0
 def test_read_metadata_with_user_defined_metadata(self):
     tiff.write(self.filename, self.image_user_defined_metadata)
     metadata = tiff.info(self.filename)
     expected = METADATA.copy()
     expected.update({
         'conjugates':
         list(CHANNELS),
         'date':
         datetime.datetime.strptime(expected['date'], '%Y-%m-%dT%H:%M:%S'),
         **USER_DEFINED_METADATA
     })
     self.assertEqual(metadata, expected)
Ejemplo n.º 18
0
    def test_sort_channels_before_writing(self):

        # Unordered indices: [2, 0, 4, 1, 3]
        unordered_channels = ((3, 'Target3'), (1, 'Target1'), (5, 'Target5'),
                              (2, 'Target2'), (4, 'Target4'))
        unordered_data = np.stack([DATA[:, :, 2], DATA[:, :, 0], DATA[:, :, 4],
                                   DATA[:, :, 1], DATA[:, :, 3]], axis=2)
        unordered_image = mi.MibiImage(unordered_data, unordered_channels,
                                       **METADATA)

        tiff.write(self.filename, unordered_image)
        image = tiff.read(self.filename)
        self.assertEqual(image, self.image)
Ejemplo n.º 19
0
 def test_read_old_mibiscope_metadata(self):
     tiff.write(self.filename, self.image_old_mibiscope_metadata)
     metadata = tiff.info(self.filename)
     expected = OLD_MIBISCOPE_METADATA.copy()
     expected.update({
         'conjugates':
         list(CHANNELS),
         'aperture':
         'B',
         'date':
         datetime.datetime.strptime(expected['date'], '%Y-%m-%dT%H:%M:%S'),
     })
     self.assertEqual(metadata, expected)
Ejemplo n.º 20
0
    def test_tiff_dtype_correct_arguments(self):
        supported_dtypes = [np.float32, np.uint16]
        for dtype in supported_dtypes:
            tiff.write(self.filename,
                       self.float_image,
                       multichannel=True,
                       dtype=dtype)

        unsupported_types = ['abcdef', np.str, np.bool, np.uint8, np.float64]
        for dtype in unsupported_types:
            with self.assertRaises(ValueError):
                tiff.write(self.filename,
                           self.float_image,
                           multichannel=True,
                           dtype=dtype)
Ejemplo n.º 21
0
    def test_write_single_channel_tiffs(self):

        basepath = os.path.split(self.filename)[0]

        tiff.write(basepath, self.image, multichannel=False)

        for i, (_, channel) in enumerate(CHANNELS):
            formatted = util.format_for_filename(channel)
            filename = os.path.join(basepath, '{}.tiff'.format(formatted))

            tif = tiff.read(filename)

            np.testing.assert_equal(np.squeeze(tif.data), DATA[:, :, i])
            self.assertTupleEqual(tif.channels, (CHANNELS[i], ))
            self.assertEqual(tif.data.dtype, np.uint16)
Ejemplo n.º 22
0
 def test_read_old_metadata(self):
     tiff.write(self.filename, self.image_old_metadata)
     metadata = tiff.info(self.filename)
     expected = METADATA.copy()
     expected.update({
         'point_name':
         OLD_METADATA['point_name'],
         'conjugates':
         list(CHANNELS),
         'date':
         datetime.datetime.strptime(expected['date'], '%Y-%m-%dT%H:%M:%S'),
         'description':
         None,
         'version':
         None
     })
     self.assertEqual(metadata, expected)
Ejemplo n.º 23
0
def _write_mibitiff(base_dir, fov_names, channel_names, shape, sub_dir, fills,
                    dtype):
    """Generates and writes mibitiffs to into base_dir

    Args:
        base_dir (str):
            Path to base directory
        fov_names (list):
            List of fov files to write
        channel_names (list):
            Channel names
        shape (tuple):
            Single image shape (x pixels, y pixels)
        sub_dir (str):
            Ignored.
        fills (bool):
            If False, data is randomized.  If True, each single image will be filled with a value
            one less than that of the next channel.  If said image is the last channel, then the
            value is one less than that of the first channel in the next fov.
        dtype (type):
            Data type for generated images

    Returns:
        tuple (dict, numpy.ndarray):

        - File locations, indexable by fov names
        - Image data as an array with shape (num_fovs, shape[0], shape[1], num_channels)
    """
    tif_data = _gen_tif_data(len(fov_names), len(channel_names), shape, fills,
                             dtype)

    filelocs = {}

    mass_map = tuple(enumerate(channel_names, 1))

    for i, fov in enumerate(fov_names):
        tif_obj = mi.MibiImage(tif_data[i, :, :, :], mass_map,
                               **MIBITIFF_METADATA)

        tiffpath = os.path.join(base_dir, f'{fov}.tiff')
        tiff.write(tiffpath, tif_obj, dtype=dtype)
        filelocs[fov] = tiffpath

    return filelocs, tif_data
Ejemplo n.º 24
0
 def test_bioformats(self):
     n = 1024
     data = np.random.randint(0, 255,
                              (n, n, len(CHANNELS_NON_ASCII))).astype(float)
     big_float_image = mi.MibiImage(data, CHANNELS_NON_ASCII, **METADATA)
     tiff.write(self.filename,
                big_float_image,
                multichannel=True,
                dtype=np.float32)
     bftools_url = ('https://downloads.openmicroscopy.org/bio-formats/'
                    '6.7.0/artifacts/bftools.zip')
     bftools_zip = os.path.basename(bftools_url)
     self.assertEqual(os.system(f'wget {bftools_url}'), 0)
     self.assertEqual(os.system(f'unzip {bftools_zip}'), 0)
     self.assertEqual(os.system(f'rm {bftools_zip}'), 0)
     # Using a convert script here since it doesn't need GUI and
     # still errors out if the MIBItiff cannot be read using the
     # bioformats plugin.
     self.assertEqual(
         os.system(f'./bftools/bfconvert {self.filename} converted.tiff'),
         0)
     self.assertEqual(os.system(f'rm -rf bftools'), 0)
     self.assertEqual(os.system(f'rm {self.filename} converted.tiff'), 0)
Ejemplo n.º 25
0
def merge_mibitiffs(input_folder, out=None):
    """Merges a folder of single-channel MIBItiff files into a single MIBItiff.

    Args:
        input_folder: Path to a folder containing MIBItiff files. While these
            files may be single-channel, they are assumed to have accurate and
            consistent MIBI metadata.
        out: Optionally, a path to a location for saving the combined TIFF. If
           not specified, defaults to 'combined.tiff' inside the input folder.
    """
    pattern = re.compile(r'.+\.tiff?$')
    paths = [
        os.path.join(input_folder, f) for f in os.listdir(input_folder)
        if re.match(pattern, f.lower())
    ]
    merged = tiff.read(paths[0])
    for path in paths[1:]:
        image = tiff.read(path)
        merged.append(image)

    if out is None:
        out = os.path.join(input_folder, 'combined.tiff')
    tiff.write(out, merged, multichannel=True)
Ejemplo n.º 26
0
 def test_write_invalid_input(self):
     # not MibiImage
     with self.assertRaises(ValueError):
         tiff.write(self.filename, DATA)
     # no coordinates
     metadata = METADATA.copy()
     del metadata['coordinates']
     image = mi.MibiImage(DATA, CHANNELS, **metadata)
     with self.assertRaises(ValueError):
         tiff.write(self.filename, image)
     # no size
     metadata = METADATA.copy()
     del metadata['size']
     image = mi.MibiImage(DATA, CHANNELS, **metadata)
     with self.assertRaises(ValueError):
         tiff.write(self.filename, image)
     # string rather than tuple channels
     channels = [c[1] for c in CHANNELS]
     image = mi.MibiImage(DATA, channels, **METADATA)
     with self.assertRaises(ValueError):
         tiff.write(self.filename, image)
    'scans': '0,5',
    'folder': 'Point1/RowNumber0/Depth_Profile0',
    'aperture': '300um',
    'instrument': 'MIBIscope1',
    'tissue': 'Random',
    'panel': '20100101_1x',
    'version': None,
    'mass_offset': 0.1,
    'mass_gain': 0.2,
    'time_resolution': 0.5,
    'miscalibrated': False,
    'check_reg': False,
    'filename': '20191113_random_old_metadata'
}

# create MibiImage with random data
np.random.seed(2468)
random_channel_data = np.random.randint(0,
                                        65535, (128, 128, 3),
                                        dtype=np.uint16)
channels = ['Channel 1', 'Channel 2', 'Channel 3']
random_mibi_image = mi.MibiImage(random_channel_data, channels, **OLD_METADATA)
# INFO: use old software if tiff should be saved with old metadata format
#       (before version '1.0')

# save a tiff
out_file_name = random_mibi_image.filename + '.tiff'
if SAVE_OUTPUT:
    print(f'Saving image to {out_file_name}')
    tiff.write(out_file_name, new_image)
Ejemplo n.º 28
0
 def test_read_with_invalid_return_types(self):
     tiff.write(self.filename, self.image)
     with self.assertRaises(ValueError):
         tiff.read(self.filename, sims=False)
Ejemplo n.º 29
0
def create_mibitiffs(input_folder,
                     run_path,
                     point,
                     panel_path,
                     slide,
                     size,
                     run_label=None,
                     instrument=None,
                     tissue=None,
                     aperture=None,
                     out=None):
    """Combines single-channel TIFFs into a MIBItiff.

    The input TIFFs are not assumed to have any MIBI metadata. If they do, it
    is suggested to use the simpler :meth:`~merge_mibitiffs` instead.

    Args:
        input_folder: Path to a folder containing single-channel TIFFs.
        run_path: Path to a run xml.
        point: Point name of the image, e.g. Point1 or Point2. This should match
            the name of folder generated for the raw data as it is listed in the
            run xml file.
        panel_path: Path to a panel CSV.
        slide: The slide ID.
        size: The size of the FOV in microns, i.e. 500.
        run_label: Optional custom run label for the combined TIFF. If uploading
            the output to MIBItracker, the run label set here must match the
            label of the MIBItracker run. Defaults to the name of the run xml.
        instrument: Optionally, the instrument ID.
        tissue: Optionally, the name of tissue.
        aperture: Optionally, the name of the aperture or imaging preset.
        out: Optionally, a path to a location for saving the combined TIFF. If
           not specified, defaults to 'combined.tiff' inside the input folder.
        run_label: Optionally, a custom run label for the `run` property of the
            image.
    """
    panel_df = panels.read_csv(panel_path)
    panel_name, _ = os.path.splitext(os.path.basename(panel_path))
    tiff_files = os.listdir(input_folder)

    fovs, calibration = runs.parse_xml(run_path)
    point_number = int(point[5:])
    try:
        fov = fovs[point_number - 1]  # point number is 1-based, not 0-based
    except IndexError:
        raise IndexError('{} not found in run xml.'.format(point))
    if fov['date']:
        run_date = datetime.datetime.strptime(fov['date'],
                                              '%Y-%m-%dT%H:%M:%S').date()
    else:
        run_date = datetime.datetime.now().date()

    image_data = []
    for i in panel_df.index:
        tiff_path = os.path.join(
            input_folder,
            _match_target_filename(tiff_files, panel_df['Target'][i]))
        data = _load_single_channel(tiff_path)
        image_data.append(data)

    image_data = np.stack(image_data, axis=2)

    image = mi.MibiImage(image_data,
                         list(zip(panel_df['Mass'], panel_df['Target'])))

    image.size = int(size)
    image.coordinates = (fov['coordinates'])
    image.filename = fov['run']
    image.run = run_label if run_label else fov['run']
    image.version = tiff.SOFTWARE_VERSION
    image.instrument = instrument
    image.slide = slide
    image.dwell = fov['dwell']
    image.scans = fov['scans']
    image.aperture = aperture
    image.point_name = fov['point_name']
    image.folder = fov['folder']
    image.tissue = tissue
    image.panel = panel_name
    image.date = run_date
    image.mass_offset = calibration['MassOffset']
    image.mass_gain = calibration['MassGain']
    image.time_resolution = calibration['TimeResolution']

    if out is None:
        out = os.path.join(input_folder, 'combined.tiff')

    tiff.write(out, image, multichannel=True)
Ejemplo n.º 30
0
 def test_read_sed_only(self):
     tiff.write(self.filename, self.image, sed=SED)
     sed = tiff.read(self.filename, sims=False, sed=True)
     np.testing.assert_array_equal(sed, SED)