Skip to content

Commit cfe8bb5

Browse files
committed
Better handled Spectrum1D images across classes
1 parent 44d3533 commit cfe8bb5

File tree

3 files changed

+49
-23
lines changed

3 files changed

+49
-23
lines changed

specreduce/background.py

+9-4
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class Background:
2727
2828
Parameters
2929
----------
30-
image : `~astropy.nddata.NDData` or array-like
30+
image : `~astropy.nddata.NDData`-like or array-like
3131
image with 2-D spectral image data
3232
traces : List
3333
list of trace objects (or integers to define FlatTraces) to
@@ -60,7 +60,7 @@ def __post_init__(self):
6060
6161
Parameters
6262
----------
63-
image : `~astropy.nddata.NDData` or array-like
63+
image : `~astropy.nddata.NDData`-like or array-like
6464
image with 2-D spectral image data
6565
traces : List
6666
list of trace objects (or integers to define FlatTraces) to
@@ -86,6 +86,11 @@ def _to_trace(trace):
8686
raise ValueError('trace_object.trace_pos must be >= 1')
8787
return trace
8888

89+
if isinstance(self.image, NDData):
90+
# NOTE: should the NDData structure instead be preserved?
91+
# (NDData includes Spectrum1D under its umbrella)
92+
self.image = self.image.data
93+
8994
bkg_wimage = np.zeros_like(self.image, dtype=np.float64)
9095
for trace in self.traces:
9196
trace = _to_trace(trace)
@@ -133,7 +138,7 @@ def two_sided(cls, image, trace_object, separation, **kwargs):
133138
134139
Parameters
135140
----------
136-
image : nddata-compatible image
141+
image : `~astropy.nddata.NDData`-like or array-like
137142
image with 2-D spectral image data
138143
trace_object: Trace
139144
estimated trace of the spectrum to center the background traces
@@ -166,7 +171,7 @@ def one_sided(cls, image, trace_object, separation, **kwargs):
166171
167172
Parameters
168173
----------
169-
image : nddata-compatible image
174+
image : `~astropy.nddata.NDData`-like or array-like
170175
image with 2-D spectral image data
171176
trace_object: Trace
172177
estimated trace of the spectrum to center the background traces

specreduce/extract.py

