Skip to content

Commit 35e9d34

Browse files
dr-rodriguezkelle
andauthored
Removing logic for wcs1d-multispec (#107)
* Removing logic for wcs1d-multispec * Update astrodbkit/spectra.py Co-authored-by: Kelle Cruz <kellecruz@gmail.com> --------- Co-authored-by: Kelle Cruz <kellecruz@gmail.com>
1 parent 58ba11d commit 35e9d34

File tree

3 files changed

+5
-182
lines changed

3 files changed

+5
-182
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,6 @@ pip-wheel-metadata/
6464

6565
# Mac OSX
6666
.DS_Store
67+
68+
.cursor
69+
uv.lock

astrodbkit/spectra.py

Lines changed: 0 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,10 @@
22

33
import os
44

5-
import astropy.units as u
6-
import numpy as np
75
from astropy.io import fits
86
from astropy.nddata import StdDevUncertainty
97
from astropy.units import Unit
10-
from astropy.wcs import WCS
118
from specutils import Spectrum
12-
from specutils.io.parsing_utils import read_fileobj_or_hdulist
139
from specutils.io.registers import data_loader
1410

1511
# pylint: disable=no-member, unused-argument
@@ -75,112 +71,6 @@ def spex_prism_loader(filename, **kwargs):
7571
return Spectrum(flux=data, spectral_axis=wave, uncertainty=uncertainty, meta=meta)
7672

7773

78-
def identify_wcs1d_multispec(origin, *args, **kwargs):
79-
"""
80-
Identifier for WCS1D multispec
81-
"""
82-
hdu = kwargs.get("hdu", 0)
83-
84-
# Check if number of axes is one and dimension of WCS is greater than one
85-
with read_fileobj_or_hdulist(*args, **kwargs) as hdulist:
86-
return (
87-
hdulist[hdu].header.get("WCSDIM", 1) > 1
88-
and hdulist[hdu].header["NAXIS"] > 1
89-
and "WAT0_001" in hdulist[hdu].header
90-
and hdulist[hdu].header.get("WCSDIM", 1) == hdulist[hdu].header["NAXIS"]
91-
and "LINEAR" in hdulist[hdu].header.get("CTYPE1", "")
92-
)
93-
94-
95-
@data_loader("wcs1d-multispec", identifier=identify_wcs1d_multispec, extensions=["fits"], dtype=Spectrum, priority=10)
96-
def wcs1d_multispec_loader(file_obj, flux_unit=None, hdu=0, verbose=False, **kwargs):
97-
"""
98-
Loader for multiextension spectra as wcs1d. Adapted from wcs1d_fits_loader
99-
100-
Parameters
101-
----------
102-
file_obj : str, file-like or HDUList
103-
FITS file name, object (provided from name by Astropy I/O Registry),
104-
or HDUList (as resulting from astropy.io.fits.open()).
105-
flux_unit : :class:`~astropy.units.Unit` or str, optional
106-
Units of the flux for this spectrum. If not given (or None), the unit
107-
will be inferred from the BUNIT keyword in the header. Note that this
108-
unit will attempt to convert from BUNIT if BUNIT is present.
109-
hdu : int
110-
The index of the HDU to load into this spectrum.
111-
verbose : bool
112-
Print extra info.
113-
**kwargs
114-
Extra keywords for :func:`~specutils.io.parsing_utils.read_fileobj_or_hdulist`.
115-
116-
Returns
117-
-------
118-
:class:`~specutils.Spectrum`
119-
"""
120-
121-
with read_fileobj_or_hdulist(file_obj, **kwargs) as hdulist:
122-
header = hdulist[hdu].header
123-
wcs = WCS(header)
124-
125-
# Load data, convert units if BUNIT and flux_unit is provided and not the same
126-
if "BUNIT" in header:
127-
data = u.Quantity(hdulist[hdu].data, unit=header["BUNIT"])
128-
if u.A in data.unit.bases:
129-
data = data * u.A / u.AA # convert ampere to Angroms
130-
if flux_unit is not None:
131-
data = data.to(flux_unit)
132-
else:
133-
data = u.Quantity(hdulist[hdu].data, unit=flux_unit)
134-
135-
if wcs.wcs.cunit[0] == "" and "WAT1_001" in header:
136-
# Try to extract from IRAF-style card or use Angstrom as default.
137-
wat_dict = dict((rec.split("=") for rec in header["WAT1_001"].split()))
138-
unit = wat_dict.get("units", "Angstrom")
139-
if hasattr(u, unit):
140-
wcs.wcs.cunit[0] = unit
141-
else: # try with unit name stripped of excess plural 's'...
142-
wcs.wcs.cunit[0] = unit.rstrip("s")
143-
if verbose:
144-
print(f"Extracted spectral axis unit '{unit}' from 'WAT1_001'")
145-
elif wcs.wcs.cunit[0] == "":
146-
wcs.wcs.cunit[0] = "Angstrom"
147-
148-
# Compatibility attribute for lookup_table (gwcs) WCS
149-
wcs.unit = tuple(wcs.wcs.cunit)
150-
151-
# Identify the correct parts of the data to store
152-
if len(data.shape) > 1:
153-
flux_data = data[0]
154-
else:
155-
flux_data = data
156-
uncertainty = None
157-
if "NAXIS3" in header:
158-
for i in range(header["NAXIS3"]):
159-
if "spectrum" in header.get(f"BANDID{i+1}", ""):
160-
flux_data = data[i]
161-
if "sigma" in header.get(f"BANDID{i+1}", ""):
162-
uncertainty = data[i]
163-
164-
# Reshape arrays if needed
165-
if len(flux_data) == 1 and len(flux_data.shape) > 1:
166-
flux_data = np.reshape(flux_data, -1)
167-
if uncertainty is not None:
168-
uncertainty = np.reshape(uncertainty, -1)
169-
170-
# Convert uncertainty to StdDevUncertainty array
171-
if uncertainty is not None:
172-
uncertainty = StdDevUncertainty(uncertainty)
173-
174-
# Manually generate spectral axis
175-
pixels = [[i] + [0] * (wcs.naxis - 1) for i in range(wcs.pixel_shape[0])]
176-
spectral_axis = [i[0] for i in wcs.all_pix2world(pixels, 0)] * wcs.wcs.cunit[0]
177-
178-
# Store header as metadata information
179-
meta = {"header": header}
180-
181-
return Spectrum(flux=flux_data, spectral_axis=spectral_axis, uncertainty=uncertainty, meta=meta)
182-
183-
18474
def load_spectrum(filename: str, spectra_format: str = None, raise_error: bool = False):
18575
"""Attempt to load the filename as a spectrum object
18676

astrodbkit/tests/test_spectra.py

Lines changed: 2 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Tests for spectra functions
22

3+
from unittest import mock
4+
35
import numpy as np
46
import pytest
57
from astropy.io import fits
@@ -8,17 +10,10 @@
810
from astrodbkit.spectra import (
911
_identify_spex,
1012
identify_spex_prism,
11-
identify_wcs1d_multispec,
1213
load_spectrum,
1314
spex_prism_loader,
14-
wcs1d_multispec_loader,
1515
)
1616

17-
try:
18-
import mock
19-
except ImportError:
20-
from unittest import mock
21-
2217

2318
@pytest.fixture(scope="module")
2419
def good_spex_file():
@@ -47,44 +42,6 @@ def bad_spex_file():
4742
return fits.HDUList([hdu1])
4843

4944

50-
@pytest.fixture(scope="module")
51-
def good_wcs1dmultispec():
52-
n = np.empty((2141, 1, 4))
53-
hdr = fits.Header()
54-
hdr["WCSDIM"] = 3
55-
hdr["NAXIS"] = 3
56-
hdr["WAT0_001"] = "system=equispec"
57-
hdr["WAT1_001"] = "wtype=linear label=Wavelength units=angstroms"
58-
hdr["WAT2_001"] = "wtype=linear"
59-
hdr["BANDID1"] = "spectrum - background fit, weights variance, clean no"
60-
hdr["BANDID2"] = "raw - background fit, weights none, clean no"
61-
hdr["BANDID3"] = "background - background fit"
62-
hdr["BANDID4"] = "sigma - background fit, weights variance, clean no"
63-
hdr["CTYPE1"] = "LINEAR "
64-
hdr["BUNIT"] = "erg/cm2/s/A"
65-
hdu1 = fits.PrimaryHDU(n, header=hdr)
66-
return fits.HDUList([hdu1])
67-
68-
69-
@pytest.fixture(scope="module")
70-
def alt_wcs1dmultispec():
71-
n = np.empty((2141,))
72-
hdr = fits.Header()
73-
hdr["WCSDIM"] = 1
74-
hdr["NAXIS"] = 1
75-
hdr["WAT0_001"] = "system=equispec"
76-
hdr["WAT1_001"] = "wtype=linear label=Wavelength units=angstroms"
77-
hdr["WAT2_001"] = "wtype=linear"
78-
hdr["BANDID1"] = "spectrum - background fit, weights variance, clean no"
79-
hdr["BANDID2"] = "raw - background fit, weights none, clean no"
80-
hdr["BANDID3"] = "background - background fit"
81-
hdr["BANDID4"] = "sigma - background fit, weights variance, clean no"
82-
hdr["CTYPE1"] = "LINEAR "
83-
hdr["BUNIT"] = "erg/cm2/s/A"
84-
hdu1 = fits.PrimaryHDU(n, header=hdr)
85-
return fits.HDUList([hdu1])
86-
87-
8845
@mock.patch("astrodbkit.spectra.fits.open")
8946
def test_identify_spex_prism(mock_fits_open, good_spex_file):
9047
mock_fits_open.return_value = good_spex_file
@@ -115,33 +72,6 @@ def test_load_spex_prism(mock_fits_open, good_spex_file, bad_spex_file):
11572
assert spectrum.unit == Unit("erg")
11673

11774

118-
@mock.patch("astrodbkit.spectra.read_fileobj_or_hdulist")
119-
def test_identify_wcs1d_multispec(mock_fits_open, good_wcs1dmultispec):
120-
mock_fits_open.return_value = good_wcs1dmultispec
121-
122-
filename = "https://s3.amazonaws.com/bdnyc/optical_spectra/U10929.fits"
123-
assert identify_wcs1d_multispec("read", filename)
124-
125-
126-
@mock.patch("astrodbkit.spectra.read_fileobj_or_hdulist")
127-
def test_wcs1d_multispec_loader(mock_fits_open, good_wcs1dmultispec, alt_wcs1dmultispec):
128-
mock_fits_open.return_value = good_wcs1dmultispec
129-
130-
spectrum = wcs1d_multispec_loader("filename")
131-
assert spectrum.unit == Unit("erg / (Angstrom cm2 s)")
132-
assert spectrum.wavelength.unit == Unit("Angstrom")
133-
134-
# Check flux_unit is converted correctly
135-
spectrum = wcs1d_multispec_loader("filename", flux_unit=Unit("erg / (um cm2 s)"))
136-
assert spectrum.unit == Unit("erg / (um cm2 s)")
137-
138-
# NAXIS=1 example
139-
mock_fits_open.return_value = alt_wcs1dmultispec
140-
spectrum = wcs1d_multispec_loader("filename")
141-
assert spectrum.unit == Unit("erg / (Angstrom cm2 s)")
142-
assert spectrum.wavelength.unit == Unit("Angstrom")
143-
144-
14575
@mock.patch("astrodbkit.spectra.Spectrum.read")
14676
def test_load_spectrum(mock_spectrum1d, monkeypatch):
14777
_ = load_spectrum("fake_file.txt")

0 commit comments

Comments
 (0)