##### visualization of rolonies
# EPY: END markdown

# EPY: START code
distance_threshold = min_dist

psd = SpotFinder.PixelSpotDetector(codebook=exp.codebook,
                                   metric='euclidean',
                                   distance_threshold=distance_threshold,
                                   magnitude_threshold=magnitude_threshold,
                                   min_area=area_threshold[0],
                                   max_area=area_threshold[1])

spot_intensities, results = psd.run(zero_norm_stack)
spot_intensities = IntensityTable(
    spot_intensities.where(spot_intensities[Features.PASSES_THRESHOLDS],
                           drop=True))
# EPY: END code

# EPY: START code
# exclude spots that don't meet our area thresholds
area_lookup = lambda x: 0 if x == 0 else results.region_properties[x - 1].area
vfunc = np.vectorize(area_lookup)
mask = np.squeeze(vfunc(results.label_image))
new_image = np.squeeze(results.decoded_image) * (mask > area_threshold[0]) * (
    mask < area_threshold[1])

plt.figure(figsize=(10, 10))
plt.imshow(new_image, cmap='nipy_spectral')
plt.axis('off')
plt.title('Coded rolonies')
    def run(
        self, intensities: IntensityTable
    ) -> Tuple[IntensityTable, ConnectedComponentDecodingResult]:
        """
        Execute the combine_adjacent_features method on an IntensityTable containing pixel
        intensities

        Parameters
        ----------
        intensities : IntensityTable
            Pixel intensities of an imaging experiment

        Returns
        -------
        IntensityTable :
            Table whose features comprise sets of adjacent pixels that decoded to the same target
        ConnectedComponentDecodingResult :
            NamedTuple containing :
                region_properties :
                    the properties of each connected component, in the same order as the
                    IntensityTable
                label_image : np.ndarray
                    An image where all pixels of a connected component share the same integer ID
                decoded_image : np.ndarray
                    Image whose pixels correspond to the targets that the given position in the
                    ImageStack decodes to.

        """

        # map target molecules to integers so they can be reshaped into an image that can
        # be subjected to a connected-component algorithm to find adjacent pixels with the
        # same targets
        targets = intensities[Features.TARGET].values
        target_map = TargetsMap(targets)

        # create the decoded_image
        decoded_image = self._intensities_to_decoded_image(
            intensities,
            target_map,
            self._mask_filtered,
        )

        # label the decoded image to extract connected component features
        label_image: np.ndarray = label(decoded_image,
                                        connectivity=self._connectivity)

        # calculate properties of each feature
        props: List = regionprops(np.squeeze(label_image))

        # calculate mean intensities across the pixels of each feature
        mean_pixel_traces = self._calculate_mean_pixel_traces(
            label_image,
            intensities,
        )

        # Create SpotAttributes and determine feature filtering outcomes
        spot_attributes, passes_filter = self._create_spot_attributes(
            props,
            decoded_image,
            target_map,
        )

        # augment the SpotAttributes with filtering results and distances from nearest codes
        spot_attributes.data[Features.DISTANCE] = mean_pixel_traces[
            Features.DISTANCE]
        spot_attributes.data[Features.PASSES_THRESHOLDS] = passes_filter

        # create new indexes for the output IntensityTable
        channel_index = mean_pixel_traces.indexes[Indices.CH]
        round_index = mean_pixel_traces.indexes[Indices.ROUND]
        coords = IntensityTable._build_xarray_coords(spot_attributes,
                                                     channel_index,
                                                     round_index)

        # create the output IntensityTable
        dims = (Features.AXIS, Indices.CH.value, Indices.ROUND.value)
        intensity_table = IntensityTable(data=mean_pixel_traces,
                                         coords=coords,
                                         dims=dims)

        # combine the various non-IntensityTable results into a NamedTuple before returning
        ccdr = ConnectedComponentDecodingResult(props, label_image,
                                                decoded_image)

        return intensity_table, ccdr
Esempio n. 3
0
    def metric_decode(self,
                      intensities: IntensityTable,
                      max_distance: Number,
                      min_intensity: Number,
                      norm_order: int,
                      metric: str = 'euclidean') -> IntensityTable:
        """Assign the closest target by euclidean distance to each feature in an intensity table

        Normalizes both the codes and the features to be unit vectors and finds the closest code
        for each feature

        Parameters
        ----------
        intensities : IntensityTable
            features to be decoded
        max_distance : Number
            maximum distance between a feature and its closest code for which the coded target will
            be assigned.
        min_intensity : Number
            minimum intensity for a feature to receive a target annotation
        norm_order : int
            the scipy.linalg norm to apply to normalize codes and intensities
        metric : str
            the sklearn metric string to pass to NearestNeighbors

        See Also
        --------
        The available norms for this function can be found at the following link:
        https://docs.scipy.org/doc/numpy-1.14.0/reference/generated/numpy.linalg.norm.html

        Returns
        -------
        IntensityTable :
            Intensity table containing normalized intensities, target assignments, distances to
            the nearest code, and the filtering status of each feature.

        """

        self._validate_decode_intensity_input_matches_codebook_shape(
            intensities)

        # normalize both the intensities and the codebook
        norm_intensities, norms = self._normalize_features(
            intensities, norm_order=norm_order)
        norm_codes, _ = self._normalize_features(self, norm_order=norm_order)

        metric_outputs, targets = self._approximate_nearest_code(
            norm_codes, norm_intensities, metric=metric)

        # only targets with low distances and high intensities should be retained
        passes_filters = np.logical_and(norms >= min_intensity,
                                        metric_outputs <= max_distance,
                                        dtype=np.bool)

        # set targets, distances, and filtering results
        norm_intensities[Features.TARGET] = (Features.AXIS, targets)
        norm_intensities[Features.DISTANCE] = (Features.AXIS, metric_outputs)
        norm_intensities[Features.PASSES_THRESHOLDS] = (Features.AXIS,
                                                        passes_filters)

        # norm_intensities is a DataArray, make it back into an IntensityTable
        return IntensityTable(norm_intensities)