From c53ea53d3a58c54cb6d576b8d5b99f1a74a4de60 Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Wed, 28 Sep 2022 08:55:52 -0400 Subject: [PATCH 1/2] Background.bkg_spectrum and sub_spectrum --- CHANGES.rst | 2 ++ specreduce/background.py | 45 ++++++++++++++++++++++++++++- specreduce/extract.py | 18 +++++------- specreduce/tests/test_background.py | 6 ++++ 4 files changed, 60 insertions(+), 11 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index f7635444..4ce7192f 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -15,6 +15,8 @@ New Features ^^^^^^^^^^^^ - ``peak_method`` as an optional argument to ``KosmosTrace`` [#115] +- ``Background`` has new methods for exposing the 1D spectrum of the background or + background-subtracted regions [#143] API Changes ^^^^^^^^^^^ diff --git a/specreduce/background.py b/specreduce/background.py index a2829622..1e3f7a55 100644 --- a/specreduce/background.py +++ b/specreduce/background.py @@ -5,8 +5,9 @@ import numpy as np from astropy.nddata import NDData +from astropy import units as u -from specreduce.extract import _ap_weight_image +from specreduce.extract import _ap_weight_image, _to_spectrum1d_pixels from specreduce.tracing import Trace, FlatTrace __all__ = ['Background'] @@ -205,6 +206,27 @@ def bkg_image(self, image=None): return np.tile(self.bkg_array, (image.shape[0], 1)) + def bkg_spectrum(self, image=None): + """ + Expose the 1D spectrum of the background. + + Parameters + ---------- + image : nddata-compatible image or None + image with 2-D spectral image data. If None, will use ``image`` passed + to extract the background. + + Returns + ------- + spec : `~specutils.Spectrum1D` + The background 1d spectrum with flux expressed in the same + units as the input image, or u.DN, and pixel units + """ + bkg_image = self.bkg_image(image=image) + + ext1d = np.sum(bkg_image, axis=self.crossdisp_axis) + return _to_spectrum1d_pixels(ext1d * getattr(image, 'unit', u.DN)) + def sub_image(self, image=None): """ Subtract the computed background from ``image``. @@ -228,6 +250,27 @@ def sub_image(self, image=None): else: return image - self.bkg_image(image) + def sub_spectrum(self, image=None): + """ + Expose the 1D spectrum of the background-subtracted image. + + Parameters + ---------- + image : nddata-compatible image or None + image with 2-D spectral image data. If None, will use ``image`` passed + to extract the background. + + Returns + ------- + spec : `~specutils.Spectrum1D` + The background-subtracted 1d spectrum with flux expressed in the same + units as the input image, or u.DN, and pixel units + """ + sub_image = self.sub_image(image=image) + + ext1d = np.sum(sub_image, axis=self.crossdisp_axis) + return _to_spectrum1d_pixels(ext1d * getattr(image, 'unit', u.DN)) + def __rsub__(self, image): """ Subtract the background from an image. diff --git a/specreduce/extract.py b/specreduce/extract.py index 2537d7ba..56d2b211 100644 --- a/specreduce/extract.py +++ b/specreduce/extract.py @@ -102,6 +102,12 @@ def _ap_weight_image(trace, width, disp_axis, crossdisp_axis, image_shape): return wimage +def _to_spectrum1d_pixels(fluxes): + # TODO: add wavelength units, uncertainty and mask to spectrum1D object + return Spectrum1D(spectral_axis=np.arange(len(fluxes)) * u.pixel, + flux=fluxes) + + @dataclass class BoxcarExtract(SpecreduceOperation): """ @@ -189,12 +195,7 @@ def __call__(self, image=None, trace_object=None, width=None, # extract ext1d = np.sum(image * wimage, axis=crossdisp_axis) - - # TODO: add wavelenght units, uncertainty and mask to spectrum1D object - spec = Spectrum1D(spectral_axis=np.arange(len(ext1d)) * u.pixel, - flux=ext1d * getattr(image, 'unit', u.DN)) - - return spec + return _to_spectrum1d_pixels(ext1d * getattr(image, 'unit', u.DN)) @dataclass @@ -432,10 +433,7 @@ def __call__(self, image=None, trace_object=None, extraction = result * norms # convert the extraction to a Spectrum1D object - pixels = np.arange(img.shape[disp_axis]) * u.pix - spec_1d = Spectrum1D(spectral_axis=pixels, flux=extraction * unit) - - return spec_1d + return _to_spectrum1d_pixels(extraction * unit) @dataclass diff --git a/specreduce/tests/test_background.py b/specreduce/tests/test_background.py index 7ccf8dce..f5808fb1 100644 --- a/specreduce/tests/test_background.py +++ b/specreduce/tests/test_background.py @@ -3,6 +3,7 @@ import astropy.units as u from astropy.nddata import CCDData +from specutils import Spectrum1D from specreduce.background import Background from specreduce.tracing import FlatTrace @@ -44,6 +45,11 @@ def test_background(): assert np.allclose(sub1, sub2) assert np.allclose(sub1, sub3) + bkg_spec = bg1.bkg_spectrum() + assert isinstance(bkg_spec, Spectrum1D) + sub_spec = bg1.sub_spectrum() + assert isinstance(sub_spec, Spectrum1D) + def test_oob(): # image.shape (30, 10) From cade20905d3ce14f76b2e8913f78b02a5297edbc Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Mon, 3 Oct 2022 09:24:44 -0400 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: ojustino --- specreduce/background.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/specreduce/background.py b/specreduce/background.py index 1e3f7a55..7345a039 100644 --- a/specreduce/background.py +++ b/specreduce/background.py @@ -194,8 +194,8 @@ def bkg_image(self, image=None): Parameters ---------- image : nddata-compatible image or None - image with 2-D spectral image data. If None, will use ``image`` passed - to extract the background. + image with 2-D spectral image data. If None, will extract + the background from ``image`` used to initialize the class. Returns ------- @@ -213,14 +213,15 @@ def bkg_spectrum(self, image=None): Parameters ---------- image : nddata-compatible image or None - image with 2-D spectral image data. If None, will use ``image`` passed - to extract the background. + image with 2-D spectral image data. If None, will extract + the background from ``image`` used to initialize the class. Returns ------- spec : `~specutils.Spectrum1D` - The background 1d spectrum with flux expressed in the same - units as the input image, or u.DN, and pixel units + The background 1-D spectrum, with flux expressed in the same + units as the input image (or u.DN if none were provided) and + the spectral axis expressed in pixel units. """ bkg_image = self.bkg_image(image=image) @@ -234,8 +235,8 @@ def sub_image(self, image=None): Parameters ---------- image : nddata-compatible image or None - image with 2-D spectral image data. If None, will use ``image`` passed - to extract the background. + image with 2-D spectral image data. If None, will extract + the background from ``image`` used to initialize the class. Returns ------- @@ -257,14 +258,15 @@ def sub_spectrum(self, image=None): Parameters ---------- image : nddata-compatible image or None - image with 2-D spectral image data. If None, will use ``image`` passed - to extract the background. + image with 2-D spectral image data. If None, will extract + the background from ``image`` used to initialize the class. Returns ------- spec : `~specutils.Spectrum1D` - The background-subtracted 1d spectrum with flux expressed in the same - units as the input image, or u.DN, and pixel units + The background 1-D spectrum, with flux expressed in the same + units as the input image (or u.DN if none were provided) and + the spectral axis expressed in pixel units. """ sub_image = self.sub_image(image=image)