コード例 #1
0
    def test_assertion_free_get_diffraction_pattern(self):
        short_sim = DiffractionSimulation(coordinates=np.asarray(
            [[0.3, 1.2, 0]]),
                                          intensities=np.ones(1),
                                          calibration=[1, 2])

        z = short_sim.get_diffraction_pattern()
コード例 #2
0
 def test_calibrated_coordinates(
         self, diffraction_simulation: DiffractionSimulation, coordinates,
         calibration, offset, expected):
     diffraction_simulation.coordinates = coordinates
     diffraction_simulation.calibration = calibration
     diffraction_simulation.offset = offset
     assert np.allclose(diffraction_simulation.calibrated_coordinates,
                        expected)
コード例 #3
0
ファイル: test_marker_plotting.py プロジェクト: swang29/pyxem
def test_marker_placement_correct_beta():
    dps = []
    dp_cord_list = np.divide(generate_dp_cord_list(), 80)
    max_r = np.max(dp_cord_list) + 0.1
    for coords in dp_cord_list:
        dp_sim = DiffractionSimulation(coordinates=coords,
                                       intensities=np.ones_like(coords[:, 0]))
        dps.append(sim_as_signal(dp_sim, 144, 0.025, max_r).data)  # stores a numpy array of pattern
    dp = pxm.ElectronDiffraction2D(np.array([dps[0:2], dps[2:]]))  # now from a 2x2 array of patterns
    dp.set_diffraction_calibration(2 * max_r / (144))
    local_plotter(dp, dp_cord_list)

    # This is human assessed, if you see this comment, you should check it
    assert True
コード例 #4
0
def create_library_and_diffraction_pattern():
    """ This creates a library, the first 4 entries of which are used to
    create the relevant diffraction patterns, we then test the we get suitable
    results for matching """

    dps = []
    half_shape = (72, 72)
    num_orientations = 11
    simulations = np.empty(num_orientations, dtype="object")
    orientations = np.empty(num_orientations, dtype="object")
    pixel_coords = np.empty(num_orientations, dtype="object")
    intensities = np.empty(num_orientations, dtype="object")

    # Creating the matchresults.
    for alpha in np.arange(11):
        coords = (np.random.rand(5, 2) -
                  0.5) * 2  # zero mean, range from -1 to +1
        simulated_pattern = DiffractionSimulation(
            coordinates=coords,
            intensities=np.ones_like(coords[:, 0]),
            calibration=1 / 72,
        )

        simulations[alpha] = simulated_pattern
        orientations[alpha] = (alpha, alpha, alpha)
        intensities[alpha] = simulated_pattern.intensities
        pixel_coords[alpha] = (
            simulated_pattern.calibrated_coordinates[:, :2] +
            half_shape).astype(int)

        if alpha < 4:
            z = sim_as_signal(simulated_pattern, 2 * 72, 0.075, 1)
            dps.append(z.data)  # stores a numpy array of pattern

    dp = pxm.ElectronDiffraction2D([dps[0:2], dps[2:]
                                    ])  # now from a 2x2 array of patterns
    library = DiffractionLibrary()
    library["Phase"] = {
        "simulations": simulations,
        "orientations": orientations,
        "pixel_coords": pixel_coords,
        "intensities": intensities,
    }

    return dp, library
コード例 #5
0
def create_library():
    dps = []
    half_side_length = 72
    half_shape = (half_side_length, half_side_length)
    num_orientations = 11
    simulations = np.empty(num_orientations, dtype='object')
    orientations = np.empty(num_orientations, dtype='object')
    pixel_coords = np.empty(num_orientations, dtype='object')
    intensities = np.empty(num_orientations, dtype='object')

    # Creating the matchresults.
    for alpha in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
        coords = (np.random.rand(5, 2) -
                  0.5) * 2  # zero mean, range from -1 to +1
        dp_sim = DiffractionSimulation(coordinates=coords,
                                       intensities=np.ones_like(coords[:, 0]),
                                       calibration=1 / half_side_length)
        simulations[alpha] = dp_sim
        orientations[alpha] = (alpha, alpha, alpha)
        pixel_coords[alpha] = (dp_sim.calibrated_coordinates[:, :2] +
                               half_shape).astype(int)
        intensities[alpha] = dp_sim.intensities
        if alpha < 4:
            dps.append(
                sim_as_signal(dp_sim, 2 * half_side_length, 0.075,
                              1).data)  # stores a numpy array of pattern

    library = DiffractionLibrary()
    library["Phase"] = {
        'simulations': simulations,
        'orientations': orientations,
        'pixel_coords': pixel_coords,
        'intensities': intensities,
    }
    dp = pxm.ElectronDiffraction2D([dps[0:2], dps[2:]
                                    ])  # now from a 2x2 array of patterns
    return dp, library
