Skip to content

Commit

Permalink
Merge branch 'master' into JP-3581
Browse files Browse the repository at this point in the history
  • Loading branch information
emolter authored Jun 14, 2024
2 parents 7e2d281 + a818479 commit 88f5754
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 19 deletions.
3 changes: 3 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ outlier_detection
to detect outliers in TSO data, with user-defined
rolling window width via the ``rolling_window_width`` parameter. [#8473]

- Fixed a bug that led to small total flux offsets between input and blotted
images if the nominal and actual wcs-computed pixel areas were different. [#8553]

pathloss
--------

Expand Down
25 changes: 23 additions & 2 deletions jwst/associations/lib/dms_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@
'nrs_brightobj'
]

# Define the valid optical paths vs detector for NIRSpect Fixed-slit Science
# Define the valid optical paths vs detector for NIRSpec Fixed-slit Science
# Tuples are (SLIT, GRATING, FILTER, DETECTOR)
# All A-slits are represented by SLIT == 'a'.
NRS_FSS_VALID_OPTICAL_PATHS = (
Expand Down Expand Up @@ -204,7 +204,7 @@
('g140m', 'flat4', 'nrs2'),
)

# Define the valid optical paths vs detector for NIRSpect IFU Science
# Define the valid optical paths vs detector for NIRSpec IFU Science
# Tuples are (GRATING, FILTER, DETECTOR)
# The only combinations that result in data on the NRS2 detector are
# g140h/f100lp, g235h/f170lp, and g395h/f290lp.
Expand All @@ -223,6 +223,13 @@
('g395h', 'f290lp', 'nrs2'),
)


# Define the uncalibrated filters for NIRISS SOSS
# Data taken with these filters should not be processed beyond
# level 2a.
NIS_SOSS_UNCALIBRATED_FILTERS = ('f277w',)


# Key that uniquely identifies members.
MEMBER_KEY = 'expname'

Expand Down Expand Up @@ -1158,3 +1165,17 @@ def nrccoron_valid_detector(item):
return True
else:
return True


def nissoss_calibrated_filter(item):
"""Check that a NIRISS filter is calibrated."""
_, exp_type = item_getattr(item, ['exp_type'])
if exp_type != 'nis_soss':
return True

try:
_, filter = item_getattr(item, ['filter'])
except KeyError:
return False

return filter not in NIS_SOSS_UNCALIBRATED_FILTERS
21 changes: 20 additions & 1 deletion jwst/associations/lib/rules_level2b.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
Constraint_WFSC,
format_list,
item_getattr,
nissoss_calibrated_filter,
nrccoron_valid_detector,
nrsfss_valid_detector,
nrsifu_valid_detector,
Expand Down Expand Up @@ -482,7 +483,7 @@ def __init__(self, *args, **kwargs):
DMSAttrConstraint(
name='exp_type',
sources=['exp_type'],
value=('nrs_brightobj')
value='nrs_brightobj'
),
SimpleConstraint(
value=False,
Expand All @@ -492,6 +493,24 @@ def __init__(self, *args, **kwargs):
]),
],
reduce=Constraint.notany
),
# Don't allow NIRISS SOSS with uncalibrated filters
Constraint(
[
Constraint([
DMSAttrConstraint(
name='exp_type',
sources=['exp_type'],
value='nis_soss'
),
SimpleConstraint(
value=False,
test=lambda value, item: nissoss_calibrated_filter(item) == value,
force_unique=False
),
]),
],
reduce=Constraint.notany
)
])

Expand Down
33 changes: 24 additions & 9 deletions jwst/associations/lib/rules_level3.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
import logging

from jwst.associations.registry import RegistryMarker
from jwst.associations.lib.dms_base import (Constraint_TargetAcq, Constraint_TSO, nrsfss_valid_detector, nrsifu_valid_detector)
from jwst.associations.lib.dms_base import (nrccoron_valid_detector)
from jwst.associations.lib.dms_base import (
Constraint_TargetAcq, Constraint_TSO,
nissoss_calibrated_filter, nrccoron_valid_detector,
nrsfss_valid_detector, nrsifu_valid_detector)
from jwst.associations.lib.process_list import ListCategory
from jwst.associations.lib.rules_level3_base import *
from jwst.associations.lib.rules_level3_base import (
dms_product_name_sources, dms_product_name_nrsfs_sources, dms_product_name_noopt, dms_product_name_coronimage,
dms_product_name_sources, dms_product_name_nrsfs_sources,
dms_product_name_noopt, dms_product_name_coronimage,
format_product
)

