def get_vector_library(self, reciprocal_radius): """Calculates a library of diffraction vectors and pairwise inter-vector angles for a library of crystal structures. Parameters ---------- reciprocal_radius : float The maximum g-vector magnitude to be included in the library. Returns ------- vector_library : :class:`DiffractionVectorLibrary` Mapping of phase identifier to a numpy array with entries in the form: [hkl1, hkl2, len1, len2, angle] ; lengths are in reciprocal Angstroms and angles are in radians. """ # Define DiffractionVectorLibrary object to contain results vector_library = DiffractionVectorLibrary() # Get structures from structure library structure_library = self.structures.struct_lib # Iterate through phases in library. for phase_name in structure_library.keys(): # Get diffpy.structure object associated with phase structure = structure_library[phase_name][0] # Get reciprocal lattice points within reciprocal_radius recip_latt = structure.lattice.reciprocal() indices, coordinates, distances = get_points_in_sphere( recip_latt, reciprocal_radius) # Iterate through all pairs calculating interplanar angle phase_vector_pairs = [] for comb in itertools.combinations(np.arange(len(indices)), 2): i, j = comb[0], comb[1] # Specify hkls and lengths associated with the crystal structure. # TODO: This should be updated to reflect systematic absences if np.count_nonzero(coordinates[i]) == 0 or np.count_nonzero( coordinates[j]) == 0: continue # Ignore combinations including [000] hkl1 = indices[i] hkl2 = indices[j] len1 = distances[i] len2 = distances[j] if len1 < len2: # Keep the longest first hkl1, hkl2 = hkl2, hkl1 len1, len2 = len1, len2 angle = get_angle_cartesian(coordinates[i], coordinates[j]) phase_vector_pairs.append( np.array([hkl1, hkl2, len1, len2, angle])) vector_library[phase_name] = np.array(phase_vector_pairs) # Pass attributes to diffraction library from structure library. vector_library.identifiers = self.structures.identifiers vector_library.structures = self.structures.structures return vector_library
def vector_library(): library = DiffractionVectorLibrary() library['A'] = np.array([ [np.array([1, 0, 0]), np.array([0, 2, 0]), 2, 1, np.pi / 2], [np.array([0, 0, 1]), np.array([2, 0, 0]), 1, 2, np.pi / 2], ]) lattice = diffpy.structure.Lattice(1, 1, 1, 90, 90, 90) library.structures = [diffpy.structure.Structure(lattice=lattice)] return library
def test_vector_indexation_generator_init(): vectors = DiffractionVectors([[1], [2]]) vectors.cartesian = [[1], [2]] vector_library = DiffractionVectorLibrary() vector_indexation_generator = VectorIndexationGenerator(vectors, vector_library) assert isinstance(vector_indexation_generator, VectorIndexationGenerator) assert vector_indexation_generator.vectors == vectors assert vector_indexation_generator.library == vector_library
def vector_library(): library = DiffractionVectorLibrary() library['A'] = { 'indices': np.array([ [[0, 2, 0], [1, 0, 0]], [[1, 2, 3], [0, 2, 0]], [[1, 2, 3], [1, 0, 0]], ]), 'measurements': np.array([ [2, 1, np.pi / 2], [np.sqrt(14), 2, 1.006853685], [np.sqrt(14), 1, 1.300246564], ]) } lattice = diffpy.structure.Lattice(1, 1, 1, 90, 90, 90) library.structures = [diffpy.structure.Structure(lattice=lattice)] return library
def get_vector_library(self, reciprocal_radius): """Calculates a library of diffraction vectors and pairwise inter-vector angles for a library of crystal structures. Parameters ---------- reciprocal_radius : float The maximum g-vector magnitude to be included in the library. Returns ------- vector_library : :class:`DiffractionVectorLibrary` Mapping of phase identifier to phase information in dictionary format. """ # Define DiffractionVectorLibrary object to contain results vector_library = DiffractionVectorLibrary() # Get structures from structure library structure_library = self.structures.struct_lib # Iterate through phases in library. for phase_name in structure_library.keys(): # Get diffpy.structure object associated with phase structure = structure_library[phase_name][0] # Get reciprocal lattice points within reciprocal_radius recip_latt = structure.lattice.reciprocal() miller_indices, coordinates, distances = get_points_in_sphere( recip_latt, reciprocal_radius) # Create pair_indices for selecting all point pair combinations num_indices = len(miller_indices) pair_a_indices, pair_b_indices = np.mgrid[:num_indices, :num_indices] # Only select one of the permutations and don't pair an index with # itself (select above diagonal) upper_indices = np.triu_indices(num_indices, 1) pair_a_indices = pair_a_indices[upper_indices].ravel() pair_b_indices = pair_b_indices[upper_indices].ravel() # Mask off origin (0, 0, 0) origin_index = num_indices // 2 pair_a_indices = pair_a_indices[pair_a_indices != origin_index] pair_b_indices = pair_b_indices[pair_b_indices != origin_index] pair_indices = np.vstack([pair_a_indices, pair_b_indices]) # Create library entries angles = get_angle_cartesian_vec(coordinates[pair_a_indices], coordinates[pair_b_indices]) pair_distances = distances[pair_indices.T] # Ensure longest vector is first len_sort = np.fliplr(pair_distances.argsort(axis=1)) # phase_index_pairs is a list of [hkl1, hkl2] phase_index_pairs = np.take_along_axis(miller_indices[pair_indices.T], len_sort[:, :, np.newaxis], axis=1) # phase_measurements is a list of [len1, len2, angle] phase_measurements = np.column_stack((np.take_along_axis(pair_distances, len_sort, axis=1), angles)) # Only keep unique triplets unique_measurements, unique_measurement_indices = np.unique(phase_measurements, axis=0, return_index=True) vector_library[phase_name] = { 'indices': phase_index_pairs[unique_measurement_indices], 'measurements': unique_measurements } # Pass attributes to diffraction library from structure library. vector_library.identifiers = self.structures.identifiers vector_library.structures = self.structures.structures vector_library.reciprocal_radius = reciprocal_radius return vector_library
def test_vector_indexation_generator_cartesian_check(): vectors = DiffractionVectors([[1], [2]]) vector_library = DiffractionVectorLibrary() vector_indexation_generator = VectorIndexationGenerator( vectors, vector_library)