+24-15
Original file line numberDiff line numberDiff line change
@@ -122,15 +122,15 @@ class BoxcarExtract(SpecreduceOperation):
122122
123123
Parameters
124124
----------
125-
image : nddata-compatible image
125+
image : `~astropy.nddata.NDData`-like or array-like, required
126126
image with 2-D spectral image data
127-
trace_object : Trace
127+
trace_object : Trace, required
128128
trace object
129-
width : float
129+
width : float, optional
130130
width of extraction aperture in pixels
131-
disp_axis : int
131+
disp_axis : int, optional
132132
dispersion axis
133-
crossdisp_axis : int
133+
crossdisp_axis : int, optional
134134
cross-dispersion axis
135135
136136
Returns
@@ -156,15 +156,15 @@ def __call__(self, image=None, trace_object=None, width=None,
156156
157157
Parameters
158158
----------
159-
image : nddata-compatible image
159+
image : `~astropy.nddata.NDData`-like or array-like, required
160160
image with 2-D spectral image data
161-
trace_object : Trace
161+
trace_object : Trace, required
162162
trace object
163-
width : float
163+
width : float, optional
164164
width of extraction aperture in pixels [default: 5]
165-
disp_axis : int
165+
disp_axis : int, optional
166166
dispersion axis [default: 1]
167-
crossdisp_axis : int
167+
crossdisp_axis : int, optional
168168
cross-dispersion axis [default: 0]
169169
170170
@@ -180,22 +180,30 @@ def __call__(self, image=None, trace_object=None, width=None,
180180
disp_axis = disp_axis if disp_axis is not None else self.disp_axis
181181
crossdisp_axis = crossdisp_axis if crossdisp_axis is not None else self.crossdisp_axis
182182

183+
# handle image processing based on its type
184+
if isinstance(image, Spectrum1D):
185+
img = image.data
186+
unit = image.unit
187+
else:
188+
img = image
189+
unit = getattr(image, 'unit', u.DN)
190+
183191
# TODO: this check can be removed if/when implemented as a check in FlatTrace
184192
if isinstance(trace_object, FlatTrace):
185193
if trace_object.trace_pos < 1:
186194
raise ValueError('trace_object.trace_pos must be >= 1')
187195

188196
# weight image to use for extraction
189-
wimage = _ap_weight_image(
197+
wimg = _ap_weight_image(
190198
trace_object,
191199
width,
192200
disp_axis,
193201
crossdisp_axis,
194-
image.shape)
202+
img.shape)
195203

196204
# extract
197205
ext1d = np.sum(image * wimage, axis=crossdisp_axis)
198-
return _to_spectrum1d_pixels(ext1d * getattr(image, 'unit', u.DN))
206+
return _to_spectrum1d_pixels(ext1d * unit)
199207

200208

201209
@dataclass
@@ -207,7 +215,7 @@ class HorneExtract(SpecreduceOperation):
207215
Parameters
208216
----------
209217
210-
image : `~astropy.nddata.NDData` or array-like, required
218+
image : `~astropy.nddata.NDData`-like or array-like, required
211219
The input 2D spectrum from which to extract a source. An
212220
NDData object must specify uncertainty and a mask. An array
213221
requires use of the ``variance``, ``mask``, & ``unit`` arguments.
@@ -270,7 +278,7 @@ def __call__(self, image=None, trace_object=None,
270278
Parameters
271279
----------
272280
273-
image : `~astropy.nddata.NDData` or array-like, required
281+
image : `~astropy.nddata.NDData`-like or array-like, required
274282
The input 2D spectrum from which to extract a source. An
275283
NDData object must specify uncertainty and a mask. An array
276284
requires use of the ``variance``, ``mask``, & ``unit`` arguments.
@@ -323,6 +331,7 @@ def __call__(self, image=None, trace_object=None,
323331

324332
# handle image and associated data based on image's type
325333
if isinstance(image, NDData):
334+
# (NDData includes Spectrum1D under its umbrella)
326335
img = np.ma.array(image.data, mask=image.mask)
327336
unit = image.unit if image.unit is not None else u.Unit()
328337

specreduce/tracing.py

+16-4
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
import warnings
66

77
from astropy.modeling import fitting, models
8-
from astropy.nddata import CCDData, NDData
8+
from astropy.nddata import NDData
99
from astropy.stats import gaussian_sigma_to_fwhm
1010
from scipy.interpolate import UnivariateSpline
11+
from specutils import Spectrum1D
1112
import numpy as np
1213

1314
__all__ = ['Trace', 'FlatTrace', 'ArrayTrace', 'KosmosTrace']
@@ -20,15 +21,15 @@ class Trace:
2021
2122
Parameters
2223
----------
23-
image : `~astropy.nddata.CCDData`
24+
image : `~astropy.nddata.NDData`-like or array-like, required
2425
Image to be traced
2526
2627
Properties
2728
----------
2829
shape : tuple
2930
Shape of the array describing the trace
3031
"""
31-
image: CCDData
32+
image: NDData
3233

3334
def __post_init__(self):
3435
self.trace_pos = self.image.shape[0] / 2
@@ -37,6 +38,11 @@ def __post_init__(self):
3738
def __getitem__(self, i):
3839
return self.trace[i]
3940

41+
def _parse_image(self):
42+
if isinstance(self.image, Spectrum1D):
43+
# NOTE: should the Spectrum1D structure instead be preserved?
44+
self.image = self.image.data
45+
4046
@property
4147
def shape(self):
4248
return self.trace.shape
@@ -95,6 +101,8 @@ class FlatTrace(Trace):
95101
trace_pos: float
96102

97103
def __post_init__(self):
104+
super()._parse_image()
105+
98106
self.set_position(self.trace_pos)
99107

100108
def set_position(self, trace_pos):
@@ -124,6 +132,8 @@ class ArrayTrace(Trace):
124132
trace: np.ndarray
125133

126134
def __post_init__(self):
135+
super()._parse_image()
136+
127137
nx = self.image.shape[1]
128138
nt = len(self.trace)
129139
if nt != nx:
@@ -158,7 +168,7 @@ class KosmosTrace(Trace):
158168
159169
Parameters
160170
----------
161-
image : `~astropy.nddata.NDData` or array-like, required
171+
image : `~astropy.nddata.NDData`-like or array-like, required
162172
The image over which to run the trace. Assumes cross-dispersion
163173
(spatial) direction is axis 0 and dispersion (wavelength)
164174
direction is axis 1.
@@ -200,6 +210,8 @@ class KosmosTrace(Trace):
200210
_disp_axis = 1
201211

202212
def __post_init__(self):
213+
super()._parse_image()
214+
203215
# handle multiple image types and mask uncaught invalid values
204216
if isinstance(self.image, NDData):
205217
img = np.ma.masked_invalid(np.ma.masked_array(self.image.data,

0 commit comments

Comments
 (0)