示例#1
0
def test_bgr_plane_data_x(data_dir, fname, p_index, ans_file):
    ans = np.load(data_dir / ans_file)
    with open(data_dir / fname, 'rb') as fp:
        czi = CziFile(czi_filename=fp)
        img, dims = czi.read_image()
        assert img[0, p_index, :, :].shape == ans.shape
        np.testing.assert_array_almost_equal(img[0, p_index, :, :], ans)
示例#2
0
def read(filename: str) -> Tuple[np.ndarray, czimd.CziMetadata]:
    """Read the pixel data of an CZI image file. Scaling factor
    of 1.0 will be used.

    :param filename: filename of the CZI to be read
    :return: CZI pixel data and the CziMetadata class
    """

    # get the CZI metadata
    md = czimd.CziMetadata(filename)

    # read CZI using aicspylibczi
    aicsczi = CziFile(filename)

    # in case of a non-mosaic CZI file
    if not aicsczi.is_mosaic():

        # get all scenes
        all_scenes, md = read_nonmosaic(filename=filename)

    # in case of a mosaic CZI file
    if aicsczi.is_mosaic():

        # get all scenes
        all_scenes, md = read_mosaic(filename=filename, scale=1.0)

    return all_scenes, md
def _read_image(
    img: Path,
    read_dims: Optional[Dict[str, int]] = None
) -> Tuple[np.ndarray, List[Tuple[str, int]]]:
    # Catch optional read dim
    if read_dims is None:
        read_dims = {}

    # Init czi
    czi = CziFile(img)

    # Read image
    log.debug(f"Reading dimensions: {read_dims}")
    data, dims = czi.read_image(**read_dims)

    # Drop dims that shouldn't be provided back
    ops = []
    real_dims = []
    for i, dim_info in enumerate(dims):
        # Expand dimension info
        dim, size = dim_info

        # If the dim was provided in the read dims we know a single plane for that
        # dimension was requested so remove it
        if dim in read_dims:
            ops.append(0)
        # Otherwise just read the full slice
        else:
            ops.append(slice(None, None, None))
            real_dims.append(dim_info)

    # Convert ops and run getitem
    return data[tuple(ops)], real_dims
示例#4
0
def test_mosaic_image_two(data_dir, fname, expects):
    with open(data_dir / fname, 'rb') as fp:
        czi = CziFile(czi_filename=fp)
        sze = czi.read_mosaic_size()
        rgion = (sze[0], sze[1], int(sze[2] / 2), int(sze[3] / 2))
        img = czi.read_mosaic(region=rgion, C=0, M=0)
    assert img.shape == expects
示例#5
0
def read_nonmosaic(filename: str) -> Tuple[Union[np.ndarray, None], czimd.CziMetadata]:
    """Read CZI pixel data from non-mosaic image data
    :param filename: filename of the CZI file to be read
    :return: CZI pixel data and the CziMetadata class
    """

    # get the CZI metadata
    md = czimd.CziMetadata(filename)

    # read CZI using aicspylibczi
    aicsczi = CziFile(filename)

    if aicsczi.is_mosaic():
        # check if this CZIn is really a non-mosaic file
        print("CZI is a mosaic file. Please use the readczi_mosaic method instead")
        return None, md

    # get the shape for the 1st scene
    scene = czimd.CziScene(aicsczi, sceneindex=0)
    shape_all = scene.shape_single_scene

    # only update the shape for the scene if the CZI has an S-Dimension
    if scene.hasS:
        shape_all[scene.posS] = md.dims.SizeS

    print("Shape all Scenes : ", shape_all)
    print("DimString all Scenes : ", scene.single_scene_dimstr)

    # create an empty array with the correct dimensions
    all_scenes = np.empty(aicsczi.size, dtype=md.npdtype)

    # loop over scenes if CZI is not a mosaic image
    if md.dims.SizeS is None:
        sizeS = 1
    else:
        sizeS = md.dims.SizeS

    for s in range(sizeS):

        # read the image stack for the current scene
        current_scene, shp = aicsczi.read_image(S=s)

        # create th index lists containing the slice objects
        if scene.hasS:
            idl_scene = [slice(None, None, None)] * (len(all_scenes.shape) - 2)
            idl_scene[aicsczi.dims.index("S")] = 0
            idl_all = [slice(None, None, None)] * (len(all_scenes.shape) - 2)
            idl_all[aicsczi.dims.index("S")] = s

            # cast current stack into the stack for all scenes
            all_scenes[tuple(idl_all)] = current_scene[tuple(idl_scene)]

        # if there is no S-Dimension use the stack directly
        if not scene.hasS:
            all_scenes = current_scene

    print("Shape all scenes (no mosaic)", all_scenes.shape)

    return all_scenes, md
示例#6
0
def test_mosaic_image(data_dir, fname, expects):
    with open(data_dir / fname, 'rb') as fp:
        czi = CziFile(czi_filename=fp)
        sze = czi.read_mosaic_size()
        assert sze[2] == 1756
        assert sze[3] == 624
        img = czi.read_mosaic(scale_factor=0.1, C=0)
    assert img.shape[0] == 1
示例#7
0
def test_read_image_from_istream(data_dir, fname, expected_img_shape,
                                 expected_img_dims):
    with open(data_dir / fname, 'rb') as fp:
        czi = CziFile(czi_filename=fp)
        assert czi.shape_is_consistent
        data = czi.read_image()
        assert data[0].shape == expected_img_shape
        assert data[1] == expected_img_dims
