Extensible periodic table of the elements with support for mass, density and X-ray/neutron scattering information
—
X-ray scattering factor calculations, scattering length densities, form factors, and optical properties including refractive indices and mirror reflectivity for crystallographic and materials science applications.
Calculate X-ray scattering length densities for materials, fundamental for X-ray reflectometry, small-angle X-ray scattering, and grazing incidence techniques.
def xray_sld(compound, density: float = None, energy: float = None,
wavelength: float = None) -> tuple:
"""
Calculate X-ray scattering length density for a compound.
Args:
compound: Formula string, Formula object, or atomic composition
density: Mass density in g/cm³ (uses compound.density if available)
energy: X-ray energy in keV
wavelength: X-ray wavelength in Ångström (alternative to energy)
Returns:
tuple: (sld_real, sld_imag) in units of 10⁻⁶ Ų⁻²
sld_real: Real scattering length density (dispersion)
sld_imag: Imaginary scattering length density (absorption)
"""
def xray_sld_from_atoms(atoms: dict, density: float, energy: float = None,
wavelength: float = None) -> tuple:
"""
Low-level SLD calculation from atomic composition.
Args:
atoms: Dictionary mapping atoms to counts
density: Mass density in g/cm³
energy: X-ray energy in keV
wavelength: X-ray wavelength in Ångström
Returns:
tuple: (sld_real, sld_imag) in 10⁻⁶ Ų⁻² units
"""Usage examples:
import periodictable as pt
# Simple compounds at Cu K-alpha (8.048 keV)
water = pt.formula("H2O", density=1.0)
sld_real, sld_imag = pt.xray_sld(water, energy=8.048)
print(f"H2O SLD at Cu K-alpha: {sld_real:.4f} + {sld_imag:.4f}i (10⁻⁶ Ų⁻²)")
# Different X-ray energies
energies = [8.048, 17.479, 21.0] # Cu K-alpha, Mo K-alpha, arbitrary
names = ["Cu K-alpha", "Mo K-alpha", "21 keV"]
for energy, name in zip(energies, names):
sld = pt.xray_sld(water, energy=energy)
print(f"H2O at {name}: {sld[0]:.4f} + {sld[1]:.4f}i")
# Using wavelength instead of energy
lambda_cu = 1.5418 # Å, Cu K-alpha
sld_wl = pt.xray_sld(water, wavelength=lambda_cu)
print(f"H2O at {lambda_cu} Å: {sld_wl[0]:.4f} + {sld_wl[1]:.4f}i")
# Complex materials
silicon = pt.formula("Si", density=2.33)
sio2 = pt.formula("SiO2", density=2.20)
si_sld = pt.xray_sld(silicon, energy=8.048)
sio2_sld = pt.xray_sld(sio2, energy=8.048)
print(f"Si SLD: {si_sld[0]:.4f} + {si_sld[1]:.4f}i")
print(f"SiO2 SLD: {sio2_sld[0]:.4f} + {sio2_sld[1]:.4f}i")
print(f"Contrast: {si_sld[0] - sio2_sld[0]:.4f}")Convert between X-ray wavelength and energy for different X-ray sources and experimental conditions.
def xray_wavelength(energy: float) -> float:
"""
Convert X-ray energy to wavelength.
Args:
energy: X-ray energy in keV
Returns:
Wavelength in Ångström
"""
def xray_energy(wavelength: float) -> float:
"""
Convert X-ray wavelength to energy.
Args:
wavelength: X-ray wavelength in Ångström
Returns:
Energy in keV
"""Usage examples:
import periodictable.xsf as xsf
# Common X-ray sources
sources = [
("Cu K-alpha", 8.048),
("Mo K-alpha", 17.479),
("Ag K-alpha", 22.163),
("Cr K-alpha", 5.417)
]
print("X-ray source wavelengths:")
for name, energy in sources:
wavelength = xsf.xray_wavelength(energy)
print(f"{name}: {energy} keV = {wavelength:.4f} Å")
# Synchrotron energies
synchrotron_energies = [6, 8, 10, 12, 15, 20] # keV
print("\nSynchrotron wavelengths:")
for energy in synchrotron_energies:
wavelength = xsf.xray_wavelength(energy)
print(f"{energy:2d} keV = {wavelength:.4f} Å")
# Convert wavelengths back to energies
wavelengths = [1.5418, 0.7107, 0.5594] # Cu, Mo, Ag K-alpha
print("\nWavelength to energy:")
for wl in wavelengths:
energy = xsf.xray_energy(wl)
print(f"{wl:.4f} Å = {energy:.3f} keV")Calculate refractive indices and optical properties from scattering length densities for X-ray optics applications.
def index_of_refraction(compound, density: float = None,
energy: float = None, wavelength: float = None) -> complex:
"""
Calculate complex refractive index from SLD.
Args:
compound: Formula string, Formula object, or atomic composition
density: Mass density in g/cm³
energy: X-ray energy in keV
wavelength: X-ray wavelength in Ångström
Returns:
complex: n = 1 - δ - iβ where δ,β are dispersion and absorption
"""
def mirror_reflectivity(compound, density: float = None,
energy: float = None, wavelength: float = None,
angle: float = None, q: float = None) -> float:
"""
Calculate X-ray reflectivity from a single-compound mirror.
Args:
compound: Mirror material
density: Material density in g/cm³
energy: X-ray energy in keV
wavelength: X-ray wavelength in Ångström
angle: Grazing angle in degrees
q: Momentum transfer in Ų⁻¹ (alternative to angle)
Returns:
Reflectivity (0-1)
"""Usage examples:
import periodictable as pt
from periodictable.xsf import index_of_refraction, mirror_reflectivity
import numpy as np
# Refractive index calculations
materials = ["Si", "SiO2", "Au", "Pt", "C"]
energy = 8.048 # keV, Cu K-alpha
print("Refractive indices at Cu K-alpha:")
for material in materials:
compound = pt.formula(material, density=pt.elements.symbol(material[0]).density)
n = index_of_refraction(compound, energy=energy)
delta = 1 - n.real
beta = -n.imag
print(f"{material:4s}: n = 1 - {delta:.6f} - i{beta:.6f}")
# Critical angle calculation (total external reflection)
silicon = pt.formula("Si", density=2.33)
n_si = index_of_refraction(silicon, energy=8.048)
critical_angle = np.sqrt(2 * (1 - n_si.real)) * 1000 # mrad
print(f"Si critical angle: {critical_angle:.2f} mrad")
# Mirror reflectivity vs angle
angles = np.logspace(-1, 1, 50) # 0.1 to 10 degrees
gold_mirror = pt.formula("Au", density=19.32)
reflectivities = []
for angle in angles:
R = mirror_reflectivity(gold_mirror, energy=8.048, angle=angle)
reflectivities.append(R)
# Find critical angle from reflectivity curve
critical_idx = np.where(np.array(reflectivities) < 0.5)[0]
if len(critical_idx) > 0:
print(f"Au mirror critical angle: ~{angles[critical_idx[0]]:.2f}°")Generate formatted tables and plots of X-ray scattering data for analysis and reference.
def sld_table(wavelength: float = None, energy: float = None,
table: PeriodicTable = None) -> None:
"""
Print X-ray SLD table for all elements.
Args:
wavelength: X-ray wavelength in Ångström
energy: X-ray energy in keV (alternative to wavelength)
table: Periodic table to use
"""
def emission_table(table: PeriodicTable = None) -> None:
"""Print X-ray emission line table for elements with data."""
def plot_xsf(element, energy_range: tuple = None, **kwargs) -> None:
"""
Plot X-ray scattering factors vs energy.
Args:
element: Element to plot
energy_range: (min_energy, max_energy) in keV
**kwargs: Additional plotting parameters
"""Usage examples:
import periodictable.xsf as xsf
import periodictable as pt
# Print SLD table at Cu K-alpha
xsf.sld_table(energy=8.048)
# Print emission line table
xsf.emission_table()
# Plot scattering factors (requires matplotlib)
try:
xsf.plot_xsf(pt.Si, energy_range=(5, 20))
xsf.plot_xsf(pt.Au, energy_range=(5, 50))
except ImportError:
print("Matplotlib required for plotting")Access detailed X-ray scattering properties for individual elements through the Xray class attached to atomic objects.
class Xray:
"""X-ray scattering properties for elements."""
def scattering_factors(self, energy: float = None,
wavelength: float = None) -> tuple:
"""
Get f1, f2 scattering factors at given energy/wavelength.
Args:
energy: X-ray energy in keV
wavelength: X-ray wavelength in Ångström
Returns:
tuple: (f1, f2) scattering factors
"""
def f0(self, q: float) -> float:
"""
Atomic form factor f0 at momentum transfer q.
Args:
q: Momentum transfer in Ų⁻¹
Returns:
Atomic form factor f0
"""
def sld(self, density: float = None, energy: float = None,
wavelength: float = None) -> tuple:
"""
Calculate SLD for this element.
Args:
density: Mass density in g/cm³
energy: X-ray energy in keV
wavelength: X-ray wavelength in Ångström
Returns:
tuple: (sld_real, sld_imag)
"""
@property
def sftable(self) -> list:
"""Three-column table of energy vs f1, f2 scattering factors."""Usage examples:
import periodictable as pt
import numpy as np
# Element X-ray properties
silicon = pt.Si
if hasattr(silicon, 'xray') and silicon.xray:
# Scattering factors at Cu K-alpha
f1, f2 = silicon.xray.scattering_factors(energy=8.048)
print(f"Si scattering factors at Cu K-alpha: f1={f1:.3f}, f2={f2:.3f}")
# Atomic form factor at different q values
q_values = [0, 1, 2, 4, 8] # Ų⁻¹
print("Si atomic form factors:")
for q in q_values:
f0 = silicon.xray.f0(q)
print(f" q={q} Ų⁻¹: f0={f0:.3f}")
# SLD calculation
sld = silicon.xray.sld(density=2.33, energy=8.048)
print(f"Si SLD: {sld[0]:.4f} + {sld[1]:.4f}i")
# Access raw scattering factor table
table = silicon.xray.sftable
print(f"Scattering factor table has {len(table)} energy points")
# Compare different elements
elements = [pt.C, pt.Si, pt.Fe, pt.Au]
energy = 8.048 # keV
print(f"\nScattering factors at {energy} keV:")
for el in elements:
if hasattr(el, 'xray') and el.xray:
f1, f2 = el.xray.scattering_factors(energy=energy)
print(f"{el.symbol:2s}: f1={f1:6.3f}, f2={f2:6.3f}")Access X-ray emission line wavelengths for elements commonly used as X-ray sources.
# Element properties (when available)
K_alpha: float # K-alpha emission line wavelength in Ångström
K_beta1: float # K-beta1 emission line wavelength in Ångström
K_alpha_units: str # Units for K-alpha (typically 'angstrom')
K_beta1_units: str # Units for K-beta1 (typically 'angstrom')Usage examples:
import periodictable as pt
# Common X-ray tube elements
tube_elements = [pt.Cr, pt.Fe, pt.Cu, pt.Mo, pt.Ag]
print("X-ray emission lines:")
for el in tube_elements:
if hasattr(el, 'K_alpha') and el.K_alpha:
energy_alpha = 12.398 / el.K_alpha # Convert Å to keV
print(f"{el.symbol} K-alpha: {el.K_alpha:.4f} Å ({energy_alpha:.3f} keV)")
if hasattr(el, 'K_beta1') and el.K_beta1:
energy_beta = 12.398 / el.K_beta1
print(f"{el.symbol} K-beta1: {el.K_beta1:.4f} Å ({energy_beta:.3f} keV)")
print()
# Copper detailed
copper = pt.Cu
if hasattr(copper, 'K_alpha'):
print(f"Cu K-alpha: {copper.K_alpha} {copper.K_alpha_units}")
print(f"Cu K-beta1: {copper.K_beta1} {copper.K_beta1_units}")class Xray:
"""X-ray scattering properties for elements."""
def scattering_factors(self, energy: float = None,
wavelength: float = None) -> tuple: ...
def f0(self, q: float) -> float: ...
def sld(self, density: float = None, energy: float = None,
wavelength: float = None) -> tuple: ...
@property
def sftable(self) -> list: ...Install with Tessl CLI
npx tessl i tessl/pypi-periodictable