Ejemplo n.º 1
0
    def filter_detector_edge(self, exclude_width, *args, **kwargs):
        """Filter the diffraction vectors to accept only those not within a
        user specified proximity to the detector edge.

        Parameters
        ----------
        exclude_width : int
            The width of the region adjacent to the detector edge from which
            vectors will be excluded.
        *args:
            Arguments to be passed to map().
        **kwargs:
            Keyword arguments to map().

        Returns
        -------
        filtered_vectors : DiffractionVectors
            Diffraction vectors within allowed detector region.
        """
        x_threshold = (
            self.pixel_calibration * (self.detector_shape[0] / 2)
            - self.pixel_calibration * exclude_width
        )
        y_threshold = (
            self.pixel_calibration * (self.detector_shape[1] / 2)
            - self.pixel_calibration * exclude_width
        )
        # If ragged the signal axes will not be defined
        if len(self.axes_manager.signal_axes) == 0:
            filtered_vectors = self.map(
                filter_vectors_edge_ragged,
                x_threshold=x_threshold,
                y_threshold=y_threshold,
                inplace=False,
                *args,
                **kwargs
            )
            # Type assignment to DiffractionVectors for return
            filtered_vectors = DiffractionVectors(filtered_vectors)
            filtered_vectors.axes_manager.set_signal_dimension(0)
        # Otherwise easier to calculate.
        else:
            x_inbounds = (
                np.absolute(self.data.T[0]) < x_threshold
            )  # True if vector is good to go
            y_inbounds = np.absolute(self.data.T[1]) < y_threshold
            filtered_vectors = self.data[np.logical_and(x_inbounds, y_inbounds)]
            # Type assignment to DiffractionVectors for return
            filtered_vectors = DiffractionVectors(filtered_vectors)
            filtered_vectors.axes_manager.set_signal_dimension(1)

        transfer_navigation_axes(filtered_vectors, self)

        return filtered_vectors
Ejemplo n.º 2
0
    def get_crystallographic_map(self, *args, **kwargs):
        """Obtain a crystallographic map specifying the best matching phase and
        orientation at each probe position with corresponding metrics.

        Returns
        -------
        cryst_map : Signal2D
            Crystallographic mapping results containing the best matching phase
            and orientation at each navigation position with associated metrics.
            The Signal at each navigation position is an array of,
                            [phase, np.array((z,x,z)), dict(metrics)]
            which defines the phase, orientation as Euler angles in the zxz
            convention and metrics associated with the matching.
            Metrics for template matching results are
                'match_rate'
                'total_error'
                'orientation_reliability'
                'phase_reliability'
        """
        crystal_map = self.map(
            crystal_from_vector_matching, inplace=False, *args, **kwargs
        )

        crystal_map = transfer_navigation_axes(crystal_map, self)
        return crystal_map
Ejemplo n.º 3
0
    def filter_magnitude(self, min_magnitude, max_magnitude, *args, **kwargs):
        """Filter the diffraction vectors to accept only those with a magnitude
        within a user specified range.

        Parameters
        ----------
        min_magnitude : float
            Minimum allowed vector magnitude.
        max_magnitude : float
            Maximum allowed vector magnitude.
        *args:
            Arguments to be passed to map().
        **kwargs:
            Keyword arguments to map().

        Returns
        -------
        filtered_vectors : DiffractionVectors
            Diffraction vectors within allowed magnitude tolerances.
        """
        # If ragged the signal axes will not be defined
        if len(self.axes_manager.signal_axes) == 0:
            filtered_vectors = self.map(
                filter_vectors_ragged,
                min_magnitude=min_magnitude,
                max_magnitude=max_magnitude,
                inplace=False,
                *args,
                **kwargs
            )
            # Type assignment to DiffractionVectors for return
            filtered_vectors = DiffractionVectors(filtered_vectors)
            filtered_vectors.axes_manager.set_signal_dimension(0)
        # Otherwise easier to calculate.
        else:
            magnitudes = self.get_magnitudes()
            magnitudes.data[magnitudes.data < min_magnitude] = 0
            magnitudes.data[magnitudes.data > max_magnitude] = 0
            filtered_vectors = self.data[np.where(magnitudes)]
            # Type assignment to DiffractionVectors for return
            filtered_vectors = DiffractionVectors(filtered_vectors)
            filtered_vectors.axes_manager.set_signal_dimension(1)

        transfer_navigation_axes(filtered_vectors, self)

        return filtered_vectors
