Exemplo n.º 1
0
    def run(
            self,
            primary_image: ImageStack,
            n_processes: Optional[int] = None,
            *args,
    ) -> Tuple[IntensityTable, ConnectedComponentDecodingResult]:
        """decode pixels and combine them into spots using connected component labeling

        Parameters
        ----------
        primary_image : ImageStack
            ImageStack containing spots
        n_processes : Optional[int]
            The number of processes to use for CombineAdjacentFeatures.
             If None, uses the output of os.cpu_count() (default = None).

        Returns
        -------
        IntensityTable :
            IntensityTable containing decoded spots
        ConnectedComponentDecodingResult :
            Results of connected component labeling

        """
        pixel_intensities = IntensityTable.from_image_stack(
            primary_image, crop_x=self.crop_x, crop_y=self.crop_y, crop_z=self.crop_z)
        decoded_intensities = self.codebook.metric_decode(
            pixel_intensities,
            max_distance=self.distance_threshold,
            min_intensity=self.magnitude_threshold,
            norm_order=self.norm_order,
            metric=self.metric
        )
        caf = CombineAdjacentFeatures(
            min_area=self.min_area,
            max_area=self.max_area,
            mask_filtered_features=True
        )
        decoded_spots, image_decoding_results = caf.run(intensities=decoded_intensities,
                                                        n_processes=n_processes)

        transfer_physical_coords_from_imagestack_to_intensity_table(image_stack=primary_image,
                                                                    intensity_table=decoded_spots)
        return decoded_spots, image_decoding_results
Exemplo n.º 2
0
    def run(
        self, stack: ImageStack,
    ) -> Tuple[IntensityTable, ConnectedComponentDecodingResult]:
        """decode pixels and combine them into spots using connected component labeling

        Parameters
        ----------
        stack : ImageStack
            ImageStack containing spots

        Returns
        -------
        IntensityTable :
            IntensityTable containing decoded spots
        ConnectedComponentDecodingResult :
            Results of connected component labeling

        """
        pixel_intensities = IntensityTable.from_image_stack(
            stack, crop_x=self.crop_x, crop_y=self.crop_y, crop_z=self.crop_z)
        decoded_intensities = self.codebook.metric_decode(
            pixel_intensities,
            max_distance=self.distance_threshold,
            min_intensity=self.magnitude_threshold,
            norm_order=self.norm_order,
            metric=self.metric
        )
        caf = CombineAdjacentFeatures(
            min_area=self.min_area,
            max_area=self.max_area,
            mask_filtered_features=True
        )
        decoded_spots, image_decoding_results = caf.run(intensities=decoded_intensities)

        transfer_physical_coords_from_imagestack_to_intensity_table(image_stack=stack,
                                                                    intensity_table=decoded_spots)
        return decoded_spots, image_decoding_results
