-
Notifications
You must be signed in to change notification settings - Fork 63
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
Roman Cycle 9 Updates #466
Conversation
1102d85
to
75a80c6
Compare
fc73761
to
8f35223
Compare
Codecov Report
@@ Coverage Diff @@
## develop #466 +/- ##
===========================================
+ Coverage 62.86% 62.89% +0.02%
===========================================
Files 11 11
Lines 4616 4622 +6
===========================================
+ Hits 2902 2907 +5
- Misses 1714 1715 +1
Continue to review full report at Codecov.
|
self._filter = value | ||
# UNRESOLVED: how do we know which pupil to reset to? make it clear in the docstring that you're unlocking *and* resetting to default. | ||
# UNRESOLVED: if you unlock_pupil_mask, lock_pupil, unlock_pupil, does the pupil mask also reset? | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It appears like this is doing the right thing, mainly because of the call to self._update_pupil(). The reset is based on the current values of wfi.filter and wfi.detector.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, thanks for the sanity check.
webbpsf/roman.py
Outdated
# Update Pupil | ||
# ------------ | ||
self._pupil_controller.validate_pupil(self._filter) | ||
UNRESOLVED: how do we know which mask to reset to? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above (line 815). The reset is based on the current values of wfi.filter
and wfi.detector
, and they seem to behave as expected.
webbpsf/roman.py
Outdated
@pupil.setter | ||
def pupil(self, value): | ||
# check if we've been through super() in init | ||
# UNRESOLVED: the check could be more explicit... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll also defer to your best programmer judgment here.
webbpsf/roman.py
Outdated
|
||
@pupil_mask.setter | ||
def pupil_mask(self, name): | ||
UNRESOLVED: better double-checking strategy than assert? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll defer to your best programmer judgment here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think these are wrong, but a better alternative isn't coming to me. I'll leave it as is for the sake of time.
_log.info("Removing custom pupil mask") | ||
self.pupil_mask = 'AUTO' | ||
UNRESOLVED: how do we know which mask to reset to? | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Limited understanding of the class here, so bear with me. I'm not sure if there's a use case where this particular method gets called.
From what I see, the locking/unlocking of the pupil and pupil_mask is done on the WFI object, not the WFIPupilController object. The former seems to be handling the unlocking as expected because it knows the values of the filter and detector, and resets them using wfi._update_pupil()
.
But WFIPupilController, by itself, has no knowledge of these values, so it cannot properly reset the pupil and pupil_mask. When we unlock the pupil, all it does is set the auto_lock
to True
, leaving the pupil and pupil_mask values as they were.
When instantiated, the pupil and pupil_mask are set to None - maybe that's what they should be reset to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right in saying that WFIPupilController
has no knowledge of the current pupil or pupil mask value and that the actual assignment of the pupil_mask
attribute happens in WFI
. This note was a reminder to re-check the WFI version of unlock_pupil_mask()
since it calls this one.
webbpsf/tests/test_roman.py
Outdated
wi.filter = filter | ||
wi.calc_psf(fov_pixels=4, oversample=1, nlambda=3) | ||
if filter == 'GRISM0': | ||
# UNRESOLVED: GRISM0 errors out. poppy's Instrument._get_weights() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I mentioned on Slack, I'm able to run calc_psf()
with GRISM0, so I'm not sure what's happening here. This particular test is passing for me even when I remove your IF GRISM0 statement:
test_roman.py::test_WFI_filters PASSED [100%]
======================== PASSES ========================
------------------------------- Captured stdout call -----------------------
F062
F087
F106
F129
F146
F158
F184
PRISM
F213
GRISM0
GRISM1
====================== 1 passed in 33.75s ===================
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the only comment that I'd say requires a follow up. calc_psf()
with GRISM0 errors out for me even with a fresh install and a new environment, and I think the failure makes sense given what I commented in the code about get_weights()
in poppy.
What do you get when you try the following (replacing the ellipsis with your path to the new data files)?
from astropy.io import fits
any(fits.getdata('.../WFI/filters/GRISM0_throughput.fits')['THROUGHPUT'] > .1)
If it's False
, I'm not sure why poppy would accept the weights as valid.
8c51443
to
c75a455
Compare
@@ -73,7 +73,7 @@ The WFI field of view is laid out as shown in the figure. To select a different | |||
['SCA01', 'SCA02', 'SCA03', 'SCA04', 'SCA05', 'SCA06', 'SCA07', 'SCA08', 'SCA09', 'SCA10', 'SCA11', 'SCA12', 'SCA13', 'SCA14', 'SCA15', 'SCA16', 'SCA17', 'SCA18'] | |||
>>> wfi.detector = 'SCA03' | |||
|
|||
The usable region of the 4096 by 4096 pixel detectors specified for the Wide Field Instrument will range from (4, 4) to (4092, 4092), accounting for the 4 pixel wide bands of reference pixels. **[The preceding may no longer be true.]** To change the position at which to calculate a PSF, simply assign an (X, Y) tuple:: | |||
The usable regions of the Wide Field Instrument's detectors are slightly smaller than their 4096 by 4096 pixel dimensions due to variations in reference pixel coverage at their edges. To change the position at which to calculate a PSF, assign an (X, Y) tuple:: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This text does not seem correct; the reference pixels don't vary. It's a fixed width of 4 pixels around all edges of all detectors. Rephrase to something like the following.
The usable, photosensitive regions of the Wide Field Instrument's detectors are slightly smaller than their 4096 by 4096 pixel dimensions, because the outermost 4 rows and columns are reference pixels that are not sensitive to light.
But that said, I don't understand entirely why this is relevant here for the PSF calculations. This is a detector property, not something in the optical models.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I talked about it with Charles but will catch up with you about this.
|
||
# UNRESOLVED: how do we know which pupil to reset to? make it clear in the docstring that you're unlocking *and* resetting to default. | ||
# UNRESOLVED: if you unlock_pupil_mask, lock_pupil, unlock_pupil, does the pupil mask also reset? | ||
Undoes the effects of lock_pupil() by resetting the class to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is out of scope for this PR, but at some point it might be worth revisiting some of the complexity that's been added into the WFI classes, such as this lock and unlock pupil functionality. What is the use case for that? Is it still needed? Does anyone actually use this part of the code? I think it may be the case that some of the code added over time is no longer particularly useful, and could potentially be simplified out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Robel and I spoke with Adric about this and Adric said it's useful in his workflows for the Roman ETC (and perhaps Pandeia). Robel also told me that there are some other, more intrepid users who like having this functionality.
@mperrin figured out that the GRISM0 discrepancy happened because I've still left GRISM0 out of |
@ojustino This looks good, apart from one quibble with some doc string text. We can fix that separately as part of other docs edits for release 1.0. I'm going to go ahead and merge this now. We ought to be able to add GRISM0 into the tests immediately, since once this is merged into develop the tests will run with synphot installed. So let's try immediately making a PR to reverse that right away after I merge this. |
Would resolve #465.
Updates
webbpsf
WFIPupilController
pupil_file_formatters
attribute that will hopefully allow for easier updates when pupil filename structures change in future cycles.update_pupil()
from the remains of the former_update_pupil()
,update_pupil_path()
, andvalidate_pupil()
. This method pointsWFI
to the appropriate pupil file and pupil mask string after the user changesWFI
's detector or filter. It is now the only standard approach for updating the pupil or pupil mask._get_filter_mask()
to help match a given filter with its corresponding pupil mask.pupil_mask
andpupil
so that direct assignment is no longer possible, though_pupil
and_pupil_mask
allow for indirect assignment inupdate_pupil()
.lock_pupil()
andlock_pupil_mask()
methods to disable default pupil/mask selection behavior by toggling the new_auto_pupil
and_auto_pupil_mask
attributes to False, respectively. Instead, they lockWFI
on the provided pupil file or pupil mask string.unlock_pupil()
andunlock_pupil_mask()
re-enable default behavior.GRISM_FILTER
GRISM_FILTERS
andPRISM_FILTER
PRISM_FILTERS
are now tuples containing the new string labels for those filters infilters.tsv
(including separate entries for grism's 0th and 1st degrees).WFI
_aberrations_files
_aberration_files
attribute to Cycle 9's Zernike files._is_custom_aberrations
_is_custom_aberration
and_current_aberrations_file
_current_aberration_file
._unmasked_pupil_path
and_masked_pupil_path
since their corresponding attributes were deleted fromWFIPupilController
.override_aberrations()
lock_aberrations()
andreset_override_aberrations()
unlock_aberrations()
.lock_pupil()
andlock_pupil_mask()
methods for advanced users who prefer to disable automatic pupil/mask selection and instead stick with a specific pupil file or mask, respectively. The correspondingunlock_pupil()
andunlock_pupil_mask()
methods return the class to its normal behavior. (These methods follow in the footsteps oflock_aberrations()
andunlock_aberrations()
.)pupil
andpupil_mask
so that direct assignment is no longer possible. Both attributes continue to dynamically update on any change to detector or filter that necessitates it._update_pupil()
as a shortcut toWFIPupilController.update_pupil()
used in the lock/unlock methods and the detector/filter setters.RomanInstrument
jitter_sigma
to 0.012 arcsec/axis to reflect new simulations (fixes Update Roman Jitter value #443).Other
webbpsf-data-source
(
webbpsf-data/
➡️webbpsf-data-source/
after #416)Out with the old...
webbpsf-data-source/WFI/wim_zernikes_cycle8.csv
➡️webbpsf-data-source/WFI/sources/cycle8/wim_zernikes_cycle8.csv
webbpsf-data-source/WFI/wim_zernikes_cycle8_grism.csv
➡️webbpsf-data-source/WFI/sources/cycle8/wim_zernikes_cycle8_grism.csv
webbpsf-data-source/WFI/wim_zernikes_cycle8_prism.csv
➡️webbpsf-data-source/WFI/sources/cycle8/wim_zernikes_cycle8_prism.csv
webbpsf-data-source/WFI/filters/*_throughput.fits
➡️webbpsf-data-source/WFI/sources/cycle8/filters/*_throughput.fits
)webbpsf-data-source/WFI/pupils
➡️webbpsf-data-source/WFI/sources/cycle8/new_pupils
)filters.tsv
already archived inwebbpsf-data-source/WFI/sources/cycle8_prism_grism/filters.tsv
)webbpsf-data-source/WFI/sources/cycle8/new_upscaled_HST_OPD.fits)
...in with the new.
(To examine file processing procedures, see
webbpsf-data-source/WFI/sources/cycle9/Process_zern_and_filters.ipynb
for Zernikes and filter files orwebbpsf-data-source/WFI/sources/cycle9/Oversample_rescale_pupil_images_cycle_9.ipynb
for pupil files.)wim
towsm
in spectral mode filenames to better distinguish them from imaging mode)webbpsf-data-source/WFI/sources/cycle9/wim_zernikes_cycle9.csv
webbpsf-data-source/WFI/sources/cycle9/wsm_zernikes_cycle9_grism.csv
webbpsf-data-source/WFI/sources/cycle9/wsm_zernikes_cycle9_prism.csv
webbpsf-data-source/WFI/sources/cycle9/filters.tsv
)webbpsf-data-source/WFI/sources/cycle9/filters/*_throughput.fits
)webbpsf-data-source/WFI/sources/cycle9/new_upscaled_HST_OPD.fits
)The files and directories were "pre-archived" in
webbpsf-data-source/WFI/sources/cycle9/
and then copied to their appropriate locations inwebbpsf-data-source
(the renamedupscaled_HST_OPD.fits
) orwebbpsf-data-source/WFI/
(the rest).Checks
[] Filter bandpasses
P120--> PRISM (newly named)G150--> GRISM0 (newly named and split)G150--> GRISM1 (newly named and split)Instrument layout (no changes)
Zernike coefficients
Pupil image compatibility
Notable Roman design changes