Пример #1
0
    def test_get_azimuthal_integrator(self):
        dect = Detector(pixel1=1e-4, pixel2=1e-4, max_shape=(20, 20))
        ai = get_azimuthal_integrator(detector=dect,
                                      detector_distance=0.001,
                                      shape=(20, 20),
                                      center=(10.5, 10.5))
        assert isinstance(ai, AzimuthalIntegrator)
        ai_mask = get_azimuthal_integrator(
            detector=dect,
            detector_distance=1,
            shape=(20, 20),
            center=(10.5, 10.5),
            mask=np.zeros((20, 20)),
        )

        assert isinstance(ai_mask, AzimuthalIntegrator)
        aff = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
        ai_affine = get_azimuthal_integrator(
            detector=dect,
            detector_distance=1,
            shape=(20, 20),
            center=(10.5, 10.5),
            mask=np.zeros((20, 20)),
            affine=aff,
        )
        assert isinstance(ai_affine, AzimuthalIntegrator)
Пример #2
0
    def test_1d_integrate_fast(self, radial_pattern):
        from pyxem.utils.pyfai_utils import get_azimuthal_integrator

        dect = Detector(pixel1=1e-4, pixel2=1e-4)
        ai = get_azimuthal_integrator(detector=dect,
                                      detector_distance=1,
                                      shape=np.shape(radial_pattern))
        integration = azimuthal_integrate1d_fast(
            radial_pattern,
            ai,
            npt_rad=100,
            method="numpy",
            unit="2th_rad",
            correctSolidAngle=True,
        )
Пример #3
0
 def to_ai(self, wavelength, **kwargs):
     sig_shape = np.shape(self.diffraction_pattern)
     unit = "k_A^-1"
     setup = _get_setup(wavelength, unit, self.diffraction_calibration)
     detector, dist, radial_range = setup
     ai = get_azimuthal_integrator(
         detector=detector,
         detector_distance=dist,
         shape=sig_shape,
         center=self.center,
         affine=self.affine_matrix,
         wavelength=wavelength,
         **kwargs,
     )
     return ai
Пример #4
0
def azimuthal_integrate2d_slow(
    z,
    detector_distance,
    detector,
    npt_rad,
    npt_azim=360,
    wavelength=None,
    unit="2th_rad",
    center=None,
    mask=None,
    affine=None,
    method="splitpixel",
    correctSolidAngle=True,
    radial_range=None,
    azimuth_range=None,
    azimuthal_kwargs={},
    integrate_kwargs={},
):
    """Calculate the azimuthal integral in 2d around a determined origin.

    This method is used for signals where the origin is iterated, compared to
    azimuthal_integrate_fast which is used when the origin, mask and affine transformation in the data is
    constant.

    Parameters
    ----------
    z : np.array()
        Two-dimensional data array containing the signal.
    origin : np.array()
        A size 2 numpy array containing the position of the origin.
    detector_distance : float
        Detector distance in meters passed to pyFAI AzimuthalIntegrator.
    detector : pyFAI.detectors.Detector object
        A pyFAI detector used for the AzimuthalIntegrator.
    wavelength : float
        The electron wavelength in meters. Used by pyFAI AzimuthalIntegrator.
    size_1d : int
        The size of the returned 1D signal. (i.e. number of pixels in the 1D
        azimuthal integral.)
    unit : str
        The unit for for PyFAI integrate1d.
    *args :
        Arguments to be passed to AzimuthalIntegrator.
    **kwargs :
        Keyword arguments to be passed to AzimuthalIntegrator.
    Returns
    -------
    tth : np.array()
        One-dimensional scattering vector axis of z.
    I : np.array()
        One-dimensional azimuthal integral of z.
    """
    shape = np.shape(z)
    ai = get_azimuthal_integrator(detector=detector,
                                  detector_distance=detector_distance,
                                  shape=shape,
                                  center=center,
                                  affine=affine,
                                  mask=mask,
                                  wavelength=wavelength,
                                  **azimuthal_kwargs)

    output = ai.integrate2d(z,
                            npt_rad=npt_rad,
                            npt_azim=npt_azim,
                            method=method,
                            unit=unit,
                            correctSolidAngle=correctSolidAngle,
                            azimuth_range=azimuth_range,
                            radial_range=radial_range,
                            **integrate_kwargs)
    return np.transpose(output[0])