コード例 #6
0
    def calculate_ed_data(
        self,
        structure,
        reciprocal_radius,
        rotation=(0, 0, 0),
        with_direct_beam=True,
        max_excitation_error=1e-2,
        shape_factor_width=None,
        debye_waller_factors={},
    ):
        """Calculates the Electron Diffraction data for a structure.

        Parameters
        ----------
        structure : diffpy.structure.structure.Structure
            The structure for which to derive the diffraction pattern.
            Note that the structure must be rotated to the appropriate
            orientation and that testing is conducted on unit cells
            (rather than supercells).
        reciprocal_radius : float
            The maximum radius of the sphere of reciprocal space to
            sample, in reciprocal Angstroms.
        rotation : tuple
            Euler angles, in degrees, in the rzxz convention. Default is
            (0, 0, 0) which aligns 'z' with the electron beam.
        with_direct_beam : bool
            If True, the direct beam is included in the simulated
            diffraction pattern. If False, it is not.
        max_excitation_error : float
            The cut-off for geometric excitation error in the z-direction
            in units of reciprocal Angstroms. Spots with a larger distance
            from the Ewald sphere are removed from the pattern.
            Related to the extinction distance and roungly equal to 1/thickness.
        shape_factor_width : float
            Determines the width of the reciprocal rel-rod, for fine-grained
            control. If not set will be set equal to max_excitation_error.
        debye_waller_factors : dict of str:value pairs
            Maps element names to their temperature-dependent Debye-Waller factors.

        Returns
        -------
        diffsims.sims.diffraction_simulation.DiffractionSimulation
            The data associated with this structure and diffraction setup.
        """
        # Specify variables used in calculation
        wavelength = self.wavelength
        latt = structure.lattice

        # Obtain crystallographic reciprocal lattice points within `reciprocal_radius` and
        # g-vector magnitudes for intensity calculations.
        recip_latt = latt.reciprocal()
        g_indices, cartesian_coordinates, g_hkls = get_points_in_sphere(
            recip_latt, reciprocal_radius
        )

        ai, aj, ak = (
            np.deg2rad(rotation[0]),
            np.deg2rad(rotation[1]),
            np.deg2rad(rotation[2]),
        )
        R = euler2mat(ai, aj, ak, axes="rzxz")
        cartesian_coordinates = np.matmul(R, cartesian_coordinates.T).T

        # Identify the excitation errors of candidate points
        r_sphere = 1 / wavelength
        r_spot = np.sqrt(np.sum(np.square(cartesian_coordinates[:, :2]), axis=1))
        z_spot = cartesian_coordinates[:, 2]

        z_sphere = -np.sqrt(r_sphere ** 2 - r_spot ** 2) + r_sphere
        excitation_error = z_sphere - z_spot

        # determine the pre-selection reflections
        if self.precession_angle == 0:
            intersection = np.abs(excitation_error) < max_excitation_error
        else:
            # only consider points that intersect the ewald sphere at some point
            # the center point of the sphere
            P_z = r_sphere * np.cos(np.deg2rad(self.precession_angle))
            P_t = r_sphere * np.sin(np.deg2rad(self.precession_angle))
            # the extremes of the ewald sphere
            z_surf_up = P_z - np.sqrt(r_sphere ** 2 - (r_spot + P_t) ** 2)
            z_surf_do = P_z - np.sqrt(r_sphere ** 2 - (r_spot - P_t) ** 2)
            intersection = (z_spot - max_excitation_error <= z_surf_up) & (
                z_spot + max_excitation_error >= z_surf_do
            )

        # select these reflections
        intersection_coordinates = cartesian_coordinates[intersection]
        excitation_error = excitation_error[intersection]
        r_spot = r_spot[intersection]
        g_indices = g_indices[intersection]
        g_hkls = g_hkls[intersection]

        if shape_factor_width is None:
            shape_factor_width = max_excitation_error
        # select and evaluate shape factor model
        if self.precession_angle == 0:
            # calculate shape factor
            shape_factor = self.shape_factor_model(
                excitation_error, shape_factor_width, **self.shape_factor_kwargs
            )
        else:
            if self.approximate_precession:
                shape_factor = lorentzian_precession(
                    excitation_error,
                    shape_factor_width,
                    r_spot,
                    np.deg2rad(self.precession_angle),
                )
            else:
                shape_factor = _shape_factor_precession(
                    excitation_error,
                    r_spot,
                    np.deg2rad(self.precession_angle),
                    self.shape_factor_model,
                    shape_factor_width,
                    **self.shape_factor_kwargs,
                )
        # Calculate diffracted intensities based on a kinematical model.
        intensities = get_kinematical_intensities(
            structure,
            g_indices,
            g_hkls,
            prefactor=shape_factor,
            scattering_params=self.scattering_params,
            debye_waller_factors=debye_waller_factors,
        )

        # Threshold peaks included in simulation as factor of maximum intensity.
        peak_mask = intensities > np.max(intensities) * self.minimum_intensity
        intensities = intensities[peak_mask]
        intersection_coordinates = intersection_coordinates[peak_mask]
        g_indices = g_indices[peak_mask]

        return DiffractionSimulation(
            coordinates=intersection_coordinates,
            indices=g_indices,
            intensities=intensities,
            with_direct_beam=with_direct_beam,
        )
