diff --git a/src/stcal/jump/twopoint_difference.py b/src/stcal/jump/twopoint_difference.py index 5be6b595..78fb425c 100644 --- a/src/stcal/jump/twopoint_difference.py +++ b/src/stcal/jump/twopoint_difference.py @@ -153,24 +153,44 @@ def find_crs( num_flagged_grps = 0 # determine the number of groups with all pixels set to DO_NOT_USE ngrps = dat.shape[1] + max_flagged_grps = 0 + total_flagged_grps = 0 for integ in range(nints): + num_flagged_grps = 0 for grp in range(dat.shape[1]): if np.all(np.bitwise_and(gdq[integ, grp, :, :], dnu_flag)): num_flagged_grps += 1 + if num_flagged_grps > max_flagged_grps: + max_flagged_grps = num_flagged_grps + total_flagged_grps += num_flagged_grps if only_use_ints: total_sigclip_groups = nints else: - total_sigclip_groups = nints * (ngrps - num_flagged_grps) - total_groups = nints * (ngrps - num_flagged_grps) - total_diffs = nints * (ngrps - 1 - num_flagged_grps) - total_usable_diffs = total_diffs - num_flagged_grps - if ((ngrps < minimum_groups and only_use_ints and nints < minimum_sigclip_groups) or - (not only_use_ints and nints * ngrps < minimum_sigclip_groups and - total_groups < minimum_groups)): + total_sigclip_groups = nints * ngrps - num_flagged_grps + min_usable_groups = ngrps - max_flagged_grps + total_groups = nints * ngrps - total_flagged_grps + min_usable_diffs = min_usable_groups - 1 + sig_clip_grps_fails = False + total_noise_min_grps_fails = False + # Determine whether there are enough usable groups the two sigma clip options + if (only_use_ints and nints < minimum_sigclip_groups) \ + or \ + (not only_use_ints and total_sigclip_groups < minimum_sigclip_groups): + sig_clip_grps_fails = True + if min_usable_groups < minimum_groups: + total_noise_min_grps_fails = True + + if total_noise_min_grps_fails and sig_clip_grps_fails: log.info("Jump Step was skipped because exposure has less than the minimum number of usable groups") - dummy = np.zeros((dataa.shape[1] - 1, dataa.shape[2], dataa.shape[3]), - dtype=np.float32) - return gdq, row_below_gdq, row_above_gdq, 0, dummy + dummy = np.zeros((dataa.shape[1] - 1, dataa.shape[2], dataa.shape[3]), dtype=np.float32) + return gdq, row_below_gdq, row_above_gdq, -99, dummy +# +# if ((only_use_ints and nints < minimum_sigclip_groups) # sigclip across ints with not enough ints +# or (not only_use_ints and (ngrps < minimum_sigclip_groups) and # sigclip within an int not enough groups +# min_usable_groups < minimum_groups)): # regular jump detection minimum groups +# log.info("Jump Step was skipped because exposure has less than the minimum number of usable groups") +# dummy = np.zeros((dataa.shape[1] - 1, dataa.shape[2], dataa.shape[3]), dtype=np.float32) +# return gdq, row_below_gdq, row_above_gdq, -99, dummy else: # set 'saturated' or 'do not use' pixels to nan in data dat[np.where(np.bitwise_and(gdq, sat_flag))] = np.nan @@ -239,7 +259,7 @@ def find_crs( # use mask on data, so the results will have sat/donotuse groups masked first_diffs = np.diff(dat, axis=1) - if total_usable_diffs >= min_diffs_single_pass: + if min_usable_diffs >= min_diffs_single_pass: # There are enough diffs in all ints to look for more than one jump warnings.filterwarnings("ignore", ".*All-NaN slice encountered.*", RuntimeWarning) median_diffs = np.nanmedian(first_diffs, axis=(0, 1)) warnings.resetwarnings() diff --git a/tests/test_twopoint_difference.py b/tests/test_twopoint_difference.py index ce6d7b14..e38f33d7 100644 --- a/tests/test_twopoint_difference.py +++ b/tests/test_twopoint_difference.py @@ -21,6 +21,98 @@ def _cube(ngroups, nints=1, nrows=204, ncols=204, readnoise=10): return _cube +def test_sigclip_not_enough_groups(setup_cube): + ngroups = 10 + nints = 9 + nrows = 200 + ncols = 200 + data, gdq, nframes, read_noise, rej_threshold = setup_cube(ngroups, nints=8, nrows=2, ncols=2, readnoise=8) + out_gdq, row_below_gdq, rows_above_gdq, total_crs, stddev = find_crs( + data, gdq, read_noise, rej_threshold, rej_threshold, rej_threshold, + nframes, False, 200, 10, DQFLAGS, + minimum_sigclip_groups=10, minimum_groups=5 + ) + assert total_crs == -99 + +def test_sigclip_not_enough_groups(setup_cube): + ngroups = 5 + nints = 9 + nrows = 200 + ncols = 200 + data, gdq, nframes, read_noise, rej_threshold = setup_cube(ngroups, nints=8, nrows=2, ncols=2, readnoise=8) + out_gdq, row_below_gdq, rows_above_gdq, total_crs, stddev = find_crs( + data, gdq, read_noise, rej_threshold, rej_threshold, rej_threshold, + nframes, False, 200, 10, DQFLAGS, + minimum_sigclip_groups=11, minimum_groups=6 + ) + assert total_crs == -99 + +def test_sigclip_not_enough_groups(setup_cube): + ngroups = 12 + nints = 9 + nrows = 200 + ncols = 200 + + data, gdq, nframes, read_noise, rej_threshold = setup_cube(ngroups, nints=8, nrows=2, ncols=2, readnoise=8) + data[0, 0:2, 0:, 0] = 1 + out_gdq, row_below_gdq, rows_above_gdq, total_crs, stddev = find_crs( + data, gdq, read_noise, rej_threshold, rej_threshold, rej_threshold, + nframes, False, 200, 10, DQFLAGS, + minimum_sigclip_groups=11, minimum_groups=16 + ) + assert total_crs == -99 + +def test_sigclip_with_num_small_groups(setup_cube): + ngroups = 12 + nints = 190 + + data, gdq, nframes, read_noise, rej_threshold = setup_cube(ngroups, nints=nints, nrows=2, ncols=2, readnoise=8) + data[0, 0:2, 0:, 0] = 1 + out_gdq, row_below_gdq, rows_above_gdq, total_crs, stddev = find_crs( + data, gdq, read_noise, rej_threshold, rej_threshold, rej_threshold, + nframes, False, 200, 10, DQFLAGS, + minimum_sigclip_groups=11, minimum_groups=16 + ) + assert total_crs != -99 + +def test_nosigclip_with_enough_groups(setup_cube): + ngroups = 12 + nints = 1 + + data, gdq, nframes, read_noise, rej_threshold = setup_cube(ngroups, nints=nints, nrows=2, ncols=2, readnoise=8) + data[0, 0:2, 0:, 0] = 1 + out_gdq, row_below_gdq, rows_above_gdq, total_crs, stddev = find_crs( + data, gdq, read_noise, rej_threshold, rej_threshold, rej_threshold, + nframes, False, 200, 10, DQFLAGS, + minimum_sigclip_groups=11, minimum_groups=5 + ) + assert total_crs != -99 + +def test_nosigclip_with_num_small_groups(setup_cube): + ngroups = 4 + nints = 1 + + data, gdq, nframes, read_noise, rej_threshold = setup_cube(ngroups, nints=nints, nrows=2, ncols=2, readnoise=8) + data[0, 0:2, 0:, 0] = 1 + out_gdq, row_below_gdq, rows_above_gdq, total_crs, stddev = find_crs( + data, gdq, read_noise, rej_threshold, rej_threshold, rej_threshold, + nframes, False, 200, 10, DQFLAGS, + minimum_sigclip_groups=11, minimum_groups=16 + ) + assert total_crs == -99 + +def test_nosigclip_with_num_small_groups(setup_cube): + ngroups = 4 + nints = 100 + + data, gdq, nframes, read_noise, rej_threshold = setup_cube(ngroups, nints=nints, nrows=2, ncols=2, readnoise=8) + data[0, 0:2, 0:, 0] = 1 + out_gdq, row_below_gdq, rows_above_gdq, total_crs, stddev = find_crs( + data, gdq, read_noise, rej_threshold, rej_threshold, rej_threshold, + nframes, False, 200, 10, DQFLAGS, + minimum_sigclip_groups=100, minimum_groups=16 + ) + assert total_crs != -99 def test_varying_groups(setup_cube): ngroups = 5