# SPDX-FileCopyrightText: 2026 John C. Travers and contributors
#
# SPDX-License-Identifier: MIT
"""The vocabulary of the curated data: quantities, abscissae, parts, conventions.
Every dataset states one *quantity* from :data:`QUANTITIES`. The quantity fixes:
- the *family* of the data, which is also the directory of its files
(``data/values/<family>/<material>/``);
- the units its values may carry (after the dataset's scale);
- the *abscissae* its values may be tabulated against (:data:`ABSCISSAE`): a
wavelength, the order of a moment, a temperature, a pressure, a density, an
intensity, an electric field, a free label, or none;
- whether it needs the state (pressure, temperature) it refers to;
- the parameters it must state;
- the extra per-row columns its files must carry (the upper edge of an interval).
Third-order values also state their process (:data:`PROCESSES`), the contributions they
contain (:data:`PARTS`) and, for a hyperpolarizability or susceptibility, the convention
of its definition (:data:`CONVENTIONS`). The documentation page *The curated data*
lists everything here.
"""
from dataclasses import dataclass, field
from types import MappingProxyType
from typing import Final
__all__ = [
"ABSCISSAE",
"CONVENTIONS",
"FAMILIES",
"PARTS",
"POLARIZABILITY_CORRECTIONS",
"POLARIZABILITY_QUANTITIES",
"PROCESSES",
"QUANTITIES",
"Quantity",
]
FAMILIES: Final = (
"refractive",
"absorption",
"third_order",
"raman",
"ionisation",
"damage",
"composition",
"transport",
"thermodynamic",
)
"""The families of quantities, each a directory of ``data/values/``."""
_WAVELENGTH_UNITS: Final = frozenset(
{"m", "nm", "um", "angstrom", "cm-1", "um-1", "eV", "hartree", "rydberg"}
)
ABSCISSAE: Final = MappingProxyType(
{
"wavelength": _WAVELENGTH_UNITS,
"order": frozenset({"1"}),
"temperature": frozenset({"K", "C"}),
"pressure": frozenset({"Pa", "kPa", "MPa", "bar", "atm", "torr", "psia"}),
"density": frozenset({"m-3", "cm-3", "amagat", "mol/m3", "mol/cm3", "mol/L"}),
"intensity": frozenset({"W/m2", "W/cm2"}),
"field": frozenset({"V/m", "V/cm", "au"}),
"duration": frozenset({"s", "ns", "ps", "fs"}),
"label": frozenset({""}),
"none": frozenset({""}),
}
)
"""The kinds of abscissa, each with its units.
``wavelength`` is a wavelength, a vacuum (or air) wavenumber or a photon energy; the
cell ``inf`` is the static limit and ``not stated`` a wavelength the source does not
give. ``order`` is the order of a moment. ``duration`` is a pulse duration (a
laser-damage threshold against pulse length). ``field`` is the amplitude of a static
(or peak) electric field; ``au`` is the atomic unit of field, E_h / (e a_0). A
``label`` abscissa is not a number: its cells name the rows (a transition, a state).
``none`` has empty cells: the value stands alone (an ionisation energy), described by
its parameters.
"""
_POLARIZABILITY_UNITS: Final = frozenset({"au", "angstrom3", "cm3", "SI"})
[docs]
@dataclass(frozen=True)
class Quantity:
"""What a dataset's values are, and what a dataset of them must state.
Attributes
----------
meaning : str
The definition, with its parameters.
family : str
One of :data:`FAMILIES`.
units : frozenset of str or None
The units the values may carry after ``scale``; None for any unit (stated as
printed, the quantity's meaning says how to read it).
abscissae : frozenset of str
The abscissae the values may be tabulated against.
needs_state : bool
Whether the values refer to a state (they depend on density).
required : tuple of str
Parameters every dataset of the quantity must state.
columns : tuple of str
Extra per-row columns every data file of the quantity must carry.
"""
meaning: str
family: str
units: frozenset[str] | None = None
abscissae: frozenset[str] = field(default=frozenset({"wavelength"}))
needs_state: bool = False
required: tuple[str, ...] = ()
columns: tuple[str, ...] = ()
def __post_init__(self) -> None:
"""Check the family and the abscissae.
Raises
------
ValueError
If either is unknown.
"""
if self.family not in FAMILIES:
msg = f"unknown family {self.family!r}"
raise ValueError(msg)
if not self.abscissae <= set(ABSCISSAE):
msg = f"unknown abscissae {sorted(self.abscissae - set(ABSCISSAE))}"
raise ValueError(msg)
_ONE: Final = frozenset({"1"})
_LINES: Final = frozenset({"label", "none"})
_CONDITIONS: Final = frozenset({"label", "none", "temperature", "pressure", "density"})
_TIMES: Final = frozenset({"fs", "ps", "ns", "s"})
_SPECTRAL_OR_NONE: Final = frozenset({"wavelength", "label", "none"})
QUANTITIES: Final = MappingProxyType(
{
# The linear (real) response and the dispersion it produces.
"refractivity": Quantity(
"n - 1 at the dataset's state", "refractive", _ONE, needs_state=True
),
"polarizability": Quantity(
"per-particle dipole polarizability; parameters.temperature_k for a "
"temperature-dependent (rotationally averaged) value",
"refractive",
_POLARIZABILITY_UNITS,
),
"molar_refractivity": Quantity(
"A_R = N_A alpha / (3 eps0); parameters.temperature_k where stated",
"refractive",
frozenset({"cm3/mol"}),
),
"refractivity_per_density": Quantity(
"(n - 1) / N at the dataset's state",
"refractive",
frozenset({"cm3"}),
needs_state=True,
),
"refractivity_ratio": Quantity(
"(n - 1) of the gas over (n - 1) of parameters.reference_material at the "
"same density",
"refractive",
_ONE,
required=("reference_material",),
),
"refractivity_difference": Quantity(
"n(lambda) - n(parameters.reference_wavelength_nm) at the dataset's state",
"refractive",
_ONE,
needs_state=True,
required=("reference_wavelength_nm",),
),
"partial_refractivity": Quantity(
"one stated contribution to n - 1 at the dataset's state "
"(parameters.contribution: what it is and how it was obtained)",
"refractive",
_ONE,
needs_state=True,
required=("contribution",),
),
"polarizability_correction": Quantity(
"a correction to the electronic polarizability (parameters.part, one of "
"POLARIZABILITY_CORRECTIONS), never a total",
"refractive",
_POLARIZABILITY_UNITS,
required=("part",),
),
"magnetic_susceptibility": Quantity(
"the diamagnetic (or paramagnetic) susceptibility: per particle (au, the "
"magnetizability chi_0) or molar (cm3/mol, m3/mol: A_mu or chi_M)",
"refractive",
frozenset({"au", "cm3/mol", "m3/mol"}),
abscissae=frozenset({"wavelength", "none"}),
),
"cauchy_moment": Quantity(
"dipole-oscillator-strength sum S(k), the order k as the abscissa",
"refractive",
frozenset({"au"}),
abscissae=frozenset({"order"}),
),
"phase_match_density_ratio": Quantity(
"density ratio rho_gas / rho_reference at which two gases phase-match a "
"harmonic (parameters.reference_material, .harmonic)",
"refractive",
_ONE,
required=("reference_material", "harmonic"),
),
"phase_match_density": Quantity(
"density at which a harmonic is phase-matched against a stated mismatch "
"(parameters.harmonic, .phase_mismatch_per_m)",
"refractive",
abscissae=frozenset({"wavelength"}),
required=("harmonic", "phase_mismatch_per_m"),
),
"phase_mismatch_per_density": Quantity(
"wave-vector mismatch of a harmonic per particle, Delta k / N "
"(parameters.harmonic)",
"refractive",
),
"group_delay": Quantity(
"group delay per unit length at the dataset's state",
"refractive",
frozenset({"fs/m"}),
needs_state=True,
),
"group_delay_dispersion": Quantity(
"GDD per unit length at the dataset's state",
"refractive",
frozenset({"fs2/m"}),
needs_state=True,
),
"third_order_dispersion": Quantity(
"TOD per unit length at the dataset's state",
"refractive",
frozenset({"fs3/m"}),
needs_state=True,
),
"dispersion_kappa": Quantity(
"kappa = -lambda^2 d/dlambda[(n - 1)/lambda] at the dataset's state",
"refractive",
_ONE,
needs_state=True,
),
"verdet_constant": Quantity(
"Verdet constant at the dataset's state (unit as printed)",
"refractive",
needs_state=True,
),
"verdet_constant_ratio": Quantity(
"Verdet constant over its value at parameters.reference_wavelength_nm "
"(the medium of the reference wavelength as the dataset's)",
"refractive",
_ONE,
required=("reference_wavelength_nm",),
),
"rayleigh_cross_section": Quantity(
"Rayleigh scattering cross section per particle (parameters.king_factor "
"as used)",
"refractive",
frozenset({"cm2"}),
),
"rayleigh_cross_section_ratio": Quantity(
"Rayleigh cross section of the gas over that of "
"parameters.reference_material",
"refractive",
_ONE,
required=("reference_material",),
),
"refractivity_virial_coefficient": Quantity(
"refractivity (or dielectric) virial coefficient of parameters.order "
"(2 for B_R, the default; 3 for C_R; 4 for D_R); "
"parameters.temperature_k",
"refractive",
frozenset({"cm6/mol2", "cm9/mol3", "cm12/mol4"}),
),
# OEP 4, section 5: a pair is not a material; filed under the first species
# of the pair in sorted order, the other as the partner.
"unlike_pair_refractivity_virial_coefficient": Quantity(
"the refractivity (or dielectric) virial coefficient B_st of the "
"dataset's material with parameters.partner, the first in sorted order "
"(the cell inf is static); parameters.temperature_k, .contribution "
"(induced, or total including orientation)",
"refractive",
frozenset({"cm6/mol2"}),
required=("partner", "temperature_k", "contribution"),
),
# The complex index of a solid, n + ik (TC-319).
"refractive_index": Quantity(
"n, the real part of a solid's complex index n + ik (parameters.axis for "
"an anisotropic crystal; .temperature_k, .grade, .form where stated)",
"refractive",
_ONE,
),
"permittivity_real": Quantity(
"epsilon_1, the real part of a solid's relative permittivity epsilon_1 + "
"i epsilon_2 = (n + ik)^2 (parameters as for refractive_index)",
"refractive",
_ONE,
),
"refractive_index_decrement": Quantity(
"delta = 1 - n, the decrement of the real part of a solid's complex index "
"below 1, as x-ray tables print it (parameters as for refractive_index)",
"refractive",
_ONE,
),
"refractive_index_deviation": Quantity(
"a solid's measured n minus the value of the formula parameters.reference "
"(a formula id, source/formula) at the same wavelength",
"refractive",
_ONE,
required=("reference",),
),
"thermo_optic_coefficient": Quantity(
"dn/dT of a solid (parameters.temperature_k)",
"refractive",
frozenset({"1/K"}),
),
# Absorption and the oscillator-strength distribution.
"absorption_cross_section": Quantity(
"total photoabsorption cross section per particle, below or above the "
"ionisation threshold (parameters.temperature_k)",
"absorption",
frozenset({"cm2", "Mb"}),
),
"photoionization_cross_section": Quantity(
"photoionisation cross section per particle, above the ionisation "
"threshold",
"absorption",
frozenset({"cm2", "Mb"}),
),
"excited_state_photoionization_cross_section": Quantity(
"one-photon photoionisation cross section of an excited level of the atom "
"or molecule "
"(parameters.initial_level: its configuration, term and J, or the "
"source's label), against the photon's wavelength",
"absorption",
frozenset({"cm2", "Mb"}),
required=("initial_level",),
),
"photodissociation_quantum_yield": Quantity(
"number of a stated product (or of a channel's events) formed per photon "
"absorbed, against the photon's wavelength (parameters.product; "
".temperature_k where stated)",
"absorption",
_ONE,
required=("product",),
),
"transition_dipole_moment": Quantity(
"electronic transition dipole moment between two states of the dataset's "
"species (parameters.states: the pair, the row label; .geometry: the "
"nuclear geometry, e.g. a bond length, where the source gives more than "
"one; .component: parallel or perpendicular to the axis, where stated)",
"absorption",
frozenset({"au", "D"}),
abscissae=_LINES,
required=("states",),
),
"two_photon_transition_strength": Quantity(
"rotationally averaged two-photon transition strength delta^TP of the "
"bound transition from the ground state to the labelled final level, in "
"atomic units (parameters.polarization: linear_parallel or circular; "
".frequencies: degenerate, or the second photon's energy; "
".rotational_average: the rotational average's F, G and H as the source "
"states them)",
"absorption",
frozenset({"au"}),
abscissae=frozenset({"label"}),
required=("polarization", "frequencies", "rotational_average"),
),
"two_photon_transition_amplitude": Quantity(
"signed second-order amplitude of the bound two-photon transition from the "
"ground state to a stated final level, both photons polarised along z and "
"both orderings summed, against the first photon's energy (the second's is "
"the level energy less it), as the source defines it (parameters."
"final_level; .gauge; .polarization; .definition: the source's equation; "
".m_zz_per_unit: the zz element of the two-photon kernel M_zz, in atomic "
"units, per unit of the printed amplitude; .method). Bound final levels "
"only",
"absorption",
frozenset({"1", "au"}),
abscissae=frozenset({"wavelength", "label"}),
required=(
"final_level",
"gauge",
"polarization",
"definition",
"m_zz_per_unit",
"method",
),
),
"two_photon_excitation_cross_section": Quantity(
"frequency-integrated generalised cross section sigma_0^(2) of the "
"two-photon excitation of a bound level from the ground state, W = "
"sigma_0^(2) g Phi^2 with Phi the photon flux and g the line profile "
"normalised to one (parameters.frequency_variable: angular or ordinary, "
"the variable g is normalised in; .polarization; .photon_statistics: "
"corrected, or the G2(0) of the measurement); a label names the final "
"level, a wavelength is the exciting photon's",
"absorption",
frozenset({"cm4", "m4"}),
abscissae=frozenset({"label", "wavelength"}),
required=("frequency_variable", "polarization", "photon_statistics"),
),
"integrated_cross_section": Quantity(
"absorption cross section integrated from the abscissa to the x_upper "
"column (unit as printed: cm2 nm, cm2 cm-1)",
"absorption",
columns=("x_upper",),
),
"polarizability_imaginary": Quantity(
"imaginary part of the polarizability above threshold",
"absorption",
_POLARIZABILITY_UNITS,
),
"oscillator_strength": Quantity(
"absorption oscillator strength of the transition at the abscissa, or of "
"the labelled transition",
"absorption",
_ONE,
abscissae=frozenset({"wavelength", "label"}),
),
"transition_probability": Quantity(
"Einstein coefficient A_ki of spontaneous emission from the upper level k "
"to the lower level i of the transition at the abscissa, or of the "
"labelled transition (parameters.notation: the level notation of the "
"labels, e.g. paschen or racah)",
"absorption",
frozenset({"1/s"}),
abscissae=frozenset({"wavelength", "label"}),
required=("notation",),
),
"radiative_lifetime": Quantity(
"radiative lifetime of the labelled level of the atom or molecule, the "
"inverse of its "
"total rate of spontaneous decay in the absence of collisions "
"(parameters.method: how it was obtained, e.g. measured and extrapolated "
"to zero pressure, semiempirical or calculated)",
"absorption",
_TIMES,
abscissae=frozenset({"label"}),
required=("method",),
),
"level_polarizability": Quantity(
"dipole polarizability of a stated level of the atom (parameters."
"configuration, .term, .j), at the abscissa's wavelength or static (inf): "
"the level shifts by -(1/2) alpha F^2 in a static field F and by -(1/4) "
"alpha F^2 in an oscillating field of amplitude F (parameters.component: "
"scalar, vector or tensor, with .definition the source's shift formula for "
"a vector or tensor part; .complex_part: real or imaginary; .method). Not "
"the "
"gas's polarizability, which is polarizability",
"absorption",
_POLARIZABILITY_UNITS | {"kHz/(kV/cm)2"},
required=(
"configuration",
"term",
"j",
"component",
"complex_part",
"method",
),
),
"light_shift_coefficient": Quantity(
"shift of the frequency of the multiphoton transition from the ground "
"level to a stated final level per unit laser intensity, in the linear "
"regime, positive to the blue, against the exciting photon's wavelength "
"(parameters.final_level; .photons; .intensity_definition: how the source "
"defines the intensity; .polarization where stated)",
"absorption",
frozenset({"Hz/(W/cm2)"}),
required=("final_level", "photons", "intensity_definition"),
),
"pressure_line_coefficient": Quantity(
"collisional (pressure) broadening or shift of a bound line of the atom, "
"per unit perturber pressure or number density, in the impact regime "
"(parameters.effect: broadening, or shift, positive to the blue; "
".transition: the line in the source's notation; .photons: 1 or 2; "
".frequency_scale: transition, the line's own frequency, laser, the "
"exciting photon's, or not stated; .width: fwhm, hwhm, not stated, or none "
"for a shift; .frequency_variable: ordinary or angular; .perturber: self "
"or a gas; .temperature_k where stated). A two-photon line's broadening is "
"the decay of the ground-to-final coherence: its pure dephasing is what "
"remains after the radiative and quenching parts",
"absorption",
frozenset({"MHz/torr", "MHz/mbar", "GHz/amagat", "cm-1/amagat", "cm3/s"}),
abscissae=frozenset({"label", "temperature"}),
required=(
"effect",
"transition",
"photons",
"frequency_scale",
"width",
"frequency_variable",
"perturber",
),
),
"collisional_quenching_rate_coefficient": Quantity(
"rate coefficient of the collisional removal of the labelled excited level "
"of the atom or molecule by a perturber, from 1/tau = 1/tau_rad + k2 [M] "
"+ k3 [M]^2 "
"(parameters.perturber: a gas, or self; .order: 2, bimolecular, or 3, "
"termolecular; .channel: total, or the product level of a state-to-state "
"coefficient; .temperature_k where stated). A loss of population, not the "
"pure dephasing of the level",
"absorption",
frozenset({"cm3/s", "m3/s", "cm6/s", "m6/s"}),
abscissae=frozenset({"label"}),
required=("perturber", "order", "channel"),
),
"interval_oscillator_strength": Quantity(
"oscillator strength integrated from the abscissa to the x_upper column",
"absorption",
_ONE,
columns=("x_upper",),
),
"partial_cauchy_moment": Quantity(
"S(parameters.order) of the oscillator strength from the abscissa to the "
"x_upper column",
"absorption",
frozenset({"au"}),
required=("order",),
columns=("x_upper",),
),
"differential_oscillator_strength": Quantity(
"df/dE of the continuum at the photon energy",
"absorption",
frozenset({"1/eV", "1/hartree", "1/rydberg"}),
),
"extinction_coefficient": Quantity(
"k, the imaginary part of a solid's complex index n + ik (k > 0 absorbs; "
"parameters as for refractive_index)",
"absorption",
_ONE,
),
"permittivity_imaginary": Quantity(
"epsilon_2, the imaginary part of a solid's relative permittivity "
"(epsilon_2 > 0 absorbs; parameters as for refractive_index)",
"absorption",
_ONE,
),
"internal_transmittance": Quantity(
"the fraction of the light entering a sample that reaches its far "
"surface, reflection losses excluded, as a glass catalogue prints it "
"(parameters.thickness_mm: the path length)",
"absorption",
_ONE,
required=("thickness_mm",),
),
"absorption_coefficient": Quantity(
"attenuation coefficient of the intensity per length in a solid "
"(parameters.base: e for I = I0 exp(-a z), 10 for I = I0 10^(-a z))",
"absorption",
frozenset({"cm-1", "m-1"}),
required=("base",),
),
"band_gap": Quantity(
"band-gap energy of a solid (parameters.kind: optical, tauc, urbach, "
"photoconductivity, exciton, mobility, effective (fitted to a model), "
"assumed for a value a model takes as input, or not stated)",
"absorption",
frozenset({"eV"}),
abscissae=_LINES,
required=("kind",),
),
# The third-order response.
"hyperpolarizability": Quantity(
"second hyperpolarizability gamma per molecule (parameters.process, "
".convention, .part)",
"third_order",
frozenset({"au", "esu", "SI"}),
required=("process", "convention", "part"),
),
"hyperpolarizability_ratio": Quantity(
"gamma of the gas over gamma of parameters.reference_material "
"(parameters.process, .part)",
"third_order",
_ONE,
required=("reference_material", "process", "part"),
),
"nonlinear_index": Quantity(
"n2, n = n0 + n2 I, at the dataset's state for a gas (parameters.part, "
".coefficient; for a solid also .pulse_fs, .technique, .polarization "
"where stated)",
"third_order",
frozenset({"cm2/W", "m2/W"}),
needs_state=True,
required=("part", "coefficient"),
),
"nonlinear_index_field": Quantity(
"n2 per squared field, n = n0 + n2 <E^2> (the esu n2 of the solid-state "
"literature; parameters.definition: the source's field average, e.g. "
"'<E^2>' of the real field, or the squared amplitude; .part, "
".coefficient)",
"third_order",
frozenset({"esu", "m2/V2"}),
required=("definition", "part", "coefficient"),
),
"nonlinear_index_ratio": Quantity(
"n2 of the gas over n2 of parameters.reference_material at the same "
"density (parameters.part)",
"third_order",
_ONE,
required=("reference_material", "part"),
),
"nonlinear_susceptibility": Quantity(
"third-order susceptibility chi(3), per volume at the dataset's state or "
"per unit density as printed (parameters.process, .convention, .part)",
"third_order",
required=("process", "convention", "part"),
),
"kerr_constant": Quantity(
"dc Kerr constant at the dataset's state, as printed "
"(parameters.temperature_k)",
"third_order",
needs_state=True,
),
"molar_kerr_constant": Quantity(
"the zero-density molar Kerr constant A_K (parameters.temperature_k; "
"against temperature, parameters.wavelength_nm)",
"third_order",
abscissae=frozenset({"wavelength", "temperature"}),
),
"kerr_virial_coefficient": Quantity(
"Kerr virial coefficient, B_K (parameters.order 2, the default) or C_K "
"(order 3) (parameters.temperature_k; against temperature, "
"parameters.wavelength_nm)",
"third_order",
abscissae=frozenset({"wavelength", "temperature"}),
),
"hyperpolarizability_density_coefficient": Quantity(
"the density (pair) coefficient of chi(3) per molecule, "
"chi(3)/N = gamma-term [1 + b N + ...] (parameters.process, .part; "
"parameters.pair for a mixture)",
"third_order",
required=("process", "part"),
),
"two_photon_absorption_coefficient": Quantity(
"two-photon absorption coefficient beta of a solid, dI/dz = -alpha I - "
"beta I^2 (parameters.pulse_fs, .technique where stated)",
"third_order",
frozenset({"m/W", "cm/W", "cm/MW", "cm/GW"}),
),
"multiphoton_absorption_coefficient": Quantity(
"N-photon absorption coefficient of a solid, dI/dz = -beta_N I^N "
"(parameters.photons; unit as printed)",
"third_order",
required=("photons",),
),
"critical_power": Quantity(
"critical power for self-focusing (parameters.definition: the formula "
"the source uses, or measured)",
"third_order",
frozenset({"W", "MW"}),
required=("definition",),
),
# Raman: the anisotropic and vibrational response.
"polarizability_anisotropy": Quantity(
"polarizability anisotropy Delta alpha per molecule",
"raman",
_POLARIZABILITY_UNITS,
),
"polarizability_derivative": Quantity(
"derivative of the polarizability with respect to a normal coordinate "
"(parameters.component: mean or anisotropy; .mode; .coordinate where it is "
"not the mass-weighted normal coordinate: a bond length or a symmetry "
"coordinate, as the source defines it; unit as printed)",
"raman",
required=("component", "mode"),
),
"depolarization_ratio": Quantity(
"depolarization ratio of scattered light (parameters.kind: rayleigh, "
"raman, rotational_raman; .polarization: linear or natural)",
"raman",
_ONE,
required=("kind", "polarization"),
),
"raman_shift": Quantity(
"Raman shift or band origin of the labelled transition "
"(parameters.transition when not per row)",
"raman",
frozenset({"cm-1"}),
abscissae=_LINES,
),
"rotational_constant": Quantity(
"spectroscopic constant of the rotational ladder (parameters.constant: B, "
"D, H, alpha_e, ...; .vibrational_state_v)",
"raman",
frozenset({"cm-1", "MHz", "GHz"}),
abscissae=_LINES,
required=("constant",),
),
"vibrational_term_value": Quantity(
"vibrational energy G(v) of the level labelled by the row (the vibrational "
"quantum number v), from parameters.reference: v0 (the ground level) or "
"minimum (the potential minimum); .electronic_state",
"raman",
frozenset({"cm-1"}),
abscissae=_LINES,
required=("reference",),
),
"raman_scattering_activity": Quantity(
"Raman scattering activity of a normal mode, the invariant combination "
"g (45 a'^2 + 7 g'^2) of the derivatives of the mean (a') and anisotropic "
"(g') polarizability with respect to the mass-weighted normal coordinate, "
"g the mode's degeneracy (parameters.mode; unit as printed, e.g. "
"angstrom4/amu)",
"raman",
abscissae=_SPECTRAL_OR_NONE,
required=("mode",),
),
"raman_cross_section_ratio": Quantity(
"Raman scattering cross section of a transition relative to that of "
"parameters.reference_material's reference transition "
"(.reference_transition, usually the N2 Q branch) at the same excitation "
"(parameters.transition; .geometry: how the scattering was observed)",
"raman",
_ONE,
abscissae=_SPECTRAL_OR_NONE,
required=("transition", "reference_material"),
),
"raman_cross_section": Quantity(
"differential Raman scattering cross section of a transition "
"(parameters.transition; unit as printed, e.g. cm2/sr)",
"raman",
required=("transition",),
),
"raman_linewidth": Quantity(
"linewidth of a Raman transition, or its pressure-broadening coefficient "
"(parameters.transition, .width: hwhm, fwhm or not stated; .perturber for "
"a coefficient: self, a gas id or air; .term for one term of a width law, "
"e.g. the Dicke coefficient A of A/rho; .temperature_k where stated; unit "
"as printed)",
"raman",
abscissae=_CONDITIONS,
required=("transition", "width"),
),
"raman_line_shift": Quantity(
"pressure (collisional) shift of a Raman line, or its coefficient "
"(parameters.transition, .perturber, .temperature_k where stated; unit as "
"printed)",
"raman",
abscissae=_CONDITIONS,
required=("transition", "perturber"),
),
"broadening_temperature_exponent": Quantity(
"exponent N of a broadening coefficient's temperature law gamma(T) = "
"gamma(T0) (T0 / T)^N (parameters.transition, .perturber, "
".reference_temperature_k)",
"raman",
_ONE,
abscissae=_LINES,
required=("transition", "perturber"),
),
"raman_transition_polarizability": Quantity(
"matrix element of a polarizability invariant between the two states of a "
"Raman transition, alpha_if (parameters.transition, .invariant: mean or "
"anisotropy, or the component parallel or perpendicular to the molecular "
"axis)",
"raman",
_POLARIZABILITY_UNITS,
abscissae=_SPECTRAL_OR_NONE,
required=("transition", "invariant"),
),
"raman_gain": Quantity(
"steady-state stimulated Raman gain coefficient of a transition at the "
"dataset's state (parameters.transition, .pump_nm when not the abscissa; "
"unit as printed, e.g. cm/GW)",
"raman",
abscissae=frozenset({"wavelength", "pressure", "density", "label", "none"}),
needs_state=True,
required=("transition",),
),
"dephasing_time": Quantity(
"coherence (T2) time of a Raman transition (parameters.transition; unit "
"as printed)",
"raman",
abscissae=_CONDITIONS,
required=("transition",),
),
"raman_fraction": Quantity(
"fraction f_R of the delayed (Raman) response in a solid's nonlinear "
"response (parameters.definition: how the source defines it)",
"raman",
_ONE,
abscissae=_LINES,
required=("definition",),
),
"raman_mode": Quantity(
"one mode of a multi-mode Raman response of a solid: its amplitude, with "
"the columns shift (cm-1) and the gaussian_width and lorentzian_width "
"(as printed, parameters.width: fwhm or hwhm)",
"raman",
abscissae=_LINES,
required=("width",),
columns=("shift", "gaussian_width", "lorentzian_width"),
),
"raman_response_time": Quantity(
"a time constant of a model Raman response (parameters.constant: tau1, "
"tau2, ...; .model)",
"raman",
_TIMES,
abscissae=_LINES,
required=("constant", "model"),
),
# Ionisation.
"ionization_energy": Quantity(
"ionisation energy (parameters.kind: adiabatic or vertical; .final_state)",
"ionisation",
frozenset({"eV", "cm-1", "hartree"}),
abscissae=_LINES,
required=("kind",),
),
"level_energy": Quantity(
"energy of a level of an atom or ion above its ground level "
"(parameters.configuration, .term, .j)",
"ionisation",
frozenset({"cm-1", "eV"}),
abscissae=_LINES,
required=("configuration", "term", "j"),
),
"electronic_state_energy": Quantity(
"energy of an excited electronic state of a molecule above its ground "
"state (parameters.state; .kind: Te, the potential minimum, T0, the "
"lowest vibrational level, or onset, the long-wavelength onset of a band; "
".one_photon and .two_photon from the ground state: allowed, forbidden or "
"spin_forbidden, where stated)",
"ionisation",
frozenset({"cm-1", "eV"}),
abscissae=_LINES,
required=("state", "kind"),
),
"appearance_energy": Quantity(
"appearance energy of a fragment ion (parameters.fragment)",
"ionisation",
frozenset({"eV", "cm-1"}),
abscissae=_LINES,
required=("fragment",),
),
"dissociation_energy": Quantity(
"energy of a dissociation limit of the dataset's species (neutral or ion) "
"into the stated products (parameters.products, with their states where "
"stated; .kind: D0 from the lowest level, De from the potential minimum, "
"or threshold: the limit measured from the ground state of parameters."
"reference_state, e.g. the neutral molecule for a dication's limit)",
"ionisation",
frozenset({"eV", "cm-1", "hartree", "kJ/mol"}),
abscissae=_LINES,
required=("products", "kind"),
),
"ionic_state_population": Quantity(
"population of an electronic state of the molecular ion that a pulse "
"leaves, as a fraction of the ions or of the molecules (parameters.state; "
".normalisation: ions or molecules; .wavelength_nm, .pulse_fs, "
".polarization: the pulse; .intensity_w_cm2 where one number; .method: "
"measured, or the calculation), against peak intensity or as one number",
"ionisation",
_ONE,
abscissae=frozenset({"intensity", "label", "none"}),
required=(
"state",
"normalisation",
"wavelength_nm",
"pulse_fs",
"polarization",
),
),
"fragmentation_branching_ratio": Quantity(
"yield of one fragmentation channel of the dataset's species over that of "
"a reference (parameters.channel: the products; .reference: the parent "
"ion, all ions, all channels, or another channel; .excitation: "
"photoionisation at the abscissa's photon energy, or a strong-field pulse "
"with .wavelength_nm, .pulse_fs, .polarization; .detection_correction: how "
"the detector's efficiency was treated), against intensity, the photon's "
"wavelength or energy, or as one number",
"ionisation",
_ONE,
abscissae=frozenset({"intensity", "wavelength", "label", "none"}),
required=("channel", "reference", "excitation", "detection_correction"),
),
"kinetic_energy_release": Quantity(
"total kinetic energy the fragments of a channel carry away "
"(parameters.channel; .kind: peak, mean, asymptotic or calculated; "
".state: the parent state where assigned; the pulse where measured)",
"ionisation",
frozenset({"eV"}),
abscissae=_LINES,
required=("channel", "kind"),
),
"dissociation_time": Quantity(
"time constant of a dissociation of the dataset's species (parameters."
"channel; .kind: lifetime of the dissociating state, appearance time of a "
"fragment, or calculated; a collisional time states its .pressure and "
"partner)",
"ionisation",
_TIMES,
abscissae=frozenset({"label", "none", "pressure"}),
required=("channel", "kind"),
),
"dissociative_recombination_rate_coefficient": Quantity(
"rate coefficient of the dissociative recombination of the dataset's "
"molecular ion with an electron, k in dn_e/dt = -k n_e n_ion "
"(parameters.products, or all channels; .law: value, the coefficient at "
"the abscissa's electron temperature, or power_law, the value at "
".reference_temperature_k scaled by (T_ref/T_e)^.exponent; .temperature_"
"range_k where stated)",
"ionisation",
frozenset({"cm3/s", "m3/s"}),
abscissae=frozenset({"temperature", "label", "none"}),
required=("products", "law"),
),
"ionization_rate": Quantity(
"field-ionisation rate against intensity or field (parameters."
"wavelength_nm, inf for a static field; .polarization: linear, circular "
"or static; unit as printed)",
"ionisation",
abscissae=frozenset({"intensity", "field"}),
required=("wavelength_nm", "polarization"),
),
"ionization_yield": Quantity(
"ion yield or probability against intensity (parameters.wavelength_nm, "
".pulse_fs, .polarization; .pulse_envelope and .cep where stated; unit as "
"printed)",
"ionisation",
abscissae=frozenset({"intensity"}),
required=("wavelength_nm", "pulse_fs", "polarization"),
),
"ground_state_survival": Quantity(
"probability that a pulse leaves the atom in its initial (ground) state, "
"against the peak intensity, read at a stated time; its complement counts "
"excitation as well as ionisation (parameters.wavelength_nm, .pulse_fs, "
".polarization, .read_at: when the population is read; .pulse_envelope "
"and .cep where stated)",
"ionisation",
_ONE,
abscissae=frozenset({"intensity"}),
required=("wavelength_nm", "pulse_fs", "polarization", "read_at"),
),
"ionization_yield_spectrum": Quantity(
"ion yield or probability against the photon energy or wavelength at a "
"fixed peak intensity (parameters.intensity_w_cm2, .pulse_cycles: the "
"pulse's length in optical cycles, which fixes its duration at each "
"wavelength, .polarization; .pulse_envelope and .cep where stated; unit as "
"printed)",
"ionisation",
abscissae=frozenset({"wavelength"}),
required=("intensity_w_cm2", "pulse_cycles", "polarization"),
),
"ionization_yield_ratio": Quantity(
"ratio of the material's ionisation yield, as the source defines it "
"(singly charged ions, or all channels, or electrons), to a companion "
"species' measured with it, against intensity, wavelength or as one "
"number (parameters.companion; .wavelength_nm, .pulse_fs, .polarization "
"where one value; .detection_correction: how the ion detector's "
"efficiency was treated, e.g. none, Z/sqrt(M), optical)",
"ionisation",
_ONE,
abscissae=frozenset({"intensity", "wavelength", "label"}),
required=("companion", "polarization", "detection_correction"),
),
"ionization_phase_shift": Quantity(
"phase shift of a probe beam from the electrons a pump pulse leaves, "
"averaged over the probe's profile and normalised to a gas pressure, "
"against the pump's peak intensity (parameters.wavelength_nm, .pulse_fs, "
".polarization: the pump; .probe_wavelength_nm; .pressure_atm: the "
"pressure normalised to; the beams' sizes where stated)",
"ionisation",
frozenset({"rad"}),
abscissae=frozenset({"intensity"}),
required=(
"wavelength_nm",
"pulse_fs",
"polarization",
"probe_wavelength_nm",
"pressure_atm",
),
),
"tunnelling_structure_coefficient": Quantity(
"asymptotic coefficient of the ionising orbital in a tunnelling theory, "
"one per partial wave l, the row label (parameters.model: moadk, adk or "
"wfat; .orbital; .m; .normalisation: how the coefficient is defined)",
"ionisation",
_ONE,
abscissae=_LINES,
required=("model", "orbital", "m", "normalisation"),
),
"ionization_model_parameter": Quantity(
"a constant fitted within a named ionisation-rate model, not a property "
"of the material alone (parameters.model, .parameter: its symbol; unit as "
"printed)",
"ionisation",
abscissae=_LINES,
required=("model", "parameter"),
),
"saturation_intensity": Quantity(
"peak intensity at which a pulse saturates the ionisation of an atom, as "
"the source defines it (parameters.definition; .photons, .pulse_fs, "
".pulse_shape: the pulse)",
"ionisation",
frozenset({"W/cm2", "W/m2"}),
abscissae=frozenset({"wavelength"}),
required=("definition", "pulse_fs"),
),
"multiphoton_ionization_cross_section": Quantity(
"generalised N-photon ionisation cross section (parameters.photons; unit "
"as printed, cm^2N s^(N-1))",
"ionisation",
required=("photons",),
),
"multiphoton_ionization_polarization_ratio": Quantity(
"ratio of the generalised N-photon ionisation cross section for circular "
"polarisation to that for linear (parameters.photons)",
"ionisation",
_ONE,
required=("photons",),
),
"effective_mass": Quantity(
"effective mass of a solid's carriers, in electron masses "
"(parameters.carrier: electron, hole, reduced or not stated)",
"ionisation",
frozenset({"m_e"}),
abscissae=_LINES,
required=("carrier",),
),
"electron_collision_time": Quantity(
"momentum-relaxation (collision) time of a solid's conduction electrons "
"in a Drude model",
"ionisation",
_TIMES,
abscissae=_LINES,
),
"electron_trapping_time": Quantity(
"decay (trapping or recombination) time of the conduction-electron density",
"ionisation",
_TIMES,
abscissae=_LINES,
),
"avalanche_coefficient": Quantity(
"impact-ionisation (avalanche) coefficient of a solid (unit as printed: "
"cm2/J, 1/s, ...; parameters.definition)",
"ionisation",
abscissae=_SPECTRAL_OR_NONE,
required=("definition",),
),
"atom_density": Quantity(
"density of the particles available for ionisation in a solid "
"(parameters.counts: molecules, atoms or valence_electrons)",
"ionisation",
frozenset({"m-3", "cm-3"}),
abscissae=_LINES,
required=("counts",),
),
# Laser damage and breakdown of solids.
"damage_threshold_fluence": Quantity(
"laser-induced damage or breakdown threshold fluence (parameters.site: "
"bulk or surface; .criterion; .shots; the pulse length as the abscissa "
"(duration, with .wavelength_nm) or as .pulse_fs)",
"damage",
frozenset({"J/cm2", "J/m2"}),
abscissae=frozenset({"wavelength", "duration"}),
required=("site",),
),
"damage_threshold_intensity": Quantity(
"laser-induced damage or breakdown threshold intensity (parameters as for "
"damage_threshold_fluence)",
"damage",
frozenset({"W/cm2", "W/m2"}),
abscissae=frozenset({"wavelength", "duration"}),
required=("site",),
),
"damage_threshold_energy": Quantity(
"pulse energy at the damage or breakdown threshold for a stated focusing "
"(parameters as for damage_threshold_fluence, and .numerical_aperture)",
"damage",
frozenset({"J", "uJ", "nJ"}),
abscissae=frozenset({"wavelength", "duration"}),
required=("site",),
),
# The composition of a gas mixture (TC-543).
"mole_fraction": Quantity(
"amount-of-substance fraction of the material (a gas) in a mixture "
"(parameters.mixture: the mixture, as the source defines it, such as "
"'dry air')",
"composition",
frozenset({"1", "ppm", "mol/mol"}),
abscissae=frozenset({"none"}),
required=("mixture",),
),
# The dilute gases' transport and ideal-gas properties (OEP 1, section 4.3).
"dilute_viscosity": Quantity(
"the shear viscosity of the gas in the limit of zero density, a function "
"of temperature alone",
"transport",
frozenset({"Pa s"}),
abscissae=frozenset({"temperature"}),
),
"ideal_gas_heat_capacity": Quantity(
"the molar isobaric heat capacity of the ideal gas, c_p0(T)",
"transport",
frozenset({"J/(mol K)"}),
abscissae=frozenset({"temperature"}),
),
# The density of gas mixtures (OEP 4, sections 4.2 and 5). A pair is filed
# under the first species in sorted order, with the other as the partner;
# mole_fraction is always the material's.
"second_virial_coefficient": Quantity(
"the second (pressure, density) virial coefficient B(T) of the pure gas, "
"Z = 1 + B rho + ...",
"thermodynamic",
frozenset({"cm3/mol"}),
abscissae=frozenset({"temperature"}),
),
"cross_second_virial_coefficient": Quantity(
"the unlike-pair second virial coefficient B_12(T) of the dataset's "
"material with parameters.partner, B_mix = sum_st x_s x_t B_st",
"thermodynamic",
frozenset({"cm3/mol"}),
abscissae=frozenset({"temperature"}),
required=("partner",),
),
"excess_second_virial_coefficient": Quantity(
"the excess second virial coefficient E = B_12 - (B_11 + B_22)/2 of the "
"dataset's material with parameters.partner",
"thermodynamic",
frozenset({"cm3/mol"}),
abscissae=frozenset({"temperature"}),
required=("partner",),
),
"mixture_second_virial_coefficient": Quantity(
"the second virial coefficient B_mix(T) of a binary mixture of the "
"dataset's material, at mole fraction parameters.mole_fraction, with "
"parameters.partner",
"thermodynamic",
frozenset({"cm3/mol"}),
abscissae=frozenset({"temperature"}),
required=("partner", "mole_fraction"),
),
"mixture_compressibility_factor": Quantity(
"Z = p / (rho R T) of a binary mixture of the dataset's material, at mole "
"fraction parameters.mole_fraction, with parameters.partner; "
"parameters.temperature_k",
"thermodynamic",
_ONE,
abscissae=frozenset({"pressure", "density"}),
required=("partner", "mole_fraction", "temperature_k"),
),
"mixture_density": Quantity(
"the molar (or mass) density of a binary mixture of the dataset's "
"material, at mole fraction parameters.mole_fraction, with "
"parameters.partner; parameters.temperature_k",
"thermodynamic",
frozenset({"mol/m3", "mol/cm3", "mol/L", "kg/m3", "g/cm3"}),
abscissae=frozenset({"pressure"}),
required=("partner", "mole_fraction", "temperature_k"),
),
}
)
"""Every quantity a dataset may hold."""
POLARIZABILITY_QUANTITIES: Final = frozenset(
{"refractivity", "polarizability", "molar_refractivity", "refractivity_per_density"}
)
"""Quantities that each determine the polarizability at their frequency."""
PROCESSES: Final = frozenset(
{"static", "kerr", "eshg", "dc_kerr", "thg", "cars", "other"}
)
"""Third-order processes: static, the intensity-dependent index gamma(-w; w, w, -w)
("kerr"), gamma(-2w; w, w, 0) ("eshg"), gamma(-w; w, 0, 0) ("dc_kerr"), gamma(-3w; w,
w, w) ("thg"), coherent anti-Stokes Raman gamma(-w_as; w_p, w_p, -w_s) ("cars")."""
PARTS: Final = frozenset(
{
"electronic",
"vibrational",
"rotational",
"vibrational_rotational",
"electronic_vibrational",
"total",
"instantaneous",
"unknown",
}
)
"""Which contributions a third-order value contains. ``vibrational_rotational`` is
Shelton's gamma^vR; ``instantaneous`` a pulse-dependent mixture (Nibbering's)."""
POLARIZABILITY_CORRECTIONS: Final = frozenset(
{"zero_point_vibrational", "pure_vibrational", "vibrational", "thermal"}
)
"""The parts of a ``polarizability_correction``: the zero-point vibrational average,
the pure vibrational polarizability, their sum, and a thermal (rovibrational)
correction at parameters.temperature_k."""
CONVENTIONS: Final = MappingProxyType(
{
"T": "Taylor series (Buckingham-Orr; Shelton & Rice 1994): p = ... + gamma "
"E^3 / 6",
"ward_1969": "Ward's per-molecule chi in esu (Ward & New 1969, Ward & Miller "
"1979, Ward & Elliott 1984, Lundeen et al. 1983): gamma_T = 6 chi",
"lehmeier_1985": "Lehmeier et al.'s gamma, P = 4 eps0 chi E E E: gamma_T = 24 "
"gamma",
"chi_cars_per_amagat": "CARS chi(3) per amagat (Farrow et al., Hahn & Lee): "
"gamma_T = 2 chi / N0",
"rosasco_1985_hellwarth": "Rosasco & Hurst's 3 sigma / 24 per amagat, "
"Hellwarth's sigma = N gamma_T / 3",
"hellwarth_sigma": "Hellwarth's electronic sigma of P = (1/2) sigma E E^2 "
"(Gaussian esu)",
"maker_terhune_c": "Maker & Terhune's c tensor (Gaussian esu), as used by "
"Hellwarth 1990",
"bjorklund_1975": "Bjorklund's chi(3) for harmonic generation in esu (Mahon "
"et al. 1979)",
}
)
"""The definitions a third-order value may be printed in (``parameters.convention``)."""