示例#8
0
    def _daread_safe(
        img: Union[str, Path],
        chunk_by_dims: List[str] = [
            Dimensions.SpatialZ,
            Dimensions.SpatialY,
            Dimensions.SpatialX,
        ],
        S: int = 0,
    ) -> Tuple[da.core.Array, str]:
        """
        Safely read a CZI image file as a delayed dask array where certain dimensions
        act as the chunk size.

        Parameters
        ----------
        img: Union[str, Path]
            The filepath to read.
        chunk_by_dims: List[str]
            The dimensions to use as the for mapping the chunks / blocks.
            Default: [Dimensions.SpatialZ, Dimensions.SpatialY, Dimensions.SpatialX]
            Note: SpatialY and SpatialX will always be added to the list if not present.
        S: int
            If the image has different dimensions on any scene from another, the dask
            array construction will fail.
            In that case, use this parameter to specify a specific scene to construct a
            dask array for.
            Default: 0 (select the first scene)

        Returns
        -------
        img: dask.array.core.Array
            The constructed dask array where certain dimensions are chunked.
        dims: str
            The dimension order as a string.
        """
        # Resolve image path
        img = CziReader._resolve_image_path(img)

        # Init temp czi
        czi = CziFile(img)

        # Safely construct the dask array or catch any exception
        try:
            return CziReader._daread(img=img,
                                     czi=czi,
                                     chunk_by_dims=chunk_by_dims,
                                     S=S)

        except Exception as e:
            # A really bad way to close any connection to the CZI object
            czi._bytes = None
            czi.reader = None

            raise e
示例#9
0
    def _read_image(
        img: Path,
        read_dims: Optional[Dict[str, int]] = None
    ) -> Tuple[np.ndarray, List[Tuple[str, int]]]:
        """
        Read and return the squeezed image data requested along with the dimension info
        that was read.

        Parameters
        ----------
        img: Path
            Path to the CZI file to read.
        read_dims: Optional[Dict[str, int]]
            The dimensions to read from the file as a dictionary of string to integer.
            Default: None (Read all data from the image)

        Returns
        -------
        data: np.ndarray
            The data read for the dimensions provided.
        read_dimensions: List[Tuple[str, int]]]
            The dimension sizes that were returned from the read.
        """
        # Catch optional read dim
        if read_dims is None:
            read_dims = {}

        # Init czi
        czi = CziFile(img)

        # Read image
        log.debug(f"Reading dimensions: {read_dims}")
        data, dims = czi.read_image(**read_dims)

        # Drop dims that shouldn't be provided back
        ops = []
        real_dims = []
        for i, dim_info in enumerate(dims):
            # Expand dimension info
            dim, size = dim_info

            # If the dim was provided in the read dims we know a single plane for that
            # dimension was requested so remove it
            if dim in read_dims:
                ops.append(0)
            # Otherwise just read the full slice
            else:
                ops.append(slice(None, None, None))
                real_dims.append(dim_info)

        # Convert ops and run getitem
        return data[tuple(ops)], real_dims
示例#10
0
 def __init__(self, slide_path: str):
     self.slide_path = slide_path
     reader = CziFile(slide_path)
     if not reader.is_mosaic():
         raise NotImplementedError(
             'This class has only been defined for mosaic czi files. '
             'You should be able to simply convert the non-mosaic czi-file '
             'into a format that can be opened with openslide.'
         )
     self.bboxes = np.array(reader.mosaic_scene_bounding_boxes())
     self.data_mask = self._get_data_mask(self.bboxes)
     self.shape = reader.read_mosaic_size()
     self.dimensions = self.shape[2:]
     self.region_mask = self._get_region_mask(self.shape)
示例#11
0
def test_metadata(data_dir, fname, xp_query, expected):
    czi = CziFile(str(data_dir / fname), metafile_out="tmp.txt")
    meta = czi.meta
    vs = meta.find(xp_query)
    assert int(vs.text) == expected
    meta = czi.meta
    vs = meta.find(xp_query)
    assert int(vs.text) == expected
示例#12
0
    def metadata(self) -> _Element:
        """
        Load and return the metadata from the CZI file

        Returns
        -------
        The lxml Element Tree of the metadata
        """
        # We can't serialize lxml element trees so don't save the tree to the object state
        return CziFile(self._file).meta
示例#13
0
    def _read_immediate(self) -> da.core.Array:
        # Init temp czi
        czi = CziFile(self._file)

        # Safely construct the numpy array or catch any exception
        try:
            # Get image dims indicies
            image_dim_indices = czi.dims_shape()

            # Catch inconsistent scene dimension sizes
            if len(image_dim_indices) > 1:
                # Choose the provided scene
                log.info(
                    f"File contains variable dimensions per scene, "
                    f"selected scene: {self.specific_s_index} for data retrieval."
                )

                # Get the specific scene
                if self.specific_s_index < len(image_dim_indices):
                    data, _ = czi.read_image(
                        **{Dimensions.Scene: self.specific_s_index})
                else:
                    raise exceptions.InconsistentShapeError(
                        f"The CZI image provided has variable dimensions per scene. "
                        f"Please provide a valid index to the 'S' parameter to create "
                        f"a dask array for the index provided. "
                        f"Provided scene index: {self.specific_s_index}. "
                        f"Scene index range: 0-{len(image_dim_indices)}.")

            else:
                # If the list is length one that means that all the scenes in the image
                # have the same dimensions
                # Read all data in the image
                data, _ = czi.read_image()

                # A really bad way to close any connection to the CZI object
                czi._bytes = None
                czi.reader = None

        except Exception as e:
            # A really bad way to close any connection to the CZI object
            czi._bytes = None
            czi.reader = None

            raise e

        return data
