optmat.gas.absorption#

The complex polarizability of a measured absorption spectrum (Kramers-Kronig).

A molecule that absorbs within the range of interest (ozone’s Hartley, Huggins and Chappuis bands) contributes to its polarizability a term fixed by the measured photoabsorption cross section \(\sigma(\omega)\). For one molecule,

\[\mathrm{Im}\,\alpha(\omega) = \frac{\varepsilon_0 c\,\sigma(\omega)}{\omega}, \qquad \mathrm{Re}\,\alpha(\omega) = \frac{2\varepsilon_0 c}{\pi}\, \mathcal{P}\!\int_0^\infty \frac{\sigma(\Omega)}{\Omega^2-\omega^2}\,\mathrm{d}\Omega = \frac{\varepsilon_0}{\pi^2}\, \mathcal{P}\!\int_0^\infty \frac{\sigma(\tilde\nu')}{\tilde\nu'^2-\tilde\nu^2}\, \mathrm{d}\tilde\nu',\]

in SI, with \(\tilde\nu\) the wavenumber (the dilute-gas relation \(n - 1 = N\alpha/2\varepsilon_0\) gives the familiar form \((n-1)/N = (c/\pi)\,\mathcal{P}\!\int \sigma/(\Omega^2-\omega^2)\,\mathrm{d}\Omega\)).

The spectrum is assembled from pieces (data/gas/absorption/<gas>.toml), each a measured data set over a wavelength window, on a uniform wavenumber grid, and smoothed with a Gaussian of a stated width in wavenumber. Smoothing in frequency before the transform is exactly causal: it is the same as smoothing the complex polarizability with that kernel, or damping the molecular response in time beyond about 0.88 / (c FWHM). The principal value is a discrete convolution on the grid (\(1/(\tilde\nu'^2-\tilde\nu^2) = [1/(\tilde\nu'-\tilde\nu) - 1/(\tilde\nu'+\tilde\nu)]/2\tilde\nu\), each part by FFT), accurate to about 1e-5 of the term at the default grid and width.

The same spectrum gives its dipole sums \(S(k) = \int (\mathrm{d}f/\mathrm{d}E) E^k\,\mathrm{d}E\) (the oscillator-strength density is \(\sigma / (\pi e^2\hbar/2\varepsilon_0 m_e c)\)), so that the absorption term can be checked against, and joined to, a dipole oscillator-strength distribution above the measured range.

Module Attributes

ABSORPTION_DIRECTORY

Configurations of measured absorption spectra, <gas>.toml.

Functions

assemble(gas, pieces, *, temperature_k[, ...])

Assemble, smooth and transform a spectrum.

measured_absorption(gas, *[, fwhm_cm, variant])

Return a gas's measured absorption spectrum (data/gas/absorption/<gas>.toml).

Classes

MeasuredAbsorption(gas, temperature_k, ...)

A measured absorption spectrum and its complex polarizability.

Piece(source, from_nm, to_nm[, note])

One measured data set over a wavelength window.

optmat.gas.absorption.ABSORPTION_DIRECTORY: Final = PosixPath('/home/docs/checkouts/optmat/checkouts/7/src/optmat/data/gas/absorption')#

Configurations of measured absorption spectra, <gas>.toml.

class optmat.gas.absorption.MeasuredAbsorption(gas, temperature_k, pieces, fwhm_cm, step_cm, wavenumber_cm, sigma_m2, real_au, *, status='user', status_reason='', modified=(), base='')[source]#

Bases: Identified

A measured absorption spectrum and its complex polarizability.

It is compared by identity, not by value (eq=False), since its spline is cached per object.

Attributes:
gasGas

The species.

temperature_kfloat

The temperature of the measurements, K.

piecestuple of Piece

The data sets and their windows, from long to short wavelength or in any order; the windows must not overlap.

fwhm_cmfloat

The Gaussian smoothing, full width at half maximum in wavenumber, cm^-1 (0 for none beyond the grid).

step_cmfloat

The wavenumber grid step, cm^-1.

wavenumber_cmnumpy.ndarray

The grid, cm^-1, from 0 to the largest wavenumber of the pieces.

sigma_m2numpy.ndarray

The smoothed cross section on the grid, m^2.

real_aunumpy.ndarray

Re alpha on the grid, atomic units.

EVALUATION_VERSION: ClassVar[int] = 1#
IDENTITY_KIND: ClassVar[str] = 'gas_absorption'#
complex_derivative_au(omega)[source]#

Return the frequency derivative of the measured term, branch by branch.

The derivative is that of the evaluator complex_polarizability_au() uses (OEP 1, section 4.1):

  • inside the grid, the real part is a cubic spline, and its derivative is the spline’s own;

  • above the grid, the real part is a trapezoid sum over the grid, and its derivative is the same sum of the differentiated integrand;

  • the imaginary part is eps0 c sigma(nu) / omega with sigma linearly interpolated, so its derivative takes the slope of the segment: the mean of the two slopes at a knot, the segment below at the grid’s upper end, zero above it.

Both are 0 at omega = 0, by definition: the real part is even in omega and the imaginary part vanishes there.

Parameters:
omeganumpy.ndarray

Photon energies, hartree.

Returns:
tuple of numpy.ndarray

d Re alpha / d omega and d Im alpha / d omega, atomic units per hartree.

complex_polarizability_au(omega)[source]#

Return the real and imaginary polarizability of the measured term.

Parameters:
omeganumpy.ndarray

Photon energies, hartree; above the measured range the real part is the regular integral and the imaginary part zero.

Returns:
tuple of numpy.ndarray

Re alpha and Im alpha, atomic units.

fwhm_cm: float#
gas: Gas#
property max_wavenumber_cm: float#

The top of the measured range, cm^-1.

Returns:
float

The largest grid wavenumber.

pieces: tuple[Piece, ...]#
real_au: Float[ndarray, 'n']#
real_derivative_au(omega, order)[source]#

Return a derivative of Re alpha with respect to the photon energy.

Parameters:
omeganumpy.ndarray

Photon energies, hartree, within the grid.

orderint

The order, 0 to 4 (finite differences of the smoothed grid values, then linear interpolation).

Returns:
numpy.ndarray

d^order Re alpha / d omega^order, atomic units per hartree^order.

sigma_m2: Float[ndarray, 'n']#
step_cm: float#
strength(low_ev, high_ev)[source]#

Return the oscillator strength between two photon energies.

Parameters:
low_ev, high_evfloat

The interval, eV.

Returns:
float

int df/dE dE over the interval.

sum_rule(k)[source]#

Return the dipole sum S(k) of the measured spectrum.

Parameters:
kfloat

The order.

Returns:
float

int (df/dE) E^k dE over the grid, atomic units.

temperature_k: float#
wavenumber_cm: Float[ndarray, 'n']#
class optmat.gas.absorption.Piece(source, from_nm, to_nm, note='')[source]#

Bases: object

One measured data set over a wavelength window.

Attributes:
sourcestr

A file under data/external (two columns: vacuum wavelength in nm, cross section in cm^2) or a curated dataset source/dataset whose values are absorption_cross_section.

from_nmfloat

The window’s short-wavelength end, nm.

to_nmfloat

Its long-wavelength end, nm.

notestr

Why this data set covers this window.

from_nm: float#
note: str = ''#
source: str#
to_nm: float#
optmat.gas.absorption.assemble(gas, pieces, *, temperature_k, fwhm_cm=50.0, step_cm=0.5)[source]#

Assemble, smooth and transform a spectrum.

Parameters:
gasGas or str

The species.

piecestuple of Piece

The data sets and their windows.

temperature_kfloat

The temperature of the measurements, K.

fwhm_cmfloat, optional

Gaussian smoothing FWHM in wavenumber, cm^-1; 50 by default.

step_cmfloat, optional

The grid step, cm^-1; 0.5 by default.

Returns:
MeasuredAbsorption

The spectrum with its real polarizability on the grid.

Raises:
DataError

If two windows overlap.

optmat.gas.absorption.measured_absorption(gas, *, fwhm_cm=None, variant=None)[source]#

Return a gas’s measured absorption spectrum (data/gas/absorption/<gas>.toml).

Parameters:
gasGas or str

The species.

fwhm_cmfloat, optional

The smoothing FWHM, cm^-1; the configuration’s by default.

variantstr, optional

A [variants.<name>] table of the configuration whose pieces replace those of the same window (for instance another temperature).

Returns:
MeasuredAbsorption

The spectrum.

Raises:
DataError

If the gas has no configuration or the variant is unknown.