Skip to content

Commit

Permalink
Better handled Spectrum1D images across classes
Browse files Browse the repository at this point in the history
  • Loading branch information
ojustino committed Oct 3, 2022
1 parent 44d3533 commit cfe8bb5
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 23 deletions.
13 changes: 9 additions & 4 deletions specreduce/background.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class Background:
Parameters
----------
image : `~astropy.nddata.NDData` or array-like
image : `~astropy.nddata.NDData`-like or array-like
image with 2-D spectral image data
traces : List
list of trace objects (or integers to define FlatTraces) to
Expand Down Expand Up @@ -60,7 +60,7 @@ def __post_init__(self):
Parameters
----------
image : `~astropy.nddata.NDData` or array-like
image : `~astropy.nddata.NDData`-like or array-like
image with 2-D spectral image data
traces : List
list of trace objects (or integers to define FlatTraces) to
Expand All @@ -86,6 +86,11 @@ def _to_trace(trace):
raise ValueError('trace_object.trace_pos must be >= 1')
return trace

if isinstance(self.image, NDData):
# NOTE: should the NDData structure instead be preserved?
# (NDData includes Spectrum1D under its umbrella)
self.image = self.image.data

bkg_wimage = np.zeros_like(self.image, dtype=np.float64)
for trace in self.traces:
trace = _to_trace(trace)
Expand Down Expand Up @@ -133,7 +138,7 @@ def two_sided(cls, image, trace_object, separation, **kwargs):
Parameters
----------
image : nddata-compatible image
image : `~astropy.nddata.NDData`-like or array-like
image with 2-D spectral image data
trace_object: Trace
estimated trace of the spectrum to center the background traces
Expand Down Expand Up @@ -166,7 +171,7 @@ def one_sided(cls, image, trace_object, separation, **kwargs):
Parameters
----------
image : nddata-compatible image
image : `~astropy.nddata.NDData`-like or array-like
image with 2-D spectral image data
trace_object: Trace
estimated trace of the spectrum to center the background traces
Expand Down
39 changes: 24 additions & 15 deletions specreduce/extract.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,15 @@ class BoxcarExtract(SpecreduceOperation):
Parameters
----------
image : nddata-compatible image
image : `~astropy.nddata.NDData`-like or array-like, required
image with 2-D spectral image data
trace_object : Trace
trace_object : Trace, required
trace object
width : float
width : float, optional
width of extraction aperture in pixels
disp_axis : int
disp_axis : int, optional
dispersion axis
crossdisp_axis : int
crossdisp_axis : int, optional
cross-dispersion axis
Returns
Expand All @@ -156,15 +156,15 @@ def __call__(self, image=None, trace_object=None, width=None,
Parameters
----------
image : nddata-compatible image
image : `~astropy.nddata.NDData`-like or array-like, required
image with 2-D spectral image data
trace_object : Trace
trace_object : Trace, required
trace object
width : float
width : float, optional
width of extraction aperture in pixels [default: 5]
disp_axis : int
disp_axis : int, optional
dispersion axis [default: 1]
crossdisp_axis : int
crossdisp_axis : int, optional
cross-dispersion axis [default: 0]
Expand All @@ -180,22 +180,30 @@ def __call__(self, image=None, trace_object=None, width=None,
disp_axis = disp_axis if disp_axis is not None else self.disp_axis
crossdisp_axis = crossdisp_axis if crossdisp_axis is not None else self.crossdisp_axis

# handle image processing based on its type
if isinstance(image, Spectrum1D):
img = image.data
unit = image.unit
else:
img = image
unit = getattr(image, 'unit', u.DN)

# TODO: this check can be removed if/when implemented as a check in FlatTrace
if isinstance(trace_object, FlatTrace):
if trace_object.trace_pos < 1:
raise ValueError('trace_object.trace_pos must be >= 1')

# weight image to use for extraction
wimage = _ap_weight_image(
wimg = _ap_weight_image(
trace_object,
width,
disp_axis,
crossdisp_axis,
image.shape)
img.shape)

# extract
ext1d = np.sum(image * wimage, axis=crossdisp_axis)
return _to_spectrum1d_pixels(ext1d * getattr(image, 'unit', u.DN))
return _to_spectrum1d_pixels(ext1d * unit)


@dataclass
Expand All @@ -207,7 +215,7 @@ class HorneExtract(SpecreduceOperation):
Parameters
----------
image : `~astropy.nddata.NDData` or array-like, required
image : `~astropy.nddata.NDData`-like or array-like, required
The input 2D spectrum from which to extract a source. An
NDData object must specify uncertainty and a mask. An array
requires use of the ``variance``, ``mask``, & ``unit`` arguments.
Expand Down Expand Up @@ -270,7 +278,7 @@ def __call__(self, image=None, trace_object=None,
Parameters
----------
image : `~astropy.nddata.NDData` or array-like, required
image : `~astropy.nddata.NDData`-like or array-like, required
The input 2D spectrum from which to extract a source. An
NDData object must specify uncertainty and a mask. An array
requires use of the ``variance``, ``mask``, & ``unit`` arguments.
Expand Down Expand Up @@ -323,6 +331,7 @@ def __call__(self, image=None, trace_object=None,

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

Expand Down
20 changes: 16 additions & 4 deletions specreduce/tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
import warnings

from astropy.modeling import fitting, models
from astropy.nddata import CCDData, NDData
from astropy.nddata import NDData
from astropy.stats import gaussian_sigma_to_fwhm
from scipy.interpolate import UnivariateSpline
from specutils import Spectrum1D
import numpy as np

__all__ = ['Trace', 'FlatTrace', 'ArrayTrace', 'KosmosTrace']
Expand All @@ -20,15 +21,15 @@ class Trace:
Parameters
----------
image : `~astropy.nddata.CCDData`
image : `~astropy.nddata.NDData`-like or array-like, required
Image to be traced
Properties
----------
shape : tuple
Shape of the array describing the trace
"""
image: CCDData
image: NDData

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

def _parse_image(self):
if isinstance(self.image, Spectrum1D):
# NOTE: should the Spectrum1D structure instead be preserved?
self.image = self.image.data

@property
def shape(self):
return self.trace.shape
Expand Down Expand Up @@ -95,6 +101,8 @@ class FlatTrace(Trace):
trace_pos: float

def __post_init__(self):
super()._parse_image()

self.set_position(self.trace_pos)

def set_position(self, trace_pos):
Expand Down Expand Up @@ -124,6 +132,8 @@ class ArrayTrace(Trace):
trace: np.ndarray

def __post_init__(self):
super()._parse_image()

nx = self.image.shape[1]
nt = len(self.trace)
if nt != nx:
Expand Down Expand Up @@ -158,7 +168,7 @@ class KosmosTrace(Trace):
Parameters
----------
image : `~astropy.nddata.NDData` or array-like, required
image : `~astropy.nddata.NDData`-like or array-like, required
The image over which to run the trace. Assumes cross-dispersion
(spatial) direction is axis 0 and dispersion (wavelength)
direction is axis 1.
Expand Down Expand Up @@ -200,6 +210,8 @@ class KosmosTrace(Trace):
_disp_axis = 1

def __post_init__(self):
super()._parse_image()

# handle multiple image types and mask uncaught invalid values
if isinstance(self.image, NDData):
img = np.ma.masked_invalid(np.ma.masked_array(self.image.data,
Expand Down

0 comments on commit cfe8bb5

Please sign in to comment.