Exemplo n.º 3
0
def detect_spots(data_stack: ImageStack,
                 spot_finding_method: Callable[..., SpotAttributes],
                 spot_finding_kwargs: Dict = None,
                 reference_image: Optional[ImageStack] = None,
                 reference_image_max_projection_axes: Optional[Tuple[
                     Axes, ...]] = None,
                 measurement_function: Callable[[Sequence], Number] = np.max,
                 radius_is_gyration: bool = False,
                 n_processes: Optional[int] = None) -> IntensityTable:
    """Apply a spot_finding_method to a ImageStack

    Parameters
    ----------
    data_stack : ImageStack
        The ImageStack containing spots
    spot_finding_method : Callable[..., IntensityTable]
        The method to identify spots
    spot_finding_kwargs : Dict
        additional keyword arguments to pass to spot_finding_method
    reference_image : xr.DataArray
        (Optional) a reference image. If provided, spots will be found in this image, and then
        the locations that correspond to these spots will be measured across each channel and round,
        filling in the values in the IntensityTable
    reference_image_max_projection_axes : Tuple[Axes]
        Generate the reference image by max-projecting reference_image across these axes.
    measurement_function : Callable[[Sequence], Number]
        the function to apply over the spot area to extract the intensity value (default 'np.max')
    radius_is_gyration : bool
        if True, indicates that the radius corresponds to radius of gyration, which is a function of
        spot intensity, but typically is a smaller unit than the sigma generated by blob_log.
        In this case, the spot's bounding box is rounded up instead of down when measuring
        intensity. (default False)
    is_volume: bool
        If True, pass 3d volumes (x, y, z) to func, else pass 2d tiles (x, y) to func. (default
        True)
    n_processes : Optional[int]
        The number of processes to use in stack.transform if reference image is None.
        If None, uses the output of os.cpu_count() (default = None).

    Notes
    -----
    - This class will always detect spots in 3d. If 2d spot detection is desired, the data should
      be projected down to "fake 3d" prior to submission to this function
    - If neither reference_image nor reference_from_max_projection are passed, spots will be
      detected _independently_ in each channel. This assumes a non-multiplex imaging experiment,
      as only one (ch, round) will be measured for each spot.

    Returns
    -------
    IntensityTable :
        IntensityTable containing the intensity of each spot, its radius, and location in pixel
        coordinates

    """

    if spot_finding_kwargs is None:
        spot_finding_kwargs = {}

    if reference_image is not None:
        if reference_image_max_projection_axes is None:
            raise ValueError(
                "axes must be provided if reference_image is provided")
        max_proj_reference_image = reference_image.max_proj(
            *reference_image_max_projection_axes)
        reference_spot_locations = spot_finding_method(
            max_proj_reference_image._squeezed_numpy(
                *reference_image_max_projection_axes), **spot_finding_kwargs)
        intensity_table = measure_spot_intensities(
            data_image=data_stack,
            spot_attributes=reference_spot_locations,
            measurement_function=measurement_function,
            radius_is_gyration=radius_is_gyration,
        )
    else:  # don't use a reference image, measure each
        spot_finding_method = partial(spot_finding_method,
                                      **spot_finding_kwargs)
        spot_attributes_list = data_stack.transform(
            func=spot_finding_method,
            group_by={Axes.ROUND, Axes.CH},
            n_processes=n_processes)
        intensity_table = concatenate_spot_attributes_to_intensities(
            spot_attributes_list)

    transfer_physical_coords_from_imagestack_to_intensity_table(
        image_stack=data_stack, intensity_table=intensity_table)

    return intensity_table
