Skip to content

Commit a8d4ef9

Browse files
emoltermeeseeksmachine
authored andcommitted
Backport PR spacetelescope#9625: JP-4052: Fix extract_1d and combine_1d failures from all-NaN slit
1 parent 8b9c2e3 commit a8d4ef9

File tree

5 files changed

+67
-8
lines changed

5 files changed

+67
-8
lines changed

changes/9625.combine_1d.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Allow all-NaN spectra to be skipped instead of causing crashes

jwst/combine_1d/combine1d.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,12 @@ def _read_input_spectra(input_model, exptime_key, input_spectra):
727727
else:
728728
spectra = input_model.spec
729729
for in_spec in spectra:
730+
if not np.any(np.isfinite(in_spec.spec_table.field("flux"))):
731+
log.warning(
732+
f"Input spectrum {in_spec.source_id} order {in_spec.spectral_order} "
733+
f"from group_id {in_spec.meta.group_id} has no valid flux values; skipping."
734+
)
735+
continue
730736
spectral_order = in_spec.spectral_order
731737
if spectral_order not in input_spectra:
732738
input_spectra[spectral_order] = []
@@ -768,6 +774,12 @@ def combine_1d_spectra(input_model, exptime_key, sigma_clip=None):
768774
else:
769775
_read_input_spectra(input_model, exptime_key, input_spectra)
770776

777+
if len(input_spectra) == 0:
778+
log.error("No valid input spectra found for source. Skipping.")
779+
result = input_model.copy()
780+
result.meta.cal_step.combine_1d = "SKIPPED"
781+
return result
782+
771783
for order in input_spectra:
772784
output_spectra[order] = OutputSpectrumModel()
773785
output_spectra[order].assign_wavelengths(input_spectra[order])

jwst/combine_1d/combine_1d_step.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,15 @@ def process(self, input_data):
7171
result = combine1d.combine_1d_spectra(
7272
model, self.exptime_key, sigma_clip=self.sigma_clip
7373
)
74-
results_list.append(result)
74+
if not result.meta.cal_step.combine_1d == "SKIPPED":
75+
results_list.append(result)
76+
if not results_list:
77+
self.log.error(
78+
"No valid input spectra found in WFSSMultiSpecModel. Skipping."
79+
)
80+
result = input_model.copy()
81+
result.meta.cal_step.combine_1d = "SKIPPED"
82+
return result
7583
result = make_wfss_multicombined(results_list)
7684
result.meta.cal_step.combine_1d = "COMPLETE"
7785
return result

jwst/combine_1d/tests/test_combine1d.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import numpy as np
44
import pytest
5+
import logging
6+
from jwst.tests.helpers import LogWatcher
57

68
from jwst import datamodels
79

@@ -227,3 +229,35 @@ def test_wfss_multi_input(wfss_multiexposure):
227229
assert np.all(tab["SOURCE_TYPE"] == "POINT")
228230

229231
assert result.spec[0].dispersion_direction == 3
232+
233+
234+
def test_allnan_skip(wfss_multiexposure, monkeypatch):
235+
"""Test that all-nan spectra are skipped."""
236+
# Set all flux values to NaN
237+
for spec in wfss_multiexposure.spec:
238+
spec.spec_table["FLUX"][:] = np.nan
239+
240+
# message when a single spectrum has no valid flux values
241+
watcher0 = LogWatcher(
242+
"Input spectrum 5 order 1 from group_id 1 has no valid flux values; skipping."
243+
)
244+
monkeypatch.setattr(logging.getLogger("jwst.combine_1d.combine1d"), "warning", watcher0)
245+
result = Combine1dStep.call(wfss_multiexposure)
246+
assert result.meta.cal_step.combine_1d == "SKIPPED"
247+
watcher0.assert_seen()
248+
249+
# check for the other log messages
250+
# these must be done one at a time because the watcher can only be monkeypatched once
251+
# message when no valid input spectra are found for the source
252+
watcher1 = LogWatcher("No valid input spectra found for source. Skipping.")
253+
monkeypatch.setattr(logging.getLogger("jwst.combine_1d.combine1d"), "error", watcher1)
254+
result = Combine1dStep.call(wfss_multiexposure)
255+
assert result.meta.cal_step.combine_1d == "SKIPPED"
256+
watcher1.assert_seen()
257+
258+
# message when no valid input spectra at all are found
259+
watcher2 = LogWatcher("No valid input spectra found in WFSSMultiSpecModel")
260+
monkeypatch.setattr(logging.getLogger("stpipe.Combine1dStep"), "error", watcher2)
261+
result = Combine1dStep.call(wfss_multiexposure)
262+
assert result.meta.cal_step.combine_1d == "SKIPPED"
263+
watcher2.assert_seen()

jwst/pipeline/calwebb_spec3.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -296,13 +296,17 @@ def process(self, input_data):
296296
extraction_complete = (
297297
result is not None and result.meta.cal_step.extract_1d == "COMPLETE"
298298
)
299-
if extraction_complete:
300-
# Combine the results for all sources
301-
comb = self.combine_1d.run(result)
302-
# add metadata that only WFSS wants
303-
comb.spec[0].source_ra = result.spec[0].spec_table["SOURCE_RA"][0]
304-
comb.spec[0].source_dec = result.spec[0].spec_table["SOURCE_DEC"][0]
305-
wfss_comb.append(comb)
299+
if not extraction_complete:
300+
continue
301+
# Combine the results for all sources
302+
comb = self.combine_1d.run(result)
303+
comb_complete = comb is not None and comb.meta.cal_step.combine_1d == "COMPLETE"
304+
if not comb_complete:
305+
continue
306+
# add metadata that only WFSS wants
307+
comb.spec[0].source_ra = result.spec[0].spec_table["SOURCE_RA"][0]
308+
comb.spec[0].source_dec = result.spec[0].spec_table["SOURCE_DEC"][0]
309+
wfss_comb.append(comb)
306310

307311
elif resample_complete is not None and resample_complete.upper() == "COMPLETE":
308312
# If 2D data were resampled and combined, just do a 1D extraction

0 commit comments

Comments
 (0)