Python API

lineshapes.Model

Model()

Composable optical-constant model; calling it returns delta + 1j*beta.

Build by chaining; every builder method mutates the model and returns it. Energies are in eV. delta is the exact Hilbert partner of beta for each peak (delta < 0 below a resonance), and amp is the height of beta at the peak center for every lineshape.

Example
m = (Model()
     .gaussian(e0=933.8, width=0.49, amp=4.1e-5)
     .continuum(bkg=3.6e-4, slope=-3.7e-7)
     .step(e0=939.4, width=6.1, height=7.2e-5))
n = m(energy)                 # complex128, single core
n = m(energy, parallel=True)  # all cores

The model also exposes a flat parameter vector (params, param_names, set_params) for fitting without rebuilding, and bind to fix an energy grid for repeated evaluation. A new model is empty and evaluates to zero.

n_components property

n_components: int

Number of peaks and steps (a pseudo-Voigt counts as one).

n_params property

n_params: int

Length of the flat parameter vector.

params property

params: FloatArray

Flat parameter vector: each component's parameters in insertion order, then continuum.bkg, continuum.slope, scale, shift.

param_names property

param_names: list[str]

Names matching params, e.g. 'gaussian[0].e0', 'step[1].height', 'scale'.

gaussian

gaussian(e0: float, width: float, amp: float) -> Self

Add a Gaussian peak with its Dawson-function delta.

Parameters:

Name Type Description Default
e0 float

Center in eV.

required
width float

1/e half-width in eV: beta falls to amp/e at e0 +- width (sigma = width/sqrt(2)).

required
amp float

Peak height of beta.

required

lorentzian

lorentzian(e0: float, gamma: float, amp: float) -> Self

Add a Lorentzian peak, delta + i beta = amp*gamma / (E - e0 - i*gamma).

Parameters:

Name Type Description Default
e0 float

Center in eV.

required
gamma float

Half width at half maximum in eV.

required
amp float

Peak height of beta.

required

voigt

voigt(e0: float, sigma: float, gamma: float, amp: float) -> Self

Add an exact Voigt peak (Gaussian convolved with Lorentzian), via the Faddeeva function.

Parameters:

Name Type Description Default
e0 float

Center in eV.

required
sigma float

Gaussian standard deviation in eV.

required
gamma float

Lorentzian half width at half maximum in eV (>= 0).

required
amp float

Peak height of beta.

required

pseudo_voigt

pseudo_voigt(e0: float, fwhm: float, eta: float, amp: float) -> Self

Add a pseudo-Voigt eta*Lorentzian + (1-eta)*Gaussian sharing one FWHM.

Its delta is exact by linearity. It is a single component with its own eta parameter.

Parameters:

Name Type Description Default
e0 float

Center in eV.

required
fwhm float

Full width at half maximum of both parts, in eV.

required
eta float

Lorentzian fraction in [0, 1].

required
amp float

Peak height of beta.

required

continuum

continuum(bkg: float = 0.0, slope: float = 0.0) -> Self

Set the linear continuum in beta, bkg + slope*E (replaces any previous one).

step

step(e0: float, width: float, height: float, decay: float = 0.0) -> Self

Add an erf ionization step to beta: 0.5*height*(1 + erf((E-e0)/width)) + decay*max(E-e0, 0).

Only beta is modeled analytically; the matching delta belongs in the fixed delta table.

Parameters:

Name Type Description Default
e0 float

Edge energy in eV.

required
width float

Erf width in eV.

required
height float

Step height of beta.

required
decay float

Linear post-edge slope added above e0.

0.0

delta_table

delta_table(energy: FloatArray, delta: FloatArray) -> Self

Set the fixed continuum delta (e.g. computed once with kkcalc), added to delta.

Interpolated linearly like numpy.interp and clamped to the end values outside the table. It is not a fit parameter.

Parameters:

Name Type Description Default
energy FloatArray

Strictly increasing energies in eV.

required
delta FloatArray

Delta values at energy.

required

scale

scale(scale: float) -> Self

Set the overall multiplicative scale (e.g. the density relative to a unit-density table).

shift

shift(shift: float) -> Self

Set the energy offset: the model is evaluated at E + shift.

copy

copy() -> Model

Return an independent copy, so a base model can be extended in several ways.

set_params

set_params(params: FloatArray) -> Self

Set all parameters from a flat vector.

Raises:

Type Description
ValueError

On a wrong length or an invalid value (non-positive width, eta outside [0, 1], non-finite entries). The model is unchanged on error.

