Calculators Module

The calculators module contains the core X-ray physics calculations and the main result data structure.

Core Calculations

Core functionality for XRayLabTool.

This module is the orchestration layer for X-ray analysis. It re-exports domain types and cache utilities from focused submodules and contains the public API functions that wire everything together.

Field Descriptions:

Field Name

Unit

Description

formula

Chemical formula of the material

density_g_cm3

g/cm³

Material density

energy_ev

eV

X-ray photon energy

wavelength_angstrom

Å

X-ray wavelength

delta

Real part of refractive index decrement

beta

Imaginary part of refractive index decrement

attenuation_length_cm

cm

1/e attenuation length

critical_angle_mrad

mrad

Critical angle for total external reflection

critical_angle_degrees

degrees

Critical angle in degrees

linear_absorption_coefficient

cm⁻¹

Linear absorption coefficient (μ)

mass_absorption_coefficient

cm²/g

Mass absorption coefficient (μ/ρ)

xraylabtool.calculators.core.calculate_multiple_xray_properties(formula_list, energy_kev, mass_density_list)[source]

Calculate X-ray optical properties for multiple chemical formulas.

Parameters:
Return type:

dict[str, dict[str, str | float | ndarray]]

Returns:

Dictionary mapping formula strings to result dictionaries

Raises:

ValueError – If input lists have different lengths or invalid values

xraylabtool.calculators.core.calculate_single_material_properties(formula, energy_keV=None, density=None, *, energy=None)[source]

Calculate X-ray optical properties for a single material composition.

This is a pure function that calculates comprehensive X-ray optical properties for a single chemical formula at given energies and density. It returns an XRayResult dataclass containing all computed properties.

Parameters:
Returns:

Dataclass containing all calculated X-ray properties.

Return type:

XRayResult

Raises:
  • FormulaError – If chemical formula cannot be parsed or contains invalid elements

  • EnergyError – If energy values are outside valid range (0.03-30.0 keV)

  • ValidationError – If density is not positive or other validation failures

Examples

>>> import xraylabtool as xlt
>>> result = xlt.calculate_single_material_properties("SiO2", 8.0, 2.2)
>>> print(f"Formula: {result.formula}")
Formula: SiO2

See also

calculate_xray_properties : Calculate properties for multiple materials XRayResult : Complete documentation of returned dataclass

xraylabtool.calculators.core.calculate_xray_properties(formulas, energies, densities)[source]

Calculate X-ray optical properties for multiple material compositions.

Parameters:
Returns:

Dictionary mapping formula strings to XRayResult objects.

Return type:

dict[str, XRayResult]

Raises:
  • ValidationError – If inputs don’t match

  • RuntimeError – If no formulas were processed successfully

See also

calculate_single_material_properties : Single material calculations XRayResult : Documentation of returned data structure

class xraylabtool.calculators.core.FastXRayCalculationEngine[source]

Bases: object

High-performance X-ray calculation engine implementing CalculationEngine protocol.

__init__()[source]

Initialize the calculation engine.

Return type:

None

calculate_optical_constants(formula, energies, density)[source]

Calculate dispersion and absorption coefficients.

Return type:

tuple[Any, Any]

Parameters:
calculate_derived_quantities(dispersion, absorption, energies)[source]

Calculate derived quantities from optical constants.

Return type:

dict[str, ndarray]

Parameters:
warm_up_cache(common_elements=None)[source]

Pre-warm caches for improved performance.

Return type:

None

Parameters:

common_elements (list[str] | None)

get_performance_info()[source]

Get performance information about the calculation engine.

Return type:

dict[str, Any]

xraylabtool.calculators.core.get_calculation_engine()[source]

Get the global calculation engine instance.

Return type:

FastXRayCalculationEngine

Derived Quantities

Derived quantities calculator for X-ray optical properties.

This module contains functions for calculating derived X-ray properties such as critical angles, attenuation lengths, and other useful quantities.