コード例 #7
0
    def calculate_ed_data(self,
                          structure,
                          reciprocal_radius,
                          rotation=(0, 0, 0),
                          with_direct_beam=True):
        """Calculates the Electron Diffraction data for a structure.

        Parameters
        ----------
        structure : Structure
            The structure for which to derive the diffraction pattern. Note that
            the structure must be rotated to the appropriate orientation and
            that testing is conducted on unit cells (rather than supercells).
        reciprocal_radius : float
            The maximum radius of the sphere of reciprocal space to sample, in
            reciprocal angstroms.
        rotation : tuple
            Euler angles, in degrees, in the rzxz convention. Default is (0,0,0)
            which aligns 'z' with the electron beam
        with_direct_beam : bool
            If True, the direct beam is included in the simulated diffraction
            pattern. If False, it is not.

        Returns
        -------
        diffsims.DiffractionSimulation
            The data associated with this structure and diffraction setup.

        """
        # Specify variables used in calculation
        wavelength = self.wavelength
        max_excitation_error = self.max_excitation_error
        debye_waller_factors = self.debye_waller_factors
        latt = structure.lattice
        scattering_params = self.scattering_params

        # Obtain crystallographic reciprocal lattice points within `max_r` and
        # g-vector magnitudes for intensity calculations.
        recip_latt = latt.reciprocal()
        spot_indicies, cartesian_coordinates, spot_distances = get_points_in_sphere(
            recip_latt, reciprocal_radius)

        ai, aj, ak = np.deg2rad(rotation[0]), np.deg2rad(
            rotation[1]), np.deg2rad(rotation[2])
        R = euler2mat(ai, aj, ak, axes='rzxz')
        cartesian_coordinates = np.matmul(R, cartesian_coordinates.T).T

        # Identify points intersecting the Ewald sphere within maximum
        # excitation error and store the magnitude of their excitation error.
        r_sphere = 1 / wavelength
        r_spot = np.sqrt(
            np.sum(np.square(cartesian_coordinates[:, :2]), axis=1))
        z_sphere = -np.sqrt(r_sphere**2 - r_spot**2) + r_sphere
        proximity = np.absolute(z_sphere - cartesian_coordinates[:, 2])
        intersection = proximity < max_excitation_error
        # Mask parameters corresponding to excited reflections.
        intersection_coordinates = cartesian_coordinates[intersection]
        intersection_indices = spot_indicies[intersection]
        proximity = proximity[intersection]
        g_hkls = spot_distances[intersection]

        # Calculate diffracted intensities based on a kinematical model.
        intensities = get_kinematical_intensities(
            structure, intersection_indices, g_hkls, proximity,
            max_excitation_error, debye_waller_factors, scattering_params)

        # Threshold peaks included in simulation based on minimum intensity.
        peak_mask = intensities > 1e-20
        intensities = intensities[peak_mask]
        intersection_coordinates = intersection_coordinates[peak_mask]
        intersection_indices = intersection_indices[peak_mask]

        return DiffractionSimulation(coordinates=intersection_coordinates,
                                     indices=intersection_indices,
                                     intensities=intensities,
                                     with_direct_beam=with_direct_beam)
