Ejemplo n.º 1
0
    def get_diffracting_pixels_map(self, in_range=None, binary=False):
        """Map of the number of vectors at each navigation position.

        Parameters
        ----------
        in_range : tuple
            Tuple (min_magnitude, max_magnitude) the minimum and maximum
            magnitude of vectors to be used to form the map.
        binary : boolean
            If True a binary image with diffracting pixels taking value == 1 is
            returned.

        Returns
        -------
        crystim : Signal2D
            2D map of diffracting pixels.
        """
        if in_range:
            filtered = self.filter_magnitude(in_range[0], in_range[1])
            xim = filtered.map(get_npeaks, inplace=False).as_signal2D((0, 1))
        else:
            xim = self.map(get_npeaks, inplace=False).as_signal2D((0, 1))
        # Make binary if specified
        if binary is True:
            xim = xim >= 1.0
        # Set properties
        xim = transfer_navigation_axes_to_signal_axes(xim, self)
        xim.change_dtype("float")
        xim.set_signal_type("signal2d")
        xim.metadata.General.title = "Diffracting Pixels Map"

        return xim
Ejemplo n.º 2
0
    def get_phase_map(self):
        """Obtain a map of the best matching phase at each navigation position."""
        phase_map = self.isig[0].as_signal2D((0, 1))
        phase_map = transfer_navigation_axes_to_signal_axes(phase_map, self)
        phase_map.change_dtype(np.int)

        return phase_map
Ejemplo n.º 3
0
    def get_diffracting_pixels_map(self, binary=False):
        """Map of the number of vectors at each navigation position.

        Parameters
        ----------
        binary : boolean
            If True a binary image with diffracting pixels taking value == 1 is
            returned.

        Returns
        -------
        crystim : Signal2D
            2D map of diffracting pixels.
        """
        crystim = self.map(get_npeaks, inplace=False).as_signal2D((0, 1))

        if binary is True:
            crystim = crystim == 1

        crystim.change_dtype('float')

        # Set calibration to same as signal
        crystim = transfer_navigation_axes_to_signal_axes(crystim, self)

        return crystim
Ejemplo n.º 4
0
    def get_concentric_vdf_images(self,
                                  k_min,
                                  k_max,
                                  k_steps,
                                  normalize=False):
        """Obtain the intensity scattered at each navigation position in an
        ElectronDiffraction2D Signal by summation over a series of concentric
        in annuli between a specified inner and outer radius in a number of
        steps.

        Parameters
        ----------
        k_min : float
            Minimum radius of the annular integration window in reciprocal
            angstroms.

        k_max : float
            Maximum radius of the annular integration window in reciprocal
            angstroms.

        k_steps : int
            Number of steps within the annular integration window

        Returns
        -------
        vdfs : VDFImage
            VDFImage object containing virtual dark field images for all steps
            within the annulus.
        """
        k_step = (k_max - k_min) / k_steps
        k0s = np.linspace(k_min, k_max - k_step, k_steps)
        k1s = np.linspace(k_min + k_step, k_max, k_steps)

        ks = np.array((k0s, k1s)).T

        vdfs = []
        for k in ks:
            annulus = roi.CircleROI(cx=0, cy=0, r=k[1], r_inner=k[0])
            vdf = annulus(self.signal,
                          axes=self.signal.axes_manager.signal_axes)
            vdfs.append(vdf.sum((2, 3)).as_signal2D((0, 1)).data)

        vdfim = VDFImage(np.asarray(vdfs))

        if normalize:
            vdfim.map(normalize_vdf)

        # Set calibration to same as signal
        vdfim = transfer_navigation_axes_to_signal_axes(vdfim, self.signal)

        return vdfim
Ejemplo n.º 5
0
    def get_vector_vdf_images(self, radius, normalize=False):
        """Obtain the intensity scattered to each diffraction vector at each
        navigation position in an ElectronDiffraction2D Signal by summation in a
        circular window of specified radius.

        Parameters
        ----------
        radius : float
            Radius of the integration window in reciprocal angstroms.

        normalize : boolean
            If True each VDF image is normalized so that the maximum intensity
            in each VDF is 1.

        Returns
        -------
        vdfs : VDFImage
            VDFImage object containing virtual dark field images for all unique
            vectors.
        """
        if self.vectors:
            vdfs = []
            for v in self.vectors.data:
                disk = roi.CircleROI(cx=v[0], cy=v[1], r=radius, r_inner=0)
                vdf = disk(self.signal,
                           axes=self.signal.axes_manager.signal_axes)
                vdfs.append(vdf.sum((2, 3)).as_signal2D((0, 1)).data)

            vdfim = VDFImage(np.asarray(vdfs))

            if normalize:
                vdfim.map(normalize_vdf)

        else:
            raise ValueError(
                "DiffractionVectors not specified by user. Please "
                "initialize VDFGenerator with some vectors. ")

        # Set calibration to same as signal
        vdfim = transfer_navigation_axes_to_signal_axes(vdfim, self.signal)

        # Assign vectors used to generate images to vdfim attribute.
        vdfim.vectors = self.vectors
        vdfim.vectors = transfer_signal_axes(vdfim.vectors, self.vectors)

        return vdfim
