Skip to content

Commit bcb6590

Browse files
authored
Add configurable PRINT card values to Struct2XAS.make_input_feff (#606)
* Add configurable PRINT card values to make_input_feff Add feff_print parameter to control FEFF output verbosity for each module (pot, xsph, fms, paths, genfmt, ff2chi). Default [1,0,0,0,0,3] matches structure2feff.py behavior. Backwards compatible - users can pass custom values if needed. * Add unit tests for Struct2XAS.make_input_feff feff_print parameter Tests verify: - Default feff_print produces [1,0,0,0,0,3] (ff2chi=3) - Custom feff_print values are applied correctly - Old behavior (ff2chi=0) is recoverable for backwards compatibility
1 parent d8678dd commit bcb6590

File tree

3 files changed

+106
-2
lines changed

3 files changed

+106
-2
lines changed

larch/xrd/struct2xas.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838

3939
__author__ = ["Beatriz G. Foschiani", "Mauro Rovezzi"]
4040
__email__ = ["beatrizgfoschiani@gmail.com", "mauro.rovezzi@esrf.fr"]
41-
__credits__ = ["Jade Chongsathapornpong", "Marius Retegan"]
41+
__credits__ = ["Jade Chongsathapornpong", "Marius Retegan", "Helen Engelhardt"]
4242
__version__ = "2024.1.0"
4343

4444

@@ -999,6 +999,7 @@ def make_input_feff(
999999
edge: str = "K",
10001000
sig2: Union[float, None] = None,
10011001
debye: Union[List[float], None] = None,
1002+
feff_print: Union[List[int], None] = None,
10021003
**kwargs,
10031004
):
10041005
"""
@@ -1026,6 +1027,11 @@ def make_input_feff(
10261027
temperature at which the Debye-Waller factors are calculated [Kelvin].
10271028
debye_temperature : float
10281029
Debye Temperature of the material [Kelvin].
1030+
feff_print : list of six ints or None, [None]
1031+
PRINT card values controlling output verbosity for each FEFF module:
1032+
[pot, xsph, fms, paths, genfmt, ff2chi]
1033+
Values: 0=minimal, 1=standard, 2+=verbose
1034+
If None, defaults to [1, 0, 0, 0, 0, 3] (matches structure2feff.py)
10291035
10301036
..note:: refer to [FEFF documentation](https://feff.phys.washington.edu/feffproject-feff-documentation.html)
10311037
@@ -1094,6 +1100,10 @@ def make_input_feff(
10941100
use_debye = ""
10951101
temperature, debye_temperature = debye[0], debye[1]
10961102

1103+
# Default PRINT values match structure2feff.py behavior
1104+
if feff_print is None:
1105+
feff_print = [1, 0, 0, 0, 0, 3]
1106+
10971107
feff_comment = f"{feff_comment}"
10981108
edge = f"{edge}"
10991109
radius = f"{radius}"
@@ -1203,6 +1213,12 @@ def make_input_feff(
12031213
replacements["potentials"] = potentials
12041214
replacements["atoms"] = atoms
12051215
replacements["title"] = title
1216+
replacements["print_pot"] = feff_print[0]
1217+
replacements["print_xsph"] = feff_print[1]
1218+
replacements["print_fms"] = feff_print[2]
1219+
replacements["print_paths"] = feff_print[3]
1220+
replacements["print_genfmt"] = feff_print[4]
1221+
replacements["print_ff2chi"] = feff_print[5]
12061222
# replacements[""] =
12071223

12081224
try:

larch/xrd/templates/feff_exafs.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ S02 0.0
88

99
* pot xsph fms paths genfmt ff2chi
1010
CONTROL 1 1 1 1 1 1
11-
PRINT 1 0 0 0 0 0
11+
PRINT {print_pot} {print_xsph} {print_fms} {print_paths} {print_genfmt} {print_ff2chi}
1212

1313
*** ixc=0 means to use Hedin-Lundqvist
1414
* ixc [ Vr Vi ]
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#!/usr/bin/env python
2+
"""Test feff_print parameter in Struct2XAS.make_input_feff()
3+
4+
Tests the configurable PRINT card values feature added to struct2xas.py.
5+
"""
6+
7+
import re
8+
import pytest
9+
import tempfile
10+
from pathlib import Path
11+
12+
from larch.xrd.struct2xas import Struct2XAS
13+
14+
toppath = Path(__file__).parent.parent
15+
structpath = toppath / "examples" / "structuredata" / "struct2xas"
16+
CIF_FILE = structpath / "ZnO_mp-2133.cif"
17+
18+
19+
@pytest.fixture
20+
def cif_file():
21+
"""Return path to test CIF file."""
22+
if not CIF_FILE.exists():
23+
pytest.skip(f"Test CIF file not found: {CIF_FILE}")
24+
return CIF_FILE
25+
26+
27+
def extract_print_values(feff_inp_path):
28+
"""Extract PRINT card values from feff.inp file."""
29+
content = Path(feff_inp_path).read_text()
30+
match = re.search(
31+
r"^PRINT\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)",
32+
content,
33+
re.MULTILINE,
34+
)
35+
if not match:
36+
return None
37+
return [int(match.group(i)) for i in range(1, 7)]
38+
39+
40+
def test_default_feff_print_has_ff2chi_3(cif_file):
41+
"""Default feff_print should be [1, 0, 0, 0, 0, 3] matching structure2feff.py."""
42+
with tempfile.TemporaryDirectory() as tmpdir:
43+
mat = Struct2XAS(file=str(cif_file), abs_atom="Zn")
44+
mat.set_abs_site(0)
45+
mat.make_input_feff(radius=6.0, parent_path=tmpdir)
46+
47+
feff_files = list(Path(tmpdir).glob("**/feff.inp"))
48+
assert len(feff_files) == 1, "feff.inp should be generated"
49+
50+
values = extract_print_values(feff_files[0])
51+
assert values is not None, "PRINT card should be present"
52+
assert values == [1, 0, 0, 0, 0, 3], f"Expected [1,0,0,0,0,3], got {values}"
53+
54+
55+
def test_custom_feff_print_values(cif_file):
56+
"""Custom feff_print values should be written to feff.inp."""
57+
custom_print = [1, 1, 1, 1, 1, 2]
58+
59+
with tempfile.TemporaryDirectory() as tmpdir:
60+
mat = Struct2XAS(file=str(cif_file), abs_atom="Zn")
61+
mat.set_abs_site(0)
62+
mat.make_input_feff(radius=6.0, parent_path=tmpdir, feff_print=custom_print)
63+
64+
feff_files = list(Path(tmpdir).glob("**/feff.inp"))
65+
assert len(feff_files) == 1
66+
67+
values = extract_print_values(feff_files[0])
68+
assert values == custom_print, f"Expected {custom_print}, got {values}"
69+
70+
71+
def test_feff_print_old_behavior_recoverable(cif_file):
72+
"""Old behavior (ff2chi=0) should be recoverable via feff_print parameter."""
73+
old_print = [1, 0, 0, 0, 0, 0]
74+
75+
with tempfile.TemporaryDirectory() as tmpdir:
76+
mat = Struct2XAS(file=str(cif_file), abs_atom="Zn")
77+
mat.set_abs_site(0)
78+
mat.make_input_feff(radius=6.0, parent_path=tmpdir, feff_print=old_print)
79+
80+
feff_files = list(Path(tmpdir).glob("**/feff.inp"))
81+
assert len(feff_files) == 1
82+
83+
values = extract_print_values(feff_files[0])
84+
assert values == old_print, f"Expected {old_print}, got {values}"
85+
86+
87+
if __name__ == "__main__":
88+
pytest.main([__file__, "-v"])

0 commit comments

Comments
 (0)