コード例 #8
0
 def diffraction_simulation(self):
     return DiffractionSimulation()
コード例 #9
0
def test_wrong_calibration_setting():
    DiffractionSimulation(
        coordinates=np.asarray([[0.3, 1.2, 0]]),
        intensities=np.ones(1),
        calibration=[1, 2, 5],
    )
コード例 #10
0
    def calculate_ed_data(self,
                          structure,
                          reciprocal_radius,
                          rotation=(0, 0, 0),
                          shape_factor_model="linear",
                          max_excitation_error=1e-2,
                          with_direct_beam=True,
                          **kwargs):
        """Calculates the Electron Diffraction data for a structure.

        Parameters
        ----------
        structure : Structure
            The structure for which to derive the diffraction pattern. Note that
            the structure must be rotated to the appropriate orientation and
            that testing is conducted on unit cells (rather than supercells).
        reciprocal_radius : float
            The maximum radius of the sphere of reciprocal space to sample, in
            reciprocal angstroms.
        rotation : tuple
            Euler angles, in degrees, in the rzxz convention. Default is (0,0,0)
            which aligns 'z' with the electron beam
        shape_factor_model : function or str
            a function that takes excitation_error and max_excitation_error (and potentially **kwargs) and returns an intensity
            scaling factor. The code provides "linear" and "binary" options accessed with by parsing the associated strings
        max_excitation_error : float
            the exctinction distance for reflections, in reciprocal Angstroms
        with_direct_beam : bool
            If True, the direct beam is included in the simulated diffraction
            pattern. If False, it is not.
        **kwargs :
            passed to shape_factor_model

        Returns
        -------
        diffsims.DiffractionSimulation
            The data associated with this structure and diffraction setup.

        """
        # Specify variables used in calculation
        wavelength = self.wavelength
        latt = structure.lattice

        # Obtain crystallographic reciprocal lattice points within `reciprocal_radius` and
        # g-vector magnitudes for intensity calculations.
        recip_latt = latt.reciprocal()
        spot_indices, cartesian_coordinates, spot_distances = get_points_in_sphere(
            recip_latt, reciprocal_radius)

        ai, aj, ak = (
            np.deg2rad(rotation[0]),
            np.deg2rad(rotation[1]),
            np.deg2rad(rotation[2]),
        )
        R = euler2mat(ai, aj, ak, axes="rzxz")
        cartesian_coordinates = np.matmul(R, cartesian_coordinates.T).T

        # Identify points intersecting the Ewald sphere within maximum
        # excitation error and store the magnitude of their excitation error.
        r_sphere = 1 / wavelength
        r_spot = np.sqrt(
            np.sum(np.square(cartesian_coordinates[:, :2]), axis=1))
        z_sphere = -np.sqrt(r_sphere**2 - r_spot**2) + r_sphere
        excitation_error = np.absolute(z_sphere - cartesian_coordinates[:, 2])
        intersection = excitation_error < max_excitation_error
        # Mask parameters corresponding to excited reflections.
        intersection_coordinates = cartesian_coordinates[intersection]
        g_indices = spot_indices[intersection]
        excitation_error = excitation_error[intersection]
        g_hkls = spot_distances[intersection]

        if shape_factor_model == "linear":
            shape_factor = 1 - (excitation_error / max_excitation_error)
        elif shape_factor_model == "binary":
            shape_factor = 1
        else:
            shape_factor = shape_factor_model(excitation_error,
                                              max_excitation_error, **kwargs)

        # Calculate diffracted intensities based on a kinematical model.
        intensities = get_kinematical_intensities(
            structure,
            g_indices,
            g_hkls,
            prefactor=shape_factor,
            scattering_params=self.scattering_params,
            debye_waller_factors=self.debye_waller_factors,
        )

        # Threshold peaks included in simulation based on minimum intensity.
        peak_mask = intensities > 1e-20
        intensities = intensities[peak_mask]
        intersection_coordinates = intersection_coordinates[peak_mask]
        g_indices = g_indices[peak_mask]

        return DiffractionSimulation(
            coordinates=intersection_coordinates,
            indices=g_indices,
            intensities=intensities,
            with_direct_beam=with_direct_beam,
        )
