diff --git a/diffsims/generators/diffraction_generator.py b/diffsims/generators/diffraction_generator.py index 34e8976a..69d0a10c 100644 --- a/diffsims/generators/diffraction_generator.py +++ b/diffsims/generators/diffraction_generator.py @@ -22,6 +22,7 @@ import numpy as np from math import pi +from transforms3d.euler import euler2mat from diffsims.sims.diffraction_simulation import DiffractionSimulation from diffsims.sims.diffraction_simulation import ProfileSimulation @@ -83,6 +84,7 @@ def __init__(self, def calculate_ed_data(self, structure, reciprocal_radius, + rotation=(0,0,0), with_direct_beam=True): """Calculates the Electron Diffraction data for a structure. @@ -95,6 +97,9 @@ def calculate_ed_data(self, 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. @@ -118,6 +123,10 @@ def calculate_ed_data(self, 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 diff --git a/diffsims/generators/library_generator.py b/diffsims/generators/library_generator.py index d1f8d696..aac52f8f 100644 --- a/diffsims/generators/library_generator.py +++ b/diffsims/generators/library_generator.py @@ -30,7 +30,6 @@ from diffsims.libraries.vector_library import DiffractionVectorLibrary from diffsims.utils.sim_utils import get_points_in_sphere -from diffsims.utils.sim_utils import simulate_rotated_structure from diffsims.utils.vector_utils import get_angle_cartesian_vec @@ -101,8 +100,7 @@ def get_diffraction_library(self, intensities = np.empty(num_orientations, dtype='object') # Iterate through orientations of each phase. for i, orientation in enumerate(tqdm(orientations, leave=False)): - matrix = euler2mat(*np.deg2rad(orientation), 'rzxz') - simulation = simulate_rotated_structure(diffractor, structure, matrix, reciprocal_radius, with_direct_beam) + simulation = diffractor.calculate_ed_data(structure,reciprocal_radius,rotation=orientation,with_direct_beam=with_direct_beam) # Calibrate simulation simulation.calibration = calibration diff --git a/diffsims/utils/sim_utils.py b/diffsims/utils/sim_utils.py index b0bc7fd9..b7c16c34 100644 --- a/diffsims/utils/sim_utils.py +++ b/diffsims/utils/sim_utils.py @@ -346,46 +346,6 @@ def simulate_kinematic_scattering(atomic_coordinates, return intensity - -def simulate_rotated_structure(diffraction_generator, structure, rotation_matrix, reciprocal_radius, with_direct_beam): - """Calculate electron diffraction data for a structure after rotating it. - - Parameters - ---------- - diffraction_generator : DiffractionGenerator - Diffraction generator used to simulate diffraction patterns - structure : diffpy.structure.Structure - Structure object to simulate - rotation_matrix : ndarray - 3x3 matrix describing the base rotation to apply to the structure, applied on the left of the vector - reciprocal_radius : float - The maximum g-vector magnitude to be included in the simulations. - with_direct_beam : bool - Include the direct beam peak - - Returns - ------- - simulation : DiffractionSimulation - The simulation data generated from the given structure and rotation. - """ - # Convert left multiply (input) to right multiply (diffpy) - stdbase = structure.lattice.stdbase - stdbase_inverse = np.linalg.inv(stdbase) - rotation_matrix_diffpy = stdbase_inverse @ rotation_matrix @ stdbase - - lattice_rotated = diffpy.structure.lattice.Lattice( - *structure.lattice.abcABG(), - baserot=rotation_matrix_diffpy) - # Don't change the original - structure_rotated = diffpy.structure.Structure(structure) - structure_rotated.placeInLattice(lattice_rotated) - - return diffraction_generator.calculate_ed_data( - structure_rotated, - reciprocal_radius, - with_direct_beam) - - def get_points_in_sphere(reciprocal_lattice, reciprocal_radius): """Finds all reciprocal lattice points inside a given reciprocal sphere. Utilised within the DiffractionGenerator.