optmat.gas.nonlinear#
The second hyperpolarizability: a process-aware dispersion model and its fit.
The third-order response of a gas molecule below resonance is its second
hyperpolarizability \(\gamma(-\omega_\sigma; \omega_1, \omega_2, \omega_3)\), which
depends on all four frequencies. Here it is expressed in the Taylor-series (“T”,
Buckingham-Orr) convention of Shelton & Rice (Chem. Rev. 94, 3 (1994)),
\(p = \dots + \gamma E^3/6\), in atomic units (AU_HYPERPOLARIZABILITY).
Bishop showed, and Shelton’s data confirm, that to fourth order in frequency the dispersion depends on the frequencies only through two symmetric sums,
with \(\nu\) the wavenumbers. \(A\) is the same for every process; \(B'\) separates processes at fourth order (Bishop & De Kee 1996). At a fundamental wavenumber \(\nu\):
the Kerr effect (the intensity-dependent index, SPM and XPM), \(\gamma(-\omega; \omega, \omega, -\omega)\), has \(W_2 = 4\nu^2\);
third-harmonic generation, \(\gamma(-3\omega; \omega, \omega, \omega)\), has \(W_2 = 12\nu^2\);
ESHG \(6\nu^2\), dc Kerr \(2\nu^2\);
a pump-probe index at pump \(\nu_p\) and probe \(\nu_r\) has \(2\nu_p^2 + 2\nu_r^2\).
The data enter in their sources’ own quantities and conventions (docs/data.md,
Third-order quantities), converted here:
Tin au, SI (C^4 m^4 J^-3) or esu;Ward’s per-molecule chi in esu, gamma_T / 6 (
ward_1969);Lehmeier’s gamma, gamma_T / 24 (
lehmeier_1985);CARS chi per amagat, gamma_T = 2 chi / N_0 (
chi_cars_per_amagat);n2, gamma_T = 8 eps0^2 c n2 / N for the self coefficient at the dataset’s density (half the probe coefficient).
The model is electronic. Data that also carry the vibrational and rotational
contributions (Shelton’s H2, D2, N2 and O2 ESHG) are corrected by subtracting Shelton’s
gamma^vR, as a dataset of the same rows or as his G nu^-2 + H nu^-4 formula.
Module Attributes
The version of this module's evaluation code, in the identity of every model that evaluates through it; raised whenever the code changes its output (OEP 1, section 4.8). |
|
One atomic unit of the second hyperpolarizability, C^4 m^4 J^-3 (6.235e-65). |
|
esu (statC cm^4 statV^-3) per SI unit (C m^4 V^-3) of gamma: 8.0776e24. |
|
How far beyond the largest fitted W2 a process may be evaluated without a warning. |
|
Fit configurations of the hyperpolarizability, |
|
The version of the support records' derivation (OEP 5), stored in each record and raised whenever the derivation changes what it writes. |
|
What a |
Functions
|
Serialise a fit as JSON text. |
|
Fit the dispersion model to a configuration's data. |
|
Return the dispersion variables |
|
Convert a third-order dataset to gamma_T in atomic units. |
Return every stored hyperpolarizability model, by gas. |
|
|
Load a hyperpolarizability fit configuration. |
|
Compare a fit with its validator datasets. |
Classes
|
What a finite absorption measurement shows: not a level, and not a bound on one. |
|
A gas's fitted electronic second hyperpolarizability, for any process. |
|
Where a gas's hyperpolarizability fit is supported: facts, with their sources. |
|
A hyperpolarizability fit's specification ( |
|
A fitted hyperpolarizability model with its statistics. |
|
One dataset's values as electronic gamma_T in atomic units. |
|
How one dataset enters a hyperpolarizability fit. |
|
One candidate of a limit taken as the smallest of several. |
|
One fact of a support record: a wavenumber, what kind of fact, and its sources. |
|
One fitted value as a quartet: where it comes from and its four signed legs. |
|
A limit's uncertainty as its source states it, or the fact that it states none. |
- optmat.gas.nonlinear.AU_HYPERPOLARIZABILITY: Final = 6.235379973541882e-65#
One atomic unit of the second hyperpolarizability, C^4 m^4 J^-3 (6.235e-65).
- class optmat.gas.nonlinear.AbsorptionEvidence(detected, sampled, qualification)[source]#
Bases:
objectWhat a finite absorption measurement shows: not a level, and not a bound on one.
- Attributes:
- detectedbool
Whether absorption was detected.
- sampledtuple of float
The lowest and highest wavenumber of the curated values, m^-1.
- qualificationstr
The source’s own qualification of the detection.
- optmat.gas.nonlinear.ESU_PER_SI: Final = 8.077608713062491e+24#
esu (statC cm^4 statV^-3) per SI unit (C m^4 V^-3) of gamma: 8.0776e24.
- optmat.gas.nonlinear.EVALUATION_VERSION: Final = 1#
The version of this module’s evaluation code, in the identity of every model that evaluates through it; raised whenever the code changes its output (OEP 1, section 4.8).
- class optmat.gas.nonlinear.HyperpolarizabilityModel(gas, parameters, covariance, reduced_chi2=0.0, wavelength_range=(0.0, inf), record=<factory>, *, status='user', status_reason='', modified=(), base='')[source]#
Bases:
IdentifiedA gas’s fitted electronic second hyperpolarizability, for any process.
- Attributes:
- gasGas
The species.
- parameterstuple of float
gamma0 (au), A (1e-10 cm^2), B, B’ (1e-20 cm^4).
- covariancenumpy.ndarray
Their covariance.
- reduced_chi2float
Of the fit.
- wavelength_rangetuple of float
The fundamental vacuum-wavelength range over which the model is valid, m.
- recorddict
The stored record.
- covariance: Float[ndarray, '4 4']#
- gamma3(process, wavelength)[source]#
Return the per-molecule coefficient
gamma3 = gamma_T / (6 eps0).The third-order polarisation of the real field is
P = eps0 gamma3 N E^3(m^5/V^2 per molecule).- Parameters:
- processstr
kerrfor SPM and XPM,thgfor the third harmonic.- wavelengtharray_like or float
Fundamental vacuum wavelength, m.
- Returns:
- numpy.ndarray
The coefficient, m^5/V^2.
- gamma_au(process, wavelength, other=None)[source]#
Return gamma_T for a process at a fundamental wavelength.
- Parameters:
- processstr
static,kerr,eshg,dc_kerr,thg,carsorpump_probe.- wavelengtharray_like or float
Fundamental (pump) vacuum wavelength, m.
- otherarray_like or float, optional
The Stokes (
cars) or probe (pump_probe) wavelength, m.
- Returns:
- numpy.ndarray
The gamma_T, atomic units.
- gamma_si(process, wavelength, other=None)[source]#
Return gamma_T in SI (C^4 m^4 J^-3).
- Parameters:
- processstr
The process.
- wavelengtharray_like or float
Fundamental vacuum wavelength, m.
- otherarray_like or float, optional
The second wavelength, m.
- Returns:
- numpy.ndarray
The gamma_T, SI.
- gamma_sigma_au(process, wavelength, other=None, *, birge=True)[source]#
Return the one-sigma uncertainty of
gamma_au()from the covariance.- Parameters:
- processstr
The process.
- wavelengtharray_like or float
Fundamental vacuum wavelength, m.
- otherarray_like or float, optional
The second wavelength, m.
- birgebool, optional
Scale the covariance by the reduced chi-squared when it exceeds one.
- Returns:
- numpy.ndarray
Atomic units.
- n2(wavelength, state, *, ideal=False)[source]#
Return the self Kerr coefficient n2 (m^2/W) in the dilute limit.
n2 = N gamma_Kerr / (8 eps0^2 c)for linearly polarised light.- Parameters:
- wavelengtharray_like or float
Vacuum wavelength, m.
- stateState
Pressure and temperature.
- idealbool, optional
Use the ideal-gas density instead of the real-gas one (always, for a species without an equation of state).
- Returns:
- numpy.ndarray
The n2, m^2/W.
- property support: HyperpolarizabilitySupport | None#
Where this fit is supported, and the gas’s resonance limits (OEP 5).
The stored record whose
model_digestis this model’s digest. It is not part of the model: it changes neither the digest nor any evaluated gamma.- Returns:
- HyperpolarizabilitySupport or None
The record; None for a model built from a caller’s parameters (status
user) that no curated record describes.
- Raises:
- DataError
If a curated model has no matching record: the stored records are missing or stale (re-derive them with
tools/fit/nonlinear_support_record.py).
- class optmat.gas.nonlinear.HyperpolarizabilitySupport(gas, model_digest, derivation_version, fitted_points, max_w2, max_w2_witnesses, leg_max, pair_max, e1, e2, e2_any, ionisation, missing_reasons=<factory>, input_digests=<factory>, *, status='user', status_reason='', modified=(), base='')[source]#
Bases:
IdentifiedWhere a gas’s hyperpolarizability fit is supported: facts, with their sources.
The record of OEP 5, read from
data/gas/models/nonlinear_support/<gas>.jsonthroughHyperpolarizabilityModel.support. Wavenumbers are signed inverse vacuum wavelengths in m^-1 (\(\omega = 2 \pi c \nu\)); a quartet’s legs are \((-\nu_\sigma, \nu_1, \nu_2, \nu_3)\), summing to zero, and \(W_2\) is the sum of their squares, m^-2. It states facts and carries no rule: how a propagation code uses them is its own decision (TC-868). It changes no evaluation, and is not part of the model’s digest; it has its own.The resonance limits hold in the electric-dipole approximation, from the ground state, with the selection assumptions each limit records (TC-865). They say nothing of rotational or vibrational Raman resonances, linewidths, thermally populated states or weak forbidden transitions, and being below them establishes no accuracy.
- Attributes:
- gasGas
The species.
- model_digeststr
The digest of the model whose fitted data it describes.
- derivation_versionint
SUPPORT_DERIVATION_VERSIONwhen it was derived.- fitted_pointsint
The number of fitted points, after the fit’s windows and row selections.
- max_w2float
The largest fitted \(W_2\), m^-2.
- max_w2_witnessestuple of SupportPoint
The fitted points that attain it.
- leg_maxSupportLimit
The largest single leg \(|\nu_k|\) of a fitted point, m^-1.
- pair_maxSupportLimit
The largest pair sum \(|\nu_a + \nu_b|\), \(a \ne b\), of a fitted point, m^-1.
- e1SupportLimit or None
The lowest included level dipole-coupled to the ground state, which no leg (the output included) is to reach; or absorption evidence where no level is curated.
- e2SupportLimit or None
The lowest included level two dipole steps from the ground state, which no pair sum is to reach, for one linear polarisation common to all legs.
- e2_anySupportLimit or None
The same for any polarisation: the smallest of all eligible levels.
- ionisationSupportLimit
The ionisation energy over hc, m^-1.
- missing_reasonsMapping of str to str
Why each of
e1,e2ande2_anythat is None is missing.- input_digestsMapping of str to str
SHA-256 digests of what it was derived from: the selection, the fit’s configuration and each selected dataset.
- Raises:
- DataError
If a resonance limit is both given and missing, or neither.
Examples
>>> from optmat.gas.gases import Gas >>> support = hyperpolarizability_models()[Gas.Ar].support >>> round(1e9 / support.leg_max.wavenumber, 1), support.leg_max.witnesses[0].process (229.0, 'eshg') >>> support.leg_max.datasets ('shelton_1990/table3_Ar_literature',) >>> round(1e9 / support.leg_max_in_w2, 1) # derived, sqrt(3 W2,max / 4), nm 215.9 >>> round(1e9 / support.e1.wavenumber, 1), support.e1.datasets (106.7, ('nist_asd_2026/level_Ar_odd_J1',)) >>> round(1e9 / support.band_edge(), 1), round(1e9 / support.band_edge("any"), 1) (189.4, 192.1) >>> hyperpolarizability_models()[Gas.SF6].support.band_edge() is None True
- band_edge(polarisation='linear')[source]#
Return the derived \(\min(E_1, E_2/2)\), a sufficient bound on all legs.
If every leg of a quartet, generated outputs included, is below it, no leg reaches \(E_1\) and no pair sum reaches \(E_2\). Bounding a field’s input band alone does not bound the outputs it generates. Exceeding it does not prove a quartet resonant. For one linear polarisation the self-phase-modulation quartet reaches \(E_2\) at the edge; for any polarisation it need not (an atom’s even \(J = 1\) level is not reached by two photons of equal frequency). The number carries no accuracy margin; its inputs’ uncertainties and qualifications are on the limits.
- Parameters:
- polarisationstr, optional
"linear", one linear polarisation common to all legs (e2), or"any"(e2_any).
- Returns:
- float or None
The bound, m^-1; None where either limit is missing or is not a level or a band origin (absorption evidence, a bound).
- Raises:
- DataError
For any other polarisation.
- property digest: str#
The record’s own digest,
identity.digest(OEP 1’s machinery).- Returns:
- str
64 hexadecimal digits.
- e1: SupportLimit | None#
- e2: SupportLimit | None#
- e2_any: SupportLimit | None#
- ionisation: SupportLimit#
- leg_max: SupportLimit#
- property leg_max_in_w2: float#
Derived: the largest leg of any quartet within the fitted W2, m^-1.
Each leg is minus the sum of the other three, so by the Cauchy-Schwarz inequality \(\nu_k^2 \le 3 W_2 / 4\), with equality for the third harmonic’s output: \(\sqrt{3 W_{2,\max} / 4}\).
- Returns:
- float
The wavenumber, m^-1.
- max_w2_witnesses: tuple[SupportPoint, ...]#
- pair_max: SupportLimit#
- optmat.gas.nonlinear.NONLINEAR_DIRECTORY: Final = PosixPath('/home/docs/checkouts/optmat/checkouts/7/src/optmat/data/gas/nonlinear')#
Fit configurations of the hyperpolarizability,
<gas>.toml.
- class optmat.gas.nonlinear.NonlinearConfig(gas, description, range_nm, b_prime_prior, fitted, validators, digest, a_prior=None, b_prior=None)[source]#
Bases:
objectA hyperpolarizability fit’s specification (
data/gas/nonlinear/<gas>.toml).- Attributes:
- gasGas
The species.
- descriptionstr
What the fit is for.
- range_nmtuple of float
The fundamental-wavelength range over which the model is declared valid, nm.
- b_prime_priortuple of float or None
Prior
(value, sigma)on B’ (1e-20 cm^4); None fixes B’ at 0.- a_prior, b_priortuple of float or None
Optional priors
(value, sigma)on A (1e-10 cm^2) and B (1e-20 cm^4): a dispersion borrowed from a similar molecule where the gas’s own data cannot fix it.- fittedtuple of NonlinearOptions
The datasets fitted.
- validatorstuple of NonlinearOptions
Datasets compared with the fit.
- digeststr
SHA-256 of the configuration file.
- fitted: tuple[NonlinearOptions, ...]#
- validators: tuple[NonlinearOptions, ...]#
- class optmat.gas.nonlinear.NonlinearFit(config, parameters, covariance, scales=<factory>, chi2=0.0, dof=0, dataset_chi2=<factory>)[source]#
Bases:
objectA fitted hyperpolarizability model with its statistics.
- Attributes:
- configNonlinearConfig
The configuration.
- parametersnumpy.ndarray
gamma0 (au), A (1e-10 cm^2), B, B’ (1e-20 cm^4).
- covariancenumpy.ndarray
Their covariance (4 x 4; B’ row and column zero when fixed).
- scalesdict of str to float
The fitted dataset scales.
- chi2float
Chi-squared of the data.
- dofint
Data points minus parameters.
- dataset_chi2dict of str to tuple
(n, chi2)per dataset.
- config: NonlinearConfig#
- covariance: Float[ndarray, '4 4']#
- parameters: Float[ndarray, '4']#
- class optmat.gas.nonlinear.NonlinearObservation(key, wavelength_nm, w2, w4, gamma, sigma, process, options)[source]#
Bases:
objectOne dataset’s values as electronic gamma_T in atomic units.
- Attributes:
- keystr
source/dataset.- wavelength_nmnumpy.ndarray
The fundamental (pump) vacuum wavelength, nm (
inffor static).- w2, w4numpy.ndarray
The dispersion variables, cm^-2 and cm^-4.
- gammanumpy.ndarray
gamma_T, atomic units.
- sigmanumpy.ndarray
One-sigma uncertainty, atomic units (NaN where none is stated).
- processstr
The process (
pump_probefor a nondegenerate index).- optionsNonlinearOptions
How the dataset enters the fit.
- gamma: Float[ndarray, 'n']#
- options: NonlinearOptions#
- sigma: Float[ndarray, 'n']#
- w2: Float[ndarray, 'n']#
- w4: Float[ndarray, 'n']#
- wavelength_nm: Float[ndarray, 'n']#
- class optmat.gas.nonlinear.NonlinearOptions(key, free_scale=False, systematic=0.0, extra_relative=0.0, range_nm=(0.0, inf), subtract_formula='', subtract_dataset='', scale_group='', rows=(), factor=1.0)[source]#
Bases:
objectHow one dataset enters a hyperpolarizability fit.
- Attributes:
- keystr
source/dataset.- free_scalebool
Fit the dataset’s scale without a prior (its shape only).
- systematicfloat
A relative scale uncertainty (one sigma): the scale is fitted with this prior.
- extra_relativefloat
Relative uncertainty added in quadrature to every value.
- range_nmtuple of float
Fundamental-wavelength window of the values used, nm.
- subtract_formulastr
source/formulaof Shelton’sgamma^vR = G nu^-2 + H nu^-4(C^4 m^4 J^-3) to subtract, or “”.- subtract_datasetstr
source/datasetof gamma^vR on the same wavelengths to subtract, or “”.- scale_groupstr
Datasets naming the same group share one scale (a calculation’s processes, whose relative dispersion informs B’ whatever its level); “” for none.
- rowstuple of str
Only these rows (one method of a table of methods, say); empty for all.
- factorfloat
A factor applied to the converted values and uncertainties, for a unit the dataset’s own conversion does not know (Bishop & Pipin’s reduced-mass atomic unit of helium, 1.00096 standard units); its reason is stated in the configuration.
- optmat.gas.nonlinear.SUPPORT_DERIVATION_VERSION: Final = 1#
The version of the support records’ derivation (OEP 5), stored in each record and raised whenever the derivation changes what it writes. It is separate from the models’
EVALUATION_VERSION: a record describes a model and changes no evaluation.
- optmat.gas.nonlinear.SUPPORT_LIMIT_KINDS: Final = ('fitted_extent', 'level', 'band_origin', 'lower_bound', 'upper_bound', 'absorption_evidence')#
What a
SupportLimitis (OEP 5, section 6).fitted_extent: the largest of a quantity over the fitted points;level: a spectroscopic level or threshold energy, as its source gives it;band_origin: a molecular state’s vibrationless origin, a sum of 0-0 bands;lower_bound,upper_bound: an experimental bound, in wavenumber;absorption_evidence: absorption detected, or not, over a finite sampled window; not a level and not a bound on one.
- class optmat.gas.nonlinear.SupportCandidate(datasets, wavenumber)[source]#
Bases:
objectOne candidate of a limit taken as the smallest of several.
- Attributes:
- datasetstuple of str
Its datasets: one level, or the chain of band origins whose sum it is.
- wavenumberfloat
Its energy over hc, m^-1.
- class optmat.gas.nonlinear.SupportLimit(wavenumber, kind, datasets, location, derivation, registers, witnesses=(), candidates=(), uncertainty=None, evidence=None, qualifications=())[source]#
Bases:
objectOne fact of a support record: a wavenumber, what kind of fact, and its sources.
- Attributes:
- wavenumberfloat
The limit, m^-1 (an inverse vacuum wavelength; an energy over hc).
- kindstr
One of
SUPPORT_LIMIT_KINDS. A bound’s direction is in wavenumber; inverting to a wavelength reverses it.- datasetstuple of str
The datasets it is taken from: for a fitted extent, those of its witnesses; for a smallest of candidates, the winner’s.
- locationstr
Where in the datasets: the rows, columns or parameters read.
- derivationstr
How the wavenumber follows from them.
- registerstuple of str
The register entries that record the choice (
TC-n).- witnessestuple of SupportPoint
For a fitted extent, every fitted point that attains it, in the order of the fit’s datasets and their rows; empty otherwise.
- candidatestuple of SupportCandidate
For a smallest of several, every candidate; empty otherwise.
- uncertaintySupportUncertainty or None
The source’s uncertainty, or that it states none; None where none applies (a fitted extent, absorption evidence).
- evidenceAbsorptionEvidence or None
For absorption evidence, what was measured; None otherwise.
- qualificationstuple of str
The approximations and selection assumptions behind it.
- Raises:
- DataError
For an unknown kind, or absorption evidence without its measurement.
- candidates: tuple[SupportCandidate, ...] = ()#
- evidence: AbsorptionEvidence | None = None#
- uncertainty: SupportUncertainty | None = None#
- witnesses: tuple[SupportPoint, ...] = ()#
- class optmat.gas.nonlinear.SupportPoint(dataset, row, process, wavelength, second_wavelength, legs)[source]#
Bases:
objectOne fitted value as a quartet: where it comes from and its four signed legs.
- Attributes:
- datasetstr
source/dataset.- rowstr
The dataset’s row.
- processstr
The process, as
frequency_sums()names it.- wavelengthfloat
The fundamental (pump) vacuum wavelength, m;
inffor a static value.- second_wavelengthfloat or None
The Stokes (
cars) or probe (pump_probe) vacuum wavelength, m.- legstuple of float
The signed wavenumbers \((-\nu_\sigma, \nu_1, \nu_2, \nu_3)\), m^-1: inverse vacuum wavelengths, the output with a minus sign, summing to zero.
- class optmat.gas.nonlinear.SupportUncertainty(stated, value, level, provenance)[source]#
Bases:
objectA limit’s uncertainty as its source states it, or the fact that it states none.
Printed precision is not an uncertainty, and an unstated one is not zero.
- Attributes:
- statedbool
Whether the source states an uncertainty.
- valuefloat or None
The stated uncertainty, m^-1; None where none is stated.
- levelstr
Its confidence level as the source gives it (
"not stated"where it does not).- provenancestr
Where it comes from, or why there is none.
- optmat.gas.nonlinear.W2_MARGIN: Final = 1.1#
How far beyond the largest fitted W2 a process may be evaluated without a warning.
- optmat.gas.nonlinear.dumps(result)[source]#
Serialise a fit as JSON text.
- Parameters:
- resultNonlinearFit
The fit.
- Returns:
- str
Indented JSON.
- optmat.gas.nonlinear.fit_hyperpolarizability(config)[source]#
Fit the dispersion model to a configuration’s data.
- Parameters:
- configNonlinearConfig
The fit.
- Returns:
- NonlinearFit
The parameters, covariance and statistics.
- Raises:
- DataError
If a fitted value has no uncertainty.
- optmat.gas.nonlinear.frequency_sums(process, wavenumber, other=None)[source]#
Return the dispersion variables
W2andW4of a process.- Parameters:
- processstr
static,kerr,eshg,dc_kerr,thg,carsorpump_probe.- wavenumbernumpy.ndarray
The fundamental (or pump) vacuum wavenumber, cm^-1.
- othernumpy.ndarray, optional
The Stokes wavenumber (
cars) or the probe wavenumber (pump_probe).
- Returns:
- tuple of numpy.ndarray
W2(cm^-2) andW4(cm^-4).
- Raises:
- DataError
For an unknown process, or
carsandpump_probewithoutother.
Examples
>>> w2, w4 = frequency_sums("thg", np.array([12500.0])) >>> float(w2[0] / 12500.0**2), float(w4[0] / 12500.0**4) (12.0, 84.0)
- optmat.gas.nonlinear.gamma_observation(dataset, options)[source]#
Convert a third-order dataset to gamma_T in atomic units.
- Parameters:
- datasetDataset
A
hyperpolarizability,nonlinear_indexor per-amagat CARSnonlinear_susceptibilitydataset.- optionsNonlinearOptions
Its window and corrections.
- Returns:
- NonlinearObservation
The values, with their dispersion variables.
- Raises:
- DataError
If the dataset’s quantity, convention or unit has no conversion, or its wavelength is not stated.
- optmat.gas.nonlinear.hyperpolarizability_models()[source]#
Return every stored hyperpolarizability model, by gas.
- Returns:
- dict of Gas to HyperpolarizabilityModel
The models of
data/gas/models/nonlinear/<gas>.json.