示例#14
0
def load_tile(coords, slide_path, data_mask,
              region_mask, width, downsample, fast):
    """Load a tile from the czi-file (parallizeable)."""
    # Load reader.
    reader = CziFile(slide_path)
    # Unpack coords.
    i, (x, y) = coords
    # Define final out_shape.
    out_shape = (int(width/downsample), int(width/downsample))
    # Get data and region percentages.
    tile_mask = Polygon(
        [[x, y], [x+width, y], [x+width, y+width], [x, y+width], [x, y]])
    intersection = tile_mask.intersection(data_mask)
    data_perc = intersection.area/tile_mask.area
    region_perc = tile_mask.intersection(region_mask).area/tile_mask.area
    if data_perc < 0.05 or region_perc < 1:
        # Return empty image.
        tile = np.ones(out_shape + (3,)) * 255
    else:
        # Load tile.
        bbox = (x, y, width, width)
        if fast:
            tile = reader.read_mosaic(bbox, C=0, scale_factor=1/downsample)
        else:
            tile = reader.read_mosaic(bbox, C=0)
        if tile.shape[0] == 1:
            # Something is wrong with the tile...
            tile = np.ones(out_shape + (3,)) * 255
        else:
            tile = np.moveaxis(tile, 0, 2)
            tile = cv2.resize(tile, out_shape, cv2.INTER_LANCZOS4)
            if data_perc < 1:
                mask = polygon_to_mask(intersection, x, y, width, downsample)
                mask = cv2.resize(mask, out_shape, cv2.INTER_LANCZOS4)
                tile[mask == 0] = 255
    tile = tile.astype(np.uint8)
    return i, tile
示例#15
0
def test_read_image_mosaic(data_dir, fname):
    czi = CziFile(str(data_dir / fname))
    czi.read_image(M=0)
    assert True
示例#16
0
def test_mosaic_subblock_rect(data_dir, fname, s_index, m_index, expected):
    with open(data_dir / fname, 'rb') as fp:
        czi = CziFile(czi_filename=fp)
        data = czi.mosaic_scene_bounding_boxes(s_index)
        assert data == expected
示例#17
0
def test_cores_arg():
    assert CziFile._get_cores_from_kwargs({'cores': 4}) == 4
示例#18
0
def test_subblock_rect(data_dir, fname, s_index, m_index, expected):
    with open(data_dir / fname, 'rb') as fp:
        czi = CziFile(czi_filename=fp)
        args = {'S': s_index} if m_index < 0 else {'S': s_index, 'M': m_index}
        data = czi.read_subblock_rect(**args)
        assert data == expected
示例#19
0
def test_collected_by(data_dir, filename, expected_creator):
    czi = CziFile(data_dir / filename)
    assert czi_metadata.created_by(czi) == expected_creator
示例#20
0
    for d in dims:

        dims_dict[d] = dimstring.find(d)
        dimindex_list.append(dimstring.find(d))

    numvalid_dims = sum(i > 0 for i in dimindex_list)

    return dims_dict, dimindex_list, numvalid_dims


filename = r"C:\Temp\input\DTScan_ID4.czi"

md, addmd = imf.get_metadata(filename)

czi = CziFile(filename)

# Get the shape of the data, the coordinate pairs are (start index, size)
dimensions = czi.dims_shape()
print(dimensions)
print(czi.dims)
print(czi.size)
print(czi.is_mosaic())  # True
# Mosaic files ignore the S dimension and use an internal mIndex to reconstruct, the scale factor allows one to generate a manageable image
mosaic_data = czi.read_mosaic(C=0, scale_factor=1)
print('CZI Mosaic Data Shape : ', mosaic_data.shape)

md = {}
md['SizeS'] = 1
md['SizeT'] = 3
md['SizeZ'] = 5
示例#21
0
    hasZ = True

if use_aicsimageio:
    img = AICSImage(filename)

    if use_dask_delayed:
        print('Using AICSImageIO to read the image (Dask Delayed Reader).')
        all_scenes_array = img.get_image_data()
    if not use_dask_delayed:
        print('Using AICSImageIO to read the image.')
        all_scenes_array = img.get_image_dask_data()

if not use_aicsimageio and use_pylibczi is True:

    # read CZI using aicspylibczi
    czi = CziFile(filename)

    # for testing
    # Get the shape of the data
    print('Dimensions   : ', czi.dims)
    print('Size         : ', czi.size)
    print('Shape        : ', czi.dims_shape())
    print('IsMoasic     : ', czi.is_mosaic())
    if czi.is_mosaic():
        print('Mosaic Size  : ', czi.read_mosaic_size())

    # get the required shape for all and single scenes
    shape_all, shape_single, same_shape = czt.get_shape_allscenes(czi, md)
    print('Required_Array Shape for all scenes: ', shape_all)
    for sh in shape_single:
        print('Required Array Shape for single scenes: ', sh)
示例#22
0
def test_read_image_two(data_dir, fname, exp_str, exp_dict):
    czi = CziFile(str(data_dir / fname))
    dims = czi.dims
    dim_dict = czi.dims_shape()
    assert dims == exp_str
    assert dim_dict == exp_dict
示例#23
0
def test_read_dims_sizes(data_dir, fname, expected):
    with open(data_dir / fname, 'rb') as fp:
        czi = CziFile(czi_filename=fp)
        data = czi.size
        assert data == expected
示例#24
0
def test_read_subblock_meta(data_dir, fname, expected):
    with open(data_dir / fname, 'rb') as fp:
        czi = CziFile(czi_filename=fp)
        data = czi.read_subblock_metadata()
        assert expected in data[0][1]
