diff --git a/src/stcal/jump/jump.py b/src/stcal/jump/jump.py index 02c6770c2..d75196696 100644 --- a/src/stcal/jump/jump.py +++ b/src/stcal/jump/jump.py @@ -14,10 +14,11 @@ def detect_jumps(frames_per_group, data, gdq, pdq, err, gain_2d, readnoise_2d, rejection_thresh, three_grp_thresh, four_grp_thresh, max_cores, max_jump_to_flag_neighbors, - min_jump_to_flag_neighbors, flag_4_neighbors, - after_jump_flag_dn1, after_jump_flag_n1, - after_jump_flag_dn2, after_jump_flag_n2, - dqflags): + min_jump_to_flag_neighbors, flag_4_neighbors, dqflags, + after_jump_flag_dn1=0.0, + after_jump_flag_n1=0, + after_jump_flag_dn2=0.0, + after_jump_flag_n2=0): """ This is the high-level controlling routine for the jump detection process. It loads and sets the various input data and parameters needed by each of @@ -87,6 +88,10 @@ def detect_jumps(frames_per_group, data, gdq, pdq, err, if set to True (default is True), it will cause the four perpendicular neighbors of all detected jumps to also be flagged as a jump. + dqflags: dict + A dictionary with at least the following keywords: + DO_NOT_USE, SATURATED, JUMP_DET, NO_GAIN_VALUE, GOOD + after_jump_flag_dn1 : float 1st flag after jumps with the specified DN jump to remove the transient seen from the slope calculation @@ -103,10 +108,6 @@ def detect_jumps(frames_per_group, data, gdq, pdq, err, 2nd flag n groups after companion threshold to remove the transient seen from the slope calculation - dqflags: dict - A dictionary with at least the following keywords: - DO_NOT_USE, SATURATED, JUMP_DET, NO_GAIN_VALUE, GOOD - Returns ------- gdq : int, 4D array @@ -166,10 +167,11 @@ def detect_jumps(frames_per_group, data, gdq, pdq, err, twopt.find_crs(data, gdq, readnoise_2d, rejection_thresh, three_grp_thresh, four_grp_thresh, frames_per_group, flag_4_neighbors, max_jump_to_flag_neighbors, - min_jump_to_flag_neighbors, - after_jump_flag_dn1, after_jump_flag_n1, - after_jump_flag_dn2, after_jump_flag_n2, - dqflags) + min_jump_to_flag_neighbors, dqflags, + after_jump_flag_dn1=after_jump_flag_dn1, + after_jump_flag_n1=after_jump_flag_n1, + after_jump_flag_dn2=after_jump_flag_dn2, + after_jump_flag_n2=after_jump_flag_n2) elapsed = time.time() - start else: diff --git a/src/stcal/jump/twopoint_difference.py b/src/stcal/jump/twopoint_difference.py index 4069f2e5f..e3cbe07e4 100644 --- a/src/stcal/jump/twopoint_difference.py +++ b/src/stcal/jump/twopoint_difference.py @@ -8,10 +8,12 @@ def find_crs(dataa, group_dq, read_noise, rejection_thresh, two_diff_rej_thresh, three_diff_rej_thresh, nframes, flag_4_neighbors, max_jump_to_flag_neighbors, - min_jump_to_flag_neighbors, - after_jump_flag_dn1, after_jump_flag_n1, - after_jump_flag_dn2, after_jump_flag_n2, - dqflags, copy_arrs=True): + min_jump_to_flag_neighbors, dqflags, + after_jump_flag_dn1=0.0, + after_jump_flag_n1=0, + after_jump_flag_dn2=0.0, + after_jump_flag_n2=0, + copy_arrs=True): """ Find CRs/Jumps in each integration within the input data array. The input @@ -57,6 +59,10 @@ def find_crs(dataa, group_dq, read_noise, rejection_thresh, neighbors (marginal detections). Any primary jump below this value will not have its neighbors flagged. + dqflags: dict + A dictionary with at least the following keywords: + DO_NOT_USE, SATURATED, JUMP_DET, NO_GAIN_VALUE, GOOD + after_jump_flag_dn1 : float 1st flag after jumps with the specified DN jump to remove the transient seen from the slope calculation @@ -73,10 +79,6 @@ def find_crs(dataa, group_dq, read_noise, rejection_thresh, 2nd flag n groups after companion threshold to remove the transient seen from the slope calculation - dqflags: dict - A dictionary with at least the following keywords: - DO_NOT_USE, SATURATED, JUMP_DET, NO_GAIN_VALUE, GOOD - copy_arrs : bool Flag for making internal copies of the arrays so the input isn't modified, defaults to True. @@ -284,9 +286,9 @@ def find_crs(dataa, group_dq, read_noise, rejection_thresh, flag_dn_threshold = [after_jump_flag_dn1, after_jump_flag_dn2] flag_groups = [after_jump_flag_n1, after_jump_flag_n2] # ensure the smallest threshold is 1st - if flag_dn_threshold[0] > flag_dn_threshold[1]: - flag_dn_threshold = np.flip(flag_dn_threshold) - flag_groups = np.flip(flag_groups) + # if flag_dn_threshold[0] > flag_dn_threshold[1]: + # flag_dn_threshold = np.flip(flag_dn_threshold) + # flag_groups = np.flip(flag_groups) cr_group, cr_row, cr_col = np.where(np.bitwise_and(gdq[integ], jump_flag)) @@ -316,7 +318,7 @@ def find_crs(dataa, group_dq, read_noise, rejection_thresh, row = cr_row[j] col = cr_col[j] if dn_jump[group - 1, row, col] >= cthres: - for kk in range(group, min(group + cgroup, ngroups)): + for kk in range(group, min(group + cgroup + 1, ngroups)): if (gdq[integ, kk, row, col] & sat_flag) == 0: if (gdq[integ, kk, row, col] & dnu_flag) == 0: gdq[integ, kk, row, col] =\ diff --git a/tests/test_twopoint_difference.py b/tests/test_twopoint_difference.py index 78deb3fb0..b753f3291 100644 --- a/tests/test_twopoint_difference.py +++ b/tests/test_twopoint_difference.py @@ -835,6 +835,113 @@ def test_first_last_3group(setup_cube): assert outgdq[0, 1, 0, 0] == 0 +def test_10grps_1cr_afterjump(setup_cube): + ngroups = 10 + data, gdq, nframes, read_noise, rej_threshold = setup_cube(ngroups, readnoise=10) + nframes = 1 + data[0, 0, 100, 100] = 0 + data[0, 1, 100, 100] = 10 + data[0, 2, 100, 100] = 21 + data[0, 3, 100, 100] = 33 + data[0, 4, 100, 100] = 46 + data[0, 5, 100, 100] = 60 + data[0, 6, 100, 100] = 1160 + data[0, 7, 100, 100] = 1175 + data[0, 8, 100, 100] = 1190 + data[0, 9, 100, 100] = 1209 + out_gdq, row_below_gdq, row_above_gdq = find_crs(data, gdq, read_noise, rej_threshold, + rej_threshold, rej_threshold, nframes, + False, 200, 10, DQFLAGS, + after_jump_flag_dn1=0.0, + after_jump_flag_n1=10) + # all groups after CR should be flagged + for k in range(6, 10): + assert 4 == out_gdq[0, k, 100, 100], f"after jump flagging failed in group {k}" + + +def test_10grps_1cr_afterjump_2group(setup_cube): + ngroups = 10 + data, gdq, nframes, read_noise, rej_threshold = setup_cube(ngroups, readnoise=10) + nframes = 1 + data[0, 0, 100, 100] = 0 + data[0, 1, 100, 100] = 10 + data[0, 2, 100, 100] = 21 + data[0, 3, 100, 100] = 33 + data[0, 4, 100, 100] = 46 + data[0, 5, 100, 100] = 60 + data[0, 6, 100, 100] = 1160 + data[0, 7, 100, 100] = 1175 + data[0, 8, 100, 100] = 1190 + data[0, 9, 100, 100] = 1209 + out_gdq, row_below_gdq, row_above_gdq = find_crs(data, gdq, read_noise, rej_threshold, + rej_threshold, rej_threshold, nframes, + False, 200, 10, DQFLAGS, + after_jump_flag_dn1=0.0, + after_jump_flag_n1=2) + + # 2 groups after CR should be flagged + for k in range(6, 9): + assert 4 == out_gdq[0, k, 100, 100], f"after jump flagging failed in group {k}" + + # rest not flagged + for k in range(9, 10): + assert 0 == out_gdq[0, k, 100, 100], f"after jump flagging incorrect in group {k}" + + +def test_10grps_1cr_afterjump_toosmall(setup_cube): + ngroups = 10 + data, gdq, nframes, read_noise, rej_threshold = setup_cube(ngroups, readnoise=10) + nframes = 1 + data[0, 0, 100, 100] = 0 + data[0, 1, 100, 100] = 10 + data[0, 2, 100, 100] = 21 + data[0, 3, 100, 100] = 33 + data[0, 4, 100, 100] = 46 + data[0, 5, 100, 100] = 60 + data[0, 6, 100, 100] = 1160 + data[0, 7, 100, 100] = 1175 + data[0, 8, 100, 100] = 1190 + data[0, 9, 100, 100] = 1209 + out_gdq, row_below_gdq, row_above_gdq = find_crs(data, gdq, read_noise, rej_threshold, + rej_threshold, rej_threshold, nframes, + False, 200, 10, DQFLAGS, + after_jump_flag_dn1=10000, + after_jump_flag_n1=10) + # all groups after CR should be flagged + for k in range(7, 10): + assert 0 == out_gdq[0, k, 100, 100], f"after jump flagging incorrect in group {k}" + + +def test_10grps_1cr_afterjump_twothresholds(setup_cube): + ngroups = 10 + data, gdq, nframes, read_noise, rej_threshold = setup_cube(ngroups, readnoise=10) + nframes = 1 + data[0, 0, 100, 100] = 0 + data[0, 1, 100, 100] = 10 + data[0, 2, 100, 100] = 121 + data[0, 3, 100, 100] = 133 + data[0, 4, 100, 100] = 146 + data[0, 5, 100, 100] = 160 + data[0, 6, 100, 100] = 1160 + data[0, 7, 100, 100] = 1175 + data[0, 8, 100, 100] = 1190 + data[0, 9, 100, 100] = 1209 + out_gdq, row_below_gdq, row_above_gdq = find_crs(data, gdq, read_noise, rej_threshold, + rej_threshold, rej_threshold, nframes, + False, 200, 10, DQFLAGS, + after_jump_flag_dn1=500, + after_jump_flag_n1=10, + after_jump_flag_dn2=10, + after_jump_flag_n2=2) + # 2 groups after CR should be flagged + for k in range(2, 5): + assert 4 == out_gdq[0, k, 100, 100], f"after jump flagging incorrect in group {k}" + + # all groups after CR should be flagged + for k in range(6, 10): + assert 4 == out_gdq[0, k, 100, 100], f"after jump flagging incorrect in group {k}" + + def test_median_func(): """