Skip to content

Commit e90ba7a

Browse files
JP-4370: Unset S_REGION if wcs is not sky-like (#10586)
Co-authored-by: Tyler Pauly <tapastro@gmail.com>
1 parent 2e5290f commit e90ba7a

10 files changed

Lines changed: 73 additions & 25 deletions

File tree

changes/10586.assign_wcs.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Unset the S_REGION if the output WCS is not celestial (e.g., NIRSpec lamp exposures).

changes/10586.resample_spec.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Make sure no S_REGION is defined for resampled data that is not sky-like (e.g., NIRSpec lamp exposures).

jwst/assign_wcs/assign_wcs.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from jwst.assign_wcs.miri import store_dithered_position
77
from jwst.assign_wcs.util import (
8+
is_sky_like,
89
update_s_region_imaging,
910
update_s_region_lrs,
1011
update_s_region_mrs,
@@ -139,6 +140,11 @@ def load_wcs(input_model, reference_files=None, nrs_slit_y_range=None, nrs_ifu_s
139140
f"Unable to update S_REGION for type {input_model.meta.exposure.type}: {exc}"
140141
)
141142

143+
# For any exposure type, unset the S_REGION if the output WCS is not
144+
# celestial (e.g. lamp exposures)
145+
if not is_sky_like(input_model.meta.wcs.output_frame):
146+
input_model.meta.wcsinfo.s_region = None
147+
142148
# Store position of dithered pointing location in metadata for later spectral extraction
143149
if input_model.meta.exposure.type.lower() == "mir_lrs-fixedslit":
144150
store_dithered_position(input_model)

jwst/assign_wcs/tests/test_nirspec.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,10 @@ def test_nirspec_imaging_via_step_call(exptype):
209209
]
210210
if exptype == "NRS_LAMP":
211211
assert result.meta.wcs.bounding_box is None
212+
assert result.meta.wcsinfo.s_region is None
212213
else:
213214
assert result.meta.wcs.bounding_box is not None
215+
assert result.meta.wcsinfo.s_region is not None
214216

215217

216218
def test_nirspec_imaging_opaque():

jwst/assign_wcs/tests/test_util.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
Test the utility functions
33
"""
44

5+
import gwcs
6+
from astropy import coordinates as coord
7+
from astropy import units as u
58
from astropy.modeling.models import Identity, Shift
69
from astropy.table import QTable
710
from astropy.utils.data import get_pkg_data_filename
@@ -10,6 +13,7 @@
1013
from jwst.assign_wcs.util import (
1114
bounding_box_from_subarray,
1215
get_object_info,
16+
is_sky_like,
1317
subarray_transform,
1418
transform_bbox_from_shape,
1519
wcs_bbox_from_shape,
@@ -98,3 +102,20 @@ def test_bounding_box_from_subarray():
98102
im.meta.subarray.xsize = 400
99103
im.meta.subarray.ysize = 600
100104
assert bounding_box_from_subarray(im) == ((-0.5, 599.5), (-0.5, 399.5))
105+
106+
107+
def test_is_sky_like():
108+
frame = "test"
109+
assert not is_sky_like(frame)
110+
111+
frame = gwcs.Frame2D()
112+
assert not is_sky_like(frame)
113+
114+
frame = gwcs.Frame2D(unit=[u.um, u.pix])
115+
assert not is_sky_like(frame)
116+
117+
frame = gwcs.Frame2D(unit=[u.arcsec, u.arcsec])
118+
assert is_sky_like(frame)
119+
120+
frame = gwcs.CelestialFrame(name="icrs", axes_order=(0, 1), reference_frame=coord.ICRS())
121+
assert is_sky_like(frame)

jwst/assign_wcs/util.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
import logging
44
import warnings
55

6+
import gwcs.coordinate_frames
67
import numpy as np
8+
from astropy import units as u
79
from astropy.constants import c
810
from astropy.modeling import models as astmodels
911
from gwcs import WCS
@@ -38,6 +40,7 @@
3840
"calc_rotation_matrix",
3941
"wrap_ra",
4042
"update_fits_wcsinfo",
43+
"is_sky_like",
4144
]
4245

4346

@@ -1286,3 +1289,26 @@ def get_wcs_reference_files(datamodel):
12861289
else:
12871290
refs[reftype] = val
12881291
return refs
1292+
1293+
1294+
def is_sky_like(frame):
1295+
"""
1296+
Check that a frame is a sky-like frame by looking at its output units.
1297+
1298+
If output units are either ``deg`` or ``arcsec`` the frame is considered
1299+
a sky-like frame (as opposed to, e.g., a Cartesian frame).
1300+
1301+
Parameters
1302+
----------
1303+
frame : `~gwcs.coordinate_frames.CoordinateFrame`
1304+
Coordinate frame to check.
1305+
1306+
Returns
1307+
-------
1308+
bool
1309+
``True`` if the frame is sky-like, ``False`` otherwise.
1310+
"""
1311+
# Make sure the frame is a coordinate frame first: if not, it's not sky-like
1312+
if not isinstance(frame, gwcs.coordinate_frames.CoordinateFrame):
1313+
return False
1314+
return u.Unit("deg") in frame.unit or u.Unit("arcsec") in frame.unit

jwst/resample/resample_spec.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from stcal.alignment.util import compute_scale, wcs_bbox_from_shape
2222
from stdatamodels.jwst import datamodels
2323

24-
from jwst.assign_wcs.util import wrap_ra
24+
from jwst.assign_wcs.util import is_sky_like, wrap_ra
2525
from jwst.datamodels import ModelLibrary
2626
from jwst.resample import resample_utils
2727
from jwst.resample.resample import ResampleImage
@@ -167,7 +167,7 @@ def __init__(self, input_models, good_bits=0, output_wcs=None, wcs_pars=None, **
167167
# These functions internally use pixel_scale_ratio to accommodate
168168
# user settings.
169169
# Any other customizations (crpix, crval, rotation) are ignored.
170-
if resample_utils.is_sky_like(input_models[0].meta.wcs.output_frame):
170+
if is_sky_like(input_models[0].meta.wcs.output_frame):
171171
if input_models[0].meta.instrument.name != "NIRSPEC":
172172
output_wcs = self.build_interpolated_output_wcs(
173173
input_models, pixel_scale_ratio=pixel_scale_ratio

jwst/resample/resample_spec_step.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from stdatamodels.jwst import datamodels
44
from stdatamodels.jwst.datamodels import ImageModel, MultiSlitModel
55

6-
from jwst.assign_wcs.util import update_s_region_spectral
6+
from jwst.assign_wcs.util import is_sky_like, update_s_region_spectral
77
from jwst.datamodels import ModelContainer, ModelLibrary
88
from jwst.exp_to_source import multislit_to_container
99
from jwst.lib.pipe_utils import match_nans_and_flags
@@ -169,7 +169,11 @@ def _process_multislit(self, input_models):
169169
with drizzled_library:
170170
for i, model in enumerate(drizzled_library):
171171
self.update_slit_metadata(model)
172-
update_s_region_spectral(model)
172+
if not is_sky_like(model.meta.wcs.output_frame):
173+
# Output WCS is not celestial: unset the S_REGION
174+
model.meta.wcsinfo.s_region = None
175+
else:
176+
update_s_region_spectral(model)
173177
result.slits.append(model)
174178
drizzled_library.shelve(model, i, modify=False)
175179
del drizzled_library
@@ -278,7 +282,11 @@ def _process_slit(self, input_models):
278282
input_wcs = input_models[0].meta.wcs
279283
self._transform_sourcepos(input_wcs, result)
280284
else:
281-
update_s_region_spectral(result)
285+
if not is_sky_like(result.meta.wcs.output_frame):
286+
# Output WCS is not celestial: unset the S_REGION
287+
result.meta.wcsinfo.s_region = None
288+
else:
289+
update_s_region_spectral(result)
282290

283291
return result
284292

jwst/resample/resample_utils.py

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -158,26 +158,6 @@ def build_mask(dqarr, bitvalue):
158158
return _stcal_build_mask(dqarr=dqarr, good_bits=bitvalue, flag_name_map=pixel)
159159

160160

161-
def is_sky_like(frame):
162-
"""
163-
Check that a frame is a sky-like frame by looking at its output units.
164-
165-
If output units are either ``deg`` or ``arcsec`` the frame is considered
166-
a sky-like frame (as opposite to, e.g., a Cartesian frame.)
167-
168-
Parameters
169-
----------
170-
frame : gwcs.wcs.WCS
171-
WCS object to check.
172-
173-
Returns
174-
-------
175-
bool
176-
``True`` if the frame is sky-like, ``False`` otherwise.
177-
"""
178-
return u.Unit("deg") in frame.unit or u.Unit("arcsec") in frame.unit
179-
180-
181161
def load_custom_wcs(asdf_wcs_file, output_shape=None):
182162
"""
183163
Load a custom output WCS from an ASDF file.

jwst/resample/tests/test_resample_step.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,6 +1779,9 @@ def test_nirspec_lamp_pixscale(nirspec_lamp, tmp_path):
17791779
assert_allclose(result.slits[0].data.shape[0], nirspec_lamp.slits[0].data.shape[0], atol=5)
17801780
assert result.slits[0].data.shape[1] == nirspec_lamp.slits[0].data.shape[1]
17811781

1782+
# no output s_region since the WCS is not sky-like
1783+
assert result.slits[0].meta.wcsinfo.s_region is None
1784+
17821785
# test pixel scale setting: will not work without sky-based WCS
17831786
result2 = ResampleSpecStep.call(nirspec_lamp, pixel_scale=0.5)
17841787
assert_allclose(result2.slits[0].data, result.slits[0].data, equal_nan=True)

0 commit comments

Comments
 (0)