def test_equality(self): """ Test that __eq__ works as expected """ c1 = Crystal.from_database("Pu-alpha") c2 = deepcopy(c1) self.assertEqual(c1, c2) c3 = Crystal.from_database("Pu-epsilon") self.assertNotEqual(c1, c3)
def test_equality(): """Test that __eq__ works as expected""" c1 = Crystal.from_database("Pu-alpha") c2 = deepcopy(c1) assert c1 == c2 c3 = Crystal.from_database("Pu-epsilon") assert c1 != c3
def test_powdersim_peak_alignment(): """ Test that the diffraction peaks align with what is expected. """ crystal = Crystal.from_database("C") for reflection in [(0, 1, 1), (1, 2, 0), (-1, 2, 0)]: qknown = np.linalg.norm(crystal.scattering_vector((0, 1, 1))) # Range of scattering vectors is tightly centered around a particular reflection # So that the maximum of the diffraction pattern MUST be at reflection (010) q = np.linspace(qknown - 0.1, qknown + 0.1, 256) pattern = powdersim(Crystal.from_database("C"), q) assert abs(q[np.argmax(pattern)] - qknown) < q[1] - q[0]
def test_constructors(self): """ Test Supercell constructors for varyous 'builtin' structures """ for name in islice(Crystal.builtins, 20): with self.subTest(name): s = Crystal.from_database(name).supercell(2, 2, 2) self.assertEqual(len(s), 8 * len(s.crystal))
def get_pendulossung(name='Si', miller=[0, 0, 0], keV=200, opt='p'): ''' give the theorertical 2-beam approximation Pendullosung thickness - `name` : compound - `miller` : [h,k,l] - `keV` : wavelength (keV) RETURN - xi : Pendullosung thickness (A) ''' # compute structure factor from crystals import Crystal crys = Crystal.from_database(name) lat_vec = crys.reciprocal_vectors pattern = np.array( [list(a.coords_fractional) + [a.atomic_number] for a in crys.atoms]) hkl, Fhkl = structure_factor3D(pattern, lat_vec, hklMax=max(miller), sym=0, v='') ax, by, cz = crys.lattice_parameters[:3] Vcell = crys.volume # compute Pendullosung h, k, l = miller Ug, K = np.abs(Fhkl[h, k, l]) / Vcell, 1 / scatf.wavelength(keV) xi = K / Ug if 'p' in opt: print(green + "\tPendullosung thickness " + name + '[%d%d%d]' % (h, k, l) + black) print('%-5s= %.2f\n%-5s= %.2f\n%-5s= %.2f' % ('K', K, 'Ug', Ug, 'xi', xi)) return xi
def test_return_shape(): """ Test that the return shape of pelectrostatic is the same as input arrays """ crystal = Crystal.from_database("C") xx, yy = np.meshgrid(np.linspace(-10, 10, 32), np.linspace(-10, 10, 32)) potential = pelectrostatic(crystal, xx, yy) assert xx.shape == potential.shape
def test_simulation_3_peaks(self): """ Test calibration from simulation, down to 1% error . Peaks (200) and (220) from monoclinic VO2 are used, """ s = np.linspace(0.11, 0.8, 1024) q = 4 * np.pi * s c = Crystal.from_database("vo2-m1") I = powdersim(c, s) peak1 = (2, 0, 0) Gx1, Gy1, Gz1 = c.scattering_vector(peak1) q1 = np.sqrt(Gx1 ** 2 + Gy1 ** 2 + Gz1 ** 2) arr_index1 = np.argmin(np.abs(q - q1)) peak2 = (2, 2, 0) Gx2, Gy2, Gz2 = c.scattering_vector(peak2) q2 = np.sqrt(Gx2 ** 2 + Gy2 ** 2 + Gz2 ** 2) arr_index2 = np.argmin(np.abs(q - q2)) peak3 = (3, 0, -2) Gx2, Gy2, Gz2 = c.scattering_vector(peak3) q3 = np.sqrt(Gx2 ** 2 + Gy2 ** 2 + Gz2 ** 2) arr_index3 = np.argmin(np.abs(q - q3)) calibrated = powder_calq( I, c, peak_indices=(arr_index1, arr_index2, arr_index3), miller_indices=(peak1, peak2, peak3), ) self.assertTupleEqual(I.shape, calibrated.shape) self.assertTrue(np.allclose(q, calibrated, rtol=0.01))
def gen_xyz(file, n=[0, 0, 1], rep=[1, 1, 1], pad=0, xyz='', **kwargs): ''' convert cif file into autoslic .xyz input file - file : cif_file - rep : super cell repeat - n : reorient of the z axis into n - pad : amount of padding on each side (in unit of super cell size) ''' if isinstance(file, str): tail = ''.join(np.array(n, dtype=str)) + '.xyz' if file.split('.')[-1] == 'cif': crys = Crystal.from_cif(file) if not xyz: xyz = file.replace('.cif', tail) elif sum(np.array(list(Crystal.builtins)) == file): crys = Crystal.from_database(file) if not xyz: xyz = file + tail lat_vec = np.array(crys.lattice_vectors) lat_params = crys.lattice_parameters[:3] pattern = np.array([[a.atomic_number] + list(a.coords_cartesian) + [a.occupancy, 1.0] for a in crys.atoms]) else: if not xyz: raise Exception('xyz filename required') pattern = file pattern, lat = make_xyz(xyz, pattern, lat_vec, lat_params, n=n, pad=pad, rep=rep, **kwargs) npy_file = xyz.replace('.xyz', '.npy') np.save(npy_file, [lat, pattern]) print(colors.green + 'binary coords file saved :' + colors.yellow + npy_file + colors.black)
def setUp(self): self.crystal = Crystal.from_database("C") self.reflections = list(combinations_with_replacement(range(-3, 4), 3)) self.intensities = [ np.abs(structure_factor(self.crystal, *reflection))**2 for reflection in self.reflections ]
def test_side_effects(): """ Test that mesh arrays are not written to in pelectrostatic """ crystal = Crystal.from_database("C") xx, yy = np.meshgrid(np.linspace(-10, 10, 32), np.linspace(-10, 10, 32)) xx.setflags(write=False) yy.setflags(write=False) potential = pelectrostatic(crystal, xx, yy)
def Li_rots(): crys = Crystal.from_database('Li') coords = np.array([a.coords_cartesian for a in crys.atoms]) # files = rcc.rotate_xyz(crys,Nrot=8,name='dat/Lithium/rots/',opt='p') files = rcc.orient_crystal(coords,ez=[0,0,1],n_u=[0,,1]) for file in files[:4] : rcc.show_grid(file,title=file,equal=1)#,xyTicks=3.49,xylims=[0,100,0,100])
def test_reciprocal_symmetry_operations(name): """Test that the reciprocal symmetry operations output makes sense""" identity = np.eye(4) c = Crystal.from_database(name) symops = c.reciprocal_symmetry_operations() assert np.allclose(identity, symops[0])
def test_primitive_for_builtins(self): """ Test that all built-in crystal have a primitive cell """ for name in Crystal.builtins: with self.subTest(name): c = Crystal.from_database(name) prim = c.primitive(symprec=0.1) self.assertLessEqual(len(prim), len(c))
def test_builtins(self): """ Test that all names in Crystal.builtins build without errors, and that Crystal.source is correctly recorded. """ for name in Crystal.builtins: with self.subTest(name): c = Crystal.from_database(name) self.assertIn(name, c.source)
def import_crys(file): if file.split('.')[-1] == 'cif': crys = Crystal.from_cif(file) elif sum(np.array(list(Crystal.builtins)) == file): crys = Crystal.from_database(file) else: raise Exception('cannot import %s' % file) return crys
def test_chemical_composition_add_to_unity(self): """ Test that AtomicStructure.chemical_composition always adds up to 1 """ # Faster to create a large atomic structure from a Crystal object # Testing for 10 crystal structures only for name in islice(Crystal.builtins, 10): with self.subTest("Chemical composition: " + name): structure = AtomicStructure(atoms=Crystal.from_database(name)) self.assertAlmostEqual(sum(structure.chemical_composition.values()), 1)
def test_reciprocal_symmetry_operations(self): """ Test that the reciprocal symmetry operations output makes sense """ identity = np.eye(4) for name in Crystal.builtins: with self.subTest(name): c = Crystal.from_database(name) symops = c.reciprocal_symmetry_operations() self.assertTrue(np.allclose(identity, symops[0]))
def Li_xyz(path,n=[0,0,1],dopt=1,lfact=1.0,wobble=0,tail=''): file = path+'Li%s%s.xyz' %(''.join(np.array(n,dtype=str)),tail) crys = Crystal.from_database('Li') pattern = np.array([ [a.atomic_number]+list(lfact*a.coords_cartesian)+[a.occupancy,wobble] for a in crys.atoms]) # lat_params = tuple(lfact*np.array(crys.lattice_parameters[:3])) lat_params = lfact*np.array(crys.lattice_vectors) coords,lat = rcc.make_xyz(file,pattern,lat_params,n,fmt='%.4f',dopt='s') return file
def test_shape_and_dtype(): """Test that output of structure_factor is same shape as input, and that the dtype is complex""" crystal = Crystal.from_database(next(iter(Crystal.builtins))) h, k, l = np.meshgrid([1, 2, 3], [1, 2, 3], [1, 2, 3]) sf = structure_factor(crystal, h, k, l) assert sf.shape == h.shape assert sf.dtype == complex
def test_str_vs_repr(name): """Test that str and repr are workign as expected""" c = Crystal.from_database(name) # If small crystal, repr and str should be the same if len(c) <= 10: assert repr(c) == str(c) else: assert repr(c) != str(c)
def test_ase_atoms_back_and_forth(name): """ Test conversion to and from ase Atoms """ crystal = Crystal.from_database(name) to_ase = crystal.to_ase() crystal2 = Crystal.from_ase(to_ase) # ase has different handling of coordinates which can lead to # rounding beyond 1e-3. Therefore, we cannot compare directly sets # assertSetEqual(set(crystal), set(crystal2)) assert len(crystal) == len(crystal2)
def test_cif_writer_idempotence(name): """ Test that conversion to CIF of a structure loaded from CIF is idempotent. """ # Testing on all built-in structure assures us that corner cases # are taken care of. cryst = Crystal.from_database(name) with tempfile.TemporaryDirectory() as temp_dir: f = Path(temp_dir) / "temp.cif" cryst.to_cif(f) cryst2 = Crystal.from_cif(f) assert cryst == cryst2
def test_lattice_parameters_back_and_forth(name): """Test that the conversion between lattice vectors and lattice parameters is working""" c = Crystal.from_database(name) lv1 = c.lattice_vectors params = c.lattice_parameters lv2 = lattice_vectors_from_parameters(*params) assert np.allclose(lv1, lv2)
def test_output_shape(self): """ Test that the output shape is as expected. """ # Simulate a powder pattern first crystal = Crystal.from_database("vo2-m1") q = np.linspace(0.2, 10, 1024) I = powdersim(crystal=crystal, q=q) radii = np.arange(0.1, 5, 1 / 50) pairdist = patterson(q=q, I=I, crystal=crystal, radii=radii) self.assertEqual(radii.shape, pairdist.shape)
def test_str_vs_repr(self): """ Test that str and repr are workign as expected """ for name in Crystal.builtins: with self.subTest(name): c = Crystal.from_database(name) # If small crystal, repr and str should be the same if len(c) <= 10: self.assertEqual(repr(c), str(c)) else: self.assertNotEqual(repr(c), str(c))
def test_powder_calq(self): """ Test scattering vector calibration """ crystal = Crystal.from_database("vo2-m1") self.dataset.powder_calq(crystal, (10, 100), [(1, 0, 0), (2, 0, 0)]) # Check that shapes match self.assertTupleEqual(self.dataset.powder_eq().shape, self.dataset.scattering_vector.shape) # Check that scattering_vector is strictly increasing self.assertTrue( np.all(np.greater(np.diff(self.dataset.scattering_vector), 0)))
def test_reciprocity_with_symmetry_expansion(self): """ Test that symmetry_reduction is reciprocal to symmetry_expansion """ structures = ["vo2-m1", "Os", "Na"] # , 'Nb', 'Pd', 'Zn'] for s in structures: with self.subTest("Crystal " + s): cryst = Crystal.from_database(s) asym_cell = symmetry_reduction(cryst.unitcell, cryst.symmetry_operations()) ucell = set( symmetry_expansion(asym_cell, cryst.symmetry_operations())) self.assertEqual(set(cryst.unitcell), ucell)
def test_dirax_indexing_initial_guess(name): """ Test that indexing succeeds with an initial guess and very few reflections. """ cryst = Crystal.from_database(name) # We restrict the number of reflections to a single (0,0,0); with # the initial guess, indexing should still succeed! lat, _ = index_dirax([(0, 0, 0)], initial=cryst) assert np.allclose(lat.lattice_parameters, cryst.lattice_parameters, atol=1)
def test_equality(self): """ Test that AtomicStructure is equal to itself but not others """ self.assertEqual(self.structure, self.structure) self.assertEqual(self.structure, deepcopy(self.structure)) self.assertNotEqual(self.structure, self.substructure) # Special case: make structures from Crystals c1 = Crystal.from_database("vo2-m1") c2 = deepcopy(c1) s1 = AtomicStructure(atoms=c1) s2 = AtomicStructure(atoms=c2.atoms) self.assertEqual(s1, s2)
def test_dirax_indexing_ideal(name, bound): """ Test that indexing always succeeds with an ideal set of reflections: no noise, no alien reflections. """ cryst = Crystal.from_database(name) refls = [ cryst.scattering_vector(r) for r in cryst.bounded_reflections(bound=bound) ] lat, hkls = index_dirax(refls) assert np.allclose(hkls - np.rint(hkls), 0, atol=0.001)