Python bindings for FEFF10 X-ray absorption spectroscopy calculations
Project description
feff10-rs
Python bindings for FEFF10, a real-space multiple-scattering code for ab initio calculations of X-ray absorption spectra (EXAFS, XANES) and related properties.
Built with PyO3 and maturin for native performance with a Pythonic API.
Installation
pip install feff10-rs
No compiler needed — prebuilt wheels are available for:
| Platform | Architecture | Python |
|---|---|---|
| Linux | x86_64, aarch64 | 3.9 – 3.14+ |
| macOS | Intel, Apple Silicon | 3.9 – 3.14+ |
| Windows | x86_64 | 3.9 – 3.14+ |
Quick Start
import feff10
# One-liner: parse, validate, and run
result = feff10.run("feff.inp", "./work")
print(f"Done in {result.total_duration_secs:.1f}s")
# Parse and compare output
xmu = feff10.FeffTable.from_file("./work/xmu.dat")
reference = feff10.FeffTable.from_file("reference_xmu.dat")
rsq = xmu.r_squared(reference, col_x=0, col_y=3)
print(f"R-squared = {rsq*100:.4f}%")
You can also pass raw feff.inp text or a FeffInput object:
# From raw text
result = feff10.run(open("feff.inp").read(), "./work")
# From a FeffInput object
inp = feff10.FeffInput.from_file("feff.inp")
inp.s02 = 0.9
result = feff10.run(inp, "./work")
Working with Input Files
Parsing
# From file
inp = feff10.FeffInput.from_file("feff.inp")
# From string
inp = feff10.FeffInput.parse(content)
# Strict mode — raises FeffParseError on malformed input
inp = feff10.FeffInput.from_file_strict("feff.inp")
Inspecting
inp.edge # "K", "L3", etc.
inp.s02 # amplitude reduction factor
inp.num_atoms # number of atoms
inp.num_potentials # number of unique potentials
inp.control # CONTROL flags (6-element list)
inp.other_cards # other cards (EXAFS, RPATH, etc.)
for pot in inp.potentials:
print(f"ipot={pot.ipot}, Z={pot.z}, tag={pot.tag}")
for atom in inp.atoms:
print(f"({atom.x}, {atom.y}, {atom.z}) ipot={atom.ipot}")
Creating from Scratch
inp = feff10.FeffInput(
title=["Cu K-edge EXAFS"],
edge="K",
s02=1.0,
potentials=[
feff10.Potential(ipot=0, z=29, tag="Cu"),
feff10.Potential(ipot=1, z=29, tag="Cu"),
],
atoms=[
feff10.Atom(x=0.0, y=0.0, z=0.0, ipot=0, tag="Cu"),
feff10.Atom(x=0.0, y=1.805, z=1.805, ipot=1, tag="Cu"),
],
other_cards=["EXAFS 20.0", "RPATH 5.5"],
)
Modifying and Writing
inp.edge = "L3"
inp.s02 = 0.85
inp.control = [1, 1, 1, 1, 0, 0]
inp.write_to_file("modified.inp")
Validation
# Validate without running (raises FeffConfigError if invalid)
feff10.validate("feff.inp")
# Or validate a FeffInput object
inp = feff10.FeffInput.from_file("feff.inp")
inp.validate()
Checks: absorber potential (ipot=0) exists, atoms reference valid potentials, no duplicate ipot values, atomic numbers in range, and more.
Running Calculations
Simple (Recommended)
# From file path — validates input automatically
result = feff10.run("feff.inp", "./work")
# From FeffInput object
result = feff10.run(inp, "./work")
Full Control
config = feff10.FeffConfig("./work", inp)
result = feff10.FeffPipeline(config).run()
for sr in result.stages:
print(f"{sr.stage.executable_name}: {sr.duration_secs:.3f}s")
print(f"Total: {result.total_duration_secs:.3f}s")
Running Specific Stages
config = feff10.FeffConfig(
"./work", inp,
stages=[feff10.Stage.RDINP, feff10.Stage.POT, feff10.Stage.XSPH],
)
Progress Callbacks
def on_progress(stage, progress):
if progress.kind == "starting":
print(f" Running {stage.executable_name}...", end="", flush=True)
else:
print(f" done ({progress.duration_secs:.2f}s)")
result = feff10.FeffPipeline(config).run_with_progress(on_progress)
Pipeline Stages
FEFF10 has 18 stages, each a separate computational step:
for stage in feff10.Stage.all():
print(f"{stage.executable_name} (control index {stage.control_index})")
Parsing Output
Reading xmu.dat
result = feff10.run("feff.inp", "./work")
xmu = result.read_xmu() # convenience on PipelineResult
outputs = result.outputs() # discover all *.dat outputs
print(xmu.ncols) # number of columns
print(xmu.nrows) # number of data points
print(xmu.header) # comment lines from file header
print(xmu) # shows first 5 rows
print(len(outputs.files))
Discovering and parsing multiple outputs
outputs = feff10.FeffOutputs.discover("./work")
for f in outputs.files:
print(f.kind, f.name)
chi = outputs.read_chi()
paths = outputs.read_paths()
print(paths.npaths, paths.total_degeneracy())
Accessing Columns
energy = xmu.column(0) # or xmu[0]
mu = xmu.column(3) # or xmu[3]
last = xmu[-1] # negative indexing
for col in xmu: # iterate over columns
print(f"{len(col)} points")
Comparing Spectra
calculated = feff10.FeffTable.from_file("./work/xmu.dat")
reference = feff10.FeffTable.from_file("reference_xmu.dat")
rsq = calculated.r_squared(reference, col_x=0, col_y=3)
print(f"R-squared = {rsq*100:.4f}%") # lower is better
Pandas Integration
pip install 'feff10-rs[pandas]'
df = xmu.to_dataframe()
print(df.describe())
Error Handling
try:
result = feff10.FeffPipeline(config).run()
except feff10.FeffPipelineError as e:
print(f"Pipeline failed: {e}")
except feff10.FeffConfigError as e:
print(f"Configuration error: {e}")
except feff10.FeffParseError as e:
print(f"Parse error: {e}")
except feff10.FeffIOError as e:
print(f"I/O error: {e}")
Exception hierarchy:
FeffError— base exceptionFeffIOError— file I/O errorsFeffParseError— input/output parsing errorsFeffPipelineError— pipeline execution errorsFeffConfigError— configuration validation errors
GIL Behavior
Both run() and run_with_progress() release the Python GIL during FEFF stage execution, allowing other Python threads to run concurrently.
API Summary
| Function / Class | Description |
|---|---|
run(input, work_dir) |
Run a FEFF calculation (accepts file path, raw text, or FeffInput) |
validate(input) |
Validate input without running (accepts file path, raw text, or FeffInput) |
FeffInput |
Parse, create, modify, and write feff.inp files |
Potential |
Scattering potential (ipot, Z, tag, l_scmt, l_fms, stoich) |
Atom |
Atomic position (x, y, z, ipot, tag, distance) |
FeffConfig |
Calculation configuration (work_dir, input, stages, timeout) |
Stage |
Pipeline stage enum (18 stages: RDINP through RHORRP) |
FeffPipeline |
Execute FEFF calculations with optional progress callbacks |
PipelineResult |
Execution results (stages, work_dir, total_duration_secs) |
StageResult |
Per-stage timing (stage, duration_secs) |
StageProgress |
Progress callback data (kind, duration_secs) |
FeffTable |
Parse xmu.dat output with column access and pandas integration |
PathsDat |
Parse structured paths.dat path-expansion output |
FeffOutputs |
Discover and read output files from a work directory |
License
MIT or Apache-2.0. The FEFF10 Fortran source is under its own license.
Links
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file feff10_rs-0.2.0-cp39-abi3-win_amd64.whl.
File metadata
- Download URL: feff10_rs-0.2.0-cp39-abi3-win_amd64.whl
- Upload date:
- Size: 4.3 MB
- Tags: CPython 3.9+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a09717bb37cf06a1530e7d860de2764f912973e3cb04e7a736ae31c681fc846f
|
|
| MD5 |
7949c4c26c14b852cfaa5c3f006732ca
|
|
| BLAKE2b-256 |
7c6df98653d5d605b0c83d778659f2d02f9632ce63f7b8f0b1f375f964892a6e
|
File details
Details for the file feff10_rs-0.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: feff10_rs-0.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 8.5 MB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
08e30cbde48d6f6a63ebdb5e7908339c41136800692c5e0472311831c3b0d866
|
|
| MD5 |
93969f6bad0b7931d442cbfa2211f0b6
|
|
| BLAKE2b-256 |
80ddeb34d2d13e0a1d01e83314a8a9fc9328af8ca872c4bf5f14f8ef7a202b30
|
File details
Details for the file feff10_rs-0.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: feff10_rs-0.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 2.6 MB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9ec5084b082dc38a9bfddb7d5a91742e70197df3d8808ba99313d2d6c4b5f170
|
|
| MD5 |
57ff1844fd3c1c69087d8dcc848d03fd
|
|
| BLAKE2b-256 |
e7d4f24bfbf552e5c48603b3f62372de3fd473810913efa267dc56c2d867eb34
|
File details
Details for the file feff10_rs-0.2.0-cp39-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: feff10_rs-0.2.0-cp39-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.5 MB
- Tags: CPython 3.9+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e20997a01e8362fe1d900c60f552a8c8b81b2fa57237b114e732cf77c859a423
|
|
| MD5 |
c24057e082fc31df241cab374f8b6898
|
|
| BLAKE2b-256 |
0dc0e01d064652d90e17c8b07c7d0b202b36e17f29ab9717130f23b7de3bcec7
|
File details
Details for the file feff10_rs-0.2.0-cp39-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: feff10_rs-0.2.0-cp39-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 3.9 MB
- Tags: CPython 3.9+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ec76456f12285b21b4ed7839f467cdf3ef10600d3fe1540f536ea9a6c60d375e
|
|
| MD5 |
5f1ebad71580e94d0cf382bcfe22cf37
|
|
| BLAKE2b-256 |
e9a464bae177692b67929145c7e4f65c15720119a354bff83e2a94bfc9b7023e
|