示例#25
0
def get_metadata_czi(filename, dim2none=False,
                     forceDim=False,
                     forceDimname='SizeC',
                     forceDimvalue=2,
                     convert_scunit=True):
    """
    Returns a dictionary with CZI metadata.

    Information CZI Dimension Characters:
    - '0': 'Sample',  # e.g. RGBA
    - 'X': 'Width',
    - 'Y': 'Height',
    - 'C': 'Channel',
    - 'Z': 'Slice',  # depth
    - 'T': 'Time',
    - 'R': 'Rotation',
    - 'S': 'Scene',  # contiguous regions of interest in a mosaic image
    - 'I': 'Illumination',  # direction
    - 'B': 'Block',  # acquisition
    - 'M': 'Mosaic',  # index of tile for compositing a scene
    - 'H': 'Phase',  # e.g. Airy detector fibers
    - 'V': 'View',  # e.g. for SPIM

    :param filename: filename of the CZI image
    :type filename: str
    :param dim2none: option to set non-existing dimension to None, defaults to False
    :type dim2none: bool, optional
    :param forceDim: option to force to not read certain dimensions, defaults to False
    :type forceDim: bool, optional
    :param forceDimname: name of the dimension not to read, defaults to SizeC
    :type forceDimname: str, optional
    :param forceDimvalue: index of the dimension not to read, defaults to 2
    :type forceDimvalue: int, optional      
    :param convert_scunit: convert scale unit string from 'µm' to 'micron', defaults to False
    :type convert_scunit: bool, optional  
    :return: metadata - dictionary with the relevant CZI metainformation
    :rtype: dict
    """

    # get CZI object
    czi = zis.CziFile(filename)

    # parse the XML into a dictionary
    metadatadict_czi = czi.metadata(raw=False)

    # initialize metadata dictionary
    metadata = create_metadata_dict()

    # get directory and filename etc.
    metadata['Directory'] = os.path.dirname(filename)
    metadata['Filename'] = os.path.basename(filename)
    metadata['Extension'] = 'czi'
    metadata['ImageType'] = 'czi'

    # add axes and shape information using czifile package
    metadata['Axes_czifile'] = czi.axes
    metadata['Shape_czifile'] = czi.shape

    # add axes and shape information using aicsimageio package
    czi_aics = AICSImage(filename)
    metadata['Axes_aics'] = czi_aics.dims
    try:
        metadata['Shape_aics'] = czi_aics.shape
        metadata['SizeX_aics'] = czi_aics.size_x
        metadata['SizeY_aics'] = czi_aics.size_y
        metadata['SizeC_aics'] = czi_aics.size_c
        metadata['SizeZ_aics'] = czi_aics.size_t
        metadata['SizeT_aics'] = czi_aics.size_t
        metadata['SizeS_aics'] = czi_aics.size_s
    except KeyError as e:
        metadata['Shape_aics'] = None
        metadata['SizeX_aics'] = None
        metadata['SizeY_aics'] = None
        metadata['SizeC_aics'] = None
        metadata['SizeZ_aics'] = None
        metadata['SizeT_aics'] = None
        metadata['SizeS_aics'] = None

    # get additional data by using pylibczi directly
    # Get the shape of the data, the coordinate pairs are (start index, size)
    aics_czi = CziFile(filename)
    metadata['dims_aicspylibczi'] = aics_czi.dims_shape()[0]
    metadata['dimorder_aicspylibczi'] = aics_czi.dims
    metadata['size_aicspylibczi'] = aics_czi.size
    metadata['czi_isMosaic'] = aics_czi.is_mosaic()

    # determine pixel type for CZI array
    metadata['NumPy.dtype'] = czi.dtype

    # check if the CZI image is an RGB image depending
    # on the last dimension entry of axes
    if czi.shape[-1] == 3:
        metadata['czi_isRGB'] = True

    try:
        metadata['PixelType'] = metadatadict_czi['ImageDocument']['Metadata']['Information']['Image']['PixelType']
    except KeyError as e:
        print('Key not found:', e)
        metadata['PixelType'] = None
    try:
        metadata['SizeX'] = np.int(metadatadict_czi['ImageDocument']['Metadata']['Information']['Image']['SizeX'])
    except KeyError as e:
        metadata['SizeX'] = None
    try:
        metadata['SizeY'] = np.int(metadatadict_czi['ImageDocument']['Metadata']['Information']['Image']['SizeY'])
    except KeyError as e:
        metadata['SizeY'] = None

    try:
        metadata['SizeZ'] = np.int(metadatadict_czi['ImageDocument']['Metadata']['Information']['Image']['SizeZ'])
    except Exception as e:
        # print('Exception:', e)
        if dim2none:
            metadata['SizeZ'] = None
        if not dim2none:
            metadata['SizeZ'] = 1

    # for special cases do not read the SizeC from the metadata
    if forceDim and forceDimname == 'SizeC':
        metadata[forceDimname] = forceDimvalue

    if not forceDim:

        try:
            metadata['SizeC'] = np.int(metadatadict_czi['ImageDocument']['Metadata']['Information']['Image']['SizeC'])
        except Exception as e:
            # print('Exception:', e)
            if dim2none:
                metadata['SizeC'] = None
            if not dim2none:
                metadata['SizeC'] = 1

    # create empty lists for channel related information
    channels = []
    channels_names = []
    channels_colors = []

    # in case of only one channel
    if metadata['SizeC'] == 1:
        # get name for dye
        try:
            channels.append(metadatadict_czi['ImageDocument']['Metadata']['DisplaySetting']
                                            ['Channels']['Channel']['ShortName'])
        except KeyError as e:
            print('Exception:', e)
            try:
                channels.append(metadatadict_czi['ImageDocument']['Metadata']['DisplaySetting']
                                ['Channels']['Channel']['DyeName'])
            except KeyError as e:
                print('Exception:', e)
                channels.append('Dye-CH1')

        # get channel name
        try:
            channels_names.append(metadatadict_czi['ImageDocument']['Metadata']['DisplaySetting']
                                  ['Channels']['Channel']['Name'])
        except KeyError as e:
            print('Exception:', e)
            channels_names.append['CH1']

        # get channel color
        try:
            channels_colors.append(metadatadict_czi['ImageDocument']['Metadata']['DisplaySetting']
                                   ['Channels']['Channel']['Color'])
        except KeyError as e:
            print('Exception:', e)
            channels_colors.append('#80808000')

    # in case of two or more channels
    if metadata['SizeC'] > 1:
        # loop over all channels
        for ch in range(metadata['SizeC']):
            # get name for dyes
            try:
                channels.append(metadatadict_czi['ImageDocument']['Metadata']['DisplaySetting']
                                                ['Channels']['Channel'][ch]['ShortName'])
            except KeyError as e:
                print('Exception:', e)
                try:
                    channels.append(metadatadict_czi['ImageDocument']['Metadata']['DisplaySetting']
                                                    ['Channels']['Channel'][ch]['DyeName'])
                except KeyError as e:
                    print('Exception:', e)
                    channels.append('Dye-CH' + str(ch))

            # get channel names
            try:
                channels_names.append(metadatadict_czi['ImageDocument']['Metadata']['DisplaySetting']
                                      ['Channels']['Channel'][ch]['Name'])
            except KeyError as e:
                print('Exception:', e)
                channels_names.append('CH' + str(ch))

            # get channel colors
            try:
                channels_colors.append(metadatadict_czi['ImageDocument']['Metadata']['DisplaySetting']
                                       ['Channels']['Channel'][ch]['Color'])
            except KeyError as e:
                print('Exception:', e)
                # use grayscale instead
                channels_colors.append('80808000')

    # write channels information (as lists) into metadata dictionary
    metadata['Channels'] = channels
    metadata['ChannelNames'] = channels_names
    metadata['ChannelColors'] = channels_colors

    try:
        metadata['SizeT'] = np.int(metadatadict_czi['ImageDocument']['Metadata']['Information']['Image']['SizeT'])
    except Exception as e:
        # print('Exception:', e)
        if dim2none:
            metadata['SizeT'] = None
        if not dim2none:
            metadata['SizeT'] = 1

    try:
        metadata['SizeM'] = np.int(metadatadict_czi['ImageDocument']['Metadata']['Information']['Image']['SizeM'])
    except Exception as e:
        # print('Exception:', e)
        if dim2none:
            metadata['SizeM'] = None
        if not dim2none:
            metadata['SizeM'] = 1

    try:
        metadata['SizeB'] = np.int(metadatadict_czi['ImageDocument']['Metadata']['Information']['Image']['SizeB'])
    except Exception as e:
        # print('Exception:', e)
        if dim2none:
            metadata['SizeB'] = None
        if not dim2none:
            metadata['SizeB'] = 1

    try:
        metadata['SizeS'] = np.int(metadatadict_czi['ImageDocument']['Metadata']['Information']['Image']['SizeS'])
    except Exception as e:
        # print('Exception:', e)
        if dim2none:
            metadata['SizeS'] = None
        if not dim2none:
            metadata['SizeS'] = 1

    try:
        metadata['SizeH'] = np.int(metadatadict_czi['ImageDocument']['Metadata']['Information']['Image']['SizeH'])
    except Exception as e:
        # print('Exception:', e)
        if dim2none:
            metadata['SizeH'] = None
        if not dim2none:
            metadata['SizeH'] = 1

    try:
        metadata['SizeI'] = np.int(metadatadict_czi['ImageDocument']['Metadata']['Information']['Image']['SizeI'])
    except Exception as e:
        # print('Exception:', e)
        if dim2none:
            metadata['SizeI'] = None
        if not dim2none:
            metadata['SizeI'] = 1

    try:
        metadata['SizeV'] = np.int(metadatadict_czi['ImageDocument']['Metadata']['Information']['Image']['SizeV'])
    except Exception as e:
        # print('Exception:', e)
        if dim2none:
            metadata['SizeV'] = None
        if not dim2none:
            metadata['SizeV'] = 1

    # get the scaling information
    try:
        # metadata['Scaling'] = metadatadict_czi['ImageDocument']['Metadata']['Scaling']
        metadata['XScale'] = float(metadatadict_czi['ImageDocument']['Metadata']['Scaling']['Items']['Distance'][0]['Value']) * 1000000
        metadata['YScale'] = float(metadatadict_czi['ImageDocument']['Metadata']['Scaling']['Items']['Distance'][1]['Value']) * 1000000
        metadata['XScale'] = np.round(metadata['XScale'], 3)
        metadata['YScale'] = np.round(metadata['YScale'], 3)
        try:
            metadata['XScaleUnit'] = metadatadict_czi['ImageDocument']['Metadata']['Scaling']['Items']['Distance'][0]['DefaultUnitFormat']
            metadata['YScaleUnit'] = metadatadict_czi['ImageDocument']['Metadata']['Scaling']['Items']['Distance'][1]['DefaultUnitFormat']
        except KeyError as e:
            print('Key not found:', e)
            metadata['XScaleUnit'] = None
            metadata['YScaleUnit'] = None
        try:
            metadata['ZScale'] = float(metadatadict_czi['ImageDocument']['Metadata']['Scaling']['Items']['Distance'][2]['Value']) * 1000000
            metadata['ZScale'] = np.round(metadata['ZScale'], 3)
            # additional check for faulty z-scaling
            if metadata['ZScale'] == 0.0:
                metadata['ZScale'] = 1.0
            try:
                metadata['ZScaleUnit'] = metadatadict_czi['ImageDocument']['Metadata']['Scaling']['Items']['Distance'][2]['DefaultUnitFormat']
            except KeyError as e:
                print('Key not found:', e)
                metadata['ZScaleUnit'] = metadata['XScaleUnit']
        except Exception as e:
            # print('Exception:', e)
            if dim2none:
                metadata['ZScale'] = None
                metadata['ZScaleUnit'] = None
            if not dim2none:
                # set to isotropic scaling if it was single plane only
                metadata['ZScale'] = metadata['XScale']
                metadata['ZScaleUnit'] = metadata['XScaleUnit']
    except Exception as e:
        print('Exception:', e)
        print('Scaling Data could not be found.')

    # try to get software version
    try:
        metadata['SW-Name'] = metadatadict_czi['ImageDocument']['Metadata']['Information']['Application']['Name']
        metadata['SW-Version'] = metadatadict_czi['ImageDocument']['Metadata']['Information']['Application']['Version']
    except KeyError as e:
        print('Key not found:', e)
        metadata['SW-Name'] = None
        metadata['SW-Version'] = None

    try:
        metadata['AcqDate'] = metadatadict_czi['ImageDocument']['Metadata']['Information']['Image']['AcquisitionDateAndTime']
    except KeyError as e:
        print('Key not found:', e)
        metadata['AcqDate'] = None

    # check if Instrument metadat actually exist
    if pydash.objects.has(metadatadict_czi, ['ImageDocument', 'Metadata', 'Information', 'Instrument']):
        # get objective data
        if isinstance(metadatadict_czi['ImageDocument']['Metadata']['Information']['Instrument']['Objectives']['Objective'], list):
            num_obj = len(metadatadict_czi['ImageDocument']['Metadata']['Information']['Instrument']['Objectives']['Objective'])
        else:
            num_obj = 1

        # if there is only one objective found
        if num_obj == 1:
            try:
                metadata['ObjName'].append(metadatadict_czi['ImageDocument']['Metadata']['Information']
                                           ['Instrument']['Objectives']['Objective']['Name'])
            except KeyError as e:
                print('Key not found:', e)
                metadata['ObjName'].append(None)

            try:
                metadata['ObjImmersion'] = metadatadict_czi['ImageDocument']['Metadata']['Information']['Instrument']['Objectives']['Objective']['Immersion']
            except KeyError as e:
                print('Key not found:', e)
                metadata['ObjImmersion'] = None

            try:
                metadata['ObjNA'] = np.float(metadatadict_czi['ImageDocument']['Metadata']['Information']
                                             ['Instrument']['Objectives']['Objective']['LensNA'])
            except KeyError as e:
                print('Key not found:', e)
                metadata['ObjNA'] = None

            try:
                metadata['ObjID'] = metadatadict_czi['ImageDocument']['Metadata']['Information']['Instrument']['Objectives']['Objective']['Id']
            except KeyError as e:
                print('Key not found:', e)
                metadata['ObjID'] = None

            try:
                metadata['TubelensMag'] = np.float(metadatadict_czi['ImageDocument']['Metadata']['Information']
                                                   ['Instrument']['TubeLenses']['TubeLens']['Magnification'])
            except KeyError as e:
                print('Key not found:', e, 'Using Default Value = 1.0 for Tublens Magnification.')
                metadata['TubelensMag'] = 1.0

            try:
                metadata['ObjNominalMag'] = np.float(metadatadict_czi['ImageDocument']['Metadata']['Information']
                                                     ['Instrument']['Objectives']['Objective']['NominalMagnification'])
            except KeyError as e:
                print('Key not found:', e, 'Using Default Value = 1.0 for Nominal Magnification.')
                metadata['ObjNominalMag'] = 1.0

            try:
                if metadata['TubelensMag'] is not None:
                    metadata['ObjMag'] = metadata['ObjNominalMag'] * metadata['TubelensMag']
                if metadata['TubelensMag'] is None:
                    print('No TublensMag found. Use 1 instead')
                    metadata['ObjMag'] = metadata['ObjNominalMag'] * 1.0

            except KeyError as e:
                print('Key not found:', e)
                metadata['ObjMag'] = None

        if num_obj > 1:
            for o in range(num_obj):

                try:
                    metadata['ObjName'].append(metadatadict_czi['ImageDocument']['Metadata']['Information']
                                               ['Instrument']['Objectives']['Objective'][o]['Name'])
                except KeyError as e:
                    print('Key not found:', e)
                    metadata['ObjName'].append(None)

                try:
                    metadata['ObjImmersion'].append(metadatadict_czi['ImageDocument']['Metadata']['Information']
                                                    ['Instrument']['Objectives']['Objective'][o]['Immersion'])
                except KeyError as e:
                    print('Key not found:', e)
                    metadata['ObjImmersion'].append(None)

                try:
                    metadata['ObjNA'].append(np.float(metadatadict_czi['ImageDocument']['Metadata']['Information']
                                                      ['Instrument']['Objectives']['Objective'][o]['LensNA']))
                except KeyError as e:
                    print('Key not found:', e)
                    metadata['ObjNA'].append(None)

                try:
                    metadata['ObjID'].append(metadatadict_czi['ImageDocument']['Metadata']['Information']
                                             ['Instrument']['Objectives']['Objective'][o]['Id'])
                except KeyError as e:
                    print('Key not found:', e)
                    metadata['ObjID'].append(None)

                try:
                    metadata['TubelensMag'].append(np.float(metadatadict_czi['ImageDocument']['Metadata']['Information']
                                                            ['Instrument']['TubeLenses']['TubeLens'][o]['Magnification']))
                except KeyError as e:
                    print('Key not found:', e, 'Using Default Value = 1.0 for Tublens Magnification.')
                    metadata['TubelensMag'].append(1.0)

                try:
                    metadata['ObjNominalMag'].append(np.float(metadatadict_czi['ImageDocument']['Metadata']['Information']
                                                              ['Instrument']['Objectives']['Objective'][o]['NominalMagnification']))
                except KeyError as e:
                    print('Key not found:', e, 'Using Default Value = 1.0 for Nominal Magnification.')
                    metadata['ObjNominalMag'].append(1.0)

                try:
                    if metadata['TubelensMag'] is not None:
                        metadata['ObjMag'].append(metadata['ObjNominalMag'][o] * metadata['TubelensMag'][o])
                    if metadata['TubelensMag'] is None:
                        print('No TublensMag found. Use 1 instead')
                        metadata['ObjMag'].append(metadata['ObjNominalMag'][o] * 1.0)

                except KeyError as e:
                    print('Key not found:', e)
                    metadata['ObjMag'].append(None)

    # get detector information

    # check if there are any detector entries inside the dictionary
    if pydash.objects.has(metadatadict_czi, ['ImageDocument', 'Metadata', 'Information', 'Instrument', 'Detectors']):

        if isinstance(metadatadict_czi['ImageDocument']['Metadata']['Information']['Instrument']['Detectors']['Detector'], list):
            num_detectors = len(metadatadict_czi['ImageDocument']['Metadata']['Information']['Instrument']['Detectors']['Detector'])
        else:
            num_detectors = 1

        # if there is only one detector found
        if num_detectors == 1:

            # check for detector ID
            try:
                metadata['DetectorID'].append(metadatadict_czi['ImageDocument']['Metadata']['Information']
                                              ['Instrument']['Detectors']['Detector']['Id'])
            except KeyError as e:
                metadata['DetectorID'].append(None)

            # check for detector Name
            try:
                metadata['DetectorName'].append(metadatadict_czi['ImageDocument']['Metadata']['Information']
                                                ['Instrument']['Detectors']['Detector']['Name'])
            except KeyError as e:
                metadata['DetectorName'].append(None)

            # check for detector model
            try:
                metadata['DetectorModel'].append(metadatadict_czi['ImageDocument']['Metadata']['Information']
                                                 ['Instrument']['Detectors']['Detector']['Manufacturer']['Model'])
            except KeyError as e:
                metadata['DetectorModel'].append(None)

            # check for detector type
            try:
                metadata['DetectorType'].append(metadatadict_czi['ImageDocument']['Metadata']['Information']
                                                ['Instrument']['Detectors']['Detector']['Type'])
            except KeyError as e:
                metadata['DetectorType'].append(None)

        if num_detectors > 1:
            for d in range(num_detectors):

                # check for detector ID
                try:
                    metadata['DetectorID'].append(metadatadict_czi['ImageDocument']['Metadata']['Information']
                                                  ['Instrument']['Detectors']['Detector'][d]['Id'])
                except KeyError as e:
                    metadata['DetectorID'].append(None)

                # check for detector Name
                try:
                    metadata['DetectorName'].append(metadatadict_czi['ImageDocument']['Metadata']['Information']
                                                    ['Instrument']['Detectors']['Detector'][d]['Name'])
                except KeyError as e:
                    metadata['DetectorName'].append(None)

                # check for detector model
                try:
                    metadata['DetectorModel'].append(metadatadict_czi['ImageDocument']['Metadata']['Information']
                                                     ['Instrument']['Detectors']['Detector'][d]['Manufacturer']['Model'])
                except KeyError as e:
                    metadata['DetectorModel'].append(None)

                # check for detector type
                try:
                    metadata['DetectorType'].append(metadatadict_czi['ImageDocument']['Metadata']['Information']
                                                    ['Instrument']['Detectors']['Detector'][d]['Type'])
                except KeyError as e:
                    metadata['DetectorType'].append(None)

    # check for well information
    metadata['Well_ArrayNames'] = []
    metadata['Well_Indices'] = []
    metadata['Well_PositionNames'] = []
    metadata['Well_ColId'] = []
    metadata['Well_RowId'] = []
    metadata['WellCounter'] = None
    metadata['SceneStageCenterX'] = []
    metadata['SceneStageCenterY'] = []

    try:
        print('Trying to extract Scene and Well information if existing ...')
        # extract well information from the dictionary
        allscenes = metadatadict_czi['ImageDocument']['Metadata']['Information']['Image']['Dimensions']['S']['Scenes']['Scene']

        # loop over all detected scenes
        for s in range(metadata['SizeS']):

            if metadata['SizeS'] == 1:
                well = allscenes
                try:
                    metadata['Well_ArrayNames'].append(allscenes['ArrayName'])
                except KeyError as e:
                    # print('Key not found in Metadata Dictionary:', e)
                    try:
                        metadata['Well_ArrayNames'].append(well['Name'])
                    except KeyError as e:
                        print('Key not found in Metadata Dictionary:', e, 'Using A1 instead')
                        metadata['Well_ArrayNames'].append('A1')

                try:
                    metadata['Well_Indices'].append(allscenes['Index'])
                except KeyError as e:
                    print('Key not found in Metadata Dictionary:', e)
                    metadata['Well_Indices'].append(1)

                try:
                    metadata['Well_PositionNames'].append(allscenes['Name'])
                except KeyError as e:
                    print('Key not found in Metadata Dictionary:', e)
                    metadata['Well_PositionNames'].append('P1')

                try:
                    metadata['Well_ColId'].append(np.int(allscenes['Shape']['ColumnIndex']))
                except KeyError as e:
                    print('Key not found in Metadata Dictionary:', e)
                    metadata['Well_ColId'].append(0)

                try:
                    metadata['Well_RowId'].append(np.int(allscenes['Shape']['RowIndex']))
                except KeyError as e:
                    print('Key not found in Metadata Dictionary:', e)
                    metadata['Well_RowId'].append(0)

                try:
                    # count the content of the list, e.g. how many time a certain well was detected
                    metadata['WellCounter'] = Counter(metadata['Well_ArrayNames'])
                except KeyError as e:
                    print('Key not found in Metadata Dictionary:', e)
                    metadata['WellCounter'].append(Counter({'A1': 1}))

                try:
                    # get the SceneCenter Position
                    sx = allscenes['CenterPosition'].split(',')[0]
                    sy = allscenes['CenterPosition'].split(',')[1]
                    metadata['SceneStageCenterX'].append(np.double(sx))
                    metadata['SceneStageCenterY'].append(np.double(sy))
                except KeyError as e:
                    metadata['SceneStageCenterX'].append(0.0)
                    metadata['SceneStageCenterY'].append(0.0)

            if metadata['SizeS'] > 1:
                try:
                    well = allscenes[s]
                    metadata['Well_ArrayNames'].append(well['ArrayName'])
                except KeyError as e:
                    # print('Key not found in Metadata Dictionary:', e)
                    try:
                        metadata['Well_ArrayNames'].append(well['Name'])
                    except KeyError as e:
                        print('Key not found in Metadata Dictionary:', e, 'Using A1 instead')
                        metadata['Well_ArrayNames'].append('A1')

                # get the well information
                try:
                    metadata['Well_Indices'].append(well['Index'])
                except KeyError as e:
                    # print('Key not found in Metadata Dictionary:', e)
                    metadata['Well_Indices'].append(None)
                try:
                    metadata['Well_PositionNames'].append(well['Name'])
                except KeyError as e:
                    # print('Key not found in Metadata Dictionary:', e)
                    metadata['Well_PositionNames'].append(None)

                try:
                    metadata['Well_ColId'].append(np.int(well['Shape']['ColumnIndex']))
                except KeyError as e:
                    print('Key not found in Metadata Dictionary:', e)
                    metadata['Well_ColId'].append(None)

                try:
                    metadata['Well_RowId'].append(np.int(well['Shape']['RowIndex']))
                except KeyError as e:
                    print('Key not found in Metadata Dictionary:', e)
                    metadata['Well_RowId'].append(None)

                # count the content of the list, e.g. how many time a certain well was detected
                metadata['WellCounter'] = Counter(metadata['Well_ArrayNames'])

                # try:
                if isinstance(allscenes, list):
                    try:
                        # get the SceneCenter Position
                        sx = allscenes[s]['CenterPosition'].split(',')[0]
                        sy = allscenes[s]['CenterPosition'].split(',')[1]
                        metadata['SceneStageCenterX'].append(np.double(sx))
                        metadata['SceneStageCenterY'].append(np.double(sy))
                    except KeyError as e:
                        print('Key not found in Metadata Dictionary:', e)
                        metadata['SceneCenterX'].append(0.0)
                        metadata['SceneCenterY'].append(0.0)
                if not isinstance(allscenes, list):
                    metadata['SceneStageCenterX'].append(0.0)
                    metadata['SceneStageCenterY'].append(0.0)

            # count the number of different wells
            metadata['NumWells'] = len(metadata['WellCounter'].keys())

    except (KeyError, TypeError) as e:
        print('No valid Scene or Well information found:', e)

    # close CZI file
    czi.close()

    # close AICSImage object
    czi_aics.close()

    # convert scale unit tom avoid encoding problems
    if convert_scunit:
        if metadata['XScaleUnit'] == 'µm':
            metadata['XScaleUnit'] = 'micron'
        if metadata['YScaleUnit'] == 'µm':
            metadata['YScaleUnit'] = 'micron'
        if metadata['ZScaleUnit'] == 'µm':
            metadata['ZScaleUnit'] = 'micron'

    return metadata
示例#26
0
def test_read_unified_subblock_meta(data_dir, fname, expected):
    with open(data_dir / fname, 'rb') as fp:
        czi = CziFile(czi_filename=fp)
        data = czi.read_subblock_metadata(unified_xml=True)
        assert expected in etree.tostring(data)
示例#27
0
def test_datetime_created(data_dir, filename, expected_datetime):
    czi = CziFile(data_dir / filename)
    assert czi_metadata.datetime_created(czi) == expected_datetime
示例#28
0
def test_conversion_types(in_, out_):
    ans = CziFile.convert_to_buffer(in_)
    assert ans.__class__ == out_.__class__
示例#29
0
def test_channel_names(data_dir, filename, expected_channels):
    czi = CziFile(data_dir / filename)
    assert czi_metadata.channel_names(czi) == expected_channels
示例#30
0
def test_image_shape(data_dir, fname, expects):
    with open(data_dir / fname, 'rb') as fp:
        czi = CziFile(czi_filename=fp)
        shape = czi.dims_shape()
    assert shape == expects