comparison larch_feff.py @ 1:8ee2cc3374fe draft

planemo upload for repository https://github.com/MaterialsGalaxy/larch-tools/tree/main/larch_feff commit 0f66842e802430e887d1c6cb7be1cc5436408fd2
author muon-spectroscopy-computational-project
date Mon, 04 Mar 2024 11:43:32 +0000
parents edf7f8ccf4af
children
comparison
equal deleted inserted replaced
0:edf7f8ccf4af 1:8ee2cc3374fe
3 import shutil 3 import shutil
4 import sys 4 import sys
5 from pathlib import Path 5 from pathlib import Path
6 6
7 from larch.xafs.feffrunner import feff6l 7 from larch.xafs.feffrunner import feff6l
8 from larch.xrd import cif2feff
8 9
10 from pymatgen.core import Species
9 from pymatgen.io.cif import CifParser 11 from pymatgen.io.cif import CifParser
10 from pymatgen.io.feff import Atoms, Header, Potential
11 12
12 13
13 def get_path_labels(paths_file): 14 def get_path_labels(paths_file):
14 is_meta = True 15 is_meta = True
15 count = 0 16 count = 0
46 47
47 def main(structure_file: str, file_format: dict): 48 def main(structure_file: str, file_format: dict):
48 crystal_f = Path(structure_file) 49 crystal_f = Path(structure_file)
49 feff_dir = "feff" 50 feff_dir = "feff"
50 feff_inp = "feff.inp" 51 feff_inp = "feff.inp"
51 header_inp = "header"
52 atoms_inp = "atoms"
53 potential_inp = "potential"
54 path = Path(feff_dir, feff_inp) 52 path = Path(feff_dir, feff_inp)
55 path.parent.mkdir(parents=True, exist_ok=True) 53 path.parent.mkdir(parents=True, exist_ok=True)
56 54
57 if file_format["format"] == "cif": 55 if file_format["format"] == "cif":
58 print(f"Parsing {crystal_f.name} and saving to {path}") 56 print(f"Parsing {crystal_f.name} and saving to {path}")
57
58 # Parse the cif file here... but only so that we can extract the
59 # chemical symbols present in the crystal
59 cif_parser = CifParser(crystal_f) 60 cif_parser = CifParser(crystal_f)
60 structures = cif_parser.get_structures() 61 structures = cif_parser.get_structures()
61 length = len(structures) 62 length = len(structures)
62 if length != 1: 63 if length != 1:
63 raise ValueError( 64 raise ValueError(
64 f"Execpted single structure in cif file but found {length}" 65 f"Expected single structure in cif file but found {length}"
65 ) 66 )
67
68 # cif2feffinp below will take the absorber to be a chemical symbol,
69 # while this tool should support integer site index or chemical symbol
70 # of site (string). Hence convert any integer input to the relevant
71 # chemical symbol string.
66 try: 72 try:
67 aborsbing_atom = int(file_format["absorbing_atom"]) 73 absorbing_atom_int = int(file_format["absorbing_atom"])
74 specie = structures[0][absorbing_atom_int].specie
75 if isinstance(specie, Species):
76 absorbing_atom = str(specie.element)
77 else:
78 absorbing_atom = str(specie)
68 except ValueError: 79 except ValueError:
69 # aborsbing_atom can be int or chemical symbol 80 absorbing_atom = file_format["absorbing_atom"]
70 aborsbing_atom = file_format["absorbing_atom"]
71 81
72 feff_header = Header(structures[0]) 82 # NOTE: Here the first site listed in the cif file with the species
73 potential = Potential(structures[0], aborsbing_atom) 83 # 'absorbing_atom' is selected as the absorbing atom.
74 atoms = Atoms(structures[0], aborsbing_atom, file_format["radius"]) 84 # NOTE: This generates output for FEFF6 via the 'version8' flag
75 # if len(atoms.struct.sites) < len(potential.): 85 inp_data = cif2feff.cif2feffinp(
86 crystal_f,
87 absorber=absorbing_atom,
88 edge=None,
89 cluster_size=file_format["radius"],
90 absorber_site=1,
91 site_index=None,
92 extra_titles=None,
93 with_h=False,
94 version8=False,
95 )
96 with open(path, "w") as feff_inp_file:
97 feff_inp_file.write(inp_data + "\n")
98 print(inp_data + "\n")
76 99
77 # print(atoms.as_dict())
78 feff_header.write_file(header_inp)
79 potential.write_file(potential_inp)
80 atoms.write_file(atoms_inp)
81 with open(path, "w") as feff_inp_file:
82 with open(header_inp) as f:
83 header_text = f.read()
84 print(header_text)
85 feff_inp_file.write(header_text + "\n")
86 with open(potential_inp) as f:
87 potential_text = f.readlines()
88 print(*potential_text)
89 feff_inp_file.writelines(potential_text + ["\n"])
90 with open(atoms_inp) as f:
91 atoms_text = f.readlines()
92 print(*atoms_text)
93 feff_inp_file.writelines(atoms_text + ["\n"])
94 if len(atoms_text) <= len(potential_text):
95 print(
96 "WARNING: Every potential in the structure must be represented"
97 " by at least one atom, consider increasing the radius"
98 )
99 else: 100 else:
100 print(f"Copying {crystal_f.name} to {path}") 101 print(f"Copying {crystal_f.name} to {path}")
101 shutil.copy(crystal_f, path) 102 shutil.copy(crystal_f, path)
102 103
103 feff6l(folder=feff_dir, feffinp=feff_inp) 104 feff6l(folder=feff_dir, feffinp=feff_inp)