Ejemplo n.º 6
0
    def get_orientation_map(self):
        """Obtain a map of the rotational angle associated with the best
        matching crystal orientation at each navigation position.

        Returns
        -------
        orientation_map : Signal2D
            The rotation angle assocaiated with the orientation at each
            navigation position.

        """
        eulers = self.isig[1]
        eulers.map(_euler2axangle_signal, inplace=True)
        orientation_map = eulers.as_signal2D((0, 1))
        orientation_map = transfer_navigation_axes_to_signal_axes(orientation_map, self)
        # Since vector matching results returns in object form, eulers inherits
        # it.
        orientation_map.change_dtype("float")

        return orientation_map
Ejemplo n.º 7
0
    def get_image_variance(self, dqe):
        """Calculates the variance in scattered intensity as a function of
        scattering vector. The calculated variance is normalised by the mean
        squared, as is appropriate for the distribution of intensities. This
        causes a problem if Poisson noise is significant in the data, resulting
        in a divergence of the Poisson noise term. To in turn remove this
        effect, we subtract a dqe/mean_dp term (although it is suggested that
        dqe=1) from the data, creating a "poisson noise-free" corrected variance
        pattern. DQE is fitted to make this pattern flat.

        Parameters
        ----------

        dqe : float
            Detective quantum efficiency of the detector for Poisson noise
            correction.

        Returns
        -------

        varims : ImageVariance
            A two dimensional Signal class object containing the mean DP, mean
            squared DP, and variance DP, and a Poisson noise-corrected variance
            DP.
        """
        im = self.signal.T
        mean_im = im.mean((0, 1))
        meansq_im = Signal2D(np.square(im.data)).mean((0, 1))
        normvar = (meansq_im.data / np.square(mean_im.data)) - 1.0
        var_im = Signal2D(normvar)
        corr_var_array = normvar - (np.divide(dqe, mean_im.data))
        corr_var_array[np.invert(np.isfinite(corr_var_array))] = 0
        corr_var = Signal2D(corr_var_array)
        varims = stack((mean_im, meansq_im, var_im, corr_var))

        sig_x = varims.data.shape[1]
        sig_y = varims.data.shape[2]
        iv = ImageVariance(varims.data.reshape((2, 2, sig_x, sig_y)))
        iv = transfer_navigation_axes_to_signal_axes(iv, self.signal)

        return iv
Ejemplo n.º 8
0
    def get_metric_map(self, metric):
        """Obtain a map of an indexation / matching metric at each navigation
        position.

        Parameters
        ----------
        metric : str
            String identifier for the indexation / matching metric to be
            mapped, for template matching valid metrics are {'correlation',
            'orientation_reliability', 'phase_reliability'}. For vector matching
            valid metrics are {'match_rate', 'ehkls', 'total_error',
            'orientation_reliability', 'phase_reliability'}.

        Returns
        -------
        metric_map : Signal2D
            A map of the specified metric at each navigation position.

        Notes
        -----
        For template matching, orientation reliability is given by
            100 * (1 - second_best_correlation/best_correlation)
        and phase reliability is given by
            100 * (1 - second_best_correlation_of_other_phase/best_correlation)

        For vector matching, orientation reliability is given by
            100 * (1 - lowest_error/second_lowest_error)
        and phase reliability is given by
            100 * (1 - lowest_error/lowest_error_of_other_phase)

        """
        if self.method == "template_matching":
            template_metrics = [
                "correlation",
                "orientation_reliability",
                "phase_reliability",
            ]
            if metric in template_metrics:
                metric_map = (
                    self.isig[2]
                    .map(_metric_from_dict, metric=metric, inplace=False)
                    .as_signal2D((0, 1))
                )

            else:
                raise ValueError(
                    "The metric `{}` is not valid for template "
                    "matching results.".format(metric)
                )

        elif self.method == "vector_matching":
            vector_metrics = [
                "match_rate",
                "ehkls",
                "total_error",
                "orientation_reliability",
                "phase_reliability",
            ]
            if metric in vector_metrics:
                metric_map = (
                    self.isig[2]
                    .map(_metric_from_dict, metric=metric, inplace=False)
                    .as_signal2D((0, 1))
                )

            else:
                raise ValueError(
                    "The metric `{}` is not valid for vector "
                    "matching results.".format(metric)
                )

        else:
            raise ValueError(
                "The crystallographic mapping method must be "
                "specified, as an attribute, as either "
                "template_matching or vector_matching."
            )

        metric_map = transfer_navigation_axes_to_signal_axes(metric_map, self)

        return metric_map