bind

bind(energy: FloatArray, cache: bool = True) -> Evaluator

Bind the model to a fixed energy grid for fitting loops.

Parameters:

Name Type Description Default
energy FloatArray

Energy grid in eV.

required
cache bool

Keep each component's contribution (n_components * len(energy) * 16 bytes) so a call recomputes only components whose parameters changed.

True

__call__

__call__(energy: FloatArray, params: FloatArray | None = None, parallel: bool = False) -> ComplexArray

Evaluate delta + 1j*beta on energy.

Parameters:

Name Type Description Default
energy FloatArray

1-D float64 energies in eV (sorted input is fastest).

required
params FloatArray | None

Evaluate at this parameter vector without modifying the model.

None
parallel bool

Use all cores; results are identical to the single-core path.

False

lineshapes.Evaluator

A Model bound to a fixed energy grid; recomputes only the components that changed.

Created by Model.bind. Changing scale, continuum.bkg or continuum.slope costs no peak work; changing shift recomputes every component.

Example
ev = model.bind(energy)
theta = ev.params.copy()
n = ev(theta)
theta[0] += 1e-3          # one peak moves
n = ev(theta, out=buf)    # only that peak is recomputed; buf is a preallocated complex128 array

n_params property

n_params: int

Length of the flat parameter vector.

params property

params: FloatArray

Current parameter vector.

param_names property

param_names: list[str]

Names matching params.

energy property

energy: FloatArray

The bound energy grid.

model property

model: Model

A copy of the bound model at the current parameters.

set_params

set_params(params: FloatArray) -> None

Set the parameters without evaluating.

__call__

__call__(params: FloatArray | None = None, out: ComplexArray | None = None) -> ComplexArray

Evaluate at params (or the current parameters).

Parameters:

Name Type Description Default
params FloatArray | None

Flat parameter vector to set first.

None
out ComplexArray | None

Optional contiguous complex128 array of the grid length to write into.

None

lineshapes.datasets

Example datasets shipped with the package: ZnPc and Alq3 carbon K-edge spectra.

All optical-constant tables are per unit density (1 g/cm^3). The continuum of each material is fixed ahead of time (bare-atom beta, with its delta from kkcalc2); the peaks are fit on top. Provenance and the generating script: tools/make_example_data.py.

Tables (see available):

name columns
znpc_nexafs energy_ev, theta_deg, mu_cm2_per_g, intensity_raw (five angles)
znpc_dft_clusters, alq3_dft_clusters energy_ev, amplitude, sigma_ev (DFT transition clusters)
alq3_oc_tey energy_ev, delta, beta (optical constants from total-electron-yield XAS)
alq3_oc_model energy_ev, delta, beta (building-block model optical constants)

available

available() -> list[str]

Names of the tables accepted by load_table.

path

path(name: str) -> Path

Filesystem path of a shipped file (name with or without .csv).

load_table

load_table(name: str) -> dict[str, FloatArray]

Load a shipped table as {column: float64 array}.

load_continuum

load_continuum(material: str) -> dict

Fixed continuum of a material ("znpc" or "alq3").

Returns the parameters (bkg, slope, step = e0, width, height, decay), provenance, and the precomputed continuum delta table as energy and delta arrays.

continuum_model

continuum_model(material: str) -> Model

A Model holding only the material's fixed continuum (beta + delta table).

Add peaks to it with the usual chained methods.

lineshapes.units

Unit conversions between absorption measurements and the optical constant beta.

mu_to_beta

mu_to_beta(energy_ev: ArrayLike, mu_cm2_per_g: ArrayLike, density_g_cm3: float = 1.0) -> FloatArray

Convert a mass absorption coefficient to beta: beta = mu * rho * lambda / (4 pi).

Parameters:

Name Type Description Default
energy_ev ArrayLike

Photon energy in eV.

required
mu_cm2_per_g ArrayLike

Mass absorption coefficient in cm^2/g.

required
density_g_cm3 float

Mass density in g/cm^3. The example tables are per unit density (1.0); the film density is applied later as the model scale.

1.0

beta_to_mu

beta_to_mu(energy_ev: ArrayLike, beta: ArrayLike, density_g_cm3: float = 1.0) -> FloatArray

Inverse of mu_to_beta.

wavelength_angstrom

wavelength_angstrom(energy_ev: ArrayLike) -> FloatArray

Photon wavelength in Angstrom for energies in eV.