예제 #1
0
    def group_metadata_per_zstack(self):
        '''Group all focal planes belonging to one z-stack (i.e. acquired
        at different z resolutions but at the same microscope stage position,
        time point and channel) together.

        Returns
        -------
        pandas.DataFrame
            metadata for each 2D *Plane* element
        '''
        md = self.metadata

        logger.info('group metadata per z-stack')
        zstacks = md.groupby([
            'well_name', 'well_position_x', 'well_position_y', 'channel_name',
            'tpoint'
        ])
        logger.debug('identified %d z-stacks', zstacks.ngroups)

        # Map the locations of each plane with the original image files
        # in order to be able to perform the intensity projection later on
        grouped_file_mapper_list = list()
        grouped_file_mapper_lut = collections.defaultdict(list)
        rows_to_drop = list()
        for key, indices in zstacks.groups.iteritems():
            fm = ImageFileMapping()
            fm.files = list()
            fm.series = list()
            fm.planes = list()
            fm.ref_index = indices[0]
            for index in indices:
                fm.files.extend(self._file_mapper_list[index].files)
                fm.series.extend(self._file_mapper_list[index].series)
                fm.planes.extend(self._file_mapper_list[index].planes)
            grouped_file_mapper_list.append(fm)
            grouped_file_mapper_lut[tuple(fm.files)].append(fm)
            # Keep only the first record
            rows_to_drop.extend(indices[1:])

        # Update metadata and file mapper objects
        self.metadata.drop(self.metadata.index[rows_to_drop], inplace=True)
        del self.metadata['zplane']
        self._file_mapper_list = grouped_file_mapper_list
        self._file_mapper_lut = grouped_file_mapper_lut

        return self.metadata
예제 #2
0
    def _combine_omexml_elements(self, omexml_images, omexml_metadata):
        logger.info('combine OMEXML elements')
        # We assume here that each image files contains the same number images.
        n_images = omexml_images.values()[0].image_count * len(omexml_images)
        if omexml_metadata is not None:
            extra_omexml_available = True
            if not isinstance(omexml_metadata, bioformats.omexml.OMEXML):
                raise TypeError('Argument "omexml_metadata" must have type '
                                'bioformats.omexml.OMEXML.')
            if omexml_metadata.image_count != n_images:
                raise MetadataError(
                    'Number of images in "omexml_metadata" must match '
                    'the total number of Image elements in "omexml_images".')
        else:
            extra_omexml_available = False
            omexml_metadata = bioformats.OMEXML(XML_DECLARATION)
            omexml_metadata.image_count = n_images

        image_element_attributes = {'AcquisitionDate', 'Name'}
        channel_element_attributes = {'Name'}
        pixel_element_attributes = {
            'PixelType', 'SizeC', 'SizeT', 'SizeX', 'SizeY', 'SizeZ'
        }
        plane_element_attributes = {
            'PositionX', 'PositionY', 'PositionZ', 'TheC', 'TheT', 'TheZ'
        }
        filenames = natsorted(omexml_images)
        count = 0
        for i, f in enumerate(filenames):
            omexml_img = omexml_images[f]
            n_series = omexml_img.image_count
            for s in xrange(n_series):
                extracted_image = omexml_img.image(s)
                md_image = omexml_metadata.image(count)
                for attr in image_element_attributes:
                    extracted_value = getattr(extracted_image, attr)
                    if extracted_value is not None:
                        setattr(md_image, attr, extracted_value)

                extracted_pixels = extracted_image.Pixels
                n_planes = extracted_pixels.plane_count
                if n_planes == 0:
                    # Sometimes an image doesn't have any plane elements.
                    # Let's create them for consistency.
                    extracted_pixels = self._create_channel_planes(
                        extracted_pixels)
                    n_planes = extracted_pixels.plane_count

                md_pixels = md_image.Pixels
                md_pixels.plane_count = n_planes
                if extra_omexml_available and (md_pixels.plane_count !=
                                               n_planes):
                    raise MetadataError(
                        'Image element #%d in OMEXML obtained from additional '
                        'metdata files must have the same number of Plane  '
                        'elements as the corresponding Image elements in the '
                        'OMEXML element obtained from image file "%s".' %
                        (i, f))

                for attr in pixel_element_attributes:
                    extracted_value = getattr(extracted_pixels, attr)
                    if extracted_value is not None:
                        # This is python-bioformats being stupid by setting
                        # random default values.
                        setattr(md_pixels, attr, extracted_value)

                for p in xrange(n_planes):
                    extracted_plane = extracted_pixels.Plane(p)
                    md_plane = md_pixels.Plane(p)
                    for attr in plane_element_attributes:
                        extracted_value = getattr(extracted_plane, attr)
                        md_value = getattr(md_plane, attr)
                        if md_value is None and extracted_value is not None:
                            setattr(md_plane, attr, extracted_value)

                    fm = ImageFileMapping()
                    fm.ref_index = count + p
                    fm.files = [f]
                    fm.series = [s]
                    fm.planes = [p]
                    self._file_mapper_list.append(fm)
                    self._file_mapper_lut[f].append(fm)

                n_channels = extracted_pixels.channel_count
                md_image.channel_count = n_channels
                for c in xrange(n_channels):
                    extracted_channel = extracted_pixels.Channel(c)
                    md_channel = md_pixels.Channel(c)
                    for attr in channel_element_attributes:
                        extracted_value = getattr(extracted_channel, attr)
                        if extracted_value is not None:
                            setattr(md_channel, attr, extracted_value)

                count += 1

        return omexml_metadata