Exemplo n.º 1
0
    def __init__(self,
                 config,
                 z_plane='best',
                 cytometer_type='2D',
                 crop=False,
                 target_shape=None,
                 segmentation_params=None,
                 quantification_params=None):
        super().__init__(config)

        params = config.cytometry_params
        self.z_plane = params.get('z_plane', z_plane)
        self.target_shape = params.get('target_shape', target_shape)

        self.segmentation_params = params.get('segmentation_params',
                                              segmentation_params or {})

        self.quantification_params = params.get('quantification_params',
                                                quantification_params or {})
        if 'channel_names' not in self.quantification_params:
            self.quantification_params['channel_names'] = config.channel_names

        self.nuc_channel_coords = config.get_channel_coordinates(
            params['nuclei_channel_name'])
        self.mem_channel_coords = None if 'membrane_channel_name' not in params else \
            config.get_channel_coordinates(params['membrane_channel_name'])

        self.cytometer_type = params.get('type', cytometer_type)
        self.cytometer = None
        self.input_shape = (config.tile_height, config.tile_width, 1)

        self.cropper = tile_crop.CytokitTileCrop(config) if params.get(
            'crop', crop) else None

        _validate_z_plane(self.z_plane)
Exemplo n.º 2
0
def get_preprocess_op_set(task_config):
    exp_config = task_config.exp_config
    return op.CytokitOpSet(
        align_op=drift_compensation.CytokitDriftCompensator(exp_config)
        if task_config.op_flags.run_drift_comp else None,
        focus_op=best_focus.CytokitFocalPlaneSelector(exp_config)
        if task_config.op_flags.run_best_focus else None,
        decon_op=deconvolution.CytokitDeconvolution(exp_config)
        if task_config.op_flags.run_deconvolution else None,
        summary_op=tile_summary.CytokitTileSummary(exp_config)
        if task_config.op_flags.run_summary else None,
        crop_op=tile_crop.CytokitTileCrop(exp_config)
        if task_config.op_flags.run_crop else None,
        cytometry_op=cytometry.get_op(exp_config)
        if task_config.op_flags.run_cytometry else None)