Пример #5
0
    def get_azimuthal_integral2d(
        self,
        npt_rad,
        npt_azim=360,
        center=None,
        affine=None,
        mask=None,
        radial_range=None,
        azimuth_range=None,
        wavelength=None,
        unit="pyxem",
        inplace=False,
        method="splitpixel",
        map_kwargs={},
        detector=None,
        detector_dist=None,
        correctSolidAngle=True,
        ai_kwargs={},
        integrate2d_kwargs={},
    ):
        """Creates a polar reprojection using pyFAI's azimuthal integrate 2d.

        This function is designed to be fairly flexible to account for 2 different cases:

        1 - If the unit is "pyxem" then it lets pyXEM take the lead. If wavelength is none in that case
        it doesn't account for the Ewald sphere.

        2 - If unit is any of the options from pyFAI then detector cannot be None and the handling of
        units is passed to pyxem and those units are used.

        Parameters
        ---------------
        npt_rad: int
            The number of radial points to calculate
        npt_azim: int
            The number of azimuthal points to calculate
        center: None or (x,y) or BaseSignal
            The center of the pattern in pixels to preform the integration around
        affine: 3x3 array or BaseSignal
            An affine transformation to apply during the transformation
             (creates a spline map that is used by pyFAI)
        mask:  boolean array or BaseSignal
            A boolean mask to apply to the data to exclude some points.
            If mask is a baseSignal then it is itereated over as well.
        radial_range: None or (float, float)
            The radial range over which to perform the integration. Default is
            the full frame
        azim_range:None or (float, float)
            The azimuthal range over which to perform the integration. Default is
            from -pi to pi
        wavelength: None or float
            The wavelength of for the microscope. Has to be in the same units as the pyxem units if you want
            it to properly work.
        unit: str
            The unit can be "pyxem" to use the pyxem units and “q_nm^-1”, “q_A^-1”, “2th_deg”, “2th_rad”, “r_mm”
            if pyFAI is used for unit handling
        inplace: bool
            If the signal is overwritten or copied to a new signal
        detector: pyFai.detector.Detector
            The detector set up to be used by the integrator
        detector_dist: float
            distance sample - detector plan (orthogonal distance, not along the beam), in meter.
        map_kwargs: dict
            Any other keyword arguments for hyperspys map function
        integrate2d_kwargs:dict
            Any keyword arguements for PyFAI's integrate2d function

        Returns
        ----------
        polar: PolarDiffraction2D
            A polar diffraction signal

        Examples
        ----------
        Basic case using "2th_deg" units (no wavelength needed)

        >>> ds.unit = "2th_deg"
        >>> ds.get_azimuthal_integral2d(npt_rad=100)

        Basic case using a curved Ewald Sphere approximation and pyXEM units
        (wavelength needed)

        >>> ds.unit = "k_nm^-1" # setting units
        >>> ds.get_azimuthal_integral1d(npt_rad=100, wavelength=2.5e-12)

        Using pyFAI to define a detector case using a curved Ewald Sphere approximation and pyXEM units

        >>> from pyFAI.detectors import Detector
        >>> det = Detector(pixel1=1e-4, pixel2=1e-4)
        >>> ds.get_azimuthal_integral1d(npt_rad=100, detector_dist=.2, detector= det, wavelength=2.508e-12)
        """
        pyxem_units = False
        sig_shape = self.axes_manager.signal_shape

        if unit == "pyxem":
            pyxem_units = True
            pixel_scale = [
                self.axes_manager.signal_axes[0].scale,
                self.axes_manager.signal_axes[1].scale,
            ]
            if wavelength is None and self.unit not in ["2th_deg", "2th_rad"]:
                print('if the unit is not "2th_deg", "2th_rad"'
                      "then a wavelength must be given. ")
                return
            setup = _get_setup(wavelength, self.unit, pixel_scale,
                               radial_range)
            detector, detector_dist, radial_range, unit, scale_factor = setup
        use_iterate = any([
            isinstance(mask, BaseSignal),
            isinstance(affine, BaseSignal),
            isinstance(center, BaseSignal),
        ])
        if use_iterate:
            if radial_range is None:  # need consistent range
                if isinstance(center, BaseSignal):
                    ind = (0, ) * len(self.axes_manager.navigation_shape)
                    cen = center.inav[ind].data
                else:
                    cen = center
                ai = get_azimuthal_integrator(
                    detector=detector,
                    detector_distance=detector_dist,
                    shape=sig_shape,
                    center=cen,
                    wavelength=wavelength,
                )  # take 1st center
                radial_range = _get_radial_extent(ai=ai,
                                                  shape=sig_shape,
                                                  unit=unit)
                radial_range[0] = 0
            integration = self.map(azimuthal_integrate2d_slow,
                                   npt_azim=npt_azim,
                                   detector=detector,
                                   center=center,
                                   mask=mask,
                                   affine=affine,
                                   detector_distance=detector_dist,
                                   npt_rad=npt_rad,
                                   wavelength=wavelength,
                                   radial_range=radial_range,
                                   azimuth_range=azimuth_range,
                                   inplace=inplace,
                                   unit=unit,
                                   method=method,
                                   correctSolidAngle=correctSolidAngle,
                                   **integrate2d_kwargs,
                                   **map_kwargs)  # Uses slow methodology

        else:  # much simpler and no changing integrator without using map iterate
            ai = get_azimuthal_integrator(detector=detector,
                                          detector_distance=detector_dist,
                                          shape=sig_shape,
                                          center=center,
                                          affine=affine,
                                          mask=mask,
                                          wavelength=wavelength,
                                          **ai_kwargs)
            if radial_range is None:
                radial_range = _get_radial_extent(ai=ai,
                                                  shape=sig_shape,
                                                  unit=unit)
                radial_range[0] = 0

            integration = self.map(azimuthal_integrate2d_fast,
                                   azimuthal_integrator=ai,
                                   npt_rad=npt_rad,
                                   npt_azim=npt_azim,
                                   azimuth_range=azimuth_range,
                                   radial_range=radial_range,
                                   method=method,
                                   inplace=inplace,
                                   unit=unit,
                                   correctSolidAngle=correctSolidAngle,
                                   **integrate2d_kwargs,
                                   **map_kwargs)

        # Dealing with axis changes
        if inplace:
            t_axis = self.axes_manager.signal_axes[0]
            k_axis = self.axes_manager.signal_axes[1]
            self.set_signal_type("polar_diffraction")
        else:
            transfer_navigation_axes(integration, self)
            integration.set_signal_type("polar_diffraction")
            t_axis = integration.axes_manager.signal_axes[0]
            k_axis = integration.axes_manager.signal_axes[1]
        t_axis.name = "Radians"
        if azimuth_range is None:
            t_axis.scale = np.pi * 2 / npt_azim
            t_axis.offset = -np.pi
        else:
            t_axis.scale = (azimuth_range[1] - azimuth_range[0]) / npt_rad
            t_axis.offset = azimuth_range[0]
        k_axis.name = "Radius"
        if pyxem_units:
            k_axis.scale = (radial_range[1] -
                            radial_range[0]) / npt_rad / scale_factor
            k_axis.offset = radial_range[0] / scale_factor
        else:
            k_axis.scale = (radial_range[1] - radial_range[0]) / npt_rad
            k_axis.units = unit
            k_axis.offset = radial_range[0]

        return integration