Ejemplo n.º 4
0
    def get_pdf(self, s_min, s_max=None, r_min=0, r_max=20, r_increment=0.01):
        """Calculates the pdf from the reduced intensity signal.

        Parameters
        ----------
        s_min : float
            Minimum scattering vector s for the pdf calculation. Note that s is
            defined here as s = 2 sin(theta)/lambda = 1/d.
        s_max : float
            Maximum scattering vector s for the pdf calculation. Note that s is
            defined here as s = 2 sin(theta)/lambda = 1/d.
        r_cutoff : list of float
            A list with the format [<r_min>, <r_max>], which sets the
            limits of the real space axis in the calculated PDF.
        r_increment : float
            Step size in r in the extracted PDF.

        Returns
        -------
        pdf : PDF1D
            A signal of pair distribution functions.
        """
        s_scale = self.signal.axes_manager.signal_axes[0].scale
        if s_max is None:
            s_max = self.signal.axes_manager.signal_axes[0].size * s_scale
            print("s_max set to maximum of signal.")

        r_values = np.arange(r_min, r_max, r_increment)
        r_values = r_values.reshape(1, r_values.size)
        s_limits = [int(s_min / s_scale), int(s_max / s_scale)]

        # check that these aren't out of bounds
        if s_limits[1] > self.signal.axes_manager.signal_axes[0].size:
            raise ValueError(
                "User specified s_max is larger than the maximum "
                "scattering vector magnitude in the data. Please reduce "
                "s_max or use s_max=None to use the full scattering range.")
        s_values = np.arange(s_limits[0], s_limits[1], 1) * s_scale
        s_values = s_values.reshape(s_values.size, 1)  # column vector

        limited_red_int = self.signal.isig[s_limits[0]:s_limits[1]].data

        pdf_sine = np.sin(2 * np.pi * np.matmul(s_values, r_values))
        # creates a vector of the pdf
        rpdf = PairDistributionFunction1D(8 * np.pi * s_scale *
                                          np.matmul(limited_red_int, pdf_sine))

        signal_axis = rpdf.axes_manager.signal_axes[0]
        signal_axis.scale = r_increment
        signal_axis.name = "Radius r"
        signal_axis.units = "$Å$"
        rpdf = transfer_navigation_axes(rpdf, self.signal)

        title = self.signal.metadata.General.title
        rpdf.metadata.General.title = f"Pair distribution function of {title}"

        return rpdf
Ejemplo n.º 5
0
    def refine_n_best_orientations(
        self,
        orientations,
        accelarating_voltage,
        camera_length,
        n_best=0,
        rank=0,
        index_error_tol=0.2,
        vary_angles=True,
        vary_center=False,
        vary_scale=False,
        method="leastsq",
    ):
        """Refines the best orientation and assigns hkl indices to diffraction vectors.

        Parameters
        ----------
        orientations : VectorMatchingResults
            List of orientations to refine, must be an instance of `VectorMatchingResults`.
        accelerating_voltage : float
            The acceleration voltage with which the data was acquired.
        camera_length : float
            The camera length in meters.
        n_best : int
            Refine the best `n` orientations starting from `rank`.
            With `n_best=0` (default), all orientations are refined.
        rank : int
            The rank of the solution to start from.
        index_error_tol : float
            Max allowed error in peak indexation for classifying it as indexed,
            calculated as :math:`|hkl_calculated - round(hkl_calculated)|`.
        method : str
            Minimization algorithm to use, choose from:
            'leastsq', 'nelder', 'powell', 'cobyla', 'least-squares'.
            See `lmfit` documentation (https://lmfit.github.io/lmfit-py/fitting.html)
            for more information.
        vary_angles : bool,
            Free the euler angles (rotation matrix) during the refinement.
        vary_center : bool
            Free the center of the diffraction pattern (beam center) during the refinement.
        vary_scale : bool
            Free the scale (i.e. pixel size) of the diffraction vectors during refinement.

        Returns
        -------
        indexation_results : VectorMatchingResults
            Navigation axes of the diffraction vectors signal containing vector
            indexation results for each probe position.
        """
        vectors = self.vectors
        library = self.library

        matched = orientations.map(
            _refine_best_orientations,
            vectors=vectors,
            library=library,
            accelarating_voltage=accelarating_voltage,
            camera_length=camera_length,
            n_best=n_best,
            rank=rank,
            method="leastsq",
            verbose=False,
            vary_angles=vary_angles,
            vary_center=vary_center,
            vary_scale=vary_scale,
            inplace=False,
            parallel=False,
        )

        indexation = matched.isig[0]
        rhkls = matched.isig[1].data

        indexation_results = VectorMatchingResults(indexation)
        indexation_results.vectors = vectors
        indexation_results.hkls = rhkls
        indexation_results = transfer_navigation_axes(indexation_results,
                                                      vectors.cartesian)

        return indexation_results
Ejemplo n.º 6
0
    def index_vectors(
        self,
        mag_tol,
        angle_tol,
        index_error_tol,
        n_peaks_to_index,
        n_best,
        *args,
        **kwargs,
    ):
        """Assigns hkl indices to diffraction vectors.

        Parameters
        ----------
        mag_tol : float
            The maximum absolute error in diffraction vector magnitude, in units
            of reciprocal Angstroms, allowed for indexation.
        angle_tol : float
            The maximum absolute error in inter-vector angle, in units of
            degrees, allowed for indexation.
        index_error_tol : float
            Max allowed error in peak indexation for classifying it as indexed,
            calculated as :math:`|hkl_calculated - round(hkl_calculated)|`.
        n_peaks_to_index : int
            The maximum number of peak to index.
        n_best : int
            The maximum number of good solutions to be retained.
        *args : arguments
            Arguments passed to the map() function.
        **kwargs : arguments
            Keyword arguments passed to the map() function.

        Returns
        -------
        indexation_results : VectorMatchingResults
            Navigation axes of the diffraction vectors signal containing vector
            indexation results for each probe position.
        """
        vectors = self.vectors
        library = self.library

        matched = vectors.cartesian.map(
            match_vectors,
            library=library,
            mag_tol=mag_tol,
            angle_tol=np.deg2rad(angle_tol),
            index_error_tol=index_error_tol,
            n_peaks_to_index=n_peaks_to_index,
            n_best=n_best,
            inplace=False,
            *args,
            **kwargs,
        )
        indexation = matched.isig[0]
        rhkls = matched.isig[1].data

        indexation_results = VectorMatchingResults(indexation)
        indexation_results.vectors = vectors
        indexation_results.hkls = rhkls
        indexation_results = transfer_navigation_axes(indexation_results,
                                                      vectors.cartesian)

        vectors.hkls = rhkls

        return indexation_results