optmat.gas.raman#
The Raman lines of the molecular gases, ready for a propagation code (TC-439).
A molecule’s delayed (Raman) third-order response is a sum of damped oscillators, one
per Raman line, each driven by the intensity. This module turns curated spectroscopic
data into those lines: the frequency of every line, its coupling amplitude and its
linewidth at a stated temperature and density. The tensor response is assembled by
optmat.gas.raman_response; a propagation
code chooses how to sample or integrate it.
The convention of the amplitudes. For a field linearly polarised along \(x\), the Raman polarisation of a gas of number density \(N\) is
with \(A_k\) in m^5 V^-2 s^-1, \(\Omega_k\) the line’s angular frequency and \(\Gamma_k = \pi \Delta\nu_k\) its dephasing rate (\(\Delta\nu_k\) the full width at half maximum in Hz). A propagation adapter maps the lines one to one.
Rotational S branch (\(J \to J + 2\) of a linear molecule):
\[A_J = \frac{2}{15} \frac{\Delta\alpha^2}{\hbar \varepsilon_0} \frac{(J + 1)(J + 2)}{2J + 3} (n_J - n_{J+2}),\]with \(\Delta\alpha\) the polarizability anisotropy (C m^2/V) and \(n_J = g_J e^{-E_J / k_B T} / Z\) the population of one of the \(2J + 1\) sublevels (Placzek-Teller; equivalently, \(p_J/(2J+1) = n_J\)).
Vibrational Q branch (\(v = 0 \to 1\), one line per rotational level):
\[A_J = \frac{|\langle 0 | \bar\alpha | 1 \rangle|^2}{\hbar \varepsilon_0} P_J,\]with \(\langle 0 | \bar\alpha | 1 \rangle\) the transition polarizability of the mean (isotropic) polarizability (C m^2/V) and \(P_J\) the fraction of molecules in level \(J\) (all sublevels). For a harmonic mode \(|\langle 0|\bar\alpha|1\rangle|^2 = (\partial\bar\alpha/\partial q)^2 \hbar / (2 \mu \Omega)\), so \(A = (\partial\bar\alpha/\partial q)^2 / (2\mu\Omega \varepsilon_0)\), with a consistent vibrational coordinate and reduced mass.
Energies come from the curated constants in cm^-1: the rotational levels \(E_J = B J(J+1) - D [J(J+1)]^2 + H [J(J+1)]^3\), and the Q-branch line \(\nu_J = \nu_0 + (B_1 - B_0) J(J+1) - (D_1 - D_0) [J(J+1)]^2\).
Module Attributes
The per-gas choices of the Raman parameters, each with its reason. |
Functions
|
Return a gas's Raman lines band by band, with their widths, at a state. |
|
Return the rotational level at about 50 k_B T, where the population is ~1e-20. |
|
Return a gas's Raman lines, with their widths, at a state. |
|
Return the curated Raman parameters of a molecular gas. |
|
Return the rotational S-branch lines of a linear molecule. |
|
Return the rotational Raman nonlinear index for a pulse long against the lines. |
|
Return the fraction of molecules in each rotational level. |
|
Return the nuclear-spin weights of a linear molecule's rotational levels. |
|
Return the steady-state Stokes gain of each line, for a pump at its centre. |
|
Return the vibrational Q-branch lines of a mode. |
Classes
|
A polarizability element that depends on the rotational level. |
|
The lines of one Raman band of a gas at a state. |
|
Raman lines in the convention of the module docstring. |
|
The curated Raman parameters of a gas. |
|
The rotational Raman band of a linear molecule. |
|
The constants of one vibrational level's rotational ladder, cm^-1. |
|
The nuclear-spin weights of the even and odd rotational levels. |
|
One vibrational Raman band (its Q branch). |
- class optmat.gas.raman.AnisotropyTable(j, value)[source]#
Bases:
objectA polarizability element that depends on the rotational level.
For H2 the anisotropy of the J -> J + 2 transition rises by 10 % from J = 0 to J = 6 (centrifugal stretching), and the Q(J) transition polarizability by 2 % from J = 0 to 5. Between tabulated levels it is interpolated linearly; beyond them it is held at the end values.
- Attributes:
- jtuple of int
The lower levels, increasing.
- valuetuple of float
The anisotropy of each, C m^2/V.
- class optmat.gas.raman.BandLines(band, lines, dispersion_factor=1.0)[source]#
Bases:
objectThe lines of one Raman band of a gas at a state.
- Attributes:
- bandRotationalBand or VibrationalBand
The band, with its curated parameters.
- linesRamanLines
Its lines, with their widths, in the convention of this module.
- dispersion_factorfloat
The factor applied to the band’s transition elements for the pump wavelength asked for (1 for the rotational band, which is not dispersed).
- band: RotationalBand | VibrationalBand#
- lines: RamanLines#
- optmat.gas.raman.RAMAN_FILE = PosixPath('/home/docs/checkouts/optmat/checkouts/7/src/optmat/data/gas/raman.toml')#
The per-gas choices of the Raman parameters, each with its reason.
- class optmat.gas.raman.RamanLines(branch, j, frequency, amplitude, fwhm=None)[source]#
Bases:
objectRaman lines in the convention of the module docstring.
- Attributes:
- branchtuple of str
S(rotational) orQ(vibrational), per line.- jnumpy.ndarray
The lower level’s rotational quantum number (-1 where the line is not resolved by J).
- frequencynumpy.ndarray
Angular frequency
Omega, rad/s.- amplitudenumpy.ndarray
A, m^5 V^-2 s^-1.- fwhmnumpy.ndarray or None
The full width at half maximum of each line at the state asked for, Hz (
Gamma = pi FWHM); None where no state was given.
- amplitude: Float[ndarray, 'n']#
- frequency: Float[ndarray, 'n']#
- j: Int[ndarray, 'n']#
- class optmat.gas.raman.RamanParameters(gas, rotational, vibrational, reasons=<factory>, missing='')[source]#
Bases:
objectThe curated Raman parameters of a gas.
- Attributes:
- gasGas
The gas.
- rotationalRotationalBand or None
The rotational band; None for a spherical top.
- vibrationaltuple of VibrationalBand
The Raman-active vibrational bands curated.
- reasonsdict of str to str
Why each choice was made (from
raman.toml).- missingstr
What is known to be missing, or an empty string.
- rotational: RotationalBand | None#
- vibrational: tuple[VibrationalBand, ...]#
- class optmat.gas.raman.RotationalBand(constants, spin, anisotropy, widths, sources)[source]#
Bases:
objectThe rotational Raman band of a linear molecule.
- Attributes:
- constantsRotationalConstants
The ground vibrational level’s constants, cm^-1.
- spinSpinStatistics
The nuclear-spin weights.
- anisotropyfloat or AnisotropyTable
The polarizability anisotropy, C m^2/V.
- widthsLinewidthLaw or LineTableLaw or ExponentialGapLaw
The width law of the lines.
- sourcesdict of str to str
The dataset or formula behind each parameter.
- anisotropy: float | AnisotropyTable#
- constants: RotationalConstants#
- spin: SpinStatistics#
- widths: LinewidthLaw | LineTableLaw | ExponentialGapLaw#
- class optmat.gas.raman.RotationalConstants(b, d=0.0, h=0.0)[source]#
Bases:
objectThe constants of one vibrational level’s rotational ladder, cm^-1.
- Attributes:
- bfloat
Rotational constant B.
- dfloat
Centrifugal distortion D.
- hfloat
Sextic distortion H.
- class optmat.gas.raman.SpinStatistics(even, odd, reason)[source]#
Bases:
objectThe nuclear-spin weights of the even and odd rotational levels.
- Attributes:
- evenint
Statistical weight of the even-J (or even-N) levels.
- oddint
Statistical weight of the odd levels.
- reasonstr
Where the weights come from.
- class optmat.gas.raman.VibrationalBand(mode, band_origin, transition_polarizability, lower, upper, widths, sources, resonance=None, reference_wavenumber=0.0, transition_anisotropy=None, depolarization=None, key='')[source]#
Bases:
objectOne vibrational Raman band (its Q branch).
- Attributes:
- modestr
The mode, as the curated data describe it.
- band_originfloat
nu_0, cm^-1.- transition_polarizabilityfloat
<0| alpha_mean |1>, C m^2/V.- lower, upperRotationalConstants or None
The rotational constants of the two vibrational levels (None for an unresolved band).
- widthsLinewidthLaw or LineTableLaw or ExponentialGapLaw
The width law of the lines.
- sourcesdict of str to str
The dataset or formula behind each parameter.
- resonancefloat or None
The effective resonance
nu_iof a single-resonance dispersion law, cm^-1: the element scales as1 / (nu_i^2 - nu_p^2)with the pump wavenumbernu_p(Bischel & Black 1983). None where no law is curated.- reference_wavenumberfloat
The pump wavenumber at which
transition_polarizabilityholds, cm^-1 (0 for a static value).- transition_anisotropyAnisotropyTable or None
<0J| alpha_par - alpha_perp |1J>per rotational level, C m^2/V, where the band’s elements are curated as components (H2, D2); None otherwise.- depolarizationfloat or None
The depolarization ratio of the Q branch for linearly polarised light at 90 degrees,
rho = 3 g^2 / (45 a^2 + 4 g^2), where one is curated (the value that reduced the cross sections, or the band’sdepolarizationkey); None where none is.- keystr
A short, stable name of the band (
v1,nu3,fermi_1388): the band of the Raman response’s lines and of their identifiers; the mode where none is curated.
- dispersion_factor(wavelength)[source]#
Return the factor on the transition polarizability at a pump wavelength.
- Parameters:
- wavelengthfloat or None
Vacuum wavelength of the pump, m; None for the element as curated.
- Returns:
- float
(nu_i^2 - nu_ref^2) / (nu_i^2 - nu_p^2), or 1 without a law or a wavelength.
- Raises:
- DataError
If the pump is at or beyond the effective resonance.
- lower: RotationalConstants | None#
- transition_anisotropy: AnisotropyTable | None = None#
- transition_polarizability: float | AnisotropyTable#
- upper: RotationalConstants | None#
- widths: LinewidthLaw | LineTableLaw | ExponentialGapLaw#
- optmat.gas.raman.band_lines(gas, temperature, density, fractions=None, *, wavelength=None, population_floor=1e-12)[source]#
Return a gas’s Raman lines band by band, with their widths, at a state.
The parameters are those of
raman_lines(), which joins these lines.- Parameters:
- gasGas or str
The gas.
- temperaturefloat
Temperature, K, > 0.
- densityfloat
Total number density, m^-3, > 0.
- fractionsmapping of str to float, optional
Mole fractions of the collision partners; the pure gas by default.
- wavelengthfloat, optional
Vacuum wavelength of the optical field, m, for the vibrational strengths’ dispersion.
- population_floorfloat, optional
Lines from levels less populated than this fraction are left out.
- Returns:
- tuple of BandLines
The rotational band (if any), then each vibrational band.
- optmat.gas.raman.default_j_max(constants, temperature)[source]#
Return the rotational level at about 50 k_B T, where the population is ~1e-20.
- Parameters:
- constantsRotationalConstants
The rotational constants, cm^-1.
- temperaturefloat
Temperature, K.
- Returns:
- int
sqrt(50 k_B T / B) + 5, at least 10.
Examples
>>> default_j_max(RotationalConstants(2.0), 295.0) 76
- optmat.gas.raman.raman_lines(gas, temperature, density, fractions=None, *, wavelength=None, population_floor=1e-12)[source]#
Return a gas’s Raman lines, with their widths, at a state.
- Parameters:
- gasGas or str
The gas.
- temperaturefloat
Temperature, K, > 0.
- densityfloat
Total number density, m^-3, > 0 (the widths depend on it; the amplitudes are per molecule).
- fractionsmapping of str to float, optional
Mole fractions of the collision partners (
selffor the gas itself); the pure gas by default.- wavelengthfloat, optional
Vacuum wavelength of the optical field, m: the vibrational strengths are scaled by their dispersion law where one is curated (TC-542). By default the strengths are as curated (static, or at the stated reference wavelength).
- population_floorfloat, optional
Lines from levels less populated than this fraction are left out.
- Returns:
- RamanLines
The rotational S-branch lines, then each vibrational band’s Q-branch lines, in the convention of this module.
- optmat.gas.raman.raman_parameters(gas)[source]#
Return the curated Raman parameters of a molecular gas.
- Parameters:
- gasGas or str
The gas.
- Returns:
- RamanParameters
Its bands, with the source of every parameter.
- Raises:
- DataError
If the gas has none (an atom, or a molecule not yet curated).
- optmat.gas.raman.rotational_lines(constants, spin, anisotropy, temperature, *, j_max=None, population_floor=1e-12)[source]#
Return the rotational S-branch lines of a linear molecule.
- Parameters:
- constantsRotationalConstants
The ground vibrational level’s constants, cm^-1.
- spinSpinStatistics
The nuclear-spin weights.
- anisotropyfloat or AnisotropyTable
Polarizability anisotropy
Delta alpha, C m^2/V, or its value per lower level.- temperaturefloat
Temperature, K, > 0.
- j_maxint, optional
The highest lower level considered; by default the level near 50 k_B T (
default_j_max()).- population_floorfloat, optional
Lines whose lower and upper populations are both below this fraction are dropped.
- Returns:
- RamanLines
One line per
J -> J + 2with a nonzero population difference.
- Raises:
- DataError
If the population at the highest level kept is not negligible.
Examples
With illustrative constants close to nitrogen’s (B = 2 cm^-1 and a polarizability anisotropy of 4.6 au), the line of largest amplitude at 295 K starts from J = 8 (an even level, which nitrogen’s spin statistics favour 2:1):
>>> from optmat.constants import AU_POLARIZABILITY >>> anisotropy = 4.6 * AU_POLARIZABILITY >>> lines = rotational_lines( ... RotationalConstants(2.0), spin_statistics("N2"), anisotropy, 295.0 ... ) >>> int(lines.j[np.argmax(lines.amplitude)]) 8
- optmat.gas.raman.rotational_nonlinear_index(lines, density)[source]#
Return the rotational Raman nonlinear index for a pulse long against the lines.
A pulse long against every rotational period sees the time integral of the response,
R0 = sum_J A_J Omega_J / (Omega_J^2 + Gamma_J^2). In the convention of this module the index change is thenN R0 I / (2 eps0 c)(n0 = 1). The response is slow, so a probe sees the same shift as the pulse itself (only the slowly varying part ofE^2drives it), unlike the instantaneous electronic response, whose probe coefficient is twice the self one.The integral is that of the coherent (Delta J = +-2) response. The isothermal, classical orientational response
Delta alpha^2 / (22.5 eps0 k_B T)is 4/3 larger at high temperature: it also contains the redistribution of the M sublevels within a level, which collisions establish but a coherent drive does not (TC-493).- Parameters:
- linesRamanLines
Lines with their widths (from
raman_lines()); only the S branch is used.- densityfloat
Number density of the gas, m^-3.
- Returns:
- float
n2, m^2/W.
- Raises:
- DataError
If the lines carry no widths.
- optmat.gas.raman.rotational_populations(constants, spin, temperature, j_max)[source]#
Return the fraction of molecules in each rotational level.
A truncated distortion series (
B x - D x^2) turns over at high J, where it no longer describes the molecule; the ladder is cut at its last increasing level, which the callers then require to be negligibly populated.- Parameters:
- constantsRotationalConstants
The ground vibrational level’s constants.
- spinSpinStatistics
The nuclear-spin weights.
- temperaturefloat
Temperature, K, > 0.
- j_maxint
The highest level wanted.
- Returns:
- tuple of numpy.ndarray
J = 0 ... min(j_max, the turning level)and the fractionP_Jof molecules in each (all2J + 1sublevels), summing to one.
- optmat.gas.raman.spin_statistics(gas)[source]#
Return the nuclear-spin weights of a linear molecule’s rotational levels.
- Parameters:
- gasGas or str
A linear molecule.
- Returns:
- SpinStatistics
The weights.
- Raises:
- DataError
If the gas is not a linear molecule (an atom, or a spherical top, which has no rotational Raman spectrum).
Examples
>>> weights = spin_statistics("N2") >>> weights.even, weights.odd (6, 3) >>> weights = spin_statistics("O2") >>> weights.even, weights.odd (0, 1)
- optmat.gas.raman.stokes_gain(lines, pump_wavelength, density)[source]#
Return the steady-state Stokes gain of each line, for a pump at its centre.
With a real pump field
E_pand Stokes fieldE_spolarised alike, the responseH(Delta) = int h(tau) exp(i Delta tau) d tauof one line at the Raman resonanceDelta = Omegaisi A / (2 Gamma). The Stokes polarisation(1/2) eps0 N |E_p|^2 E_s H*then gives the intensity gaing = omega_s N A / (2 c^2 eps0 Gamma), withGamma = pi FWHMandomega_s = omega_p - Omega. That is the plane-wave, narrow-band (steady-state) gain,dI_s / dz = g I_p I_s.- Parameters:
- linesRamanLines
Lines with their widths (from
raman_lines()).- pump_wavelengthfloat
Vacuum wavelength of the pump, m.
- densityfloat
Number density of the Raman-active gas, m^-3.
- Returns:
- numpy.ndarray
The gain of each line, m/W.
- Raises:
- DataError
If the lines carry no widths.
- optmat.gas.raman.vibrational_lines(band_origin, transition_polarizability, *, lower=None, upper=None, spin=None, temperature=296.0, j_max=None, population_floor=1e-12)[source]#
Return the vibrational Q-branch lines of a mode.
- Parameters:
- band_originfloat
The band origin
nu_0, cm^-1.- transition_polarizabilityfloat or AnisotropyTable
<0| alpha_mean |1>, C m^2/V, or its value per rotational level (the table’sJis the level of the Q(J) line).- lower, upperRotationalConstants, optional
The rotational constants of
v = 0andv = 1. Without them (a spherical top, or an unresolved band) the branch is one line at the band origin.- spinSpinStatistics, optional
The nuclear-spin weights; needed with the constants.
- temperaturefloat, optional
Temperature, K.
- j_maxint, optional
The highest rotational level considered; by default the level near 50 k_B T (
default_j_max()).- population_floorfloat, optional
Levels below this fraction are dropped.
- Returns:
- RamanLines
The Q(J) lines, or one line.
- Raises:
- DataError
If constants are given without spin weights, or the population at the highest level kept is not negligible.
Examples
With illustrative constants close to hydrogen’s (B = 60 cm^-1 in v = 0 and 57 cm^-1 in v = 1), Q(1) lies 2 (B_1 - B_0) = -6 cm^-1 from Q(0):
>>> lines = vibrational_lines( ... 4160.0, 1e-41, lower=RotationalConstants(60.0), ... upper=RotationalConstants(57.0), spin=spin_statistics("H2")) >>> f"{(lines.frequency[1] - lines.frequency[0]) / (2 * np.pi * C * 100):.1f}" '-6.0'