Exemplo n.º 4
0
def detect_spots(data_stack: ImageStack,
                 spot_finding_method: Callable[..., SpotAttributes],
                 spot_finding_kwargs: Dict = None,
                 reference_image: Union[xr.DataArray, np.ndarray] = None,
                 reference_image_from_max_projection: bool = False,
                 measurement_function: Callable[[Sequence], Number] = np.max,
                 radius_is_gyration: bool = False) -> IntensityTable:
    """Apply a spot_finding_method to a ImageStack

    Parameters
    ----------
    data_stack : ImageStack
        The ImageStack containing spots
    spot_finding_method : Callable[..., IntensityTable]
        The method to identify spots
    spot_finding_kwargs : Dict
        additional keyword arguments to pass to spot_finding_method
    reference_image : xr.DataArray
        (Optional) a reference image. If provided, spots will be found in this image, and then
        the locations that correspond to these spots will be measured across each channel and round,
        filling in the values in the IntensityTable
    reference_image_from_max_projection : Tuple[Axes]
        (Optional) if True, create a reference image by max-projecting the channels and imaging
        rounds found in data_image.
    measurement_function : Callable[[Sequence], Number]
        the function to apply over the spot area to extract the intensity value (default 'np.max')
    radius_is_gyration : bool
        if True, indicates that the radius corresponds to radius of gyration, which is a function of
        spot intensity, but typically is a smaller unit than the sigma generated by blob_log.
        In this case, the spot's bounding box is rounded up instead of down when measuring
        intensity. (default False)
    is_volume: bool
        If True, pass 3d volumes (x, y, z) to func, else pass 2d tiles (x, y) to func. (default
        True)

    Notes
    -----
    - This class will always detect spots in 3d. If 2d spot detection is desired, the data should
      be projected down to "fake 3d" prior to submission to this function
    - If neither reference_image nor reference_from_max_projection are passed, spots will be
      detected _independently_ in each channel. This assumes a non-multiplex imaging experiment,
      as only one (ch, round) will be measured for each spot.

    Returns
    -------
    IntensityTable :
        IntensityTable containing the intensity of each spot, its radius, and location in pixel
        coordinates

    """

    if spot_finding_kwargs is None:
        spot_finding_kwargs = {}

    if reference_image is not None and reference_image_from_max_projection:
        raise ValueError(
            'Please pass only one of reference_image and reference_image_from_max_projection'
        )

    if reference_image_from_max_projection:
        reference_image = data_stack.max_proj(Axes.CH, Axes.ROUND)
        reference_image = reference_image._squeezed_numpy(Axes.CH, Axes.ROUND)

    group_by = {Axes.ROUND, Axes.CH}

    if reference_image is not None:
        # Throw error here if tiles are not aligned. Trying to do this with unregistered
        if not data_stack.tiles_aligned:
            raise ValueError(
                'Detected tiles in the image stack that correspond to different positions '
                'in coordinate space. Please make sure your data are'
                'pre aligned, as per our spaceTx file format specification')
        reference_spot_locations = spot_finding_method(reference_image,
                                                       **spot_finding_kwargs)
        intensity_table = measure_spot_intensities(
            data_image=data_stack,
            spot_attributes=reference_spot_locations,
            measurement_function=measurement_function,
            radius_is_gyration=radius_is_gyration,
        )
    else:  # don't use a reference image, measure each
        spot_finding_method = partial(spot_finding_method,
                                      **spot_finding_kwargs)
        spot_attributes_list = data_stack.transform(func=spot_finding_method,
                                                    group_by=group_by)
        intensity_table = concatenate_spot_attributes_to_intensities(
            spot_attributes_list)

    transfer_physical_coords_from_imagestack_to_intensity_table(
        image_stack=data_stack, intensity_table=intensity_table)

    return intensity_table
Exemplo n.º 5
0
    def run(
        self,
        primary_image: ImageStack,
        blobs_image: Optional[ImageStack] = None,
        blobs_axes: Optional[Tuple[Axes, ...]] = None,
        verbose: bool = False,
        n_processes: Optional[int] = None,
        *args,
    ) -> IntensityTable:
        """Find 1-hot coded spots in data.

        Parameters
        ----------
        data : ImageStack
            Image data containing coded spots.
        verbose : bool
            If True, report on progress of spot finding.
        n_processes : Optional[int]
            Number of processes to devote to spot finding. If None, will use the number of available
            cpus (Default None).

        Notes
        -----
        blobs_image is an unused parameter that is included for testing purposes. It should not
        be passed to this method. If it is passed, the method will trigger a ValueError.

        Returns
        -------
        IntensityTable
            Contains detected coded spots.

        """

        if blobs_image is not None:
            raise ValueError(
                "blobs_image shouldn't be set for LocalSearchBlobDetector.  This is likely a usage "
                "error.")

        per_tile_spot_results = self._find_spots(primary_image,
                                                 verbose=verbose,
                                                 n_processes=n_processes)

        per_round_spot_results = self._merge_spots_by_round(
            per_tile_spot_results)

        distances, indices = self._match_spots(
            per_round_spot_results,
            search_radius=self.search_radius,
            anchor_round=self.anchor_round)

        # TODO implement consensus seeding (SeqFISH)

        intensity_table = self._build_intensity_table(
            per_round_spot_results,
            distances,
            indices,
            rounds=primary_image.xarray[Axes.ROUND.value].values,
            channels=primary_image.xarray[Axes.CH.value].values,
            search_radius=self.search_radius,
            anchor_round=self.anchor_round)

        transfer_physical_coords_from_imagestack_to_intensity_table(
            image_stack=primary_image, intensity_table=intensity_table)

        return intensity_table