optmat.gas.two_photon#

Two-photon ionisation of the noble gases: the continuum model (OEP 6, Phase 1).

The generalised two-photon ionisation cross section \(\sigma^{(2)}\) of a gas’s ground state is defined by the rate per atom

\[W = \sigma^{(2)} \Phi^2, \qquad \Phi = I / \hbar\omega,\]

with \(\Phi\) the photon flux; in SI, \(\sigma^{(2)}\) is in m^4 s (1 cm^4 s = 1e-8 m^4 s). A quasi-monochromatic wave in a gas of number density \(N\) then loses intensity as \(dI/dz = -\beta I^2\) with \(\beta = 2 N \sigma^{(2)} / \hbar\omega\), two photons per event.

Each model is a curated reference curve that the author approved under data rule 8 (TC-943), interpolated linearly in \(\log\sigma^{(2)}\) between the curve’s own drawn vertices and never fitted or extrapolated:

  • helium: Mihelič and Horvat (2021), the 1S and 1D partial cross sections summed;

  • neon and argon: McKenna and van der Hart (2004), R-matrix Floquet;

  • xenon: Lagutin et al. (2017), linear and circular polarisation.

Krypton has none: no vector-drawn or tabulated cross section is curated (OEP 6, Q2), and asking for it raises UnavailableModelError.

A model covers the window from the lowest two-photon threshold \(I_p/2\) to the first one-photon resonance \(E_1\), and states its regions (regions):

  • below_threshold: the direct continuum cross section is zero. Bound two-photon excitation and (2+1) ionisation there are not modelled (OEP 6, Phase 2).

  • supported: the reference’s values.

  • unsupported_detail: the reference’s values, with ModelRangeWarning. The source does not qualify them: an LS-coupled calculation between the ion’s two fine-structure thresholds, or the wing of the first one-photon resonance, which the sources place differently.

  • unavailable: no value. The reference does not reach it (between xenon’s two thresholds, for instance), or it is at or above \(E_1\).

Evaluation never raises on a frequency grid. It returns NaN where the model is unavailable, and available() gives the mask (the author’s decision, TC-943). A propagation code decides what to do there.

The model supplies the degenerate cross section. It does not supply a time-resolved loss for a broadband pulse, nor the mixed pairs of two bands. The pair-spectral yield of OEP 6, section 4, is an integral identity in a stated approximation, and its time dependence is a documented gap (TC-903). Nor does it double as a strong-field rate: applying it and ionisation_rate_model() to the same spectral component counts that component twice.

Examples#

>>> import math
>>> from optmat.constants import C
>>> argon = two_photon_ionisation_model("Ar")
>>> [round(2 * math.pi * C / t.omega * 1e9, 2) for t in argon.thresholds]
[157.34, 155.59]
>>> omega = 2 * math.pi * C / 120e-9  # 120 nm
>>> f"{float(argon.cross_section(omega)):.3e}"  # m^4 s
'1.146e-58'
>>> bool(argon.available(2 * math.pi * C / 100e-9))  # beyond E1 (106.7 nm)
False

Module Attributes

EVALUATION_VERSION

The version of the evaluation: interpolation, regions and conversions.

DERIVATION_VERSION

The version of the stored models' derivation, raised whenever it writes otherwise.

REGION_LABELS

The kinds of region a model's frequency axis is divided into.

Functions

two_photon_ionisation_model(gas[, polarization])

Return a noble gas's two-photon ionisation model (OEP 6, Phase 1).

two_photon_ionisation_models()

Return every two-photon ionisation model, by gas and polarisation.

Classes

TwoPhotonIonisationModel(gas, polarization, ...)

The two-photon ionisation cross section of a noble gas's ground state.

TwoPhotonReference(datasets, gauge, method, ...)

The approved reference curve of a model, and why it was chosen.

TwoPhotonRegion(label, lower, upper, reason)

A half-open band of photon angular frequency, [lower, upper), and its label.

TwoPhotonSpread(label, datasets, form, role, ...)

Another calculation against the reference over their supported overlap.

TwoPhotonThreshold(name, omega, photons, ...)

A threshold or resonance as a photon's angular frequency, with its source.

TwoPhotonUncertainty(source, source_level, ...)

What is known of a model's uncertainty, kept as three separate kinds (Q6).

optmat.gas.two_photon.DERIVATION_VERSION: Final = 1#

The version of the stored models’ derivation, raised whenever it writes otherwise.

optmat.gas.two_photon.EVALUATION_VERSION: Final = 1#

The version of the evaluation: interpolation, regions and conversions.

optmat.gas.two_photon.REGION_LABELS: Final = ('below_threshold', 'supported', 'unsupported_detail', 'unavailable')#

The kinds of region a model’s frequency axis is divided into.

