def write_structure(structure, filename): """ Write a structure to a file based on file extension. For example, anything ending in a "cif" is assumed to be a Crystallographic Information Format file. Supported formats include CIF, POSCAR, CSSR and pymatgen's JSON serialized structures. Args: structure (Structure/IStructure): Structure to write filename (str): A filename to write to. """ fname = os.path.basename(filename) if fnmatch(fname, "*.cif*"): writer = CifWriter(structure) elif fnmatch(fname, "POSCAR*") or fnmatch(fname, "CONTCAR*"): writer = Poscar(structure) elif fnmatch(fname.lower(), "*.cssr*"): writer = Cssr(structure) elif fnmatch(fname, "*.json*") or fnmatch(fname, "*.mson*"): with zopen(filename, "wt") as f: f.write(str2unicode(json.dumps(structure, cls=MontyEncoder))) return else: raise ValueError("Unrecognized file extension!") writer.write_file(filename)
def write_structure(structure, filename): """ Write a structure to a file based on file extension. For example, anything ending in a "cif" is assumed to be a Crystallographic Information Format file. Supported formats include CIF, POSCAR, CSSR and pymatgen's JSON serialized structures. Args: structure: Structure to write filename: A filename to write to. """ lower_filename = os.path.basename(filename).lower() if re.search("\.cif", lower_filename): writer = CifWriter(structure) elif lower_filename.startswith("poscar") \ or lower_filename.startswith("contcar"): writer = Poscar(structure) elif re.search("\.cssr", lower_filename): writer = Cssr(structure) elif re.search("\.[mj]son", lower_filename): with zopen(lower_filename, "w") as f: json.dump(structure, f, cls=PMGJSONEncoder) return else: raise ValueError("Unrecognized file extension!") writer.write_file(filename)
def convert_fmt(args): iformat = args.input_format[0] oformat = args.output_format[0] filename = args.input_filename[0] out_filename = args.output_filename[0] try: if iformat == "smart": structure = read_structure(filename) if iformat == "POSCAR": p = Poscar.from_file(filename) structure = p.structure elif iformat == "CIF": r = CifParser(filename) structure = r.get_structures()[0] elif iformat == "CSSR": structure = Cssr.from_file(filename).structure if oformat == "smart": write_structure(structure, out_filename) elif oformat == "POSCAR": p = Poscar(structure) p.write_file(out_filename) elif oformat == "CIF": w = CifWriter(structure) w.write_file(out_filename) elif oformat == "CSSR": c = Cssr(structure) c.write_file(out_filename) elif oformat == "VASP": input_set = MPVaspInputSet() ts = TransformedStructure(structure, [], history=[{ "source": "file", "datetime": str(datetime.datetime.now()), "original_file": open(filename).read() }]) ts.write_vasp_input(input_set, output_dir=out_filename) elif oformat == "MITVASP": input_set = MITVaspInputSet() ts = TransformedStructure(structure, [], history=[{ "source": "file", "datetime": str(datetime.datetime.now()), "original_file": open(filename).read() }]) ts.write_vasp_input(input_set, output_dir=out_filename) except Exception as ex: print "Error converting file. Are they in the right format?" print str(ex)
def cif(src="POSCAR"): """ cifファイルを作成 """ srcpos = Poscar.from_file(src) finder = SpacegroupAnalyzer(srcpos.structure) std = finder.get_conventional_standard_structure() cif = CifWriter(std, find_spacegroup=True, symprec=0.1) cif.write_file("poscar.cif")
def prim_cif(self, dst): """ primitive cellでのcifフォーマットをgetする """ finder = SpacegroupAnalyzer(self.structure) structure = finder.get_primitive_standard_structure() structure = finder.get_conventional_standard_structure() cif = CifWriter(structure, find_spacegroup=True, symprec=0.1) cif.write_file(dst)
def convert_fmt(args): iformat = args.input_format[0] oformat = args.output_format[0] filename = args.input_filename[0] out_filename = args.output_filename[0] try: if iformat == "smart": structure = read_structure(filename) if iformat == "POSCAR": p = Poscar.from_file(filename) structure = p.structure elif iformat == "CIF": r = CifParser(filename) structure = r.get_structures()[0] elif iformat == "CSSR": structure = Cssr.from_file(filename).structure if oformat == "smart": write_structure(structure, out_filename) elif oformat == "POSCAR": p = Poscar(structure) p.write_file(out_filename) elif oformat == "CIF": w = CifWriter(structure) w.write_file(out_filename) elif oformat == "CSSR": c = Cssr(structure) c.write_file(out_filename) elif oformat == "VASP": input_set = MPVaspInputSet() ts = TransformedStructure( structure, [], history=[ {"source": "file", "datetime": str(datetime.datetime.now()), "original_file": open(filename).read()} ], ) ts.write_vasp_input(input_set, output_dir=out_filename) elif oformat == "MITVASP": input_set = MITVaspInputSet() ts = TransformedStructure( structure, [], history=[ {"source": "file", "datetime": str(datetime.datetime.now()), "original_file": open(filename).read()} ], ) ts.write_vasp_input(input_set, output_dir=out_filename) except Exception as ex: print "Error converting file. Are they in the right format?" print str(ex)
def batch_write_vasp_input(structures, vasp_input_set, output_dir, make_dir_if_not_present=True, subfolder=None, sanitize=False, include_cif=False): """ Batch write vasp input for a sequence of structures to output_dir, following the format output_dir/{group}/{formula}_{number}. Args: structures: Sequence of Structures. vasp_input_set: pymatgen.io.vaspio_set.VaspInputSet like object that creates vasp input files from structures output_dir: Directory to output files make_dir_if_not_present: Create the directory if not present. Defaults to True. subfolder: function to create subdirectory name from structure. Defaults to simply "formula_count". sanitize: Boolean indicating whether to sanitize the structure before writing the VASP input files. Sanitized output are generally easier for viewing and certain forms of analysis. Defaults to False. include_cif: Boolean indication whether to output a CIF as well. CIF files are generally better supported in visualization programs. """ for i, s in enumerate(structures): formula = re.sub("\s+", "", s.formula) if subfolder is not None: subdir = subfolder(s) dirname = os.path.join(output_dir, subdir) else: dirname = os.path.join(output_dir, '{}_{}'.format(formula, i)) if sanitize: s = s.copy(sanitize=True) vasp_input_set.write_input( s, dirname, make_dir_if_not_present=make_dir_if_not_present) if include_cif: from pymatgen.io.cifio import CifWriter writer = CifWriter(s) writer.write_file( os.path.join(dirname, "{}_{}.cif".format(formula, i)))
def process_vasprun(cls, dir_name, taskname, filename, parse_dos): """ Process a vasprun.xml file. """ vasprun_file = os.path.join(dir_name, filename) r = Vasprun(vasprun_file) d = r.to_dict d["dir_name"] = os.path.abspath(dir_name) d["completed_at"] = \ str(datetime.datetime.fromtimestamp(os.path.getmtime( vasprun_file))) d["cif"] = str(CifWriter(r.final_structure)) d["density"] = r.final_structure.density if parse_dos: try: d["dos"] = r.complete_dos.to_dict except Exception: logger.warn( "No valid dos data exist in {}.\n Skipping dos".format( dir_name)) if taskname == "relax1" or taskname == "relax2": d["task"] = {"type": "aflow", "name": taskname} else: d["task"] = {"type": "standard", "name": "standard"} return d
def batch_write_vasp_input(structures, vasp_input_set, output_dir, make_dir_if_not_present=True, subfolder=None, sanitize=False, include_cif=False): """ Batch write vasp input for a sequence of structures to output_dir, following the format output_dir/{group}/{formula}_{number}. Args: structures: Sequence of Structures. vasp_input_set: pymatgen.io.vaspio_set.VaspInputSet like object that creates vasp input files from structures output_dir: Directory to output files make_dir_if_not_present: Create the directory if not present. Defaults to True. subfolder: function to create subdirectory name from structure. Defaults to simply "formula_count". sanitize: Boolean indicating whether to sanitize the structure before writing the VASP input files. Sanitized output are generally easier for viewing and certain forms of analysis. Defaults to False. include_cif: Boolean indication whether to output a CIF as well. CIF files are generally better supported in visualization programs. """ for i, s in enumerate(structures): formula = re.sub("\s+", "", s.formula) if subfolder is not None: subdir = subfolder(s) dirname = os.path.join(output_dir, subdir) else: dirname = os.path.join(output_dir, '{}_{}'.format(formula, i)) if sanitize: s = s.copy(sanitize=True) vasp_input_set.write_input( s, dirname, make_dir_if_not_present=make_dir_if_not_present ) if include_cif: from pymatgen.io.cifio import CifWriter writer = CifWriter(s) writer.write_file(os.path.join(dirname, "{}_{}.cif".format(formula, i)))
def test_CifWriter(self): filepath = os.path.join(test_dir, 'POSCAR') poscar = Poscar.from_file(filepath) writer = CifWriter(poscar.structure, find_spacegroup=True) ans = """#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 _cell_angle_alpha 90.00000000 _cell_angle_beta 90.00000000 _cell_angle_gamma 90.00000000 _symmetry_Int_Tables_number 62 _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_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 """ for l1, l2 in zip(str(writer).split("\n"), ans.split("\n")): self.assertEqual(l1.strip(), l2.strip())
def batch_write_vasp_input(transformed_structures, vasp_input_set, output_dir, create_directory=True, subfolder=None, include_cif=False): """ Batch write vasp input for a sequence of transformed structures to output_dir, following the format output_dir/{group}/{formula}_{number}. Args: transformed_structures: Sequence of TransformedStructures. vasp_input_set: pymatgen.io.vaspio_set.VaspInputSet like object that creates vasp input files from structures output_dir: Directory to output files create_directory: Create the directory if not present. Defaults to True. subfolder: function to create subdirectory name from transformed_structure. eg. lambda x: x.other_parameters["tags"][0] to use the first tag. include_cif: Boolean indication whether to output a CIF as well. CIF files are generally better supported in visualization programs. """ for i, s in enumerate(transformed_structures): formula = re.sub("\s+", "", s.final_structure.formula) if subfolder is not None: subdir = subfolder(s) dirname = os.path.join(output_dir, subdir, "{}_{}".format(formula, i)) else: dirname = os.path.join(output_dir, "{}_{}".format(formula, i)) s.write_vasp_input(vasp_input_set, dirname, create_directory=create_directory) if include_cif: from pymatgen.io.cifio import CifWriter writer = CifWriter(s.final_structure) writer.write_file(os.path.join(dirname, "{}.cif".format(formula)))
def write_structure(structure, filename): """ Write a structure to a file based on file extension. For example, anything ending in a "cif" is assumed to be a Crystallographic Information Format file. Supported formats include CIF, POSCAR, CSSR and pymatgen's JSON serialized structures. Args: structure (Structure/IStructure): Structure to write filename (str): A filename to write to. """ fname = os.path.basename(filename) if fnmatch(fname, "*.cif*"): writer = CifWriter(structure) elif fnmatch(fname, "POSCAR*") or fnmatch(fname, "CONTCAR*"): writer = Poscar(structure) elif fnmatch(fname.lower(), "*.cssr*"): writer = Cssr(structure) elif fnmatch(fname, "*.json*") or fnmatch(fname, "*.mson*"): with zopen(filename, "w") as f: json.dump(structure, f, cls=PMGJSONEncoder) return else: raise ValueError("Unrecognized file extension!") writer.write_file(filename)
def test_specie_cifwriter(self): si4 = Specie("Si", 4) si3 = Specie("Si", 3) n = Specie("N", -3) coords = list() coords.append(np.array([0, 0, 0])) coords.append(np.array([0.75, 0.5, 0.75])) coords.append(np.array([0.5, 0.5, 0.5])) lattice = Lattice(np.array([[3.8401979337, 0.00, 0.00], [1.9200989668, 3.3257101909, 0.00], [0.00, -2.2171384943, 3.1355090603]])) struct = Structure(lattice, [si4, {si3:0.5, n:0.5}, n], coords) writer = CifWriter(struct) ans = """#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 Si4+ Si1 1 0.000000 0.000000 0.000000 1 Si3+ Si2 1 0.750000 0.500000 0.750000 0.5 N3- N3 1 0.750000 0.500000 0.750000 0.5 N3- N4 1 0.500000 0.500000 0.500000 1 """ for l1, l2 in zip(str(writer).split("\n"), ans.split("\n")): self.assertEqual(l1.strip(), l2.strip())
def convert_fmt(args): iformat = args.input_format[0] oformat = args.output_format[0] filename = args.input_filename[0] out_filename = args.output_filename[0] try: if iformat == "smart": structure = read_structure(filename) if iformat == "POSCAR": p = Poscar.from_file(filename) structure = p.structure elif iformat == "CIF": r = CifParser(filename) structure = r.get_structures()[0] elif iformat == "CSSR": structure = Cssr.from_file(filename).structure if oformat == "smart": write_structure(structure, out_filename) elif oformat == "POSCAR": p = Poscar(structure) p.write_file(out_filename) elif oformat == "CIF": w = CifWriter(structure) w.write_file(out_filename) elif oformat == "CSSR": c = Cssr(structure) c.write_file(out_filename) elif oformat == "VASP": input_set = MaterialsProjectVaspInputSet() transmuter = StandardTransmuter.from_structures([structure], []) transmuter.write_vasp_input(input_set, output_dir=out_filename) except Exception as ex: print "Error converting file. Are they in the right format?" print str(ex)
def move_atom(input_cif, output_cif, atom_idx, displacement_vec): """ Reads input cif (as file name), moves atom by displacement vector (in angstroms), and writes to output_cif (as file name). Currently, doesn't take into account the symmetry operations. This is theoretically possible with PyMatGen, although I found it to be buggy so decided it might not be worth it. Useful things to look up for implementing this: pymatgen.symmetry.analyzer.SpacegroupAnalyzer.get_symmetrized_structure and its resulting method find_equivalent_sites() """ parser = CifParser(input_cif) struct = parser.get_structures()[0] lat_const = np.array(struct.lattice.abc) frac_pos = struct[atom_idx].frac_coords new_pos = frac_pos + displacement_vec/lat_const struct[atom_idx] = struct[atom_idx].species_and_occu.elements[0], new_pos writer = CifWriter(struct) writer.write_file(output_cif)
def move_atom(input_cif, output_cif, atom_idx, displacement_vec): """ Reads input cif (as file name), moves atom by displacement vector (in angstroms), and writes to output_cif (as file name). Currently, doesn't take into account the symmetry operations. This is theoretically possible with PyMatGen, although I found it to be buggy so decided it might not be worth it. Useful things to look up for implementing this: pymatgen.symmetry.analyzer.SpacegroupAnalyzer.get_symmetrized_structure and its resulting method find_equivalent_sites() """ parser = CifParser(input_cif) struct = parser.get_structures()[0] lat_const = np.array(struct.lattice.abc) frac_pos = struct[atom_idx].frac_coords new_pos = frac_pos + displacement_vec / lat_const struct[atom_idx] = struct[atom_idx].species_and_occu.elements[0], new_pos writer = CifWriter(struct) writer.write_file(output_cif)
def write_structure(structure, filename): """ Write a structure to a file based on file extension. For example, anything ending in a "cif" is assumed to be a Crystallographic Information Format file. Args: structure: Structure to write filename: A filename to write to. """ lower_filename = os.path.basename(filename).lower() if re.search("\.cif", lower_filename): writer = CifWriter(structure) elif lower_filename.startswith("poscar") \ or lower_filename.startswith("contcar"): writer = Poscar(structure) elif re.search("\.cssr", lower_filename): writer = Cssr(structure) else: raise ValueError("Unrecognized file extension!") writer.write_file(filename)
def test_symmetrized(self): filepath = os.path.join(test_dir, 'POSCAR') poscar = Poscar.from_file(filepath) writer = CifWriter(poscar.structure, find_spacegroup=True, symprec=0.1) ans = """#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 _cell_angle_alpha 90.00000000 _cell_angle_beta 90.00000000 _cell_angle_gamma 90.00000000 _symmetry_Int_Tables_number 62 _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' 2 '-x, -y, -z' 3 '-x+1/2, -y, z+1/2' 4 'x+1/2, y, -z+1/2' 5 'x+1/2, -y+1/2, -z+1/2' 6 '-x+1/2, y+1/2, z+1/2' 7 '-x, y+1/2, -z' 8 'x, -y+1/2, 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 4 0.218728 0.750000 0.474867 1 P P2 4 0.094613 0.250000 0.418243 1 O O3 4 0.043372 0.750000 0.707138 1 O O4 4 0.096642 0.250000 0.741320 1 O O5 8 0.165710 0.046072 0.285384 1""" for l1, l2 in zip(str(writer).split("\n"), ans.split("\n")): self.assertEqual(l1.strip(), l2.strip())
def test_specie_cifwriter(self): si4 = Specie("Si", 4) si3 = Specie("Si", 3) n = Specie("N", -3) coords = list() coords.append(np.array([0, 0, 0])) coords.append(np.array([0.75, 0.5, 0.75])) coords.append(np.array([0.5, 0.5, 0.5])) lattice = Lattice( np.array([[3.8401979337, 0.00, 0.00], [1.9200989668, 3.3257101909, 0.00], [0.00, -2.2171384943, 3.1355090603]])) struct = Structure(lattice, [si4, {si3: 0.5, n: 0.5}, n], coords) writer = CifWriter(struct) ans = """#\#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_Si1.5N1.5 _symmetry_space_group_name_H-M 'P 1' _cell_length_a 3.8401979337 _cell_length_b 3.84019899434 _cell_length_c 3.84019793372 _cell_angle_alpha 119.999990864 _cell_angle_beta 90.0 _cell_angle_gamma 60.0000091373 _chemical_name_systematic 'Generated by pymatgen' _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 Si4+ 4.0 N3- -3.0 Si3+ 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_attached_hydrogens _atom_site_B_iso_or_equiv _atom_site_occupancy Si4+ Si1 1 0.000000 0.000000 0.000000 0 . 1 N3- N2 1 0.750000 0.500000 0.750000 0 . 0.5 Si3+ Si3 1 0.750000 0.500000 0.750000 0 . 0.5 N3- N4 1 0.500000 0.500000 0.500000 0 . 1 """ for l1, l2 in zip(str(writer).split("\n"), ans.split("\n")): self.assertEqual(l1.strip(), l2.strip())
__email__ = "*****@*****.**" __date__ = "Nov 14, 2011" import argparse from pymatgen.io.vaspio import Poscar from pymatgen.io.cifio import CifParser, CifWriter parser = argparse.ArgumentParser(description='''Convenient file format convertor. Author: Shyue Ping Ong Version: 1.0 Last updated: Oct 26 2011''') parser.add_argument('input_file', metavar='input file', type=str, nargs = 1, help='input file') parser.add_argument('output_file', metavar='output file', type=str, nargs = 1, help='output file') parser.add_argument('-c', '--conversion', dest='conversion', type=str, nargs = 1, choices=['poscar2cif','cif2poscar'], default='poscar2cif', help='Format conversion desired. ') args = parser.parse_args() try: if args.conversion[0] == 'poscar2cif': p = Poscar.from_file(args.input_file[0]) w = CifWriter(p.struct) w.write_file(args.output_file[0]) else: r = CifParser(args.input_file[0]) p = Poscar(r.get_structures()[0]) p.write_file(args.output_file[0]) except Exception as ex: print "Error converting file. Are they in the right format?" print str(ex)
def test_CifWriter(self): filepath = os.path.join(test_dir, 'POSCAR') poscar = Poscar.from_file(filepath) writer = CifWriter(poscar.structure, find_spacegroup=True) print str(writer) ans = """#\#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 Pnma _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 62 _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 """ for l1, l2 in zip(str(writer).split("\n"), ans.split("\n")): self.assertEqual(l1.strip(), l2.strip())
def test_symmetrized(self): filepath = os.path.join(test_dir, 'POSCAR') poscar = Poscar.from_file(filepath) writer = CifWriter(poscar.structure, symprec=0.1) ans = """#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 _cell_angle_alpha 90.00000000 _cell_angle_beta 90.00000000 _cell_angle_gamma 90.00000000 _symmetry_Int_Tables_number 62 _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' 2 '-x, -y, -z' 3 '-x+1/2, -y, z+1/2' 4 'x+1/2, y, -z+1/2' 5 'x+1/2, -y+1/2, -z+1/2' 6 '-x+1/2, y+1/2, z+1/2' 7 '-x, y+1/2, -z' 8 'x, -y+1/2, 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 4 0.218728 0.750000 0.474867 1 P P2 4 0.094613 0.250000 0.418243 1 O O3 8 0.165710 0.046072 0.285384 1 O O4 4 0.043372 0.750000 0.707138 1 O O5 4 0.096642 0.250000 0.741320 1""" for l1, l2 in zip(str(writer).split("\n"), ans.split("\n")): self.assertEqual(l1.strip(), l2.strip()) ans = """#generated using pymatgen data_LiFePO4 _symmetry_space_group_name_H-M Pnma _cell_length_a 4.74480000 _cell_length_b 6.06577000 _cell_length_c 10.41037000 _cell_angle_alpha 90.50179000 _cell_angle_beta 90.00019000 _cell_angle_gamma 90.00362000 _symmetry_Int_Tables_number 62 _chemical_formula_structural LiFePO4 _chemical_formula_sum 'Li4 Fe4 P4 O16' _cell_volume 299.607967711 _cell_formula_units_Z 4 loop_ _symmetry_equiv_pos_site_id _symmetry_equiv_pos_as_xyz 1 'x, y, z' 2 '-x, -y, -z' 3 'x+1/2, -y, -z+1/2' 4 '-x+1/2, y, z+1/2' 5 '-x+1/2, -y+1/2, z+1/2' 6 'x+1/2, y+1/2, -z+1/2' 7 '-x, y+1/2, -z' 8 'x, -y+1/2, 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 Li Li1 4 0.000010 0.999990 0.999990 1.0 Fe Fe2 4 0.025080 0.746540 0.281160 1.0 P P3 4 0.082070 0.248300 0.405560 1.0 O O4 8 0.213450 0.044060 0.334190 1.0 O O5 4 0.208450 0.251100 0.543160 1.0 O O6 4 0.241490 0.750460 0.596220 1.0 """ s = Structure.from_file(os.path.join(test_dir, 'LiFePO4.cif')) writer = CifWriter(s, symprec=0.1) self.assertEqual(writer.__str__().strip(), ans.strip())