Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JP-3805: Change prior-group flagging to DO_NOT_USE instead of SATURATION #321

Merged
merged 9 commits into from
Dec 20, 2024
1 change: 1 addition & 0 deletions changes/321.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Change flagging of 'pre-saturation' grouped data to use DO_NOT_USE instead of SATURATION flag to avoid confusing the snowball routine downstream.
9 changes: 3 additions & 6 deletions src/stcal/saturation/saturation.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,11 @@ def flag_saturated_pixels(

# Reset flag array to only pixels passing this gauntlet
flagarray[:] = 0
flagarray[indx] = 2
flagarray[indx] = dnu

# Grow the newly-flagged saturating pixels
if n_pix_grow_sat > 0:
flagarray = adjacent_pixels(flagarray, saturated, n_pix_grow_sat)
flagarray = adjacent_pixels(flagarray, dnu, n_pix_grow_sat)

# Add them to the gdq array
np.bitwise_or(gdq[ints, group, :, :], flagarray, gdq[ints, group, :, :])
Expand Down Expand Up @@ -166,10 +166,7 @@ def flag_saturated_pixels(

# Flag the 2nd group for the pixels passing that gauntlet
flagarray = np.zeros_like(mask,dtype='uint8')
flagarray[mask] = saturated
# flag any pixels that border these new pixels
if n_pix_grow_sat > 0:
flagarray = adjacent_pixels(flagarray, saturated, n_pix_grow_sat)
flagarray[mask] = dnu

# Add them to the gdq array
np.bitwise_or(gdq[ints, 1, :, :], flagarray, gdq[ints, 1, :, :])
Expand Down
42 changes: 41 additions & 1 deletion tests/test_saturation.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

"""
from enum import IntEnum

import pytest
import numpy as np

from stcal.saturation.saturation import flag_saturated_pixels
Expand Down Expand Up @@ -40,6 +40,7 @@ def test_basic_saturation_flagging():
assert np.all(gdq[0, satindex:, 5, 5] == DQFLAGS["SATURATED"])


@pytest.mark.xfail(reason="stcal PR#321 broke this test")
def test_read_pattern_saturation_flagging():
"""Check that the saturation threshold varies depending on how the reads
are allocated into resultants."""
Expand Down Expand Up @@ -78,6 +79,45 @@ def test_read_pattern_saturation_flagging():
assert np.all(gdq[0, 2:, 5, 5] == DQFLAGS["SATURATED"])


def test_read_pattern_saturation_flagging_dnu():
"""Check that the saturation threshold varies depending on how the reads
are allocated into resultants. First resultant expected to have DNU while
PR#321 band-aid still in place."""

# Create inputs, data, and saturation maps
data = np.zeros((1, 5, 20, 20)).astype("float32")
gdq = np.zeros((1, 5, 20, 20)).astype("uint32")
pdq = np.zeros((20, 20)).astype("uint32")
sat_thresh = np.ones((20, 20)) * 100000.0
sat_dq = np.zeros((20, 20)).astype("uint32")

# Add ramp values up to the saturation limit
data[0, 0, 5, 5] = 0
data[0, 1, 5, 5] = 20000
data[0, 2, 5, 5] = 40000
data[0, 3, 5, 5] = 60000 # Signal reaches saturation limit
data[0, 4, 5, 5] = 62000

# Set saturation value in the saturation model
satvalue = 60000
sat_thresh[5, 5] = satvalue

# set read_pattern to have many reads in the third resultant, so that
# its mean exposure time is much smaller than its last read time
# (in this case, the ratio is 13 / 20).
# This means that the effective saturation for the third resultant
# is 60000 * 13 / 20 = 39000 and the third resultant should be marked
# saturated.
read_pattern = [[1], [2], [3, 4, 5, 6, 7, 8, 9, 10], [11], [12], [13]]

gdq, pdq, _ = flag_saturated_pixels(
data, gdq, pdq, sat_thresh, sat_dq, ATOD_LIMIT, DQFLAGS, read_pattern=read_pattern
)

# Make sure that groups after the third get flagged
assert np.all(gdq[0, 2:, 5, 5] == [DQFLAGS["DO_NOT_USE"], DQFLAGS["SATURATED"], DQFLAGS["SATURATED"]])


def test_no_sat_check_at_limit():
"""Test to verify that pixels at the A-to-D limit (65535), but flagged with
NO_SAT_CHECK do NOT get flagged as saturated, and that their neighbors
Expand Down
Loading