xraylabtool.calculators.derived_quantities.calculate_critical_angle(dispersion_delta)[source]

Calculate critical angle for total external reflection.

Parameters:

dispersion_delta (ndarray) – Dispersion coefficient δ

Return type:

ndarray

Returns:

Critical angle in degrees

xraylabtool.calculators.derived_quantities.calculate_attenuation_length(wavelength_angstrom, absorption_beta)[source]

Calculate X-ray attenuation length (1/e length).

Parameters:
  • wavelength_angstrom (ndarray) – X-ray wavelength in Angstroms

  • absorption_beta (ndarray) – Absorption coefficient β

Return type:

ndarray

Returns:

Attenuation length in centimeters

xraylabtool.calculators.derived_quantities.calculate_transmission(thickness_cm, attenuation_length_cm)[source]

Calculate transmission through a material thickness.

Parameters:
  • thickness_cm (float) – Material thickness in centimeters

  • attenuation_length_cm (ndarray) – Attenuation length in centimeters

Return type:

ndarray

Returns:

Transmission coefficient (0-1)

xraylabtool.calculators.derived_quantities.calculate_scattering_length_density(dispersion_delta, absorption_beta, wavelength_angstrom)[source]

Calculate real and imaginary scattering length densities.

Parameters:
  • dispersion_delta (ndarray) – Dispersion coefficient δ

  • absorption_beta (ndarray) – Absorption coefficient β

  • wavelength_angstrom (ndarray) – X-ray wavelength in Angstroms

Return type:

tuple[ndarray, ndarray]

Returns:

Tuple of (real_sld, imaginary_sld) in units of Å⁻²

XRay Result

XRayResult dataclass for X-ray optical property calculations.

class xraylabtool.calculators.xray_result.XRayResult(formula, molecular_weight_g_mol, total_electrons, density_g_cm3, electron_density_per_ang3, energy_kev, wavelength_angstrom, dispersion_delta, absorption_beta, scattering_factor_f1, scattering_factor_f2, critical_angle_degrees, attenuation_length_cm, real_sld_per_ang2, imaginary_sld_per_ang2)[source]

Bases: object

Dataclass containing complete X-ray optical property calculations for a material.

This comprehensive data structure holds all computed X-ray properties including fundamental scattering factors, optical constants, and derived quantities like critical angles and attenuation lengths. All fields use descriptive snake_case names with clear units for maximum clarity.

The dataclass is optimized for scientific workflows, supporting both single-energy calculations and energy-dependent analysis. All array fields are automatically converted to numpy arrays for efficient numerical operations.

Legacy Compatibility: Deprecated CamelCase property aliases are available for backward compatibility but emit DeprecationWarning when accessed. Use the new snake_case field names for all new code.

Parameters:
Material Properties
formula

Chemical formula string exactly as provided

Type:

str

molecular_weight_g_mol

Molecular weight in g/mol

Type:

float

total_electrons

Total electrons per molecule (sum over all atoms)

Type:

float

density_g_cm3

Mass density in g/cm³

Type:

float

electron_density_per_ang3

Electron density in electrons/ų

Type:

float

X-ray Energy and Wavelength
energy_kev

X-ray photon energies in keV

Type:

np.ndarray

wavelength_angstrom

Corresponding X-ray wavelengths in Å

Type:

np.ndarray

Fundamental X-ray Properties
dispersion_delta

Dispersion coefficient δ (real part of refractive index decrement: n = 1 - δ - iβ)

Type:

np.ndarray

absorption_beta

Absorption coefficient β (imaginary part of refractive index decrement)

Type:

np.ndarray

scattering_factor_f1

Real part of atomic scattering factor

Type:

np.ndarray

scattering_factor_f2

Imaginary part of atomic scattering factor

Type:

np.ndarray

Derived Optical Properties
critical_angle_degrees

Critical angles for total external reflection in degrees (θc = √(2δ))

Type:

np.ndarray

attenuation_length_cm