Expand Down Expand Up @@ -881,12 +884,12 @@ def __init__(self, *args, **kwargs):
DMSAttrConstraint(
name='restricted_grism',
sources=['exp_type'],
value=('nrc_tsgrism')
value='nrc_tsgrism'
),
DMSAttrConstraint(
name='grism_clear',
sources=['pupil'],
value=('clear')
value='clear'
),
]),
Constraint([
Expand All @@ -904,19 +907,31 @@ def __init__(self, *args, **kwargs):
],
reduce=Constraint.notany
),
# Don't allow NIRISS SOSS with NINTS=1 in tso3
# Don't allow NIRISS SOSS with NINTS=1 or uncalibrated filters
Constraint(
[
Constraint([
DMSAttrConstraint(
name='exp_type',
sources=['exp_type'],
value=('nis_soss')
value='nis_soss'
),
DMSAttrConstraint(
name='nints',
sources=['nints'],
value=('1')
value='1'
),
]),
Constraint([
DMSAttrConstraint(
name='exp_type',
sources=['exp_type'],
value='nis_soss'
),
SimpleConstraint(
value=False,
test=lambda value, item: nissoss_calibrated_filter(item) == value,
force_unique=False
),
]),
],
Expand All @@ -929,7 +944,7 @@ def __init__(self, *args, **kwargs):
DMSAttrConstraint(
name='exp_type',
sources=['exp_type'],
value=('nrs_brightobj')
value='nrs_brightobj'
),
SimpleConstraint(
value=False,
Expand Down
8 changes: 7 additions & 1 deletion jwst/outlier_detection/outlier_detection.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from jwst.resample import resample
from jwst.resample.resample_utils import build_driz_weight, calc_gwcs_pixmap
from jwst.stpipe import Step
from jwst.resample.resample import compute_image_pixel_area

log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)
Expand Down Expand Up @@ -568,7 +569,12 @@ def gwcs_blot(median_model, blot_img, interp='poly5', sinscl=1.0):
log.debug("Pixmap shape: {}".format(pixmap[:, :, 0].shape))
log.debug("Sci shape: {}".format(blot_img.data.shape))

pix_ratio = 1
if 'SPECTRAL' not in blot_img.meta.wcs.output_frame.axes_type:
input_pixflux_area = blot_img.meta.photometry.pixelarea_steradians
input_pixel_area = compute_image_pixel_area(blot_img.meta.wcs)
pix_ratio = np.sqrt(input_pixflux_area / input_pixel_area)
else:
pix_ratio = 1.0
log.info('Blotting {} <-- {}'.format(blot_img.data.shape, median_model.data.shape))

outsci = np.zeros(blot_img.shape, dtype=np.float32)
Expand Down
4 changes: 4 additions & 0 deletions jwst/outlier_detection/tests/test_outlier_detection.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ def we_many_sci(
sci1.var_rnoise = np.zeros(shape) + 1.0
sci1.meta.filename = "foo1_cal.fits"

# add pixel areas
sci1.meta.photometry.pixelarea_steradians = 1.0
sci1.meta.photometry.pixelarea_arcsecsq = 1.0

# Make copies with different noise
all_sci = [sci1]
for i in range(numsci - 1):
Expand Down
8 changes: 4 additions & 4 deletions jwst/resample/resample.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def __init__(self, input_models, output=None, single=False, blendheaders=True,
self.output_wcs.array_shape = output_shape[::-1]

if output_wcs.pixel_area is None:
output_pix_area = _compute_image_pixel_area(self.output_wcs)
output_pix_area = compute_image_pixel_area(self.output_wcs)
if output_pix_area is None:
raise ValueError(
"Unable to compute output pixel area from 'output_wcs'."
Expand Down Expand Up @@ -250,7 +250,7 @@ def resample_many_to_many(self):
if (input_pixflux_area and
'SPECTRAL' not in img.meta.wcs.output_frame.axes_type):
img.meta.wcs.array_shape = img.data.shape
input_pixel_area = _compute_image_pixel_area(img.meta.wcs)
input_pixel_area = compute_image_pixel_area(img.meta.wcs)
if input_pixel_area is None:
raise ValueError(
"Unable to compute input pixel area from WCS of input "
Expand Down Expand Up @@ -336,7 +336,7 @@ def resample_many_to_one(self):
if (input_pixflux_area and
'SPECTRAL' not in img.meta.wcs.output_frame.axes_type):
img.meta.wcs.array_shape = img.data.shape
input_pixel_area = _compute_image_pixel_area(img.meta.wcs)
input_pixel_area = compute_image_pixel_area(img.meta.wcs)
if input_pixel_area is None:
raise ValueError(
"Unable to compute input pixel area from WCS of input "
Expand Down Expand Up @@ -805,7 +805,7 @@ def _get_boundary_points(xmin, xmax, ymin, ymax, dx=None, dy=None, shrink=0):
return x, y, area, center, b, r, t, l


def _compute_image_pixel_area(wcs):
def compute_image_pixel_area(wcs):
""" Computes pixel area in steradians.
"""
if wcs.array_shape is None:
Expand Down
4 changes: 2 additions & 2 deletions jwst/resample/tests/test_resample_step.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from jwst.assign_wcs.util import compute_fiducial, compute_scale
from jwst.extract_2d import Extract2dStep
from jwst.resample import ResampleSpecStep, ResampleStep
from jwst.resample.resample import _compute_image_pixel_area
from jwst.resample.resample import compute_image_pixel_area
from jwst.resample.resample_spec import ResampleSpecData


Expand All @@ -28,7 +28,7 @@ def _set_photom_kwd(im):
bb = ((xmin - 0.5, xmax - 0.5), (ymin - 0.5, ymax - 0.5))
im.meta.wcs.bounding_box = bb

mean_pixel_area = _compute_image_pixel_area(im.meta.wcs)
mean_pixel_area = compute_image_pixel_area(im.meta.wcs)
if mean_pixel_area:
im.meta.photometry.pixelarea_steradians = mean_pixel_area
im.meta.photometry.pixelarea_arcsecsq = (
Expand Down

0 comments on commit 88f5754

Please sign in to comment.