Mercurial > repos > muon-spectroscopy-computational-project > larch_feff
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) |