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-1860: Fix ramp_fit counting of segments #5653

Merged
merged 6 commits into from
Jan 22, 2021

Conversation

hbushouse
Copy link
Collaborator

Update the function in ramp_fitting that attempts to estimate the max number of segments that will be needed to fit any pixel, given the number of CR and DO_NOT_USE flags that break up each pixel's ramp. Previously the function only looked for CR (JUMP_DET) flags, but a recent update to the saturation step allows for adding DO_NOT_USE flags to groups with values below the A-to-D floor (< 0). So now the ramp for a given pixel can be broken into multiple segments due to both JUMP_DET and DO_NOT_USE flags, so we need to check for both. Checking for only JUMP_DET was causing the data arrays to be created too small to hold data from all segments, leading to an "index out of bounds" error when trying to stuff data into the array.

Fixes #5630 / JP-1860

@codecov
Copy link

codecov bot commented Jan 21, 2021

Codecov Report

Merging #5653 (31ac154) into master (a03ec7d) will increase coverage by 0.22%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #5653      +/-   ##
==========================================
+ Coverage   74.46%   74.68%   +0.22%     
==========================================
  Files         416      416              
  Lines       38109    38632     +523     
  Branches     5101     5101              
==========================================
+ Hits        28378    28854     +476     
- Misses       9731     9778      +47     
Flag Coverage Δ *Carryforward flag
nightly 76.00% <100.00%> (ø) Carriedforward from a03ec7d
unit 54.17% <100.00%> (-0.01%) ⬇️

*This pull request uses carry forward flags. Click here to find out more.

Impacted Files Coverage Δ
jwst/ramp_fitting/ramp_fit.py 83.16% <100.00%> (+3.56%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a03ec7d...31ac154. Read the comment docs.

gdq_cr = np.bitwise_and( gdq[nint, :, :, :], dqflags.group['JUMP_DET'])
temp_max_cr = int((gdq_cr.sum(axis=0)).max()/dqflags.group['JUMP_DET'])
max_cr = max( max_cr, temp_max_cr )
gdq_cr = np.bitwise_and(gdq[nint], dqflags.group['JUMP_DET'] | dqflags.group['DO_NOT_USE'])
Copy link
Collaborator

@jdavies-st jdavies-st Jan 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The expression:

dqflags.group['JUMP_DET'] | dqflags.group['DO_NOT_USE']

always evaluates to 5. So the above is really:

gdq_cr = np.bitwise_and(gdq[nint], 5)

which will pick out all the 1, 4 and 5 values in gdq. For example:

In [24]: gdq                                                                                                          
Out[24]: array([0, 1, 4, 5, 8])

In [25]: np.bitwise_and(gdq, 5)                                                                                       
Out[25]: array([0, 1, 4, 5, 0])

But then when you sum the resulting array above, instead of getting 3, the 4 and 5 are going to give you a much higher count, 10 in this case. When really all you needed was 4 segments for 3 CRs.

Instead of summing you may want to count them using np.count_nonzero. Summing was fine when the values were all 4 and that could be corrected by dividing by 4, but not now.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, please write a quick unit test for this so we don't break it again. 😄

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm, could've sworn I had put in an appropriate expression that basically returned an array of 1's and 0's (equivalent to True/False), such that the .sum() really did just count up the number of hits, as opposed to the sum of all the flag values. Will look at that again.

Unit tests: to quote the Beatles, "yeah, yeah, yeah, ..."

Copy link
Collaborator

@jdavies-st jdavies-st Jan 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also also, I would pick either:

np.bitwise_and(gdq[nint], np.bitwise_or(dqflags.group['JUMP_DET'], dqflags.group['DO_NOT_USE']))

or

gdq[nint] & (dqflags.group['JUMP_DET'] | dqflags.group['DO_NOT_USE'])

not mix up the function calls and operators (which point to the function calls).

Also also also, might be nice to put something like

DO_NOT_USE = dqflags.group['DO_NOT_USE']

globally in this module as we've done elsewhere to make these sorts of things a bit more clear and concise:

gdq[nint] & (JUMP_DET | DO_NOT_USE)

Copy link
Collaborator

@stscieisenhamer stscieisenhamer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides the existing commentary, LGTM.

@hbushouse hbushouse requested a review from jdavies-st January 21, 2021 21:15
# ramps, to use as a surrogate for the number of segments along the ramps
# Note that we only care about flags that are NOT in the first or last groups,
# because exclusion of a first or last group won't result in an additional segment.
max_cr = np.count_nonzero(np.bitwise_and(gdq[:, 1:-1], JUMP_DET | DO_NOT_USE), axis=1).max()
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note that max_cr is bumped up by 1 later in line 2956, to account for the fact that n flags implies n+1 segments.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor comment: Is there a reason not to bump now? Or is the later use a conceptually different value, segments, as opposed to "maximum rejects".

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No really good reason I suppose, although they are a bit different conceptually. This line simply computes the max number "interrupts" in any ramp, and then that number of interrupts turns into n+1 segments for fitting. Besides, the line is so long already, I didn't want to add yet another operation on the end of it!

# ramps, to use as a surrogate for the number of segments along the ramps
# Note that we only care about flags that are NOT in the first or last groups,
# because exclusion of a first or last group won't result in an additional segment.
max_cr = np.count_nonzero(np.bitwise_and(gdq[:, 1:-1], JUMP_DET | DO_NOT_USE), axis=1).max()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor comment: Is there a reason not to bump now? Or is the later use a conceptually different value, segments, as opposed to "maximum rejects".

@hbushouse
Copy link
Collaborator Author

Errors in CI appear to be due to access problems with crds_cache. Trying again.

@hbushouse hbushouse closed this Jan 22, 2021
@hbushouse hbushouse added this to the Build 7.7.x milestone Jan 22, 2021
@hbushouse hbushouse reopened this Jan 22, 2021
@hbushouse hbushouse merged commit 60b9914 into spacetelescope:master Jan 22, 2021
@hbushouse hbushouse deleted the jp1860 branch January 22, 2021 15:21
@hbushouse hbushouse modified the milestones: Build 7.7.x, Build 7.7 Jan 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ramp_fit crashing for some NIRCam images in DMS B7.7 testing
3 participants