コード例 #11
0
    def calculate_ed_data(
        self,
        structure,
        reciprocal_radius,
        rotation=(0, 0, 0),
        with_direct_beam=True,
        max_excitation_error=1e-2,
        debye_waller_factors={},
    ):
        """Calculates the Electron Diffraction data for a structure.

        Parameters
        ----------
        structure : diffpy.structure.structure.Structure
            The structure for which to derive the diffraction pattern.
            Note that the structure must be rotated to the appropriate
            orientation and that testing is conducted on unit cells
            (rather than supercells).
        reciprocal_radius : float
            The maximum radius of the sphere of reciprocal space to
            sample, in reciprocal Angstroms.
        rotation : tuple
            Euler angles, in degrees, in the rzxz convention. Default is
            (0, 0, 0) which aligns 'z' with the electron beam.
        with_direct_beam : bool
            If True, the direct beam is included in the simulated
            diffraction pattern. If False, it is not.
        max_excitation_error : float
            The extinction distance for reflections, in reciprocal
            Angstroms. Roughly equal to 1/thickness.
        debye_waller_factors : dict of str:value pairs
            Maps element names to their temperature-dependent Debye-Waller factors.

        Returns
        -------
        diffsims.sims.diffraction_simulation.DiffractionSimulation
            The data associated with this structure and diffraction setup.
        """
        # Specify variables used in calculation
        wavelength = self.wavelength
        latt = structure.lattice

        # Obtain crystallographic reciprocal lattice points within `reciprocal_radius` and
        # g-vector magnitudes for intensity calculations.
        recip_latt = latt.reciprocal()
        g_indices, cartesian_coordinates, g_hkls = get_points_in_sphere(
            recip_latt, reciprocal_radius)

        ai, aj, ak = (
            np.deg2rad(rotation[0]),
            np.deg2rad(rotation[1]),
            np.deg2rad(rotation[2]),
        )
        R = euler2mat(ai, aj, ak, axes="rzxz")
        cartesian_coordinates = np.matmul(R, cartesian_coordinates.T).T

        # Identify the excitation errors of candidate points
        r_sphere = 1 / wavelength
        r_spot = np.sqrt(
            np.sum(np.square(cartesian_coordinates[:, :2]), axis=1))
        z_spot = cartesian_coordinates[:, 2]

        z_sphere = -np.sqrt(r_sphere**2 - r_spot**2) + r_sphere
        excitation_error = z_sphere - z_spot

        if self.precession_angle == 0:
            # Mask parameters corresponding to excited reflections.
            intersection = np.abs(excitation_error) < max_excitation_error
            intersection_coordinates = cartesian_coordinates[intersection]
            excitation_error = excitation_error[intersection]
            r_spot = r_spot[intersection]
            g_indices = g_indices[intersection]
            g_hkls = g_hkls[intersection]

            # calculate shape factor
            shape_factor = self.shape_factor_model(excitation_error,
                                                   max_excitation_error,
                                                   **self.shape_factor_kwargs)
        else:
            intersection_coordinates = cartesian_coordinates  #for naming simplicity

            if self.approximate_precession:
                shape_factor = lorentzian_precession(
                    excitation_error,
                    max_excitation_error,
                    r_spot,
                    np.deg2rad(self.precession_angle),
                )
            else:
                shape_factor = _shape_factor_precession(
                    excitation_error,
                    r_spot,
                    np.deg2rad(self.precession_angle),
                    self.shape_factor_model,
                    max_excitation_error,
                    **self.shape_factor_kwargs,
                )
        # Calculate diffracted intensities based on a kinematical model.
        intensities = get_kinematical_intensities(
            structure,
            g_indices,
            g_hkls,
            prefactor=shape_factor,
            scattering_params=self.scattering_params,
            debye_waller_factors=debye_waller_factors,
        )

        # Threshold peaks included in simulation based on minimum intensity.
        peak_mask = intensities > np.max(intensities) * self.minimum_intensity
        intensities = intensities[peak_mask]
        intersection_coordinates = intersection_coordinates[peak_mask]
        g_indices = g_indices[peak_mask]

        return DiffractionSimulation(
            coordinates=intersection_coordinates,
            indices=g_indices,
            intensities=intensities,
            with_direct_beam=with_direct_beam,
        )