Wavelength template line detection - #2133
Conversation
profxj
left a comment
There was a problem hiding this comment.
Excellent addition. I might give Debora a head's up about it too
If you haven't already
tbowers7
left a comment
There was a problem hiding this comment.
Thanks for figuring out this issue. There is only one place that needs an actual change -- the rest are questions and comments. Approving now.
| # NOTE: I've hard-coded the values for good_frac, fwhm_incr, and | ||
| # max_good_iter. We may want to revisit this during testing and/or as | ||
| # we continue to develop. |
There was a problem hiding this comment.
Is there any reason at all to expose these as user-tunable parameters, or are they strictly algorithm-specific parameters that need to be tested and set for good?
There was a problem hiding this comment.
My hope is that these are actually (somewhat) temporary parameters, so I think the answer to your first question is no. Particularly because it's would be difficult to add a way for a user to assess what the parameters should be without digging into the code.
| f'shift = {shift_vec[iarxiv]:5.3f}, stretch = {stretch_vec[iarxiv]:5.3f}, cc = ' | ||
| f'{ccorr_vec[iarxiv]:5.3f}' |
There was a problem hiding this comment.
Formatting annoyance: place the "cc =" on the next line -- doesn't affect anything other than me reading the code.
| # Grab the observed arc spectrum | ||
| obs_spec_i = spec[:,slit] | ||
| # get FWHM for this slit | ||
| # TODO: Doesn't this mean measured_fwhms *cannot* be None? |
There was a problem hiding this comment.
That's how I read it. Maybe add a defensive check for None?
There was a problem hiding this comment.
Instead of checking for None, I made it a positional argument.
|
|
||
| # TODO: JFH This continue statement deals with the case when the | ||
| # msnippet derives from *entirely* zero-padded pixels, and allows | ||
| # the code to continue with crashing. This code is constantly |
There was a problem hiding this comment.
Good catch! Fixed.
| if all(iter_args) and len(w)/len(tampl) < good_frac: | ||
| # Iteratively increase the FWHM in an attempt to improve the line detection | ||
| for i in range(max_good_iter): | ||
| _fwhm = fwhm*fwhm_incr**(i+1) |
There was a problem hiding this comment.
So, if fwhm_incr were less than 1, we would be decreasing the FWHM with each iteration. Is there a case where this would be useful at all?
There was a problem hiding this comment.
In the limited testing I've done, it seems like you tend to miss lines if the FWHM is too small, but not if it is too big. That means there is not much to be gained by iteratively making the FWHM smaller. But, I didn't think it was worth imposing that fwhm_incr be greater than 1, particularly given that it's effectively a developer-only parameter in the current workflow. I've added a comment along these lines.
| zerolag_shift_stretch, args=(y1,y2), x0=x0_guess, tol=toler, | ||
| bounds=bounds, disp=False, polish=True, seed=seed) | ||
| zerolag_shift_stretch, args=(y1,y2), x0=x0_guess, tol=toler, bounds=bounds, disp=False, | ||
| polish=True, rng=seed |
There was a problem hiding this comment.
The seed keyword is being deprecated by scipy, in favor of rng.
| continue | ||
| # Detect lines and store the spectral FWHM | ||
| _, _, cent, wdth, _, best, _, nsig = arc.detect_lines(arc_spec.squeeze(), sigdetect=sigdetect, fwhm=fwhm, bpm=arc_spec_bpm.squeeze()) | ||
| # NOTE: "best" is a list of line indices, NOT a boolean array! |
There was a problem hiding this comment.
This kind of NOTE occurs often in this PR...
This indicates that a boolean array is expected for this kind of variable... is there a good reason it is not and/or would it be prohibitively expensive (code changes / in-process computation / etc.) to make it thus?
There was a problem hiding this comment.
Personally, I often expect that these kinds of arrays are boolean. So I added these (admittedly obnoxious) notes mostly as a reminder to me. At the same time, I didn't think it was worth actually trying to change the object from an int array to a bool array. Punting...
kbwestfall
left a comment
There was a problem hiding this comment.
Thanks for the reviews! All comments addressed. Next is to run the tests!
| # NOTE: I've hard-coded the values for good_frac, fwhm_incr, and | ||
| # max_good_iter. We may want to revisit this during testing and/or as | ||
| # we continue to develop. |
There was a problem hiding this comment.
My hope is that these are actually (somewhat) temporary parameters, so I think the answer to your first question is no. Particularly because it's would be difficult to add a way for a user to assess what the parameters should be without digging into the code.
| f'shift = {shift_vec[iarxiv]:5.3f}, stretch = {stretch_vec[iarxiv]:5.3f}, cc = ' | ||
| f'{ccorr_vec[iarxiv]:5.3f}' |
| continue | ||
| # Detect lines and store the spectral FWHM | ||
| _, _, cent, wdth, _, best, _, nsig = arc.detect_lines(arc_spec.squeeze(), sigdetect=sigdetect, fwhm=fwhm, bpm=arc_spec_bpm.squeeze()) | ||
| # NOTE: "best" is a list of line indices, NOT a boolean array! |
There was a problem hiding this comment.
Personally, I often expect that these kinds of arrays are boolean. So I added these (admittedly obnoxious) notes mostly as a reminder to me. At the same time, I didn't think it was worth actually trying to change the object from an int array to a bool array. Punting...
| # Grab the observed arc spectrum | ||
| obs_spec_i = spec[:,slit] | ||
| # get FWHM for this slit | ||
| # TODO: Doesn't this mean measured_fwhms *cannot* be None? |
There was a problem hiding this comment.
Instead of checking for None, I made it a positional argument.
|
|
||
| # TODO: JFH This continue statement deals with the case when the | ||
| # msnippet derives from *entirely* zero-padded pixels, and allows | ||
| # the code to continue with crashing. This code is constantly |
There was a problem hiding this comment.
Good catch! Fixed.
| if all(iter_args) and len(w)/len(tampl) < good_frac: | ||
| # Iteratively increase the FWHM in an attempt to improve the line detection | ||
| for i in range(max_good_iter): | ||
| _fwhm = fwhm*fwhm_incr**(i+1) |
There was a problem hiding this comment.
In the limited testing I've done, it seems like you tend to miss lines if the FWHM is too small, but not if it is too big. That means there is not much to be gained by iteratively making the FWHM smaller. But, I didn't think it was worth imposing that fwhm_incr be greater than 1, particularly given that it's effectively a developer-only parameter in the current workflow. I've added a comment along these lines.
| zerolag_shift_stretch, args=(y1,y2), x0=x0_guess, tol=toler, | ||
| bounds=bounds, disp=False, polish=True, seed=seed) | ||
| zerolag_shift_stretch, args=(y1,y2), x0=x0_guess, tol=toler, bounds=bounds, disp=False, | ||
| polish=True, rng=seed |
There was a problem hiding this comment.
The seed keyword is being deprecated by scipy, in favor of rng.
I wanted to reduce the data in the
RAW_DATA/keck_deimos/830G_L_8410directory as a way of producing a test for flux calibration that would use themulti_spec_detoption. Wavelength calibration on detector 3 was failing becausepypeit.core.wavecal.wvutils.arc_lines_from_specwas not detecting lines in the template spectrumkeck_deimos_830G.fits. This is because the FWHM is too small. I.e., the FWHM of the observed data is smaller than in the template, which is causing the lines in the template to be rejected.This is a short term fix that adds a loop that iteratively increments the FWHM until the number of good template lines reaches some minimum fraction of all lines detected. This works for this data set, but we'll need to run the dev-suite to check how this affects other instruments.
In the longer term, I think we should
The primary changes are in
pypeit.core.wavecal.wvutils.arc_lines_from_specandpypeit.core.wavecal.autoid.reidentify. Particularly for the latter, I took the opportunity to clean-up the code and docs a bit.