Post-process using SpecutilsΒΆ
Find peaks or uncertainties using the specutils library. A Radis Spectrum
object can easily be converted to a specutils specutils.spectra.spectrum1d.Spectrum1D
using to_specutils().
Below, we create a noisy spectrum based on a synthetic CO spectrum,
we convert it to specutils, add uncertainties by targeting a
noisy region, then determine the lines using find_lines_threshold() :
import astropy.units as u
import numpy as np
from radis import spectrum_test
""" We create a synthetic CO spectrum"""
s = (
spectrum_test(molecule="CO", wavenum_min=2000, wavenum_max=2030)
.apply_slit(1.5, "nm")
.take("radiance")
)
s.trim() # removes nans created by the slit convolution boundary effects
noise = np.random.normal(0.0, s.max().value * 0.03, len(s))
s_exp = s + noise
s_exp.plot()

--------------------------------------------------------------------------------
CO - HITRAN - Downloading database
--------------------------------------------------------------------------------
Download:
- All files already downloaded.
Caching to HDF5/H5 format:
- All files already cached.
Calculating Equilibrium Spectrum
Physical Conditions
----------------------------------------
Tgas 700 K
isotope 1,2,3
mole_fraction 0.1
path_length 1 cm
pressure 1.01325 bar
self_absorption True
species CO
state X
wavenum_max 2030.0000 cm-1
wavenum_min 2000.0000 cm-1
Computation Parameters
----------------------------------------
Tref 296 K
add_at_used numpy
broadening_method voigt
cutoff 1e-27 cm-1/(#.cm-2)
dbformat hitran
dbpath /home/docs/.radisdb/hitran/CO.h5
diluent air
folding_thresh 1e-06
include_neighbouring_lines True
isatom False
isneutral None
lbfunc None
memory_mapping_engine auto
neighbour_lines 0 cm-1
optimization simple
parsum_mode full summation
pfsource default
potential_lowering None
pseudo_continuum_threshold 0
sparse_ldm True
truncation 50 cm-1
waveunit cm-1
wstep 0.01 cm-1
zero_padding 3001
----------------------------------------
0.02s - Spectrum calculated
<matplotlib.lines.Line2D object at 0x7208578aea50>
Determine the noise level by selecting a noisy region from the graph above :
spectrum = s_exp.to_specutils()
from specutils import SpectralRegion
from specutils.manipulation import noise_region_uncertainty
from specutils.spectra import Spectrum1D
noise_region = SpectralRegion(2010.5 / u.cm, 2009.5 / u.cm)
spectrum = noise_region_uncertainty(spectrum, noise_region)
if not isinstance(spectrum, Spectrum1D):
spectrum = Spectrum1D(
flux=spectrum.flux,
spectral_axis=spectrum.spectral_axis,
uncertainty=getattr(spectrum, "uncertainty", None),
wcs=getattr(spectrum, "wcs", None),
mask=getattr(spectrum, "mask", None),
meta=getattr(spectrum, "meta", None),
)
/home/docs/checkouts/readthedocs.org/user_builds/radis/checkouts/master/radis/spectrum/spectrum.py:4372: AstropyDeprecationWarning: The Spectrum1D class is deprecated and may be removed in a future version.
Use Spectrum instead.
return Spectrum1D(
/home/docs/checkouts/readthedocs.org/user_builds/radis/conda/master/lib/python3.14/site-packages/astropy/nddata/mixins/ndslicing.py:68: AstropyDeprecationWarning: The Spectrum1D class is deprecated and may be removed in a future version.
Use Spectrum instead.
return self.__class__(**kwargs)
/home/docs/checkouts/readthedocs.org/user_builds/radis/conda/master/lib/python3.14/site-packages/specutils/spectra/spectrum.py:582: AstropyDeprecationWarning: The Spectrum1D class is deprecated and may be removed in a future version.
Use Spectrum instead.
return self.__class__(**alt_kwargs)
/home/docs/checkouts/readthedocs.org/user_builds/radis/checkouts/master/examples/2_Experimental_spectra/plot_specutils_processing.py:47: AstropyDeprecationWarning: The Spectrum1D class is deprecated and may be removed in a future version.
Use Spectrum instead.
spectrum = Spectrum1D(
Find lines :
from specutils.fitting import find_lines_threshold
lines = find_lines_threshold(spectrum, noise_factor=2)
print(lines)
s_exp.plot(lw=2, show_ruler=True)
import matplotlib.pyplot as plt
for line in lines.to_pandas().line_center.values:
plt.axvline(line, color="r", zorder=-1)
s.plot(nfig="same")
plt.axvspan(noise_region.lower.value, noise_region.upper.value, color="b", alpha=0.1)

/home/docs/checkouts/readthedocs.org/user_builds/radis/conda/master/lib/python3.14/site-packages/specutils/analysis/flux.py:289: AstropyUserWarning: Spectrum is not below the threshold signal-to-noise 0.01. This may indicate you have not continuum subtracted this spectrum (or that you have but it has high SNR features).
If you want to suppress this warning either type 'specutils.conf.do_continuum_function_check = False' or see http://docs.astropy.org/en/stable/config/#adding-new-configuration-items for other ways to configure the warning.
warnings.warn(message, AstropyUserWarning)
line_center line_type line_center_index
1 / cm
------------------ ---------- -----------------
2000.8899999999992 emission 28
2001.019999999999 emission 41
2001.119999999999 emission 51
2001.2999999999988 emission 69
2001.5299999999986 emission 92
2001.6899999999985 emission 108
2001.7699999999984 emission 116
2001.9399999999982 emission 133
2002.0199999999982 emission 141
... ... ...
2011.2199999999898 absorption 1061
2013.9799999999873 absorption 1337
2014.299999999987 absorption 1369
2014.8199999999865 absorption 1421
2015.0899999999863 absorption 1448
2017.3399999999842 absorption 1673
2017.469999999984 absorption 1686
2018.9999999999827 absorption 1839
2019.5599999999822 absorption 1895
2026.0199999999763 absorption 2541
Length = 290 rows
/home/docs/checkouts/readthedocs.org/user_builds/radis/checkouts/master/radis/tools/plot_tools.py:614: UserWarning: Couldn't add Ruler tool (still an experimental feature in RADIS : please report the error !)
warn(
<matplotlib.patches.Rectangle object at 0x72085f1039d0>
Note: we can also create a RADIS spectrum object from Specutils
specutils.spectra.spectrum1d.Spectrum1D :
from radis import Spectrum
s2 = Spectrum.from_specutils(spectrum)
s2.plot(Iunit="mW/cm2/sr/nm", wunit="nm")
s_exp.plot(Iunit="mW/cm2/sr/nm", wunit="nm", nfig="same")
assert s_exp == s2

Total running time of the script: (0 minutes 1.518 seconds)