Skip to content

Commit 3fbd99d

Browse files
committed
Fixed Spectrum1D parsing in Background and tests
1 parent 4276526 commit 3fbd99d

File tree

3 files changed

+54
-34
lines changed

3 files changed

+54
-34
lines changed

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ python_requires = >=3.7
1818
setup_requires = setuptools_scm
1919
install_requires =
2020
astropy
21-
specutils
21+
specutils>=1.7
2222
synphot
2323
matplotlib
2424
photutils

specreduce/background.py

Lines changed: 47 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@
55

66
import numpy as np
77
from astropy.nddata import NDData
8+
from astropy.units import UnitTypeError
89
from astropy import units as u
910
from specutils import Spectrum1D
1011

1112
from specreduce.core import _ImageParser
12-
from specreduce.extract import _ap_weight_image, _to_spectrum1d_pixels
13+
from specreduce.extract import _ap_weight_image
1314
from specreduce.tracing import Trace, FlatTrace
1415

1516
__all__ = ['Background']
@@ -155,8 +156,10 @@ def two_sided(cls, image, trace_object, separation, **kwargs):
155156
Parameters
156157
----------
157158
image : `~astropy.nddata.NDData`-like or array-like
158-
image with 2-D spectral image data
159-
trace_object: Trace
159+
Image with 2-D spectral image data. Assumes cross-dispersion
160+
(spatial) direction is axis 0 and dispersion (wavelength)
161+
direction is axis 1.
162+
trace_object: `~specreduce.tracing.Trace`
160163
estimated trace of the spectrum to center the background traces
161164
separation: float
162165
separation from ``trace_object`` for the background regions
@@ -171,6 +174,7 @@ def two_sided(cls, image, trace_object, separation, **kwargs):
171174
crossdisp_axis : int
172175
cross-dispersion axis
173176
"""
177+
image = cls._parse_image(cls, image)
174178
kwargs['traces'] = [trace_object-separation, trace_object+separation]
175179
return cls(image=image, **kwargs)
176180

@@ -188,8 +192,10 @@ def one_sided(cls, image, trace_object, separation, **kwargs):
188192
Parameters
189193
----------
190194
image : `~astropy.nddata.NDData`-like or array-like
191-
image with 2-D spectral image data
192-
trace_object: Trace
195+
Image with 2-D spectral image data. Assumes cross-dispersion
196+
(spatial) direction is axis 0 and dispersion (wavelength)
197+
direction is axis 1.
198+
trace_object: `~specreduce.tracing.Trace`
193199
estimated trace of the spectrum to center the background traces
194200
separation: float
195201
separation from ``trace_object`` for the background, positive will be
@@ -205,6 +211,7 @@ def one_sided(cls, image, trace_object, separation, **kwargs):
205211
crossdisp_axis : int
206212
cross-dispersion axis
207213
"""
214+
image = cls._parse_image(cls, image)
208215
kwargs['traces'] = [trace_object+separation]
209216
return cls(image=image, **kwargs)
210217

