Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
raise u.UnitsError("Rest value must be "
"energy/wavelength/frequency equivalent.")
# Attempt to parse the spectral axis. If none is given, try instead to
# parse a given wcs. This is put into a GWCS object to
# then be used behind-the-scenes for all specutils operations.
if spectral_axis is not None:
# Ensure that the spectral axis is an astropy Quantity
if not isinstance(spectral_axis, u.Quantity):
raise ValueError("Spectral axis must be a `Quantity` or "
"`SpectralCoord` object.")
# If spectral axis is provided as an astropy Quantity, convert it
# to a specutils SpectralCoord object.
if not isinstance(spectral_axis, SpectralCoord):
self._spectral_axis = SpectralCoord(
spectral_axis, redshift=redshift,
radial_velocity=radial_velocity, doppler_rest=rest_value,
doppler_convention=velocity_convention)
# If a SpectralCoord object is provided, we assume it doesn't need
# information from other keywords added
else:
for a in [radial_velocity, redshift]:
if a is not None:
raise ValueError("Cannot separately set redshift or "
"radial_velocity if a SpectralCoord "
"object is input to spectral_axis")
self._spectral_axis = spectral_axis
wcs = gwcs_from_array(spectral_axis)
elif wcs is None:
import warnings
import astropy.units as u
from astropy.utils.decorators import lazyproperty
import numpy as np
from .spectral_coordinate import SpectralCoord
__all__ = ['SpectralAxis']
# We don't want to run doctests in the docstrings we inherit from Quantity
__doctest_skip__ = ['SpectralAxis.*']
class SpectralAxis(SpectralCoord):
"""
Coordinate object representing spectral values corresponding to a specific
spectrum. Overloads SpectralCoord with additional information (currently
only bin edges).
Parameters
----------
bin_specification: str, optional
Must be "edges" or "centers". Determines whether specified axis values
are interpreted as bin edges or bin centers. Defaults to "centers".
"""
def __new__(cls, value, *args, bin_specification="centers", **kwargs):
# Convert to bin centers if bin edges were given, since SpectralCoord
# only accepts centers
and not rest_value.unit.is_equivalent(u.Hz):
raise u.UnitsError("Rest value must be "
"energy/wavelength/frequency equivalent.")
# Attempt to parse the spectral axis. If none is given, try instead to
# parse a given wcs. This is put into a GWCS object to
# then be used behind-the-scenes for all specutils operations.
if spectral_axis is not None:
# Ensure that the spectral axis is an astropy Quantity
if not isinstance(spectral_axis, u.Quantity):
raise ValueError("Spectral axis must be a `Quantity` or "
"`SpectralCoord` object.")
# If spectral axis is provided as an astropy Quantity, convert it
# to a specutils SpectralCoord object.
if not isinstance(spectral_axis, SpectralCoord):
self._spectral_axis = SpectralCoord(
spectral_axis, redshift=redshift,
radial_velocity=radial_velocity, doppler_rest=rest_value,
doppler_convention=velocity_convention)
# If a SpectralCoord object is provided, we assume it doesn't need
# information from other keywords added
else:
for a in [radial_velocity, redshift]:
if a is not None:
raise ValueError("Cannot separately set redshift or "
"radial_velocity if a SpectralCoord "
"object is input to spectral_axis")
self._spectral_axis = spectral_axis
wcs = gwcs_from_array(spectral_axis)
"Spectral axis ({}) and the last flux axis ({}) lengths "
"must be the same.".format(
spectral_axis.shape[0], flux.shape[-1]))
super(Spectrum1D, self).__init__(
data=flux.value if isinstance(flux, u.Quantity) else flux,
wcs=wcs, **kwargs)
# If no spectral_axis was provided, create a SpectralCoord based on
# the WCS
if spectral_axis is None:
# If spectral_axis wasn't provided, set _spectral_axis based on
# the WCS
spec_axis = self.wcs.pixel_to_world(np.arange(self.flux.shape[-1]))
self._spectral_axis = SpectralCoord(
spec_axis,
redshift=redshift, radial_velocity=radial_velocity,
doppler_rest=rest_value,
doppler_convention=velocity_convention)
if hasattr(self, 'uncertainty') and self.uncertainty is not None:
if not flux.shape == self.uncertainty.array.shape:
raise ValueError(
"Flux axis ({}) and uncertainty ({}) shapes must be the "
"same.".format(flux.shape, self.uncertainty.array.shape))
# Compose multi-dimensional ndarrays for each property
flux = u.Quantity([spec.flux for spec in spectra])
# Check that the spectral parameters are the same for each input
# spectral_axis and create the multi-dimensional SpectralCoord
sa = [x.spectral_axis for x in spectra]
if not all(x.radial_velocity == sa[0].radial_velocity for x in sa) or \
not all(x.target == sa[0].target for x in sa) or \
not all(x.observer == sa[0].observer for x in sa) or \
not all(x.doppler_convention == sa[0].doppler_convention for
x in sa) or \
not all(x.doppler_rest == sa[0].doppler_rest for x in sa):
raise ValueError("All input spectral_axis SpectralCoord "
"objects must have the same parameters.")
spectral_axis = SpectralCoord(sa,
radial_velocity=sa[0].radial_velocity,
doppler_rest=sa[0].doppler_rest,
doppler_convention=sa[0].doppler_convention,
observer=sa[0].observer,
target=sa[0].target)
# Check that either all spectra have associated uncertainties, or that
# none of them do. If only some do, log an error and ignore the
# uncertainties.
if not all((x.uncertainty is None for x in spectra)) and \
any((x.uncertainty is not None for x in spectra)) and \
all((x.uncertainty.uncertainty_type ==
spectra[0].uncertainty.uncertainty_type
for x in spectra)):
quncs = u.Quantity([spec.uncertainty.quantity for spec in spectra])
def __init__(self, flux, spectral_axis=None, wcs=None, uncertainty=None,
mask=None, meta=None):
# Check for quantity
if not isinstance(flux, u.Quantity):
raise u.UnitsError("Flux must be a `Quantity`.")
if spectral_axis is not None:
if not isinstance(spectral_axis, u.Quantity):
raise u.UnitsError("Spectral axis must be a `Quantity`.")
spectral_axis = SpectralCoord(spectral_axis)
# Ensure that the input values are the same shape
if not (flux.shape == spectral_axis.shape):
raise ValueError("Shape of all data elements must be the same.")
if uncertainty is not None and uncertainty.array.shape != flux.shape:
raise ValueError("Uncertainty must be the same shape as flux and "
"spectral axis.")
if mask is not None and mask.shape != flux.shape:
raise ValueError("Mask must be the same shape as flux and "
"spectral axis.")
# Convert uncertainties to standard deviations if not already defined
# to be of some type
if uncertainty is not None and not isinstance(uncertainty, NDUncertainty):