SingleSpeciesAbsorption

 1import pyarts
 2import numpy as np
 3import matplotlib.pyplot as plt
 4
 5# %% Select a strong absorption line for one species
 6species = "O2-66"  # Main isotope of O2
 7line_f0 = 118750348044.712  # Lowest energy absorption line
 8f = np.linspace(-500e6, 500e6, 1001) + line_f0  # Some range around it
 9
10# %% Activate the recipe for this species
11absorption = pyarts.recipe.SingleSpeciesAbsorption(species=species)
12
13# Single temperature, some range of pressures
14atm = pyarts.arts.AtmPoint()
15atm.set_species_vmr("O2", 0.2095)
16atm.temperature = 273
17ps = np.logspace(5, -2, 8)
18
19# %% Use the recipe and convert the results to cross-sections
20xsec = []
21for p in ps:
22    atm.pressure = p
23    xsec.append(absorption(f, atm) / atm.number_density(species))
24xsec = np.array(xsec)
25
26# %% Plot the results
27plt.semilogy((f - line_f0) / 1e6, xsec.T)
28plt.xlabel("Frequency offset [MHz]")
29plt.ylabel("Cross-section [$m^2$]")
30plt.title("Cross-section of O$_2$ 16-16")
31plt.ylim(ymin=1e-3 * np.min(xsec))
32plt.legend(
33    [f"P: $10^{'{'}{round(np.log10(x))}{'}'}$" for x in ps],
34    ncols=4,
35    loc="lower center",
36)
37
38# %% Integration test by ensuring some statistics look good
39assert np.isclose(6.7940695853245560e-28 / xsec.mean(), 1)
40assert np.isclose(5.4406909239279050e-24 / xsec.sum(), 1)
41assert np.isclose(1.3361953365612772e-24 / xsec.max(), 1)
42assert np.isclose(2.5383142016771395e-26 / xsec.std(), 1)
43assert np.isclose(8.2386317491421410e-35 / xsec.min(), 1)