1/e penetration depths in cm

Type:

np.ndarray

real_sld_per_ang2

Real part of scattering length density in Å⁻²

Type:

np.ndarray

imaginary_sld_per_ang2

Imaginary part of scattering length density in Å⁻²

Type:

np.ndarray

Physical Relationships:

  • Refractive Index: n = 1 - δ - iβ where δ and β are wavelength-dependent

  • Critical Angle: θc = √(2δ) for grazing incidence geometry

  • Attenuation Length: μ^-1 = (4πβ/λ)^-1 for exponential decay

  • Dispersion/Absorption: Related to f1, f2 via classical electron radius

Examples

Basic Property Access:

>>> import xraylabtool as xlt
>>> result = xlt.calculate_single_material_properties("SiO2", 10.0, 2.2)
>>> print(f"Material: {result.formula}")
Material: SiO2
>>> print(f"MW: {result.molecular_weight_g_mol:.2f} g/mol")
MW: 60.08 g/mol
>>> print(result.critical_angle_degrees[0] > 0.1)  # Reasonable critical angle
True

Array Properties for Energy Scans:

>>> import numpy as np
>>> energies = np.linspace(8, 12, 5)
>>> result = xlt.calculate_single_material_properties("Si", energies, 2.33)
>>> print(f"Energies: {result.energy_kev}")
Energies: [ 8.  9. 10. 11. 12.]
>>> print(len(result.wavelength_angstrom))
5

Optical Constants Analysis:

>>> print(result.dispersion_delta.min() > 0)  # δ should be positive
True
>>> print(result.absorption_beta.min() >= 0)  # β should be non-negative
True

Derived Quantities:

>>> print(len(result.critical_angle_degrees))
5
>>> print(len(result.attenuation_length_cm))
5

Note

All numpy arrays have the same length as the input energy array. For scalar energy inputs, arrays will have length 1. Use standard numpy operations for analysis (e.g., np.min(), np.max(), np.argmin(), indexing).

See also

calculate_single_material_properties : Primary function returning this class calculate_xray_properties : Function returning Dict[str, XRayResult]

formula: str
molecular_weight_g_mol: float
total_electrons: float
density_g_cm3: float
electron_density_per_ang3: float
energy_kev: ndarray[tuple[Any, ...], dtype[float64]]
wavelength_angstrom: ndarray[tuple[Any, ...], dtype[float64]]
dispersion_delta: ndarray[tuple[Any, ...], dtype[float64]]
absorption_beta: ndarray[tuple[Any, ...], dtype[float64]]
scattering_factor_f1: ndarray[tuple[Any, ...], dtype[float64]]
scattering_factor_f2: ndarray[tuple[Any, ...], dtype[float64]]
critical_angle_degrees: ndarray[tuple[Any, ...], dtype[float64]]
attenuation_length_cm: ndarray[tuple[Any, ...], dtype[float64]]
real_sld_per_ang2: ndarray[tuple[Any, ...], dtype[float64]]
imaginary_sld_per_ang2: ndarray[tuple[Any, ...], dtype[float64]]
__post_init__()[source]

Post-initialization to handle any setup after object creation.

Return type:

None

property energy_ev
property delta
property beta
property critical_angle_mrad
property linear_absorption_coefficient
property Formula: str

Use ‘formula’ instead.

Type:

Deprecated

property MW: float

Use ‘molecular_weight_g_mol’ instead.

Type:

Deprecated

property Number_Of_Electrons: float

Use ‘total_electrons’ instead.

Type:

Deprecated

property Density: float

Use ‘density_g_cm3’ instead.

Type:

Deprecated

property Electron_Density: float

Use ‘electron_density_per_ang3’ instead.

Type:

Deprecated

property Energy: ndarray

Use ‘energy_kev’ instead.

Type:

Deprecated

property Wavelength: ndarray

Use ‘wavelength_angstrom’ instead.

Type:

Deprecated

