1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
|
.. the "raw" directive below is used to hide the title in favor of just the logo being visible
.. raw:: html
<style media="screen" type="text/css">
h1 { display:none; }
</style>
***********************
Specutils Documentation
***********************
.. _specutils:
.. image:: _static/logo.png
``specutils`` is a Python package for representing, loading,
manipulating, and analyzing astronomical spectroscopic data. The
generic data containers and accompanying modules provide a toolbox that the
astronomical community can use to build more domain-specific packages. For more
details about the underlying principles, see
`APE13 <https://github.com/astropy/astropy-APEs/blob/main/APE13.rst>`_, the
guiding document for spectroscopic development in the Astropy Project.
Changes in version 2
====================
The ``Spectrum1D`` class has been renamed to `~specutils.Spectrum` to reduce confusion
about multi-dimensional flux arrays being supported. The current class name will be
deprecated in version 2.1; importing the old name will work but raise a deprecation
warning until then.
Single-dimensional flux use cases should be mostly unchanged in 2.0, with the exception
being that spectrum arithmetic now checks that the spectral axis of both operands are
equal, rather than simply checking that they are the same length. Thus, you will need
to resample onto a common spectral axis if doing arithmetic on spectra with differing
spectral axes.
Specutils version 2 implemented a major change in that `~specutils.Spectrum`
no longer forces the spectral axis to be last for multi-dimensional data. This
was motivated by the desire for greater flexibility to allow for interoperability
with other packages that may wish to use ``specutils`` classes as the basis for
their own, and by the desire for consistency with the axis order that results
from a simple ``astropy.io.fits.read`` of a file. The legacy behavior can be
replicated by setting ``move_spectral_axis='last'`` when creating a new
`~specutils.Spectrum` object. `~specutils.Spectrum` will attempt to automatically
determine which flux axis corresponds to the spectral axis during initialization
based on the WCS (if provided) or the shape of the flux and spectral axis arrays,
but if the spectral axis index is unable to be automatically determined you will
need to specify which flux array axis is the dispersion axis with the
``spectral_axis_index`` keyword. Note that since the ``spectral_axis`` can specify
either bin edges or bin centers, a flux array of shape ``(10,11)`` with spectral axis
of length 11 would be ambigious. In this case you could initialize a
`~specutils.Spectrum` with ``bin_specification`` set to either "edges" or "centers"
to break the degeneracy.
An additional change for multi-dimensional spectra is that previously, initializing
such a `~specutils.Spectrum` with a ``spectral_axis`` specified, but no WCS, would
create a `~specutils.Spectrum` instance with a one-dimensional GWCS that was essentially
a lookup table with the spectral axis values. This case will now result in a GWCS with
dimensionality matching that of the flux array to facilitate use with downstream packages
that expect WCS dimensionality to match that of the data. The resulting spatial axes
transforms are simple pixel to pixel identity operations, since no actual spatial
coordinate information is available.
In addition to the changes to the generated GWCS, handling of input GWCS has also been
improved. This mostly manifests in the full GWCS (including spatial information) being
retained in the resulting `~specutils.Spectrum` objects when reading, e.g., JWST spectral
cubes.
For a summary of the changes in version 2, you many also refer to the
`release notes <https://github.com/astropy/specutils/releases>`_.
Getting started with :ref:`specutils <specutils>`
=================================================
As a basic example, consider an emission line galaxy spectrum from the
`SDSS <https://www.sdss.org/>`_. We will use this as a proxy for a spectrum you
may have downloaded from some archive, or reduced from your own observations.
.. plot::
:include-source:
:align: center
:context: close-figs
We begin with some basic imports:
>>> from astropy.io import fits
>>> from astropy import units as u
>>> import numpy as np
>>> from matplotlib import pyplot as plt
>>> from astropy.visualization import quantity_support
>>> quantity_support() # for getting units on the axes below # doctest: +IGNORE_OUTPUT
Now we load the dataset from its canonical source:
>>> filename = 'https://data.sdss.org/sas/dr16/sdss/spectro/redux/26/spectra/1323/spec-1323-52797-0012.fits'
>>> # The spectrum is in the second HDU of this file.
>>> with fits.open(filename) as f: # doctest: +IGNORE_OUTPUT +REMOTE_DATA
... specdata = f[1].data # doctest: +REMOTE_DATA
Then we re-format this dataset into astropy quantities, and create a
`~specutils.Spectrum` object:
>>> from specutils import Spectrum
>>> lamb = 10**specdata['loglam'] * u.AA # doctest: +REMOTE_DATA
>>> flux = specdata['flux'] * 10**-17 * u.Unit('erg cm-2 s-1 AA-1') # doctest: +REMOTE_DATA
>>> spec = Spectrum(spectral_axis=lamb, flux=flux) # doctest: +REMOTE_DATA
And we plot it:
>>> f, ax = plt.subplots() # doctest: +IGNORE_OUTPUT +REMOTE_DATA
>>> ax.step(spec.spectral_axis, spec.flux) # doctest: +IGNORE_OUTPUT +REMOTE_DATA
.. testsetup::
>>> fig = plt.figure() # necessary because otherwise the doctests fail due to quantity_support and the flux units being different from the last figure
.. plot::
:include-source:
:align: center
:context: close-figs
Now maybe you want the equivalent width of a spectral line. That requires
normalizing by a continuum estimate:
>>> import warnings
>>> from specutils.fitting import fit_generic_continuum
>>> with warnings.catch_warnings(): # Ignore warnings
... warnings.simplefilter('ignore')
... cont_norm_spec = spec / fit_generic_continuum(spec)(spec.spectral_axis) # doctest: +REMOTE_DATA
>>> f, ax = plt.subplots() # doctest: +IGNORE_OUTPUT +REMOTE_DATA
>>> ax.step(cont_norm_spec.wavelength, cont_norm_spec.flux) # doctest: +IGNORE_OUTPUT +REMOTE_DATA
>>> ax.set_xlim(654 * u.nm, 660 * u.nm) # doctest: +IGNORE_OUTPUT +REMOTE_DATA
But then you can apply a single function over the region of the spectrum
containing the line:
>>> from specutils import SpectralRegion
>>> from specutils.analysis import equivalent_width
>>> equivalent_width(cont_norm_spec, regions=SpectralRegion(6562 * u.AA, 6575 * u.AA)) # doctest: +REMOTE_DATA +FLOAT_CMP
<Quantity -14.82013888 Angstrom>
While there are other tools and spectral representations detailed more below,
this gives a test of the sort of analysis :ref:`specutils <specutils>` enables.
Using :ref:`specutils <specutils>`
==================================
For more details on usage of specutils, see the sections listed below.
.. toctree::
:maxdepth: 2
installation
types_of_spectra
spectrum
spectrum_collection
spectral_cube
spectral_regions
analysis
fitting
manipulation
arithmetic
wcs_utils
custom_loading
identify
Get Involved - Developer Docs
-----------------------------
Please see :doc:`contributing` for information on bug reporting and
contributing to the specutils project.
.. toctree::
:maxdepth: 2
contributing
releasing
|