def test_strain_mapping_affine_transform(): latt = diffpy.structure.lattice.Lattice(3, 3, 3, 90, 90, 90) atom = diffpy.structure.atom.Atom(atype='Zn', xyz=[0, 0, 0], lattice=latt) structure = diffpy.structure.Structure(atoms=[atom], lattice=latt) ediff = DiffractionGenerator(300., 0.025) affines = [[[1, 0, 0], [0, 1, 0], [0, 0, 1]], [[1.04, 0, 0], [0, 1, 0], [0, 0, 1]], [[1.08, 0, 0], [0, 1, 0], [0, 0, 1]], [[1.12, 0, 0], [0, 1, 0], [0, 0, 1]]] data = [] for affine in affines: # same coords as used for latt above latt_rot = diffpy.structure.lattice.Lattice(3, 3, 3, 90, 90, 90, baserot=affine) structure.placeInLattice(latt_rot) diff_dat = ediff.calculate_ed_data(structure, 2.5) dpi = sim_as_signal(diff_dat, 64, 0.02, 2.5) data.append(dpi.data) data = np.array(data) dp = ElectronDiffraction2D(data.reshape((2, 2, 64, 64))) m = dp.create_model() ref = ScalableReferencePattern(dp.inav[0, 0]) m.append(ref) m.multifit() disp_grad = ref.construct_displacement_gradient() assert disp_grad.data.shape == np.asarray(affines).reshape(2, 2, 3, 3).shape
def update_pattern(_=None): reciprocal_angstrom_per_pixel = slider_scale.val simulated_gaussian_sigma = slider_sigma.val phi = np.deg2rad(slider_phi.val) theta = np.deg2rad(slider_theta.val) psi = np.deg2rad(slider_psi.val) structure_rotation = euler2mat(phi, theta, psi, axes='rzxz') lattice_rotated = diffpy.structure.lattice.Lattice( structure.lattice.a, structure.lattice.b, structure.lattice.c, structure.lattice.alpha, structure.lattice.beta, structure.lattice.gamma, baserot=structure_rotation) structure.placeInLattice(lattice_rotated) reciprocal_radius = reciprocal_angstrom_per_pixel * (half_pattern_size - 1) sim = gen.calculate_ed_data(structure, reciprocal_radius, with_direct_beam=False) # sim.intensities = np.full(sim.direct_beam_mask.shape, 1) # For testing, ignore intensities # sim._intensities = np.log(1 + sim._intensities) s = sim.as_signal(target_pattern_dimension_pixels, simulated_gaussian_sigma, reciprocal_radius) img.set_data(s.data) rotation_matrices = generate_rotation_list(structure, phi, theta, psi, max_theta, resolution) update_rotation(rotation_matrices) fig.canvas.draw_idle()
def test_kinematic_intensities_error_raise(structure, rotation): """Test that kinematically forbidden diffraction spots gets zero intensity also after rotation.""" rotated_lattice = diffpy.structure.lattice.Lattice(structure.lattice) rotated_lattice.setLatPar(baserot=rotation) structure.placeInLattice(rotated_lattice) reciprocal_lattice = structure.lattice.reciprocal() g_indices = [(0, 0, 1)] g_hkls = reciprocal_lattice.dist(g_indices, [0, 0, 0]) intensities = get_kinematical_intensities(structure, g_indices, g_hkls, excitation_error=0, maximum_excitation_error=1, debye_waller_factors={}, scattering_params='_empty')
def test_kinematic_intensities_rotation(structure, rotation): """Test that kinematically forbidden diffraction spots gets zero intensity also after rotation.""" rotated_lattice = diffpy.structure.lattice.Lattice(structure.lattice) rotated_lattice.setLatPar(baserot=rotation) structure.placeInLattice(rotated_lattice) reciprocal_lattice = structure.lattice.reciprocal() g_indices = [(0, 0, 1)] g_hkls = reciprocal_lattice.dist(g_indices, [0, 0, 0]) scattering_params_list = ['lobato', 'xtables'] for scattering_params in scattering_params_list: intensities = get_kinematical_intensities( structure, g_indices, g_hkls, excitation_error=0, maximum_excitation_error=1, debye_waller_factors={}, scattering_params=scattering_params) np.testing.assert_almost_equal(intensities, [0])
def get_diffraction_library(self, structure_library, calibration, reciprocal_radius, half_shape, with_direct_beam=True): """Calculates a dictionary of diffraction data for a library of crystal structures and orientations. Each structure in the structure library is rotated to each associated orientation and the diffraction pattern is calculated each time. Angles must be in the Euler representation (Z,X,Z) and in degrees Parameters ---------- structure_library : pyxem:StructureLibrary Object Dictionary of structures and associated orientations for which electron diffraction is to be simulated. calibration : float The calibration of experimental data to be correlated with the library, in reciprocal Angstroms per pixel. reciprocal_radius : float The maximum g-vector magnitude to be included in the simulations. half_shape: tuple The half shape of the target patterns, for 144x144 use (72,72) etc Returns ------- diffraction_library : dict of :class:`DiffractionSimulation` Mapping of crystal structure and orientation to diffraction data objects. """ # Define DiffractionLibrary object to contain results diffraction_library = DiffractionLibrary() # The electron diffraction calculator to do simulations diffractor = self.electron_diffraction_calculator structure_library = structure_library.struct_lib # Iterate through phases in library. for key in structure_library.keys(): phase_diffraction_library = dict() structure = structure_library[key][0] a, b, c = structure.lattice.a, structure.lattice.b, structure.lattice.c alpha = structure.lattice.alpha beta = structure.lattice.beta gamma = structure.lattice.gamma orientations = structure_library[key][1] # Iterate through orientations of each phase. for orientation in tqdm(orientations, leave=False): _orientation = np.deg2rad(orientation) matrix = euler2mat(_orientation[0], _orientation[1], _orientation[2], 'rzxz') latt_rot = diffpy.structure.lattice.Lattice(a, b, c, alpha, beta, gamma, baserot=matrix) structure.placeInLattice(latt_rot) # Calculate electron diffraction for rotated structure data = diffractor.calculate_ed_data(structure, reciprocal_radius, with_direct_beam) # Calibrate simulation data.calibration = calibration pattern_intensities = data.intensities pixel_coordinates = np.rint( data.calibrated_coordinates[:, :2] + half_shape).astype(int) # Construct diffraction simulation library, removing those that # contain no peaks if len(pattern_intensities) > 0: phase_diffraction_library[tuple(orientation)] = \ {'Sim': data, 'intensities': pattern_intensities, 'pixel_coords': pixel_coordinates, 'pattern_norm': np.sqrt(np.dot(pattern_intensities, pattern_intensities))} diffraction_library[key] = phase_diffraction_library return diffraction_library