class optmat.gas.two_photon.TwoPhotonIonisationModel(gas, polarization, derivation_version, omega, sigma, thresholds, e1, regions, reference, uncertainty, input_digests=<factory>, *, status='user', status_reason='', modified=(), base='')[source]#

Bases: Identified

The two-photon ionisation cross section of a noble gas’s ground state.

Built by two_photon_ionisation_model() from its stored derivation. SI throughout: photon angular frequency in rad/s, cross section in m^4 s.

Attributes:
gasGas

The species.

polarizationstr

"linear" or "circular".

derivation_versionint

DERIVATION_VERSION when it was derived.

omeganumpy.ndarray

The reference’s vertices, photon angular frequency, rad/s, increasing.

sigmanumpy.ndarray

The reference’s cross section at them, m^4 s.

thresholdstuple of TwoPhotonThreshold

The lowest ionic channel’s two-photon threshold first; the ion’s \({}^2P_{1/2}\) channel’s second, for Ne to Xe.

e1TwoPhotonThreshold

The first one-photon resonance, where the window ends.

regionstuple of TwoPhotonRegion

Bands covering every positive frequency, in order.

referenceTwoPhotonReference

The approved reference.

uncertaintyTwoPhotonUncertainty

Its uncertainty, by kind.

input_digestsMapping of str to str

SHA-256 digests of what it was derived from: the selection and each dataset.

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

Return where the model has a value: below threshold, or on its reference.

Parameters:
omegaarray_like

Photon angular frequency, rad/s, finite and positive.

Returns:
numpy.ndarray

Booleans with the shape of omega: False where cross_section() is NaN.

Raises:
ArgumentError

If a frequency is not finite and positive.

cross_section(omega)[source]#

Return the two-photon ionisation cross section at photon frequencies.

Parameters:
omegaarray_like

Photon angular frequency, rad/s, finite and positive.

Returns:
numpy.ndarray

\(\sigma^{(2)}\), m^4 s, with the shape of omega: exactly 0 below the lowest threshold, NaN where available() is False.

Raises:
ArgumentError

If a frequency is not finite and positive.

Warns:
ModelRangeWarning

If a frequency lies in an unsupported_detail region.

derivation_version: int#
property digest: str#

The model’s digest, identity.digest.

Returns:
str

64 hexadecimal digits.

e1: TwoPhotonThreshold#
gas: Gas#
input_digests: Mapping[str, str]#
loss_coefficient(omega, number_density)[source]#

Return the two-photon loss coefficient beta, dI/dz = -beta I^2.

Parameters:
omegaarray_like

Photon angular frequency, rad/s, finite and positive.

number_densityarray_like

The density of ground-state atoms, m^-3, finite and non-negative; broadcast with omega.

Returns:
numpy.ndarray

\(\beta = 2 N \sigma^{(2)} / \hbar\omega\), m/W: two photons per event; NaN where the model is unavailable.

Raises:
ArgumentError

If a frequency is not finite and positive, or a density is not finite and non-negative.

Warns:
ModelRangeWarning

If a frequency lies in an unsupported_detail region.

omega: Float[ndarray, 'n']#
pair_cross_section(pair_omega)[source]#

Return the cross section indexed by a photon pair’s summed frequency.

Parameters:
pair_omegaarray_like

The sum of the two photons’ angular frequencies, rad/s, finite and positive.

Returns:
numpy.ndarray

\(\sigma^{(2)}(\Omega/2)\), m^4 s, as cross_section().

Raises:
ArgumentError

If a frequency is not finite and positive.

Warns:
ModelRangeWarning

If a frequency lies in an unsupported_detail region.

polarization: str#
rate(omega, intensity)[source]#

Return the two-photon ionisation rate per atom of a monochromatic wave.

Parameters:
omegaarray_like

Photon angular frequency, rad/s, finite and positive.

intensityarray_like

Intensity, W/m^2, finite and non-negative; broadcast with omega.

Returns:
numpy.ndarray

\(W = \sigma^{(2)} (I / \hbar\omega)^2\), 1/s; NaN where the model is unavailable.

Raises:
ArgumentError

If a frequency is not finite and positive, or an intensity is not finite and non-negative.

Warns:
ModelRangeWarning

If a frequency lies in an unsupported_detail region.

reference: TwoPhotonReference#
region(omega)[source]#

Return the label of the region each frequency lies in.

Parameters:
omegaarray_like

Photon angular frequency, rad/s, finite and positive.

Returns:
numpy.ndarray

Labels (REGION_LABELS), with the shape of omega.

Raises:
ArgumentError

If a frequency is not finite and positive.

regions: tuple[TwoPhotonRegion, ...]#
sigma: Float[ndarray, 'n']#
thresholds: tuple[TwoPhotonThreshold, ...]#
uncertainty: TwoPhotonUncertainty#
class optmat.gas.two_photon.TwoPhotonReference(datasets, gauge, method, intensity_w_cm2, reason, registers)[source]#

