Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update spectrum class name from Spectrum1D to Spectrum #1126

Merged
merged 17 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ New Features
- Spectral axis can now be any axis, rather than being forced to be last. See docs
for more details. [#1033]

- Spectrum1D now properly handles GWCS input for wcs attribute. [#1074]
- Spectrum now properly handles GWCS input for wcs attribute. [#1074]

- JWST reader no longer transposes the input data cube for 3D data and retains
full GWCS information (including spatial). [#1074]

Other Changes and Additions
^^^^^^^^^^^^^^^^^^^^^^^^^^^

- Spectrum1D renamed to Spectrum. [#1126]

1.13.0 (2024-02-19)
-------------------

Expand Down
22 changes: 11 additions & 11 deletions docs/analysis.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ The specutils package comes with a set of tools for doing common analysis
tasks on astronomical spectra. Some examples of applying these tools are
described below. The basic spectrum shown here is used in the examples in the
sub-sections below - a gaussian-profile line with flux of 5 GHz Jy. See
:doc:`spectrum1d` for more on creating spectra:
:doc:`spectrum` for more on creating spectra:

.. plot::
:include-source: true
Expand All @@ -18,14 +18,14 @@ sub-sections below - a gaussian-profile line with flux of 5 GHz Jy. See
>>> from astropy import units as u
>>> from astropy.nddata import StdDevUncertainty
>>> from astropy.modeling import models
>>> from specutils import Spectrum1D, SpectralRegion
>>> from specutils import Spectrum, SpectralRegion
>>> np.random.seed(42)
>>> spectral_axis = np.linspace(11., 1., 200) * u.GHz
>>> spectral_model = models.Gaussian1D(amplitude=5*(2*np.pi*0.8**2)**-0.5*u.Jy, mean=5*u.GHz, stddev=0.8*u.GHz)
>>> flux = spectral_model(spectral_axis)
>>> flux += np.random.normal(0., 0.05, spectral_axis.shape) * u.Jy
>>> uncertainty = StdDevUncertainty(0.2*np.ones(flux.shape)*u.Jy)
>>> noisy_gaussian = Spectrum1D(spectral_axis=spectral_axis, flux=flux, uncertainty=uncertainty)
>>> noisy_gaussian = Spectrum(spectral_axis=spectral_axis, flux=flux, uncertainty=uncertainty)
>>> import matplotlib.pyplot as plt #doctest:+SKIP
>>> plt.step(noisy_gaussian.spectral_axis, noisy_gaussian.flux) #doctest:+SKIP

Expand All @@ -48,7 +48,7 @@ spectrum:


A second method to calculate SNR does not require the uncertainty defined
on the `~specutils.Spectrum1D` object. This computes the signal to noise
on the `~specutils.Spectrum` object. This computes the signal to noise
ratio DER_SNR following the definition set forth by the Spectral
Container Working Group of ST-ECF, MAST and CADC. This algorithm is described at
https://esahubble.org/static/archives/stecfnewsletters/pdf/hst_stecf_0042.pdf
Expand Down Expand Up @@ -257,15 +257,15 @@ An example of how to do template matching with an unknown redshift is:
>>> resample_method = "flux_conserving"
>>> rs_values = np.arange(min_redshift, max_redshift+delta_redshift, delta_redshift)

>>> observed_spectrum = Spectrum1D(spectral_axis=spec_axis*(1+observed_redshift), flux=np.random.randn(50) * u.Jy, uncertainty=StdDevUncertainty(np.random.sample(50), unit='Jy'))
>>> spectral_template = Spectrum1D(spectral_axis=spec_axis, flux=np.random.randn(50) * u.Jy, uncertainty=StdDevUncertainty(np.random.sample(50), unit='Jy'))
>>> observed_spectrum = Spectrum(spectral_axis=spec_axis*(1+observed_redshift), flux=np.random.randn(50) * u.Jy, uncertainty=StdDevUncertainty(np.random.sample(50), unit='Jy'))
>>> spectral_template = Spectrum(spectral_axis=spec_axis, flux=np.random.randn(50) * u.Jy, uncertainty=StdDevUncertainty(np.random.sample(50), unit='Jy'))
>>> tm_result = template_comparison.template_match(observed_spectrum=observed_spectrum, spectral_templates=spectral_template, resample_method=resample_method, redshift=rs_values) # doctest:+FLOAT_CMP


Dust extinction
---------------

Dust extinction can be applied to Spectrum1D instances via their internal arrays, using
Dust extinction can be applied to Spectrum instances via their internal arrays, using
the ``dust_extinction`` package (http://dust-extinction.readthedocs.io/en/latest)

Below is an example of how to apply extinction.
Expand All @@ -277,14 +277,14 @@ Below is an example of how to apply extinction.

wave = np.logspace(np.log10(1000), np.log10(3e4), num=10) * u.AA
flux = blackbody_lambda(wave, 10000 * u.K)
spec = Spectrum1D(spectral_axis=wave, flux=flux)
spec = Spectrum(spectral_axis=wave, flux=flux)

# define the model
ext = F99(Rv=3.1)

# extinguish (redden) the spectrum
flux_ext = spec.flux * ext.extinguish(spec.spectral_axis, Ebv=0.5)
spec_ext = Spectrum1D(spectral_axis=wave, flux=flux_ext)
spec_ext = Spectrum(spectral_axis=wave, flux=flux_ext)


Template Cross-correlation
Expand All @@ -311,8 +311,8 @@ value set.
>>> flux1 = f1 + g1(spec_axis)
>>> flux2 = f2 + g2(spec_axis)
>>> uncertainty = StdDevUncertainty(0.2*np.ones(size)*u.Jy)
>>> ospec = Spectrum1D(spectral_axis=spec_axis, flux=flux1, uncertainty=uncertainty, velocity_convention='optical', rest_value=rest_value)
>>> tspec = Spectrum1D(spectral_axis=spec_axis, flux=flux2, uncertainty=uncertainty)
>>> ospec = Spectrum(spectral_axis=spec_axis, flux=flux1, uncertainty=uncertainty, velocity_convention='optical', rest_value=rest_value)
>>> tspec = Spectrum(spectral_axis=spec_axis, flux=flux2, uncertainty=uncertainty)
>>> corr, lag = correlation.template_correlate(ospec, tspec)

The lag values are reported in km/s units. The correlation values are computed after the template spectrum is
Expand Down
12 changes: 6 additions & 6 deletions docs/arithmetic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ Arithmetic support includes addition, subtract, multiplication, and division.

.. code-block:: python

>>> from specutils import Spectrum1D
>>> from specutils import Spectrum
>>> import astropy.units as u
>>> import numpy as np

>>> rng = np.random.default_rng(12345)
>>> spec1 = Spectrum1D(spectral_axis=np.arange(1, 50) * u.nm, flux=rng.random(49)*u.Jy)
>>> spec2 = Spectrum1D(spectral_axis=np.arange(1, 50) * u.nm, flux=rng.random(49)*u.Jy)
>>> spec1 = Spectrum(spectral_axis=np.arange(1, 50) * u.nm, flux=rng.random(49)*u.Jy)
>>> spec2 = Spectrum(spectral_axis=np.arange(1, 50) * u.nm, flux=rng.random(49)*u.Jy)
>>> spec3 = spec1 + spec2
>>> spec3 # doctest: +FLOAT_CMP
<Spectrum1D(flux=[0.8559405665668484 ... 0.9711264429515736] Jy (shape=(49,), mean=0.91592 Jy); spectral_axis=<SpectralAxis
<Spectrum(flux=[0.8559405665668484 ... 0.9711264429515736] Jy (shape=(49,), mean=0.91592 Jy); spectral_axis=<SpectralAxis
(observer to target:
radial_velocity=0.0 km / s
redshift=0.0)
Expand All @@ -47,10 +47,10 @@ Arithmetic operations also support the propagation of unceratinty information.

>>> rng = np.random.default_rng(12345)
>>> wave = np.arange(10) * u.nm
>>> spec1 = Spectrum1D(spectral_axis=wave,
>>> spec1 = Spectrum(spectral_axis=wave,
... flux=rng.random(10)*u.Jy,
... uncertainty=StdDevUncertainty(rng.random(10) * 0.1))
>>> spec2 = Spectrum1D(spectral_axis=wave,
>>> spec2 = Spectrum(spectral_axis=wave,
... flux=rng.random(10)*u.Jy,
... uncertainty=StdDevUncertainty(rng.random(10) * 0.1))
>>> spec1.uncertainty
Expand Down
32 changes: 16 additions & 16 deletions docs/custom_loading.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,21 @@ a separate python file and place the file in their ``~/.specutils`` directory.
Loading from a FITS File
------------------------
A spectra with a *Linear Wavelength Solution* can be read using the ``read``
method of the :class:`~specutils.Spectrum1D` class to parse the file name and
method of the :class:`~specutils.Spectrum` class to parse the file name and
format


.. code-block:: python

import os
from specutils import Spectrum1D
from specutils import Spectrum

file_path = os.path.join('path/to/folder', 'file_with_1d_wcs.fits')

spec = Spectrum1D.read(file_path, format='wcs1d-fits')
spec = Spectrum.read(file_path, format='wcs1d-fits')


This will create a :class:`~specutils.Spectrum1D` object that you can manipulate later.
This will create a :class:`~specutils.Spectrum` object that you can manipulate later.

For instance, you could plot the spectrum.

Expand All @@ -51,7 +51,7 @@ Defining a custom loader consists of importing the
`~specutils.io.registers.data_loader` decorator from specutils and attaching
it to a function that knows how to parse the user's data. The return object
of this function must be an instance of one of the spectral classes
(:class:`~specutils.Spectrum1D`, :class:`~specutils.SpectrumCollection`,
(:class:`~specutils.Spectrum`, :class:`~specutils.SpectrumCollection`,
:class:`~specutils.SpectrumList`).

Optionally, the user may define an identifier function. This function acts to
Expand All @@ -69,11 +69,11 @@ ensure that the data file being loaded is compatible with the loader function.
from astropy.wcs import WCS

from specutils.io.registers import data_loader
from specutils import Spectrum1D
from specutils import Spectrum


# Define an optional identifier. If made specific enough, this circumvents the
# need to add ``format="my-format"`` in the ``Spectrum1D.read`` call.
# need to add ``format="my-format"`` in the ``Spectrum.read`` call.
def identify_generic_fits(origin, *args, **kwargs):
return (isinstance(args[0], str) and
os.path.splitext(args[0].lower())[1] == '.fits')
Expand All @@ -92,7 +92,7 @@ ensure that the data file being loaded is compatible with the loader function.
uncertainty = StdDevUncertainty(tab["err"])
data = tab["flux"] * Unit("Jy")

return Spectrum1D(flux=data, wcs=wcs, uncertainty=uncertainty, meta=meta)
return Spectrum(flux=data, wcs=wcs, uncertainty=uncertainty, meta=meta)


An ``extensions`` keyword can be provided. This allows for basic filename
Expand All @@ -109,17 +109,17 @@ with a particular extension.
loaders = get_loaders_by_extension('fits')

The returned list contains the format labels that can be fed into the ``format``
keyword argument of the ``Spectrum1D.read`` method.
keyword argument of the ``Spectrum.read`` method.

After placing this python file in the user's ``~/.specutils`` directory, it
can be utilized by referencing its name in the ``read`` method of the
:class:`~specutils.Spectrum1D` class
:class:`~specutils.Spectrum` class

.. code-block:: python

from specutils import Spectrum1D
from specutils import Spectrum

spec = Spectrum1D.read("path/to/data", format="my-format")
spec = Spectrum.read("path/to/data", format="my-format")

.. _multiple_spectra:

Expand All @@ -134,11 +134,11 @@ custom JWST data loader as an example:
.. literalinclude:: ../specutils/io/default_loaders/jwst_reader.py
:language: python

Note that by default, any loader that uses ``dtype=Spectrum1D`` will also
Note that by default, any loader that uses ``dtype=Spectrum`` will also
automatically add a reader for `~specutils.SpectrumList`. This enables user
code to call `specutils.SpectrumList.read <astropy.nddata.NDIOMixin.read>` in
all cases if it can't make assumptions about whether a loader returns one or
many `~specutils.Spectrum1D` objects. This method is available since
many `~specutils.Spectrum` objects. This method is available since
`~specutils.SpectrumList` makes use of the Astropy IO registry (see
`astropy.io.registry.read`).

Expand Down Expand Up @@ -171,11 +171,11 @@ This again will be done in a separate python file and placed in the user's

The custom writer can be used by passing the name of the custom writer to the
``format`` argument of the ``write`` method on the
:class:`~specutils.Spectrum1D`.
:class:`~specutils.Spectrum`.

.. code-block:: python

spec = Spectrum1D(flux=np.random.sample(100) * u.Jy,
spec = Spectrum(flux=np.random.sample(100) * u.Jy,
spectral_axis=np.arange(100) * u.AA)

spec.write("my_output.fits", format="fits-writer")
Expand Down
Loading
Loading