property Dispersion: ndarray

Use ‘dispersion_delta’ instead.

Type:

Deprecated

property Absorption: ndarray

Use ‘absorption_beta’ instead.

Type:

Deprecated

property f1: ndarray

Use ‘scattering_factor_f1’ instead.

Type:

Deprecated

property f2: ndarray

Use ‘scattering_factor_f2’ instead.

Type:

Deprecated

property Critical_Angle: ndarray

Use ‘critical_angle_degrees’ instead.

Type:

Deprecated

property Attenuation_Length: ndarray

Use ‘attenuation_length_cm’ instead.

Type:

Deprecated

property reSLD: ndarray

Use ‘real_sld_per_ang2’ instead.

Type:

Deprecated

property imSLD: ndarray

Use ‘imaginary_sld_per_ang2’ instead.

Type:

Deprecated

classmethod from_legacy(formula=None, mw=None, number_of_electrons=None, density=None, electron_density=None, energy=None, wavelength=None, dispersion=None, absorption=None, f1=None, f2=None, critical_angle=None, attenuation_length=None, re_sld=None, im_sld=None, **kwargs)[source]

Create XRayResult from legacy field names (for internal use).

Return type:

XRayResult

Parameters:
__init__(formula, molecular_weight_g_mol, total_electrons, density_g_cm3, electron_density_per_ang3, energy_kev, wavelength_angstrom, dispersion_delta, absorption_beta, scattering_factor_f1, scattering_factor_f2, critical_angle_degrees, attenuation_length_cm, real_sld_per_ang2, imaginary_sld_per_ang2)
Parameters:
Return type:

None

Calculation Cache

Cache infrastructure for scattering factor data and interpolators.

xraylabtool.calculators.cache.get_cached_elements()[source]

Get list of elements currently cached in the scattering factor cache.

Return type:

list[str]

Returns:

List of element symbols currently loaded in cache

xraylabtool.calculators.cache.get_bulk_atomic_data(elements_tuple)[source]

Bulk load atomic data for multiple elements with high-performance caching.

This optimization uses a preloaded cache of common elements to eliminate expensive database queries to the Mendeleev library during runtime.

Parameters:

elements_tuple (tuple[str, ...]) – Tuple of element symbols to load data for

Return type:

dict[str, MappingProxyType[str, float]]

Returns:

Dictionary mapping element symbols to their atomic data

xraylabtool.calculators.cache.clear_scattering_factor_cache()[source]

Clear the module-level scattering factor cache.

This function removes all cached scattering factor data from memory. Useful for testing or memory management.

Return type:

None

xraylabtool.calculators.cache.is_element_cached(element)[source]

Check if scattering factor data for an element is already cached.

Parameters:

element (str) – Element symbol to check

Return type:

bool

Returns:

True if element data is cached, False otherwise

xraylabtool.calculators.cache.create_scattering_factor_interpolators(element)[source]

Create PCHIP interpolators for f1 and f2 scattering factors.

This helper function loads scattering factor data for a specific element and returns two callable PCHIP interpolator objects for f1 and f2 that behave identically to Julia interpolation behavior.

Parameters:

element (str) – Element symbol (e.g., ‘H’, ‘C’, ‘N’, ‘O’, ‘Si’, ‘Ge’)

Return type:

tuple[InterpolatorProtocol, InterpolatorProtocol]

Returns:

Tuple of (f1_interpolator, f2_interpolator) where each is a callable that takes energy values and returns interpolated scattering factors

Raises:
  • FileNotFoundError – If the .nff file for the element is not found

  • ValueError – If the element symbol is invalid or data is insufficient

Examples