Bases: object

The approved reference curve of a model, and why it was chosen.

Attributes:
datasetstuple of str

Its datasets, summed where they are partial cross sections.

gaugestr

The gauge, as the record states it.

methodstr

The calculation.

intensity_w_cm2float or None

The intensity of a non-perturbative calculation, W/cm^2; None for a lowest-order one.

reasonstr

Why it is the reference (the author’s approval, TC-943).

registerstuple of str

The register entries.

datasets: tuple[str, ...]#
gauge: str#
intensity_w_cm2: float | None#
method: str#
reason: str#
registers: tuple[str, ...]#
class optmat.gas.two_photon.TwoPhotonRegion(label, lower, upper, reason)[source]#

Bases: object

A half-open band of photon angular frequency, [lower, upper), and its label.

Attributes:
labelstr

One of REGION_LABELS.

lowerfloat

The lower edge, rad/s.

upperfloat

The upper edge, rad/s; inf for the last region.

reasonstr

Why the band is so labelled.

label: str#
lower: float#
reason: str#
upper: float#
class optmat.gas.two_photon.TwoPhotonSpread(label, datasets, form, role, lower, upper, points, lower_ratio, upper_ratio)[source]#

Bases: object

Another calculation against the reference over their supported overlap.

Attributes:
labelstr

The calculation.

datasetstuple of str

Its datasets, summed where they are partial cross sections.

formstr

"vector" or "raster": how its values were read.

rolestr

"independent", another calculation, which enters the envelope; or "gauge", the reference’s other gauge, a diagnostic only.

lowerfloat

The lowest photon angular frequency compared, rad/s.

upperfloat

The highest, rad/s.

pointsint

The number of reference vertices compared.

lower_ratiofloat

The smallest ratio of it to the reference.

upper_ratiofloat

The largest.

datasets: tuple[str, ...]#
form: str#
label: str#
lower: float#
lower_ratio: float#
points: int#
role: str#
upper: float#
upper_ratio: float#
class optmat.gas.two_photon.TwoPhotonThreshold(name, omega, photons, energy, datasets)[source]#

Bases: object

A threshold or resonance as a photon’s angular frequency, with its source.

Attributes:
namestr

What it is, e.g. "Ar+ 2P3/2" or "E1".

omegafloat

The photon’s angular frequency, rad/s: the level’s energy over the number of photons that reach it, over hbar.

photonsint

2 for an ionisation threshold, 1 for \(E_1\).

energyfloat

The energy above the ground state, J.

datasetstuple of str

The curated datasets it is computed from.

datasets: tuple[str, ...]#
energy: float#
name: str#
omega: float#
photons: int#
class optmat.gas.two_photon.TwoPhotonUncertainty(source, source_level, source_provenance, digitising, digitising_provenance, spreads)[source]#

Bases: object

What is known of a model’s uncertainty, kept as three separate kinds (Q6).

Attributes:
sourcefloat or None

The source’s own relative accuracy, None where it states none (never zero).

source_levelstr

Its level, as stated, or "not stated".

source_provenancestr

Where it is stated.

digitisingfloat

The relative digitising uncertainty at a drawn vertex.

digitising_provenancestr

Its record and register entry.

spreadstuple of TwoPhotonSpread

The other calculations against the reference, over the supported region.

digitising: float#
digitising_provenance: str#
property envelope: tuple[float, float] | None#

The smallest and largest ratio of the independent calculations.

It is an empirical envelope of other calculations, not a confidence interval or a bound on the true cross section.

Returns:
tuple of float or None

(lower, upper) ratios to the reference; None with no independent calculation.

source: float | None#
source_level: str#
source_provenance: str#
spreads: tuple[TwoPhotonSpread, ...]#
optmat.gas.two_photon.two_photon_ionisation_model(gas, polarization='linear')[source]#

Return a noble gas’s two-photon ionisation model (OEP 6, Phase 1).

Parameters:
gasGas or str

The gas: He, Ne, Ar or Xe (Kr has none).

polarizationstr, optional

"linear" (default), or "circular" where an approved reference gives it (Xe).

Returns:
TwoPhotonIonisationModel

The model.

Raises:
UnavailableModelError

For a gas or polarisation with no approved reference, with the reason.

ArgumentError

For a polarisation other than linear or circular.

Examples

>>> xenon = two_photon_ionisation_model("Xe", "circular")
>>> xenon.reference.datasets
('lagutin_2017/fig8_cipfcp_circular',)
optmat.gas.two_photon.two_photon_ionisation_models()[source]#

Return every two-photon ionisation model, by gas and polarisation.

Returns:
dict

{(gas, polarization): model} for every approved reference.

Examples

>>> sorted(f"{g.value}/{p}" for g, p in two_photon_ionisation_models())
['Ar/linear', 'He/linear', 'Ne/linear', 'Xe/circular', 'Xe/linear']