def test_symmetrized(self): filepath = self.TEST_FILES_DIR / "POSCAR" poscar = Poscar.from_file(filepath, check_for_POTCAR=False) writer = CifWriter(poscar.structure, symprec=0.1) cif = CifParser.from_string(str(writer)) m = StructureMatcher() self.assertTrue(m.fit(cif.get_structures()[0], poscar.structure)) # for l1, l2 in zip(str(writer).split("\n"), ans.split("\n")): # self.assertEqual(l1.strip(), l2.strip()) s = Structure.from_file(self.TEST_FILES_DIR / "LiFePO4.cif") writer = CifWriter(s, symprec=0.1) s2 = CifParser.from_string(str(writer)).get_structures()[0] self.assertTrue(m.fit(s, s2)) s = self.get_structure("Li2O") writer = CifWriter(s, symprec=0.1) s2 = CifParser.from_string(str(writer)).get_structures()[0] self.assertTrue(m.fit(s, s2)) # test angle tolerance. s = Structure.from_file(self.TEST_FILES_DIR / "LiFePO4.cif") writer = CifWriter(s, symprec=0.1, angle_tolerance=0) d = list(writer.ciffile.data.values())[0] self.assertEqual(d["_symmetry_Int_Tables_number"], 14) s = Structure.from_file(self.TEST_FILES_DIR / "LiFePO4.cif") writer = CifWriter(s, symprec=0.1, angle_tolerance=2) d = list(writer.ciffile.data.values())[0] self.assertEqual(d["_symmetry_Int_Tables_number"], 62)
def get_string(self, df_head_only=False): from pymatgen import Structure lines, scope = [], [] for key, value in self.document.iterate(): if isinstance(value, Table): lines[-1] = lines[-1].replace("{", "[+").replace("}", "]") header = any([isinstance(col, str) for col in value]) if isinstance(value.index, MultiIndex): value.reset_index(inplace=True) if df_head_only: value = value.head() csv_string = value.to_csv(index=False, header=header, float_format="%g", encoding="utf-8")[:-1] lines += csv_string.split("\n") if df_head_only: lines.append("...") elif isinstance(value, Structure): from pymatgen.io.cif import CifWriter cif = CifWriter(value, symprec=1e-10).__str__() lines.append( make_pair("".join([replacements.get(c, c) for c in key]), cif + ":end")) elif Quantity is not None and isinstance(value, Quantity): lines.append( make_pair(value.display_symbols[0], value.pretty_string())) else: level, key = key # truncate scope level_reduction = bool(level < len(scope)) if level_reduction: del scope[level:] # append scope if value is None: scope.append("".join([replacements.get(c, c) for c in key])) # correct scope to omit internal 'general' section scope_corr = scope if scope[0] == mp_level01_titles[0]: scope_corr = scope[1:] # insert scope line if (value is None and scope_corr) or (value is not None and level_reduction): lines.append("\n{" + ".".join(scope_corr) + "}") # insert key-value line if value is not None: val = str(value) value_lines = ([val] if val.startswith("http") else textwrap.wrap(val)) if len(value_lines) > 1: value_lines = [""] + value_lines + [":end"] lines.append( make_pair( "".join([replacements.get(c, c) for c in key]), "\n".join(value_lines), )) return "\n".join(lines) + "\n"
def test_cifwrite_without_refinement(self): si2 = Structure.from_file(self.TEST_FILES_DIR / "abinit" / "si.cif") writer = CifWriter(si2, symprec=1e-3, significant_figures=10, refine_struct=False) s = str(writer) assert "Fd-3m" in s same_si2 = CifParser.from_string(s).get_structures()[0] assert len(si2) == len(same_si2)
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_cif( filename: str, struct: Structure, refine_cell=False, resize_volume=False, symprec=1e-2, comment="", ): """ dump structure in CIF format after resizing to feasible volume and refing cell by symmetry. Parameters ---------- filename: str struct: pymatgen.core.Structure refine_cell: bool, optional if true, refine cell setting by spglib resize_volume: bool, optional if true, resize lattice by DLSVolumePredictor in pymatgen symprec: float, optional symprec in spglib """ struct = refine_and_resize_structure(struct, refine_cell, resize_volume) cw = CifWriter(struct, symprec=symprec) comment = f"# generated by {__version__}\n" + comment with open(filename, "w") as f: if comment: f.write(comment + "\n" + cw.__str__()) else: f.write(cw.__str__())
def pre_save_post_validation(cls, sender, document, **kwargs): from mpcontribs.api.structures.views import StructuresResource resource = StructuresResource() d = resource.serialize(document, fields=["lattice", "sites", "charge"]) s = json.dumps(d, sort_keys=True).encode("utf-8") document.md5 = md5(s).hexdigest() structure = Structure.from_dict(d) try: writer = CifWriter(structure, symprec=1e-10) except TypeError: # save CIF string without symmetry information writer = CifWriter(structure) document.cif = writer.__str__()
def get_cif_string(self, temp=300): """ Return string with structure and anisotropic U tensor in CIF format at temperature `temp` in Kelvin """ # Get string with structure in CIF format. # Don't use symprec because it changes the order of the sites # and we must be consistent with site_labels when writing aniso_U terms! from pymatgen.io.cif import CifWriter cif = CifWriter(self.structure, symprec=None) aniso_u = """loop_ _atom_site_aniso_label _atom_site_aniso_U_11 _atom_site_aniso_U_22 _atom_site_aniso_U_33 _atom_site_aniso_U_23 _atom_site_aniso_U_13 _atom_site_aniso_U_12""".splitlines() # Compute U tensor in CIF format (reduced coords) natom = len(self.structure) msq = self.get_msq_tmesh([float(temp)], what_list="displ") ucart = getattr(msq, "displ") ucart = np.reshape(ucart, (natom, 3, 3)) ucif = self.convert_ucart(ucart, fmt="cif") # Add matrix elements. Use 0 based index for iatom, site in enumerate(self.structure): site_label = "%s%d" % (site.specie.symbol, iatom) m = ucif[iatom] aniso_u.append("%s %10.5f %10.5f %10.5f %10.5f %10.5f %10.5f" % (site_label, m[0, 0], m[1, 1], m[2, 2], m[1, 2], m[0, 2], m[0, 1])) return str(cif) + "\n".join(aniso_u)
def process_vasprun(self, dir_name, taskname, filename): """ Process a vasprun.xml file. """ vasprun_file = os.path.join(dir_name, filename) if self.parse_projected_eigen and (self.parse_projected_eigen != 'final' or \ taskname == self.runs[-1]): parse_projected_eigen = True else: parse_projected_eigen = False r = Vasprun(vasprun_file, parse_projected_eigen=parse_projected_eigen) d = r.as_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 self.parse_dos and (self.parse_dos != 'final' \ or taskname == self.runs[-1]): try: d["dos"] = r.complete_dos.as_dict() except Exception: logger.warning( "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": taskname, "name": taskname} d["oxide_type"] = oxide_type(r.final_structure) return d
def get_structure(d=10, a=0, atom="Li"): species = [] coords = [] # does not work with cluster # parser = CifParser( # "/home/srr70/coo2/other_compoun/group_1_atoms/test/licoo2.cif") # structure = parser.get_structures()[0] # does not work with cluster structure = Structure.from_file( "/home/srr70/coo2/other_compoun/group_1_atoms/test/licoo2.cif") for i in structure: if i.species_string == "Li": species.append(i.species) coords.append(i.coords + [0, 0, +.5 * d + a]) else: species.append(i.species) coords.append(i.coords) a = structure.lattice.matrix.copy() a[2][2] = a[2][2] - d struc = Structure(Lattice(a), species, coords, coords_are_cartesian=True) struc.replace_species({"Li": atom}) CifWriter(struc).write_file(f"{atom}" + 'coo2_' + str(struc.lattice.c)[:4] + '.cif') # CifWriter(struc).write_file(fname+'licoo2_big.cif') # os.system("open "+fname+'licoo2_big.cif') return p2ase().get_atoms(struc)
def write_symmetry_cifs(self, properties): ''' Computes symmetry of structure using Pymatgen Then writes cit to out_folder ''' count = 1 for struct, en, ID in properties: # identify space group structp = struct.get_pymatgen_structure() sg = SGA(structp, symprec=self.symprec).get_space_group_number() # Pymatgen CIFwriter cw = CifWriter(structp, symprec=self.symprec) # Name output cif file if count < 10: count = "0" + str(count) # makes, e.g. 1 be 01 if not isdir(self.out_folder): mkdir(self.out_folder) name = join(self.out_folder, str(count) + "_" + str(ID) + "_" + str(sg) + ".cif") cw.write_file(name) # Increment count count = int(count) count += 1 print("Done with struct %s" % (ID))
def get(self, cid, name): """Retrieve structure for contribution in CIF format. --- operationId: get_cif parameters: - name: cid in: path type: string pattern: '^[a-f0-9]{24}$' required: true description: contribution ID (ObjectId) - name: name in: path type: string required: true description: name of structure responses: 200: description: structure in CIF format schema: type: string """ mask = [f'content.structures.{name}'] entry = Contributions.objects.only(*mask).get(id=cid) structure = Structure.from_dict(entry.content.structures.get(name)) if structure: return CifWriter(structure, symprec=1e-10).__str__() return f"Structure with name {name} not found for {cid}!" # TODO raise 404?
def test_specie_cifwriter(self): si4 = Species("Si", 4) si3 = Species("Si", 3) n = DummySpecies("X", -3) coords = list() coords.append(np.array([0.5, 0.5, 0.5])) coords.append(np.array([0.75, 0.5, 0.75])) coords.append(np.array([0, 0, 0])) 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, [n, {si3: 0.5, n: 0.5}, si4], coords) writer = CifWriter(struct) ans = """# generated using pymatgen data_X1.5Si1.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 X1.5Si1.5 _chemical_formula_sum 'X1.5 Si1.5' _cell_volume 40.04479464 _cell_formula_units_Z 1 loop_ _symmetry_equiv_pos_site_id _symmetry_equiv_pos_as_xyz 1 'x, y, z' loop_ _atom_type_symbol _atom_type_oxidation_number X3- -3.0 Si3+ 3.0 Si4+ 4.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 X3- X0 1 0.50000000 0.50000000 0.50000000 1 X3- X1 1 0.75000000 0.50000000 0.75000000 0.5 Si3+ Si2 1 0.75000000 0.50000000 0.75000000 0.5 Si4+ Si3 1 0.00000000 0.00000000 0.00000000 1 """ for l1, l2 in zip(str(writer).split("\n"), ans.split("\n")): self.assertEqual(l1.strip(), l2.strip()) # test that mixed valence works properly s2 = Structure.from_str(ans, "cif") self.assertEqual(struct.composition, s2.composition)
def in_struc(fin, tolerance=0.001): natot = get_natot(fin) lines_cell = extract_cell_parameters(fin) lines_atom = extract_atomic_positions(fin, natot) structure = from_lines(lines_cell, lines_atom) # pymatgen format structure.to(fmt='poscar', filename='in_struc.vasp') cif = CifWriter(structure, symprec=tolerance) cif.write_file('in_struc.cif')
def export_structure(struc, filename, fileformat='poscar'): with open(filename, 'w') as f: for s in struc: if fileformat == 'poscar': content = s.to(fmt='poscar') else: content = CifWriter(struc, symprec=0.01).write_file() f.writelines(content)
def get_string(self, df_head_only=False): from pymatgen import Structure lines, scope = [], [] for key,value in self.document.iterate(): if isinstance(value, Table): lines[-1] = lines[-1].replace('{', '[+').replace('}', ']') header = any([isinstance(col, str) for col in value]) if isinstance(value.index, MultiIndex): value.reset_index(inplace=True) if df_head_only: value = value.head() csv_string = value.to_csv( index=False, header=header, float_format='%g', encoding='utf-8' )[:-1] lines += csv_string.split('\n') if df_head_only: lines.append('...') elif isinstance(value, Structure): from pymatgen.io.cif import CifWriter cif = CifWriter(value, symprec=symprec).__str__() lines.append(make_pair( ''.join([replacements.get(c, c) for c in key]), cif+':end' )) elif Quantity is not None and isinstance(value, Quantity): lines.append(make_pair( value.display_symbols[0], value.pretty_string() )) else: level, key = key # truncate scope level_reduction = bool(level < len(scope)) if level_reduction: del scope[level:] # append scope if value is None: scope.append(''.join([ replacements.get(c, c) for c in key ])) # correct scope to omit internal 'general' section scope_corr = scope if scope[0] == mp_level01_titles[0]: scope_corr = scope[1:] # insert scope line if (value is None and scope_corr) or \ (value is not None and level_reduction): lines.append('\n{' + '.'.join(scope_corr) + '}') # insert key-value line if value is not None: val = str(value) value_lines = [val] if val.startswith('http') \ else textwrap.wrap(val) if len(value_lines) > 1: value_lines = [''] + value_lines + [':end'] lines.append(make_pair( ''.join([replacements.get(c, c) for c in key]), '\n'.join(value_lines) )) return '\n'.join(lines) + '\n'
def get_cif(filename, tolerance=0.1): if filename[-5:] == '.vasp': with open(filename, 'r') as f: struc_str = f.read() struc = Structure.from_str(struc_str, fmt='poscar') else: struc = Structure.from_file(filename) cif = CifWriter(struc, symprec=tolerance) cif.write_file(filename + '.cif')
def value_for_field(self, obj, field): # add cif key to response if requested if field == "cif": s = Structures.objects.get(id=obj.id) fields = self.get_optional_fields()[:-1] structure = Structure.from_dict(self.serialize(s, fields=fields)) return CifWriter(structure, symprec=1e-10).__str__() else: raise UnknownFieldError
def write_cif_input(self): cif_writer = CifWriter(struct=self.input_structure, symprec=None, write_magmoms=True, significant_figures=8, angle_tolerance=5.0, refine_struct=True) cif_writer.write_file(self.input_filename_cif)
def dump(self, fileName): """ Write current structure to CIF. fileName: str Name of output file """ #TODO: format this to work with custom WriteCIF. CifWriter(self.atoms).write_file(fileName+".cif")
def out_struc(fin, fout, tolerance=0.1): natot = get_natot(fin) lines_cell = extract_cell_parameters(fout) if lines_cell is None: # 'relax' --> no CELL_PARAMETERS lines_cell = extract_cell_parameters(fin) # get from input lines_atom = extract_atomic_positions(fout, natot) structure = from_lines(lines_cell, lines_atom) # pymatgen format structure.to(fmt='poscar', filename='out_struc.vasp') cif = CifWriter(structure, symprec=tolerance) cif.write_file('out_struc.cif')
def add_cifs(doc): symprec = 0.1 struc = Structure.from_dict(doc["structure"]) sym_finder = SpacegroupAnalyzer(struc, symprec=symprec) doc["cif"] = str(CifWriter(struc)) doc["cifs"] = {} try: primitive = sym_finder.get_primitive_standard_structure() conventional = sym_finder.get_conventional_standard_structure() refined = sym_finder.get_refined_structure() doc["cifs"]["primitive"] = str(CifWriter(primitive)) doc["cifs"]["refined"] = str(CifWriter(refined, symprec=symprec)) doc["cifs"]["conventional_standard"] = str( CifWriter(conventional, symprec=symprec)) doc["cifs"]["computed"] = str(CifWriter(struc, symprec=symprec)) except: doc["cifs"]["primitive"] = None doc["cifs"]["refined"] = None doc["cifs"]["conventional_standard"] = None
def predict_structure(species, struc_list, check_dir=False, threshold=0.00001): """ Predicted structures for set of pymatgen species using the Pymatgen structure predictor and save as cif file. TODO: This will be superceded by our own implementation of the structure prediction algorithm in future versions of SMACT. Args: species (list): Pymatgen Species for which structure should be predicted. struc_list (list): Pymatgen Structure objects to consider as parent structures in the substitution algorithm. check_dir (bool): check if directory already exists and only carry out prediction and write new files if it doesn't. threshold (float): Log-probability threshold for the Pymatgen structure predictor. Returns: Saves cif files of possible structures in new directory along with a summary .txt file containing info including probabilities. """ sub = Substitutor(threshold=0.00001) print('{} ........'.format(species)) dirname = ''.join([str(i) for i in species]) path_exists = True if os.path.exists( './SP_results/{0}'.format(dirname)) else False if (check_dir and path_exists): print('Already exists') else: print('{} not already there'.format(dirname)) suggested_strucs = sub.pred_from_structures(target_species=species, structures_list=struc_list, remove_existing=False, remove_duplicates=True) suggested_strucs = sorted(suggested_strucs, key=lambda k: k.other_parameters['proba'], reverse=True) # Save the structures as cifs if not path_exists: os.makedirs('./SP_results/{0}'.format(dirname)) for i, d in enumerate(suggested_strucs): cw = CifWriter(d.final_structure) cw.write_file("SP_results/{0}/{1}_BasedOn_{2}.cif".format( dirname, i, d.history[0]['source'])) # Save the summary as a text file with open('SP_results/{0}/{0}_summary.txt'.format(dirname), 'w') as f: f.write('Formula, Probability, Based on, Substitutions \n') for i, struc in enumerate(suggested_strucs): f.write( ' {0}, {1:12}, {2:.5f}, {3:9}, {4} \n'.format( i, struc.composition.reduced_formula, struc.other_parameters['proba'], struc.history[0]['source'], re.sub('Specie', '', str(struc.history[1]['species_map'])))) print('Done.')
def get_string(self): lines, scope = [], [] table_start = mp_level01_titles[1]+'_' replacements = {' ': '_', ',': '', '[': '', ']': ''} for key,value in self.document.iterate(): if key is None and isinstance(value, dict): pd_obj = pandas.DataFrame.from_dict(value) header = any([bool( isinstance(col, unicode) or isinstance(col, str) ) for col in pd_obj]) csv_string = pd_obj.to_csv( index=False, header=header, float_format='%g' )[:-1] lines += csv_string.split('\n') elif isinstance(value, Structure): cif = CifWriter(value).__str__() lines.append(make_pair( ''.join([replacements.get(c, c) for c in key]), cif+':end' )) else: level, key = key # truncate scope level_reduction = bool(level < len(scope)) if level_reduction: del scope[level:] # append scope and set delimiters if value is None: is_table = key.startswith(table_start) if is_table: # account for 'data_' prefix key = key[len(table_start):] start, end = '\n[+', ']' else: start, end = '\n{', '}' scope.append( ''.join([replacements.get(c, c) for c in key]) ) # correct scope to omit internal 'general' section scope_corr = scope if scope[0] == mp_level01_titles[0]: scope_corr = scope[1:] # insert scope line if (value is None and scope_corr)or \ (value is not None and level_reduction): lines.append(start+'.'.join(scope_corr)+end) # insert key-value line if value is not None: value_lines = textwrap.wrap(value) if len(value_lines) > 1: value_lines = [''] + value_lines + [':end'] lines.append(make_pair( ''.join([replacements.get(c, c) for c in key]), '\n'.join(value_lines) )) return '\n'.join(lines) + '\n'
def struct2ase(struct): """ convert pymatgen sructure to ASE structure """ from ase.io import read from pymatgen.io.cif import CifWriter w = CifWriter(struct) w.write_file("temp.cif") structure = read("temp.cif",format="cif") subprocess.call(["rm", "temp.cif"]) return structure
def export_structure(self, filename, fileformat='poscar'): """export incar""" atomNames = self.values["name_array"] latt = self.values["finalpos"]["basis"] pos = self.values["finalpos"]["positions"] struc = Structure(latt, atomNames, pos) if fileformat == 'poscar': Poscar(struc).write_file(filename=filename) else: CifWriter(struc, symprec=0.01).write_file(filename)
def stidy(self): ''' Run STRUCTURE TIDY as implemented in the PLATON software package. PLATON must either be in the PATH or in ../bin. References: A. L. Spek (2009). Acta Cryst., D65, 148-155. E. Parthé and L. M. Gelato (1984). Acta Cryst., A40, 169-183. L. M. Gelato and E. Parthé (1987). J. Appl. Cryst. 20, 139-143. S-Z. Hu and E. Parthé (2004). Chinese J. Struct. Chem. 23, 1150-1160. ''' ang = 5 d1 = 0.55 d2 = 0.55 d3 = 0.55 PLATON = find_executable('platon') if not PLATON: PLATON = '../bin/platon' with NamedTemporaryFile(suffix='.cif') as temp_file: # write temporary cif file CifWriter(self.ctx.structure).write_file(temp_file.name) temp_file.flush() # run ADDSYM_SHX to make PLATON recognize symmetries addsym_shx_process = Popen(['platon', '-o', temp_file.name], stdout=PIPE, stderr=STDOUT, stdin=PIPE) addsym_shx_process.communicate( input=b'ADDSYM_SHX {} {} {} {}'.format(ang, d1, d2, d3)) # call STIDY on the ADDSYM_SHX output temp_file_dirname, temp_file_basena dme = path.split( temp_file.name) temp_file_basename_extless, _ = path.splitext( temp_file_basename) temp_file_basename_spf = temp_file_basename_extless + '_pl.spf' temp_file_spf = path.join( temp_file_dirname, temp_file_basename_spf) stidy_process = Popen(['platon', '-o', temp_file_spf], stdout=PIPE, stderr=STDOUT, stdin=PIPE) stidy_data = stidy_process.communicate(input=b'STIDY') stidy_output = stidy_data[0].decode('utf-8') # clean up files if path.isfile('check.def'): remove('check.def') self.ctx.stidy_output = stidy_output
def place_files(self, structure, source_uuid=None, metadata=None): """place files Parameters ---------- structure: pymatgen.structure material structure source_uuid : string uuid file metadata: dic metadata to add Returns ------- boolean: True if created False if not created """ super_place_files = super().place_files() if super_place_files: targetdir = self.get_currentdir() if source_uuid is not None: dic = {"source_uuid": source_uuid} else: dic = {} if metadata is not None: dic.update(metadata) kind = self.structurefile_kind dic.update({"kind": kind}) if kind == "cif": # as cif file ciffilename = self.cif_filename dic.update({"positionfile": ciffilename}) cifpath = os.path.join(targetdir, ciffilename) cifwriter = CifWriter(structure) cifwriter.write_file(cifpath) else: # as POSCAR poscarfilename = "POSCAR" dic.update({"positionfile": poscarfilename}) poscarpath = os.path.join(targetdir, poscarfilename) poscar = Poscar(structure) poscar.write_file(poscarpath) species = element_list(structure.species) dic.update({"species": species, "nspecies": len(species)}) self.save_currentdir_metadata(dic) return True else: return False
def value_for_field(self, obj, field): # add cif key to response if requested if field == "cif": # make sure to have full structure object available s = Structures.objects.get(id=obj.id) fields = self.get_optional_fields()[:-1] structure = Structure.from_dict(self.serialize(s, fields=fields)) cif = CifWriter(structure, symprec=1e-10).__str__() s.update(set__cif=cif) return cif else: raise UnknownFieldError
def add_cifs(doc): struc = Structure.from_dict(doc["structure"]) sym_finder = SpacegroupAnalyzer(struc, symprec=0.1) doc["cif"] = str(CifWriter(struc)) doc["cifs"] = {} if sym_finder.get_hall(): primitive = sym_finder.get_primitive_standard_structure() conventional = sym_finder.get_conventional_standard_structure() refined = sym_finder.get_refined_structure() doc["cifs"]["primitive"] = str(CifWriter(primitive)) doc["cifs"]["refined"] = str(CifWriter(refined)) doc["cifs"]["conventional_standard"] = str(CifWriter(conventional)) doc["cifs"]["computed"] = str(CifWriter(struc)) doc["spacegroup"]["symbol"] = sym_finder.get_space_group_symbol() doc["spacegroup"]["number"] = sym_finder.get_space_group_number() doc["spacegroup"]["point_group"] = sym_finder.get_point_group_symbol() doc["spacegroup"]["crystal_system"] = sym_finder.get_crystal_system() doc["spacegroup"]["hall"] = sym_finder.get_hall() else: doc["cifs"]["primitive"] = None doc["cifs"]["refined"] = None doc["cifs"]["conventional_standard"] = None
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 == "POSCAR": p = Poscar.from_file(filename) structure = p.structure elif iformat == "CIF": r = CifParser(filename) structure = r.get_structures()[0] elif iformat == "CONVENTIONAL_CIF": r = CifParser(filename) structure = r.get_structures(primitive=False)[0] elif iformat == "CSSR": structure = Cssr.from_file(filename).structure else: structure = Structure.from_file(filename) if oformat == "smart": structure.to(filename=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": ts = TransformedStructure( structure, [], history=[{"source": "file", "datetime": str(datetime.datetime.now()), "original_file": open(filename).read()}]) ts.write_vasp_input(MPRelaxSet, output_dir=out_filename) elif oformat == "MITVASP": ts = TransformedStructure( structure, [], history=[{"source": "file", "datetime": str(datetime.datetime.now()), "original_file": open(filename).read()}]) ts.write_vasp_input(MITRelaxSet, output_dir=out_filename) except Exception as ex: print("Error converting file. Are they in the right format?") print(str(ex))