@@ -214,28 +221,32 @@ def bkg_image(self, image=None):
214221
215222
Parameters
216223
----------
217-
image : nddata-compatible image or None
218-
image with 2-D spectral image data. If None, will extract
219-
the background from ``image`` used to initialize the class.
224+
image : `~astropy.nddata.NDData`-like or array-like, optional
225+
Image with 2-D spectral image data. Assumes cross-dispersion
226+
(spatial) direction is axis 0 and dispersion (wavelength)
227+
direction is axis 1. If None, will extract the background
228+
from ``image`` used to initialize the class. [default: None]
220229
221230
Returns
222231
-------
223-
array with same shape as ``image``.
232+
Spectrum1D object with same shape as ``image``.
224233
"""
225-
if image is None:
226-
image = self.image
227-
228-
return np.tile(self.bkg_array, (image.shape[0], 1))
234+
image = self._parse_image(image)
235+
return Spectrum1D(np.tile(self.bkg_array,
236+
(image.shape[0], 1)) * image.unit,
237+
spectral_axis=image.spectral_axis)
229238

230239
def bkg_spectrum(self, image=None):
231240
"""
232241
Expose the 1D spectrum of the background.
233242
234243
Parameters
235244
----------
236-
image : nddata-compatible image or None
237-
image with 2-D spectral image data. If None, will extract
238-
the background from ``image`` used to initialize the class.
245+
image : `~astropy.nddata.NDData`-like or array-like, optional
246+
Image with 2-D spectral image data. Assumes cross-dispersion
247+
(spatial) direction is axis 0 and dispersion (wavelength)
248+
direction is axis 1. If None, will extract the background
249+
from ``image`` used to initialize the class. [default: None]
239250
240251
Returns
241252
-------
@@ -244,10 +255,15 @@ def bkg_spectrum(self, image=None):
244255
units as the input image (or u.DN if none were provided) and
245256
the spectral axis expressed in pixel units.
246257
"""
247-
bkg_image = self.bkg_image(image=image)
258+
bkg_image = self.bkg_image(image)
248259

249-
ext1d = np.sum(bkg_image, axis=self.crossdisp_axis)
250-
return _to_spectrum1d_pixels(ext1d * getattr(image, 'unit', u.DN))
260+
try:
261+
return bkg_image.collapse(np.sum, axis=self.crossdisp_axis)
262+
except UnitTypeError:
263+
# can't collapse with a spectral axis in pixels because
264+
# SpectralCoord only allows frequency/wavelength equivalent units...
265+
ext1d = np.sum(bkg_image.flux, axis=self.crossdisp_axis)
266+
return Spectrum1D(ext1d, bkg_image.spectral_axis)
251267

252268
def sub_image(self, image=None):
253269
"""
@@ -263,14 +279,12 @@ def sub_image(self, image=None):
263279
-------
264280
array with same shape as ``image``
265281
"""
266-
if image is None:
267-
image = self.image
282+
image = self._parse_image(image)
268283

269-
if isinstance(image, NDData):
270-
# https://docs.astropy.org/en/stable/nddata/mixins/ndarithmetic.html
271-
return image.subtract(self.bkg_image(image)*image.unit)
272-
else:
273-
return image - self.bkg_image(image)
284+
# https://docs.astropy.org/en/stable/nddata/mixins/ndarithmetic.html
285+
# (compare_wcs argument needed to avoid TypeError from SpectralCoord
286+
# when image's spectral axis is in pixels)
287+
return image.subtract(self.bkg_image(image), compare_wcs=None)
274288

275289
def sub_spectrum(self, image=None):
276290
"""
@@ -291,8 +305,13 @@ def sub_spectrum(self, image=None):
291305
"""
292306
sub_image = self.sub_image(image=image)
293307

294-
ext1d = np.sum(sub_image, axis=self.crossdisp_axis)
295-
return _to_spectrum1d_pixels(ext1d * getattr(image, 'unit', u.DN))
308+
try:
309+
return sub_image.collapse(np.sum, axis=self.crossdisp_axis)
310+
except UnitTypeError:
311+
# can't collapse with a spectral axis in pixels because
312+
# SpectralCoord only allows frequency/wavelength equivalent units...
313+
ext1d = np.sum(sub_image.flux, axis=self.crossdisp_axis)
314+
return Spectrum1D(ext1d, spectral_axis=sub_image.spectral_axis)
296315

297316
def __rsub__(self, image):
298317
"""

specreduce/tests/test_background.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import numpy as np
33

44
import astropy.units as u
5-
from astropy.nddata import CCDData
5+
from astropy.nddata import CCDData, VarianceUncertainty
66
from specutils import Spectrum1D
77

88
from specreduce.background import Background
@@ -16,7 +16,8 @@
1616
image = np.ones(shape=(30, 10))
1717
for j in range(image.shape[0]):
1818
image[j, ::] *= j
19-
image = CCDData(image, unit=u.Jy)
19+
image = Spectrum1D(image * u.DN,
20+
uncertainty=VarianceUncertainty(np.ones_like(image)))
2021

2122

2223
def test_background():
@@ -45,16 +46,16 @@ def test_background():
4546
sub1 = image - bg1
4647
sub2 = bg1.sub_image(image)
4748
sub3 = bg1.sub_image()
48-
assert np.allclose(sub1, sub2)
49-
assert np.allclose(sub1, sub3)
49+
assert np.allclose(sub1.flux, sub2.flux)
50+
assert np.allclose(sub1.flux, sub3.flux)
5051

5152
bkg_spec = bg1.bkg_spectrum()
5253
assert isinstance(bkg_spec, Spectrum1D)
5354
sub_spec = bg1.sub_spectrum()
5455
assert isinstance(sub_spec, Spectrum1D)
5556
# test that width==0 results in no background
5657
bg = Background.two_sided(image, trace, bkg_sep, width=0)
57-
assert np.all(bg.bkg_image() == 0)
58+
assert np.all(bg.bkg_image().flux == 0)
5859

5960

6061
def test_warnings_errors():

0 commit comments

Comments
 (0)