>>> from xraylabtool.calculators.cache import create_scattering_factor_interpolators
>>> import numpy as np
>>> f1_interp, f2_interp = create_scattering_factor_interpolators('Si')
>>> energy = 100.0  # eV
>>> f1_value = f1_interp(energy)
>>> isinstance(f1_value, (int, float, np.number, np.ndarray))
True
>>> f2_value = f2_interp(energy)
>>> isinstance(f2_value, (int, float, np.number, np.ndarray))
True
>>> # Can also handle arrays
>>> energies = np.array([100.0, 200.0, 300.0])
>>> f1_values = f1_interp(energies)
>>> len(f1_values) == 3
True

Scattering Data

Scattering factor data loading and element path management.

xraylabtool.calculators.scattering_data.load_scattering_factor_data(element)[source]

Load f1/f2 scattering factor data for a specific element from .nff files.

This function reads .nff files using CSV parsing and caches the results in a module-level dictionary keyed by element symbol. Returns a pandas-compatible data structure for accessing columns E, f1, f2.

Parameters:

element (str) – Element symbol (e.g., ‘H’, ‘C’, ‘N’, ‘O’, ‘Si’, ‘Ge’)

Returns:

E (energy), f1, f2

Return type:

Any

Raises:
  • FileNotFoundError – If the .nff file for the element is not found

  • ValueError – If the element symbol is invalid, empty, or file format is invalid

Examples

>>> from xraylabtool.calculators.scattering_data import load_scattering_factor_data
>>> data = load_scattering_factor_data('Si')
>>> print(data.columns)
['E', 'f1', 'f2']
>>> print(len(data) > 100)  # Verify we have enough data points
True
class xraylabtool.calculators.scattering_data.ScatteringData(data_array, column_names)[source]

Bases: object

Pandas-like interface for scattering factor data arrays.

Parameters:
  • data_array (np.ndarray)

  • column_names (list[str])

__init__(data_array, column_names)[source]
Parameters:
Return type:

None

class xraylabtool.calculators.scattering_data.AtomicScatteringFactor[source]

Bases: object

Class for handling atomic scattering factors.

This class loads and manages atomic scattering factor data from NFF files using the module-level cache.

__init__()[source]
Return type:

None

load_element_data(element)[source]

Load scattering factor data for a specific element.

Parameters:

element (str) – Element symbol (e.g., ‘H’, ‘C’, ‘N’, ‘O’, ‘Si’, ‘Ge’)

Returns:

E, f1, f2

Return type:

Any

Raises:
get_scattering_factor(_element, q_values)[source]

Calculate scattering factors for given q values.

Parameters:
  • element – Element symbol

  • q_values (ndarray) – Array of momentum transfer values

  • _element (str)

Return type:

ndarray

Returns:

Array of scattering factor values

class xraylabtool.calculators.scattering_data.CrystalStructure(lattice_parameters)[source]

Bases: object

Class for representing and manipulating crystal structures.

Parameters:

lattice_parameters (tuple[float, float, float, float, float, float])

__init__(lattice_parameters)[source]

Initialize crystal structure.

Parameters:

lattice_parameters (tuple[float, float, float, float, float, float]) – (a, b, c, alpha, beta, gamma) in Angstroms and degrees

add_atom(element, position, occupancy=1.0)[source]

Add an atom to the crystal structure.

Parameters:
  • element (str) – Element symbol

  • position (tuple[float, float, float]) – Fractional coordinates (x, y, z)

  • occupancy (float) – Site occupancy factor

Return type:

None

calculate_structure_factor(hkl)[source]

Calculate structure factor for given Miller indices.

F(hkl) = sum_j f_j * occ_j * exp(2*pi*i*(h*x_j + k*y_j + l*z_j))

where the sum runs over all atoms in the unit cell. The atomic form factor f_j is currently taken as 1.0 for all atoms (geometric structure factor).

Parameters:

hkl (tuple[int, int, int]) – Miller indices (h, k, l)

Return type:

complex

Returns:

Complex structure factor

xraylabtool.calculators.scattering_data.load_data_file(filename)[source]

Load data from various file formats commonly used in X-ray analysis.

Parameters:

filename (str) – Path to the data file

Return type:

Any

Returns:

DataFrame containing the loaded data

Kernels

JIT-compiled math kernels and scattering factor calculation functions.

xraylabtool.calculators.kernels.calculate_scattering_factors(energy_ev, wavelength, mass_density, molecular_weight, element_data)[source]

Optimized vectorized calculation of X-ray scattering factors and properties.

This function performs the core calculation of dispersion, absorption, and total scattering factors for a material based on its elemental composition. Interpolation runs in Python; the linear algebra is JIT-compiled when JAX is active.

Parameters:
Return type:

tuple[ndarray[tuple[Any, ...], dtype[double]], ndarray[tuple[Any, ...], dtype[double]], ndarray[tuple[Any, ...], dtype[double]], ndarray[tuple[Any, ...], dtype[double]]]

Returns:

Tuple of (dispersion, absorption, f1_total, f2_total) arrays

Mathematical Background: The dispersion and absorption coefficients are calculated using: - δ = (λ²/2π) × rₑ × ρ × Nₐ × (Σᵢ nᵢ × f1ᵢ) / M # noqa: RUF002 - β = (λ²/2π) × rₑ × ρ × Nₐ × (Σᵢ nᵢ × f2ᵢ) / M # noqa: RUF002

Where: - λ: X-ray wavelength - rₑ: Thomson scattering length - ρ: Mass density - Nₐ: Avogadro’s number - nᵢ: Number of atoms of element i - f1ᵢ, f2ᵢ: Atomic scattering factors for element i - M: Molecular weight

xraylabtool.calculators.kernels.calculate_derived_quantities(wavelength, dispersion, absorption, mass_density, molecular_weight, number_of_electrons)[source]

Calculate derived X-ray optical quantities from dispersion and absorption.

Parameters:
Return type:

tuple[float, ndarray[tuple[Any, ...], dtype[double]], ndarray[tuple[Any, ...], dtype[double]], ndarray[tuple[Any, ...], dtype[double]], ndarray[tuple[Any, ...], dtype[double]]]

Returns:

Tuple of (electron_density, critical_angle, attenuation_length, re_sld, im_sld) - electron_density: Electron density in electrons/ų (scalar) - critical_angle: Critical angle in degrees (numpy array) - attenuation_length: Attenuation length in cm (numpy array) - re_sld: Real part of SLD in Å⁻² (numpy array) - im_sld: Imaginary part of SLD in Å⁻² (numpy array)

Physics Background

The calculations are based on the complex refractive index for X-rays:

\[\begin{split}n = 1 - \\delta - i\\beta\end{split}\]

Where:

  • δ (delta): Real part of the refractive index decrement, related to phase shifts

  • β (beta): Imaginary part, related to absorption

The critical angle for total external reflection is:

\[\begin{split}\\theta_c = \\sqrt{2\\delta}\end{split}\]

The linear absorption coefficient is:

\[\begin{split}\\mu = \\frac{4\\pi \\beta}{\\lambda}\end{split}\]

Usage Examples

Single Energy Calculation:

from xraylabtool.calculators.core import calculate_single_material_properties

result = calculate_single_material_properties(
    formula="Si",
    density=2.33,
    energy=8000
)

print(f"Critical angle: {result.critical_angle_degrees:.3f}°")
print(f"Attenuation length: {result.attenuation_length_cm:.2f} cm")

Energy Array Calculation:

import numpy as np
from xraylabtool.calculators.core import calculate_single_material_properties

energies = np.logspace(3, 5, 100)  # 1 keV to 100 keV

results = []
for energy in energies:
    result = calculate_single_material_properties(
        formula="Si", density=2.33, energy=energy
    )
    results.append(result)

Multiple Materials:

from xraylabtool.calculators.core import calculate_xray_properties

materials = [
    {"formula": "Si", "density": 2.33},
    {"formula": "SiO2", "density": 2.20},
    {"formula": "Al", "density": 2.70}
]

results = calculate_xray_properties(materials, energy=8000)