55
66import numpy as np
77from astropy .nddata import NDData
8+ from astropy .units import UnitTypeError
89from astropy import units as u
910from specutils import Spectrum1D
1011
1112from specreduce .core import _ImageParser
12- from specreduce .extract import _ap_weight_image , _to_spectrum1d_pixels
13+ from specreduce .extract import _ap_weight_image
1314from 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 """
0 commit comments