astropy / specutils

An Astropy coordinated package for astronomical spectroscopy. Maintainers: @rosteen @keflavich @eteq
http://specutils.readthedocs.io/en/latest/
170 stars 127 forks source link

LinearInterpolatedResampler fails on uncertainty of UnknownUncertainty type #648

Open dhomeier opened 4 years ago

dhomeier commented 4 years ago

When (unsuccessfully) trying to reproduce #647 I raised a different exception by modifying the docs' example:

input_spectrum = Spectrum1D(flux=[1, 3, 7, 6, 20] * u.mJy,
                            spectral_axis=[2, 4, 12, 16, 20] * u.nm,
                            uncertainty=[0.4, 0.5, 0.6, 0.8, 1])
resample_grid = [1, 5, 9, 13, 14, 17, 21, 22, 23] * u.nm                                                                                                                        
fluxc_resample = LinearInterpolatedResampler()

input_spectrum.uncertainty                                                                                                                                                      
    UnknownUncertainty([0.4, 0.5, 0.6, 0.8, 1. ])
output_spectrum1D = fluxc_resample(input_spectra, resample_grid)

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-153-d2ada17e1ff7> in <module>
----> 1 output_spectrum1D = fluxc_resample(input_spectrum, resample_grid)

~/lib/python3.8/site-packages/specutils/manipulation/resample.py in __call__(self, orig_spectrum, fin_spec_axis)
     37         Return the resulting `~specutils.Spectrum1D` of the resampling.
     38         """
---> 39         return self.resample1d(orig_spectrum, fin_spec_axis)
     40 
     41     @abstractmethod

~/lib/python3.8/site-packages/specutils/manipulation/resample.py in resample1d(self, orig_spectrum, fin_spec_axis)
    321                                                           unit=orig_spectrum.unit)
    322 
--> 323         return Spectrum1D(spectral_axis=fin_spec_axis,
    324                           flux=out_flux,
    325                           uncertainty=new_unc)

~/lib/python3.8/site-packages/specutils/spectra/spectrum1d.py in __init__(self, flux, spectral_axis, wcs, velocity_convention, rest_value, redshift, radial_velocity, **kwargs)
    157                         spectral_axis.shape[0], flux.shape[-1]))
    158 
--> 159         super(Spectrum1D, self).__init__(
    160             data=flux.value if isinstance(flux, u.Quantity) else flux,
    161             wcs=wcs, **kwargs)

~/lib/python3.8/site-packages/astropy/nddata/nddata.py in __init__(self, data, uncertainty, mask, wcs, meta, unit, copy)
    232         self._unit = unit
    233         # Call the setter for uncertainty to further check the uncertainty
--> 234         self.uncertainty = uncertainty
    235 
    236     def __str__(self):

~/lib/python3.8/site-packages/astropy/nddata/nddata.py in uncertainty(self, value)
    324                 # to be saved as weakref but that's done by NDUncertainty
    325                 # setter).
--> 326                 value.parent_nddata = self
    327         self._uncertainty = value

~/lib/python3.8/site-packages/astropy/nddata/nduncertainty.py in parent_nddata(self, value)
    231                 unit_from_data = self._data_unit_to_uncertainty_unit(parent_unit)
    232                 try:
--> 233                     unit_from_data.to(self.unit)
    234                 except UnitConversionError:
    235                     raise UnitConversionError("Unit {} of uncertainty "

AttributeError: 'NoneType' object has no attribute 'to'

Is there other functionality that would handle an astropy.nddata.nduncertainty.UnknownUncertainty correctly, or should this best be checked on initialising Spectrum1D?

nmearl commented 4 years ago

We're discussing ways to make the uncertainty creation easier, but currently, you should be initializing the Spectrum1D with an explicit uncertainty class in order for everything to Just Work™️

from astropy.nddata import StdDevUncertainty

input_spectrum = Spectrum1D(flux=[1, 3, 7, 6, 20] * u.mJy,
                            spectral_axis=[2, 4, 12, 16, 20] * u.nm,
                            uncertainty=StdDevUncertainty([0.4, 0.5, 0.6, 0.8, 1]))
resample_grid = [1, 5, 9, 13, 14, 17, 21, 22, 23] * u.nm                                                                                                                        
fluxc_resample = LinearInterpolatedResampler()
dhomeier commented 4 years ago

We're discussing ways to make the uncertainty creation easier, but currently, you should be initializing the Spectrum1D with an explicit uncertainty class in order for everything to Just Work™️

Yes, was just wondering if incorrect instantiation should be intercepted earlier – e.g. adding an additional check for uncertainty_type to if hasattr(self, 'uncertainty') and self.uncertainty is not None: ...

But an optional keyword like uncertainty_type='std' would be convenient, too.

nmearl commented 4 years ago

Indeed. See #529 for some early discussion. Most recent discussion has happened out-of-band.

kelle commented 2 years ago

I was also unable to write out a spectrum with an uncertainty of UnknownUncertainty type.