def from_cif_string(cif_string, transformations=[], primitive=True): """ Generates TransformedStructure from a cif string. Args: cif_string: Input cif string. Should contain only one structure. For cifs containing multiple structures, please use CifTransmuter. transformations: Sequence of transformations to be applied to the input structure. primitive: Option to set if the primitive cell should be extracted. Defaults to True. However, there are certain instances where you might want to use a non-primitive cell, e.g., if you are trying to generate all possible orderings of partial removals or order a disordered structure. """ parser = CifParser.from_string(cif_string) raw_string = re.sub("'", "\"", cif_string) cif_dict = parser.to_dict cif_keys = cif_dict.keys() s = parser.get_structures(primitive)[0] partial_cif = cif_dict[cif_keys[0]] if '_database_code_ICSD' in partial_cif: source = partial_cif['_database_code_ICSD'] + "-ICSD" else: source = 'uploaded cif' source_info = {'source':source, 'datetime':str(datetime.datetime.now()), 'original_file':raw_string, 'cif_data':cif_dict[cif_keys[0]]} return TransformedStructure(s, transformations, [source_info])
def test_get_lattice_from_lattice_type(self): cif_structure = """#generated using pymatgen data_FePO4 _symmetry_space_group_name_H-M Pnma _cell_length_a 10.41176687 _cell_length_b 6.06717188 _cell_length_c 4.75948954 _chemical_formula_structural FePO4 _chemical_formula_sum 'Fe4 P4 O16' _cell_volume 300.65685512 _cell_formula_units_Z 4 _symmetry_cell_setting Orthorhombic loop_ _symmetry_equiv_pos_site_id _symmetry_equiv_pos_as_xyz 1 'x, y, z' loop_ _atom_site_type_symbol _atom_site_label _atom_site_symmetry_multiplicity _atom_site_fract_x _atom_site_fract_y _atom_site_fract_z _atom_site_occupancy Fe Fe1 1 0.218728 0.750000 0.474867 1 Fe Fe2 1 0.281272 0.250000 0.974867 1 Fe Fe3 1 0.718728 0.750000 0.025133 1 Fe Fe4 1 0.781272 0.250000 0.525133 1 P P5 1 0.094613 0.250000 0.418243 1 P P6 1 0.405387 0.750000 0.918243 1 P P7 1 0.594613 0.250000 0.081757 1 P P8 1 0.905387 0.750000 0.581757 1 O O9 1 0.043372 0.750000 0.707138 1 O O10 1 0.096642 0.250000 0.741320 1 O O11 1 0.165710 0.046072 0.285384 1 O O12 1 0.165710 0.453928 0.285384 1 O O13 1 0.334290 0.546072 0.785384 1 O O14 1 0.334290 0.953928 0.785384 1 O O15 1 0.403358 0.750000 0.241320 1 O O16 1 0.456628 0.250000 0.207138 1 O O17 1 0.543372 0.750000 0.792862 1 O O18 1 0.596642 0.250000 0.758680 1 O O19 1 0.665710 0.046072 0.214616 1 O O20 1 0.665710 0.453928 0.214616 1 O O21 1 0.834290 0.546072 0.714616 1 O O22 1 0.834290 0.953928 0.714616 1 O O23 1 0.903358 0.750000 0.258680 1 O O24 1 0.956628 0.250000 0.292862 1 """ cp = CifParser.from_string(cif_structure) s_test = cp.get_structures(False)[0] filepath = os.path.join(test_dir, 'POSCAR') poscar = Poscar.from_file(filepath) s_ref = poscar.structure sm = StructureMatcher(stol=0.05, ltol=0.01, angle_tol=0.1) self.assertTrue(sm.fit(s_ref, s_test))
def from_cif_string(cif_string, transformations=None, primitive=True, occupancy_tolerance=1.): """ Generates TransformedStructure from a cif string. Args: cif_string (str): Input cif string. Should contain only one structure. For cifs containing multiple structures, please use CifTransmuter. transformations ([Transformations]): Sequence of transformations to be applied to the input structure. primitive (bool): Option to set if the primitive cell should be extracted. Defaults to True. However, there are certain instances where you might want to use a non-primitive cell, e.g., if you are trying to generate all possible orderings of partial removals or order a disordered structure. occupancy_tolerance (float): If total occupancy of a site is between 1 and occupancy_tolerance, the occupancies will be scaled down to 1. Returns: TransformedStructure """ parser = CifParser.from_string(cif_string, occupancy_tolerance) raw_string = re.sub("'", "\"", cif_string) cif_dict = parser.to_dict cif_keys = cif_dict.keys() s = parser.get_structures(primitive)[0] partial_cif = cif_dict[cif_keys[0]] if "_database_code_ICSD" in partial_cif: source = partial_cif["_database_code_ICSD"] + "-ICSD" else: source = "uploaded cif" source_info = { "source": source, "datetime": str(datetime.datetime.now()), "original_file": raw_string, "cif_data": cif_dict[cif_keys[0]] } return TransformedStructure(s, transformations, history=[source_info])
def from_cif_string(cif_string, transformations=None, primitive=True, occupancy_tolerance=1.): """ Generates TransformedStructure from a cif string. Args: cif_string (str): Input cif string. Should contain only one structure. For cifs containing multiple structures, please use CifTransmuter. transformations ([Transformations]): Sequence of transformations to be applied to the input structure. primitive (bool): Option to set if the primitive cell should be extracted. Defaults to True. However, there are certain instances where you might want to use a non-primitive cell, e.g., if you are trying to generate all possible orderings of partial removals or order a disordered structure. occupancy_tolerance (float): If total occupancy of a site is between 1 and occupancy_tolerance, the occupancies will be scaled down to 1. Returns: TransformedStructure """ parser = CifParser.from_string(cif_string, occupancy_tolerance) raw_string = re.sub("'", "\"", cif_string) cif_dict = parser.to_dict cif_keys = cif_dict.keys() s = parser.get_structures(primitive)[0] partial_cif = cif_dict[cif_keys[0]] if "_database_code_ICSD" in partial_cif: source = partial_cif["_database_code_ICSD"] + "-ICSD" else: source = "uploaded cif" source_info = {"source": source, "datetime": str(datetime.datetime.now()), "original_file": raw_string, "cif_data": cif_dict[cif_keys[0]]} return TransformedStructure(s, transformations, history=[source_info])
def test_no_coords_or_species(self): string= """#generated using pymatgen data_Si1.5N1.5 _symmetry_space_group_name_H-M 'P 1' _cell_length_a 3.84019793 _cell_length_b 3.84019899 _cell_length_c 3.84019793 _cell_angle_alpha 119.99999086 _cell_angle_beta 90.00000000 _cell_angle_gamma 60.00000914 _symmetry_Int_Tables_number 1 _chemical_formula_structural Si1.5N1.5 _chemical_formula_sum 'Si1.5 N1.5' _cell_volume 40.0447946443 _cell_formula_units_Z 0 loop_ _symmetry_equiv_pos_site_id _symmetry_equiv_pos_as_xyz 1 'x, y, z' loop_ _atom_type_symbol _atom_type_oxidation_number Si3+ 3.0 Si4+ 4.0 N3- -3.0 loop_ _atom_site_type_symbol _atom_site_label _atom_site_symmetry_multiplicity _atom_site_fract_x _atom_site_fract_y _atom_site_fract_z _atom_site_occupancy ? ? ? ? ? ? ? """ parser = CifParser.from_string(string) self.assertEqual(len(parser.get_structures()), 0)
def test_CifParser(self): parser = CifParser(os.path.join(test_dir, 'LiFePO4.cif')) for s in parser.get_structures(True): self.assertEqual(s.formula, "Li4 Fe4 P4 O16", "Incorrectly parsed cif.") parser = CifParser(os.path.join(test_dir, 'V2O3.cif')) for s in parser.get_structures(True): self.assertEqual(s.formula, "V4 O6") parser = CifParser(os.path.join(test_dir, 'Li2O.cif')) prim = parser.get_structures(True)[0] self.assertEqual(prim.formula, "Li2 O1") conv = parser.get_structures(False)[0] self.assertEqual(conv.formula, "Li8 O4") #test for disordered structures parser = CifParser(os.path.join(test_dir, 'Li10GeP2S12.cif')) for s in parser.get_structures(True): self.assertEqual(s.formula, "Li20.2 Ge2.06 P3.94 S24", "Incorrectly parsed cif.") cif_str = """#\#CIF1.1 ########################################################################## # Crystallographic Information Format file # Produced by PyCifRW module # # This is a CIF file. CIF has been adopted by the International # Union of Crystallography as the standard for data archiving and # transmission. # # For information on this file format, follow the CIF links at # http://www.iucr.org ########################################################################## data_FePO4 _symmetry_space_group_name_H-M 'P 1' _cell_length_a 10.4117668699 _cell_length_b 6.06717187997 _cell_length_c 4.75948953998 loop_ # sometimes this is in a loop (incorrectly) _cell_angle_alpha 91.0 _cell_angle_beta 92.0 _cell_angle_gamma 93.0 _chemical_name_systematic 'Generated by pymatgen' _symmetry_Int_Tables_number 1 _chemical_formula_structural FePO4 _chemical_formula_sum 'Fe4 P4 O16' _cell_volume 300.65685512 _cell_formula_units_Z 4 loop_ _symmetry_equiv_pos_site_id _symmetry_equiv_pos_as_xyz 1 'x, y, z' loop_ _atom_site_type_symbol _atom_site_label _atom_site_symmetry_multiplicity _atom_site_fract_x _atom_site_fract_y _atom_site_fract_z _atom_site_attached_hydrogens _atom_site_B_iso_or_equiv _atom_site_occupancy Fe Fe1 1 0.218728 0.750000 0.474867 0 . 1 Fe JJ2 1 0.281272 0.250000 0.974867 0 . 1 # there's a typo here, parser should read the symbol from the # _atom_site_type_symbol Fe Fe3 1 0.718728 0.750000 0.025133 0 . 1 Fe Fe4 1 0.781272 0.250000 0.525133 0 . 1 P P5 1 0.094613 0.250000 0.418243 0 . 1 P P6 1 0.405387 0.750000 0.918243 0 . 1 P P7 1 0.594613 0.250000 0.081757 0 . 1 P P8 1 0.905387 0.750000 0.581757 0 . 1 O O9 1 0.043372 0.750000 0.707138 0 . 1 O O10 1 0.096642 0.250000 0.741320 0 . 1 O O11 1 0.165710 0.046072 0.285384 0 . 1 O O12 1 0.165710 0.453928 0.285384 0 . 1 O O13 1 0.334290 0.546072 0.785384 0 . 1 O O14 1 0.334290 0.953928 0.785384 0 . 1 O O15 1 0.403358 0.750000 0.241320 0 . 1 O O16 1 0.456628 0.250000 0.207138 0 . 1 O O17 1 0.543372 0.750000 0.792862 0 . 1 O O18 1 0.596642 0.250000 0.758680 0 . 1 O O19 1 0.665710 0.046072 0.214616 0 . 1 O O20 1 0.665710 0.453928 0.214616 0 . 1 O O21 1 0.834290 0.546072 0.714616 0 . 1 O O22 1 0.834290 0.953928 0.714616 0 . 1 O O23 1 0.903358 0.750000 0.258680 0 . 1 O O24 1 0.956628 0.250000 0.292862 0 . 1 """ parser = CifParser.from_string(cif_str) struct = parser.get_structures(primitive=False)[0] self.assertEqual(struct.formula, "Fe4 P4 O16", "Incorrectly parsed cif.") self.assertAlmostEqual(struct.lattice.a, 10.4117668699) self.assertAlmostEqual(struct.lattice.b, 6.06717187997) self.assertAlmostEqual(struct.lattice.c, 4.75948953998) self.assertAlmostEqual(struct.lattice.alpha, 91) self.assertAlmostEqual(struct.lattice.beta, 92) self.assertAlmostEqual(struct.lattice.gamma, 93) with warnings.catch_warnings(): warnings.simplefilter("ignore") parser = CifParser(os.path.join(test_dir, 'srycoo.cif')) self.assertEqual(parser.get_structures()[0].formula, "Sr5.6 Y2.4 Co8 O21") # Test with a decimal Xyz. This should parse as two atoms in # conventional cell if it is correct, one if not. parser = CifParser(os.path.join(test_dir, "Fe.cif")) self.assertEqual(len(parser.get_structures(primitive=False)[0]), 2)
def test_CifParser(self): parser = CifParser(os.path.join(test_dir, 'LiFePO4.cif')) for s in parser.get_structures(True): self.assertEqual(s.formula, "Li4 Fe4 P4 O16", "Incorrectly parsed cif.") parser = CifParser(os.path.join(test_dir, 'V2O3.cif')) for s in parser.get_structures(True): self.assertEqual(s.formula, "V4 O6") parser = CifParser(os.path.join(test_dir, 'Li2O.cif')) prim = parser.get_structures(True)[0] self.assertEqual(prim.formula, "Li2 O1") conv = parser.get_structures(False)[0] self.assertEqual(conv.formula, "Li8 O4") #test for disordered structures parser = CifParser(os.path.join(test_dir, 'Li10GeP2S12.cif')) for s in parser.get_structures(True): self.assertEqual(s.formula, "Li20.2 Ge2.06 P3.94 S24", "Incorrectly parsed cif.") cif_str = """#\#CIF1.1 ########################################################################## # Crystallographic Information Format file # Produced by PyCifRW module # # This is a CIF file. CIF has been adopted by the International # Union of Crystallography as the standard for data archiving and # transmission. # # For information on this file format, follow the CIF links at # http://www.iucr.org ########################################################################## data_FePO4 _symmetry_space_group_name_H-M 'P 1' _cell_length_a 10.4117668699 _cell_length_b 6.06717187997 _cell_length_c 4.75948953998 _cell_angle_alpha 90.0 _cell_angle_beta 90.0 _cell_angle_gamma 90.0 _chemical_name_systematic 'Generated by pymatgen' _symmetry_Int_Tables_number 1 _chemical_formula_structural FePO4 _chemical_formula_sum 'Fe4 P4 O16' _cell_volume 300.65685512 _cell_formula_units_Z 4 loop_ _symmetry_equiv_pos_site_id _symmetry_equiv_pos_as_xyz 1 'x, y, z' loop_ _atom_site_type_symbol _atom_site_label _atom_site_symmetry_multiplicity _atom_site_fract_x _atom_site_fract_y _atom_site_fract_z _atom_site_attached_hydrogens _atom_site_B_iso_or_equiv _atom_site_occupancy Fe Fe1 1 0.218728 0.750000 0.474867 0 . 1 Fe Fe2 1 0.281272 0.250000 0.974867 0 . 1 Fe Fe3 1 0.718728 0.750000 0.025133 0 . 1 Fe Fe4 1 0.781272 0.250000 0.525133 0 . 1 P P5 1 0.094613 0.250000 0.418243 0 . 1 P P6 1 0.405387 0.750000 0.918243 0 . 1 P P7 1 0.594613 0.250000 0.081757 0 . 1 P P8 1 0.905387 0.750000 0.581757 0 . 1 O O9 1 0.043372 0.750000 0.707138 0 . 1 O O10 1 0.096642 0.250000 0.741320 0 . 1 O O11 1 0.165710 0.046072 0.285384 0 . 1 O O12 1 0.165710 0.453928 0.285384 0 . 1 O O13 1 0.334290 0.546072 0.785384 0 . 1 O O14 1 0.334290 0.953928 0.785384 0 . 1 O O15 1 0.403358 0.750000 0.241320 0 . 1 O O16 1 0.456628 0.250000 0.207138 0 . 1 O O17 1 0.543372 0.750000 0.792862 0 . 1 O O18 1 0.596642 0.250000 0.758680 0 . 1 O O19 1 0.665710 0.046072 0.214616 0 . 1 O O20 1 0.665710 0.453928 0.214616 0 . 1 O O21 1 0.834290 0.546072 0.714616 0 . 1 O O22 1 0.834290 0.953928 0.714616 0 . 1 O O23 1 0.903358 0.750000 0.258680 0 . 1 O O24 1 0.956628 0.250000 0.292862 0 . 1 """ parser = CifParser.from_string(cif_str) self.assertEqual(parser.get_structures()[0].formula, "Fe4 P4 O16", "Incorrectly parsed cif.")
def test_CifParser(self): parser = CifParser(os.path.join(test_dir, 'LiFePO4.cif')) for s in parser.get_structures(True): self.assertEqual(s.formula, "Li4 Fe4 P4 O16", "Incorrectly parsed cif.") parser = CifParser(os.path.join(test_dir, 'V2O3.cif')) for s in parser.get_structures(True): self.assertEqual(s.formula, "V4 O6") parser = CifParser(os.path.join(test_dir, 'Li2O.cif')) prim = parser.get_structures(True)[0] self.assertEqual(prim.formula, "Li2 O1") conv = parser.get_structures(False)[0] self.assertEqual(conv.formula, "Li8 O4") #test for disordered structures parser = CifParser(os.path.join(test_dir, 'Li10GeP2S12.cif')) for s in parser.get_structures(True): self.assertEqual(s.formula, "Li20.2 Ge2.06 P3.94 S24", "Incorrectly parsed cif.") cif_str = """#\#CIF1.1 ########################################################################## # Crystallographic Information Format file # Produced by PyCifRW module # # This is a CIF file. CIF has been adopted by the International # Union of Crystallography as the standard for data archiving and # transmission. # # For information on this file format, follow the CIF links at # http://www.iucr.org ########################################################################## data_FePO4 _symmetry_space_group_name_H-M 'P 1' _cell_length_a 10.4117668699 _cell_length_b 6.06717187997 _cell_length_c 4.75948953998 _cell_angle_alpha 90.0 _cell_angle_beta 90.0 _cell_angle_gamma 90.0 _chemical_name_systematic 'Generated by pymatgen' _symmetry_Int_Tables_number 1 _chemical_formula_structural FePO4 _chemical_formula_sum 'Fe4 P4 O16' _cell_volume 300.65685512 _cell_formula_units_Z 4 loop_ _symmetry_equiv_pos_site_id _symmetry_equiv_pos_as_xyz 1 'x, y, z' loop_ _atom_site_type_symbol _atom_site_label _atom_site_symmetry_multiplicity _atom_site_fract_x _atom_site_fract_y _atom_site_fract_z _atom_site_attached_hydrogens _atom_site_B_iso_or_equiv _atom_site_occupancy Fe Fe1 1 0.218728 0.750000 0.474867 0 . 1 Fe Fe2 1 0.281272 0.250000 0.974867 0 . 1 Fe Fe3 1 0.718728 0.750000 0.025133 0 . 1 Fe Fe4 1 0.781272 0.250000 0.525133 0 . 1 P P5 1 0.094613 0.250000 0.418243 0 . 1 P P6 1 0.405387 0.750000 0.918243 0 . 1 P P7 1 0.594613 0.250000 0.081757 0 . 1 P P8 1 0.905387 0.750000 0.581757 0 . 1 O O9 1 0.043372 0.750000 0.707138 0 . 1 O O10 1 0.096642 0.250000 0.741320 0 . 1 O O11 1 0.165710 0.046072 0.285384 0 . 1 O O12 1 0.165710 0.453928 0.285384 0 . 1 O O13 1 0.334290 0.546072 0.785384 0 . 1 O O14 1 0.334290 0.953928 0.785384 0 . 1 O O15 1 0.403358 0.750000 0.241320 0 . 1 O O16 1 0.456628 0.250000 0.207138 0 . 1 O O17 1 0.543372 0.750000 0.792862 0 . 1 O O18 1 0.596642 0.250000 0.758680 0 . 1 O O19 1 0.665710 0.046072 0.214616 0 . 1 O O20 1 0.665710 0.453928 0.214616 0 . 1 O O21 1 0.834290 0.546072 0.714616 0 . 1 O O22 1 0.834290 0.953928 0.714616 0 . 1 O O23 1 0.903358 0.750000 0.258680 0 . 1 O O24 1 0.956628 0.250000 0.292862 0 . 1 """ parser = CifParser.from_string(cif_str) self.assertEqual(parser.get_structures()[0].formula, "Fe4 P4 O16", "Incorrectly parsed cif.") parser = CifParser(os.path.join(test_dir, 'srycoo.cif')) self.assertEqual(parser.get_structures()[0].formula, "Sr5.6 Y2.4 Co8 O21")