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 calculate_ed_data(self, structure, reciprocal_radius, 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. Returns ------- pyxem.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) # 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)