Exemplo n.º 3
0
    def extract(self,
                name,
                channels,
                z='best',
                region_indexes=None,
                tile_indexes=None,
                raw_dir=None):
        """Create a new data extraction include either raw, processed, or cytometric imaging data

        Args:
            name: Name of extraction to be created; This will be used to construct result path like
                EXP_DIR/output/extract/`name`
            channels: List of strings indicating channel names (case-insensitive) prefixed by source for that
                channel (e.g. proc_DAPI, raw_CD4, cyto_nucleus_boundary); Available sources are:
                - "raw": Raw data images
                - "proc": Data generated as a results of preprocessing
                - "cyto": Cytometric object data (nuclei and cell boundaries)
            z: String or 1-based index selector for z indexes constructed as any of the following:
                - "best": Indicates that z slices should be inferred based on focal quality (default option)
                - "all": Indicates that a slice for all z-planes should be used
                - str or int: A single value will be interpreted as a single index
                - tuple: A 2-item or 3-item tuple forming the slice (start, stop[, step]); stop is inclusive
                - list: A list of integers will be used as is
            region_indexes: 1-based sequence of region indexes to process; can be specified as:
                - None: Region indexes will be inferred from experiment configuration
                - str or int: A single value will be interpreted as a single index
                - tuple: A 2-item or 3-item tuple forming the slice (start, stop[, step]); stop is inclusive
                - list: A list of integers will be used as is
            tile_indexes: 1-based sequence of tile indexes to process; has same semantics as `region_indexes`
            raw_dir: If using any channels sourced from raw data, this directory must be specified and should
                be equivalent to the same raw directory used during processing (i.e. nearly all operations like
                this are run relative to an `output_dir` -- the result of processing -- but in this case
                the original raw data path is needed as well)
        """
        channel_map = _map_channels(self.config, channels).groupby('source')
        channel_sources = sorted(list(channel_map.groups.keys()))

        z_slice_fn = _get_z_slice_fn(z, self.data_dir)
        region_indexes = cli.resolve_index_list_arg(region_indexes,
                                                    zero_based=True)
        tile_indexes = cli.resolve_index_list_arg(tile_indexes,
                                                  zero_based=True)

        logging.info('Creating extraction "%s"', name)

        tile_locations = _get_tile_locations(self.config, region_indexes,
                                             tile_indexes)

        extract_path = None
        for i, loc in enumerate(tile_locations):
            logging.info('Extracting tile {} of {}'.format(
                i + 1, len(tile_locations)))
            extract_tile = []

            # Create function used to crop out z-slices from extracted volumes
            z_slice = z_slice_fn(loc.region_index, loc.tile_x, loc.tile_y)

            slice_labels = []
            for src in channel_sources:

                # Initialize tile generator for this data source (which are all the same except
                # for when using raw data, which does not have pre-assembled tiles available)
                tile_gen_dir = self.data_dir
                tile_gen_mode = 'stack'
                if src == CH_SRC_RAW:
                    if not raw_dir:
                        raise ValueError(
                            'When extracting raw data channels, the `raw_dir` argument must be provided'
                        )
                    tile_gen_dir = raw_dir
                    tile_gen_mode = 'raw'
                generator = tile_generator.CytokitTileGenerator(
                    self.config,
                    tile_gen_dir,
                    loc.region_index,
                    loc.tile_index,
                    mode=tile_gen_mode,
                    path_fmt_name=PATH_FMT_MAP[src])
                tile = generator.run(None)

                # Crop raw images if necessary
                if src == CH_SRC_RAW:
                    tile = tile_crop.CytokitTileCrop(self.config).run(tile)

                # Sort channels by name to make extract channel order deterministic
                for _, r in channel_map.get_group(src).sort_values(
                        'channel_name').iterrows():

                    # Extract (z, h, w) subtile
                    sub_tile = tile[r['cycle_index'], z_slice,
                                    r['channel_index']]
                    logging.debug(
                        'Extraction for cycle %s, channel %s (%s), z slice %s, source "%s" complete (tile shape = %s)',
                        r['cycle_index'], r['channel_index'],
                        r['channel_name'], z_slice, src, sub_tile.shape)
                    assert sub_tile.ndim == 3, \
                        'Expecting sub_tile to have 3 dimensions but got shape {}'.format(sub_tile.shape)
                    slice_labels.append('{}_{}'.format(src, r['channel_name']))
                    extract_tile.append(sub_tile)

            # Stack the subtiles to give array with shape (z, channels, h, w) and then reshape to 5D
            # format like (cycles, z, channels, h, w)
            extract_tile = np.stack(extract_tile, axis=1)[np.newaxis]
            assert extract_tile.ndim == 5, \
                'Expecting extract tile to have 5 dimensions but got shape {}'.format(extract_tile.shape)

            extract_path = cytokit_io.get_extract_image_path(
                loc.region_index, loc.tile_x, loc.tile_y, name)
            extract_path = osp.join(self.data_dir, extract_path)
            logging.debug('Saving tile with shape %s (dtype = %s) to "%s"',
                          extract_tile.shape, extract_tile.dtype, extract_path)

            # Construct slice labels as repeats across z-dimension (there is only one time/cycle dimension)
            slice_label_tags = ij_utils.get_channel_label_tags(
                slice_labels, z=extract_tile.shape[1], t=1)
            cytokit_io.save_tile(extract_path,
                                 extract_tile,
                                 config=self.config,
                                 infer_labels=False,
                                 extratags=slice_label_tags)

        logging.info('Extraction complete (results saved to %s)',
                     osp.dirname(extract_path) if extract_path else None)