Skip to content

Commit

Permalink
JP-3325: bypass extract1d for SOSS observations in FULL subarray (#8225)
Browse files Browse the repository at this point in the history
Co-authored-by: Ned Molter <[email protected]>
Co-authored-by: Howard Bushouse <[email protected]>
  • Loading branch information
3 people committed Feb 8, 2024
1 parent bb57c7e commit 88f14f6
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 24 deletions.
7 changes: 7 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ extract_1d

- Fixed a bug in the calling of optional MIRI MRS 1d residual fringe
correction that could cause defringing to fail in some cases. [#8180]

- Added a hook to bypass the ``extract_1d`` step for NIRISS SOSS data in
the FULL subarray with warning. [#8225]

outlier_detection
-----------------
Expand All @@ -59,6 +62,10 @@ photom
the pipeline put the (variable, calculated per pixel) dispersion back in. Assumes that
the dispersion needs to be in Angstroms/pixel to match the required factor of ~10. [#8207]

- Added a hook to bypass the ``photom`` step when the ``extract_1d`` step
was bypassed and came before the ``photom`` step, e.g. for NIRISS SOSS
data in the FULL subarray. [#8225]

refpix
------

Expand Down
2 changes: 1 addition & 1 deletion docs/jwst/references_general/drizpars_reffile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,6 @@ filter integer The filter used to obtain the images
pixfrac float The pixel "shrinkage" fraction
kernel string The kernel function used to distribute flux
fillval float Value assigned to pixels with no input flux
wht_type sting The input image weighting type
wht_type string The input image weighting type
stepsize integer Output WCS grid interpolation step size
=========== ======= ===========================================
11 changes: 4 additions & 7 deletions jwst/extract_1d/extract_1d_step.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,19 +412,16 @@ def process(self, input):
self.log.info('Exposure is in the SUBSTRIP256 subarray.')
self.log.info('Traces 1 and 2 will be modelled and decontaminated before extraction.')
subarray = 'SUBSTRIP256'
elif input_model.meta.subarray.name == 'FULL':
self.log.info('Exposure is in the FULL subarray.')
self.log.info('Traces 1 and 2 will be modelled and decontaminated before extraction.')
subarray = 'FULL'
elif input_model.meta.subarray.name == 'SUBSTRIP96':
self.log.info('Exposure is in the SUBSTRIP96 subarray.')
self.log.info('Traces of orders 1 and 2 will be modelled but only order 1'
' will be decontaminated before extraction.')
subarray = 'SUBSTRIP96'
else:
self.log.error('The SOSS extraction is implemented for the SUBSTRIP256,'
' SUBSTRIP96 and FULL subarray only.')
self.log.error('extract_1d will be skipped.')
self.log.error('The SOSS extraction is implemented for the SUBSTRIP256'
'and SUBSTRIP96 subarrays only. Subarray is currently '
f'{input_model.meta.subarray.name}.')
self.log.error('Extract1dStep will be skipped.')
input_model.meta.cal_step.extract_1d = 'SKIPPED'
return input_model

Expand Down
31 changes: 31 additions & 0 deletions jwst/extract_1d/tests/test_expected_skips.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import stdatamodels.jwst.datamodels as dm
from jwst.extract_1d import Extract1dStep
from jwst.photom import PhotomStep
import pytest
import numpy as np


@pytest.fixture(scope='module')
def mock_niriss_full():
model = dm.CubeModel((3, 3, 3))
model.meta.instrument.name = 'NIRISS'
model.meta.instrument.detector = 'NIS'
model.meta.observation.date = '2023-07-22'
model.meta.observation.time = '06:24:45.569'
model.meta.instrument.name = 'NIRISS'
model.meta.instrument.detector = 'NIS'
model.meta.instrument.filter = 'CLEAR'
model.meta.exposure.type = 'NIS_SOSS'
model.meta.subarray.name = 'FULL'
model.data = np.arange(27).reshape((3, 3, 3))
return model


def test_expected_skip_niriss_soss_full(mock_niriss_full):

with mock_niriss_full as model:
result = Extract1dStep().process(model)
result2 = PhotomStep().process(result)
assert result2.meta.cal_step.photom == 'SKIPPED'
assert result2.meta.cal_step.extract_1d == 'SKIPPED'
assert np.all(result2.data == model.data)
19 changes: 15 additions & 4 deletions jwst/photom/photom.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ def __init__(self, message):
super().__init__(message)


class DataModelTypeError(Exception):

def __init__(self, message):
if message is None:
message = "Unexpected DataModel type."
super().__init__(message)


def find_row(fits_table, match_fields):
"""
Find a row in a FITS table matching fields.
Expand Down Expand Up @@ -413,6 +421,9 @@ def calc_niriss(self, ftab):
continue
self.photom_io(ftab.phot_table[row])

elif isinstance(self.input, datamodels.CubeModel):
raise DataModelTypeError(f"Unexpected input data model type for NIRISS: {self.input.__class__.__name__}")

elif self.exptype in ['NIS_SOSS']:
for spec in self.input.spec:
self.specnum += 1
Expand Down Expand Up @@ -481,13 +492,13 @@ def calc_miri(self, ftab):
photom_corr = miri_imager.time_corr_photom(ftab.timecoeff[row], mid_time)

data = np.array(
[(self.filter, self.subarray, ftab.phot_table[row]['photmjsr']+photom_corr, ftab.phot_table[row]['uncertainty'])],
[(self.filter, self.subarray, ftab.phot_table[row]['photmjsr'] + photom_corr, ftab.phot_table[row]['uncertainty'])],
dtype=[
("filter", "O"),
("subarray", "O"),
("photmjsr", "<f4"),
("uncertainty", "<f4")
],
],
)
fftab = datamodels.MirImgPhotomModel(phot_table=data)
self.photom_io(fftab.phot_table[0])
Expand Down Expand Up @@ -539,12 +550,12 @@ def calc_miri(self, ftab):
log.info("Skipping MRS MIRI time correction. Extensions not found in the reference file.")
self.mrs_time_correction = False

#if np.any(ftab.timecoeff_ch1['binwave']) and self.mrs_time_correction:
# if np.any(ftab.timecoeff_ch1['binwave']) and self.mrs_time_correction:
if self.mrs_time_correction:
log.info("Applying MRS IFU time dependent correction.")
mid_time = self.input.meta.exposure.mid_time
correction = miri_mrs.time_correction(self.input, self.detector,
ftab, mid_time)
ftab, mid_time)
self.input.data /= correction
self.input.err /= correction
else:
Expand Down
26 changes: 17 additions & 9 deletions jwst/photom/photom_step.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,21 @@ def process(self, input):
result.meta.cal_step.photom = 'SKIPPED'
return result

# Do the correction
phot = photom.DataSet(input_model, self.inverse, self.source_type,
self.mrs_time_correction, correction_pars)
result = phot.apply_photom(phot_filename, area_filename)
result.meta.cal_step.photom = 'COMPLETE'

self.correction_pars = phot.correction_pars
self.correction_pars['refs'] = {'photom': phot_filename, 'area': area_filename}

try:
# Do the correction
phot = photom.DataSet(input_model, self.inverse, self.source_type,
self.mrs_time_correction, correction_pars)
result = phot.apply_photom(phot_filename, area_filename)
result.meta.cal_step.photom = 'COMPLETE'
self.correction_pars = phot.correction_pars
self.correction_pars['refs'] = {'photom': phot_filename, 'area': area_filename}

except photom.DataModelTypeError:
# should trip e.g. for NIRISS SOSS data in FULL subarray
self.log.error(f'Unexpected data model type {model_type} for '
f'{input_model.meta.instrument.name.upper()}. '
'Photom will be skipped.')
result = input_model.copy()
result.meta.cal_step.photom = 'SKIPPED'
return result
return result
21 changes: 18 additions & 3 deletions jwst/photom/tests/test_photom.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ def create_input(instrument, detector, exptype,
input_model.var_flat = np.ones(shape, dtype=np.float32)
input_model.meta.subarray.name = 'SUB256' # matches 'GENERIC'
input_model.meta.target.source_type = 'POINT'
input_model.meta.exposure.mid_time = 60000.0 # Added for new PHOTOM step
input_model.meta.exposure.mid_time = 60000.0 # Added for new PHOTOM step
input_model.meta.photometry.pixelarea_arcsecsq = 0.0025
input_model.meta.photometry.pixelarea_steradians = 0.0025 * A2_TO_SR
elif instrument == 'FGS':
Expand Down Expand Up @@ -803,7 +803,7 @@ def create_photom_miri_image(min_wl=16.5, max_wl=19.5,
('tau', '<f4'),
('t0', '<f4')])
reftabc = np.array(list(zip(timecoeff_amp, timecoeff_tau, timecoeff_t0)),
dtype=dtypec)
dtype=dtypec)
ftab = datamodels.MirImgPhotomModel(phot_table=reftab, timecoeff=reftabc)

return ftab
Expand Down Expand Up @@ -1342,6 +1342,21 @@ def test_niriss_image():
assert np.allclose(ratio, compare, rtol=1.e-7)


def test_expected_failure_niriss_cubemodel():
"""
Test that passing a CubeModel to calc_niriss raises an exception
This occurs when extract_1d step is skipped, e.g. for NIRISS SOSS data
in FULL subarray.
"""

input_model = create_input('NIRISS', 'NIS', 'NIS_SOSS',
filter='CLEAR', pupil='GR700XD')
ds = photom.DataSet(input_model)
ds.input = datamodels.CubeModel()
with pytest.raises(photom.DataModelTypeError):
ds.calc_niriss(None)


def test_miri_mrs():
"""Test calc_miri, MRS data"""

Expand Down Expand Up @@ -1431,7 +1446,7 @@ def test_miri_image():
shape = input.shape
ix = shape[1] // 2
iy = shape[0] // 2
compare = photmjsr + amplitude * np.exp(-(60000 - t0)/tau) # Added for new PHOTOM step
compare = photmjsr + amplitude * np.exp(-(60000 - t0) / tau) # Added for new PHOTOM step
# Compare the values at the center pixel.
ratio = output[iy, ix] / input[iy, ix]
assert np.allclose(ratio, compare, rtol=1.e-7)
Expand Down

0 comments on commit 88f14f6

Please sign in to comment.