def test_fit(self): """ Take two known matched structures 1) Ensure match 2) Ensure match after translation and rotations 3) Ensure no-match after large site translation 4) Ensure match after site shuffling """ sm = StructureMatcher() self.assertTrue(sm.fit(self.struct_list[0], self.struct_list[1])) # Test rotational/translational invariance op = SymmOp.from_axis_angle_and_translation([0, 0, 1], 30, False, np.array([0.4, 0.7, 0.9])) editor = StructureEditor(self.struct_list[1]) editor.apply_operation(op) self.assertTrue(sm.fit(self.struct_list[0], editor.modified_structure)) #Test failure under large atomic translation editor.translate_sites([0], [.4, .4, .2], frac_coords=True) self.assertFalse(sm.fit(self.struct_list[0], editor.modified_structure)) editor.translate_sites([0], [-.4, -.4, -.2], frac_coords=True) # random.shuffle(editor._sites) self.assertTrue(sm.fit(self.struct_list[0], editor.modified_structure)) #Test FrameworkComporator sm2 = StructureMatcher(comparator=FrameworkComparator()) lfp = read_structure(os.path.join(test_dir, "LiFePO4.cif")) nfp = read_structure(os.path.join(test_dir, "NaFePO4.cif")) self.assertTrue(sm2.fit(lfp, nfp)) self.assertFalse(sm.fit(lfp, nfp)) #Test anonymous fit. self.assertEqual(sm.fit_anonymous(lfp, nfp), {Composition("Li"): Composition("Na")}) self.assertAlmostEqual(sm.get_minimax_rms_anonymous(lfp, nfp)[0], 0.096084154118549828) #Test partial occupancies. s1 = Structure([[3, 0, 0], [0, 3, 0], [0, 0, 3]], [{"Fe": 0.5}, {"Fe": 0.5}, {"Fe": 0.5}, {"Fe": 0.5}], [[0, 0, 0], [0.25, 0.25, 0.25], [0.5, 0.5, 0.5], [0.75, 0.75, 0.75]]) s2 = Structure([[3, 0, 0], [0, 3, 0], [0, 0, 3]], [{"Fe": 0.25}, {"Fe": 0.5}, {"Fe": 0.5}, {"Fe": 0.75}], [[0, 0, 0], [0.25, 0.25, 0.25], [0.5, 0.5, 0.5], [0.75, 0.75, 0.75]]) self.assertFalse(sm.fit(s1, s2)) self.assertFalse(sm.fit(s2, s1)) s2 = Structure([[3, 0, 0], [0, 3, 0], [0, 0, 3]], [{"Fe": 0.25}, {"Fe": 0.25}, {"Fe": 0.25}, {"Fe": 0.25}], [[0, 0, 0], [0.25, 0.25, 0.25], [0.5, 0.5, 0.5], [0.75, 0.75, 0.75]]) self.assertEqual(sm.fit_anonymous(s1, s2), {Composition("Fe0.5"): Composition("Fe0.25")}) self.assertAlmostEqual(sm.get_minimax_rms_anonymous(s1, s2)[0], 0)
class StructureEditorTest(unittest.TestCase): def setUp(self): self.si = Element("Si") self.fe = Element("Fe") self.ge = Element("Ge") coords = list() coords.append(np.array([0, 0, 0])) coords.append(np.array([0.75, 0.5, 0.75])) lattice = Lattice.cubic(10) s = Structure(lattice, [self.si, self.fe], coords) self.modifier = StructureEditor(s) def test_translate_sites(self): self.modifier.translate_sites([0, 1], [0.5, 0.5, 0.5], frac_coords=True) self.assertTrue(np.array_equal(self.modifier.modified_structure.frac_coords[0], np.array([ 0.5, 0.5, 0.5]))) self.modifier.translate_sites([0], [0.5, 0.5, 0.5], frac_coords=False) self.assertTrue(np.array_equal(self.modifier.modified_structure.cart_coords[0], np.array([ 5.5, 5.5, 5.5]))) def test_append_site(self): self.modifier.append_site(self.si, [0, 0.5, 0]) self.assertEqual(self.modifier.modified_structure.formula, "Fe1 Si2", "Wrong formula!") self.assertRaises(ValueError, self.modifier.append_site, self.si, np.array([0, 0.5, 0])) def test_modified_structure(self): self.modifier.insert_site(1, self.si, [0, 0.25, 0]) self.assertEqual(self.modifier.modified_structure.formula, "Fe1 Si2", "Wrong formula!") self.modifier.delete_site(0) self.assertEqual(self.modifier.modified_structure.formula, "Fe1 Si1", "Wrong formula!") self.modifier.replace_site(0, self.ge) self.assertEqual(self.modifier.modified_structure.formula, "Fe1 Ge1", "Wrong formula!") self.modifier.append_site(self.si, [0, 0.75, 0]) self.modifier.replace_species({self.si: self.ge}) self.assertEqual(self.modifier.modified_structure.formula, "Fe1 Ge2", "Wrong formula!") self.modifier.replace_species({self.ge: {self.ge:0.5, self.si:0.5}}) self.assertEqual(self.modifier.modified_structure.formula, "Fe1 Si1 Ge1", "Wrong formula!") #this should change the .5Si .5Ge sites to .75Si .25Ge self.modifier.replace_species({self.ge: {self.ge:0.5, self.si:0.5}}) self.assertEqual(self.modifier.modified_structure.formula, "Fe1 Si1.5 Ge0.5", "Wrong formula!") d = 0.1 pre_perturbation_sites = self.modifier.modified_structure.sites self.modifier.perturb_structure(distance=d) post_perturbation_sites = self.modifier.modified_structure.sites for i, x in enumerate(pre_perturbation_sites): self.assertAlmostEqual(x.distance(post_perturbation_sites[i]), d, 3, "Bad perturbation distance") def test_add_site_property(self): self.modifier.add_site_property("charge", [4.1, 5]) s = self.modifier.modified_structure self.assertEqual(s[0].charge, 4.1) self.assertEqual(s[1].charge, 5) #test adding multiple properties. mod2 = StructureEditor(s) mod2.add_site_property("magmom", [3, 2]) s = mod2.modified_structure self.assertEqual(s[0].charge, 4.1) self.assertEqual(s[0].magmom, 3)
class StructureEditorTest(unittest.TestCase): def setUp(self): self.si = Element("Si") self.fe = Element("Fe") self.ge = Element("Ge") coords = list() coords.append(np.array([0, 0, 0])) coords.append(np.array([0.75, 0.5, 0.75])) lattice = Lattice.cubic(10) s = Structure(lattice, ["Si", "Fe"], coords) self.modifier = StructureEditor(s) def test_to_unit_cell(self): self.modifier.append_site(self.fe, [1.75, 0.5, 0.75], validate_proximity=False) self.modifier.to_unit_cell() self.assertEqual(self.modifier.modified_structure.formula, "Fe1 Si1", "Wrong formula!") def test_to_unit_cell(self): self.modifier.apply_strain(0.01) self.assertEqual(self.modifier.modified_structure.lattice.abc, (10.1, 10.1, 10.1)) def test_translate_sites(self): self.modifier.translate_sites([0, 1], [0.5, 0.5, 0.5], frac_coords=True) self.assertTrue(np.array_equal(self.modifier.modified_structure .frac_coords[0], np.array([0.5, 0.5, 0.5]))) self.modifier.translate_sites([0], [0.5, 0.5, 0.5], frac_coords=False) self.assertTrue(np.array_equal(self.modifier.modified_structure .cart_coords[0], np.array([5.5, 5.5, 5.5]))) def test_append_site(self): self.modifier.append_site(self.si, [0, 0.5, 0]) self.assertEqual(self.modifier.modified_structure.formula, "Fe1 Si2", "Wrong formula!") self.assertRaises(ValueError, self.modifier.append_site, self.si, np.array([0, 0.5, 0])) def test_modified_structure(self): self.modifier.insert_site(1, self.si, [0, 0.25, 0]) self.assertEqual(self.modifier.modified_structure.formula, "Fe1 Si2", "Wrong formula!") self.modifier.delete_site(0) self.assertEqual(self.modifier.modified_structure.formula, "Fe1 Si1", "Wrong formula!") self.modifier.replace_site(0, self.ge) self.assertEqual(self.modifier.modified_structure.formula, "Fe1 Ge1", "Wrong formula!") self.modifier.append_site(self.si, [0, 0.75, 0]) self.modifier.replace_species({self.si: self.ge}) self.assertEqual(self.modifier.modified_structure.formula, "Fe1 Ge2", "Wrong formula!") self.modifier.replace_species({self.ge: {self.ge: 0.5, self.si: 0.5}}) self.assertEqual(self.modifier.modified_structure.formula, "Fe1 Si1 Ge1", "Wrong formula!") #this should change the .5Si .5Ge sites to .75Si .25Ge self.modifier.replace_species({self.ge: {self.ge: 0.5, self.si: 0.5}}) self.assertEqual(self.modifier.modified_structure.formula, "Fe1 Si1.5 Ge0.5", "Wrong formula!") d = 0.1 pre_perturbation_sites = self.modifier.modified_structure.sites self.modifier.perturb_structure(distance=d) post_perturbation_sites = self.modifier.modified_structure.sites for i, x in enumerate(pre_perturbation_sites): self.assertAlmostEqual(x.distance(post_perturbation_sites[i]), d, 3, "Bad perturbation distance") def test_add_site_property(self): self.modifier.add_site_property("charge", [4.1, 5]) s = self.modifier.modified_structure self.assertEqual(s[0].charge, 4.1) self.assertEqual(s[1].charge, 5) #test adding multiple properties. mod2 = StructureEditor(s) mod2.add_site_property("magmom", [3, 2]) s = mod2.modified_structure self.assertEqual(s[0].charge, 4.1) self.assertEqual(s[0].magmom, 3) def test_add_oxidation_states(self): si = Element("Si") fe = Element("Fe") coords = list() coords.append([0, 0, 0]) coords.append([0.75, 0.5, 0.75]) lattice = Lattice.cubic(10) s = Structure(lattice, [si, fe], coords) oxidation_states = {"Fe": 2, "Si": -4} mod = StructureEditor(s) mod.add_oxidation_state_by_element(oxidation_states) mod_s = mod.modified_structure for site in mod_s: for k in site.species_and_occu.keys(): self.assertEqual(k.oxi_state, oxidation_states[k.symbol], "Wrong oxidation state assigned!") oxidation_states = {"Fe": 2} self.assertRaises(ValueError, mod.add_oxidation_state_by_element, oxidation_states) mod.add_oxidation_state_by_site([2, -4]) mod_s = mod.modified_structure self.assertEqual(mod_s[0].specie.oxi_state, 2) self.assertRaises(ValueError, mod.add_oxidation_state_by_site, [1]) def test_remove_oxidation_states(self): co_elem = Element("Co") o_elem = Element("O") co_specie = Specie("Co", 2) o_specie = Specie("O", -2) coords = list() coords.append([0, 0, 0]) coords.append([0.75, 0.5, 0.75]) lattice = Lattice.cubic(10) s_elem = Structure(lattice, [co_elem, o_elem], coords) s_specie = Structure(lattice, [co_specie, o_specie], coords) mod = StructureEditor(s_specie) mod.remove_oxidation_states() mod_s = mod.modified_structure self.assertEqual(s_elem, mod_s, "Oxidation state remover failed")
def apply_transformation(self, structure): editor = StructureEditor(structure) editor.translate_sites(self._indices, self._vector, self._frac) return editor.modified_structure