-
Notifications
You must be signed in to change notification settings - Fork 28
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
PSF fitting methods #794
PSF fitting methods #794
Conversation
Codecov ReportPatch coverage is
📢 Thoughts on this report? Let us know!. |
53c6468
to
ced3642
Compare
@zacharyburnett @WilliamJamieson – it appears the failure on py39-oldestdeps-cov comes from the photutils minpin for numpy >= 1.22, while the others usually require >= 1.20. Any tips on what to do there? |
I don't know why |
pinned in #800 |
fetch-depth: 0 | ||
- id: data | ||
run: | | ||
echo "webbpsf_url=https://stsci.box.com/shared/static/n1fealx9q0m6sdnass6wnyfikvxtc0zz.gz" >> $GITHUB_OUTPUT |
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 note here that this file on Box that is shared between several folks at INS. If changes are necessary in the future, contact Marcio Melendez and/or Brad Sappington.
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.
No changes needed here, but for romanisim it's annoying that we have to update this each time a new webbpsf release happens. I haven't understood why this file can't have a name like webbpsf-latest-release-test.gz or something, and when a new version comes out the new test data file gets updated. That would mean that each new version doesn't require new CI updates.
pyproject.toml
Outdated
# temporary pin to photutils dev until >1.8.0 is available: | ||
'photutils @ git+https://github.com/astropy/photutils.git', |
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.
The next release of photutils may be out within a week or so, and I will update this pin when it's available.
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 looks great to me.
Some things to think about:
- If we didn't use IterativePSFPhotometry, could we avoid the scikit-learn dependency? It is pretty big and people might push back. On the other hand, it would be nice to be able to use the IterativePSFPhotometry eventually. I don't actually see it in the code, but I had thought that source grouping was a crowded field feature and we could get by with single star fits here.
- Re romancal vs. stcal vs. photutils: do you think fit_psf_to_image_model(...) would be sensible as part of photutils?
- dq_to_boolean_mask might fit better in romancal.lib.dqflags, but I don't feel strongly.
- There's a world where we precompute the gridded PSFs for each filter / SCA combination and save them somewhere (e.g., in CRDS). How long is that computation?
- Does your wiki page use this code? Can you link to it as part of this PR?
- Can you provide a little bit of run time information?
- I do think we need to understand the flipping of the stamps, though not as part of this PR. But let's at least make an issue.
- This probably more naturally belongs under source_detection/psf.py rather than lib/psf.py?
"WFI_Filter_F158_Center": 1.577, | ||
"WFI_Filter_F184_Center": 1.842, | ||
"WFI_Filter_F213_Center": 2.125, | ||
} |
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 wonder if there is a more natural place for these constants, but I don't have one in mind. I think the filters are fairly fixed now, but I don't actually know that either. If not, we need to update these for consistency's sake as the filters change.
Some day someone will ask to to real integrals over these filters in create_gridded_psf_model (i.e., not monochromatic), but I don't think we should go there for this PR.
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.
Is this info a good candidate for a reference file in CRDS? Then it can be changed by end users or INS without changing the code.
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's not crazy. I think if we wanted to go this route, we should instead get the whole filter curves into CRDS. i.e. what Goddard has here:
https://roman.gsfc.nasa.gov/science/RRI/Roman_effarea_20201130.xlsx
If we had that kind of thing we could also put other summary information about the bandpasses in those files; e.g., central wavelengths. The existing 'photom' file is some part of the way toward that end; one option would be to add more attributes there. Obviously, let's not make that part of this PR, though!
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.
Great, some options for moving forward: shall we make a ticket to add these quantities to CRDS, reference that ticket in a TODO
comment in the file in this PR, and make an RCAL ticket to do a follow-up PR when those quantities are available?
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.
sounds good to me
psf_model = CCDData.read(expected_output_path, unit=u.electron / u.s, ext=0) | ||
# the FITS file saved by webbpsf gets loaded with pixel | ||
# axes flipped in both dimensions, so flip them back after loading: | ||
psf_model.data = psf_model.data[::-1, ::-1] |
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 think we need to at least file an issue to follow up on this; it worries me.
slc_lg, _ = overlap_slices(synth_image.shape, psf_shape, (y0, x0), mode="trim") | ||
yy, xx = np.mgrid[slc_lg] | ||
model_data = fit_model(xx, yy) * image_model.data.unit | ||
model_err = np.sqrt(model_data.value) * model_data.unit |
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 see where this noise is added to the data?
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.
Good point. So far I'm not yet adding the shot noise to the data array, but I am increasing the uncertainties as the counts change.
# difference between input and output, normalized by the | ||
# uncertainty. Has units of sigma: | ||
delta_x = np.abs(true_x - results_table["x_fit"]) / results_table["x_err"] | ||
delta_y = np.abs(true_y - results_table["y_fit"]) / results_table["y_err"] |
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.
Can we also assert something about the size of x_err / y_err? Maybe x_err < 1 / (amp / (sqrt(noise^2 + amp)) * fudge factor? I just want to be able to catch failure modes like "all of the errors are very large, so we have small delta_x / delta_y but did a poor fit? I'm trying to use the rule-of-thump x_err ~ FWHM / (S/N), which doesn't apply for this undersampled data but isn't terrible, and using 1 pix for the FWHM, and doing a bad approximation to the S/N.
RE @schlafly:
Yes! The additional
The two methods in this PR are pretty simple – they allow a user fit PSF models to Roman ImageModels. Almost all of the work in this PR was choosing and vetting sensible defaults for the input parameters for PSF fitting specifically for Roman ImageModels. So personally, I think the Roman-specificity of this PR is the primary feature of this PR, making the other repos ill-fitting homes for this PR.
I agree, that's fair. The only reason I've put it in
This depends on a few parameters, primarily: (1) the number of PSFs to synthesize across each SCA, (2) the width of the FOV of the rendered PSF. The default gridded PSF model from this PR has a FOV of 50 pixels, rendered in 16 locations distributed across the SCA, and takes 10 seconds to run. For all SCAs, runtime will be a few minutes.
I wrote up a performance evaluation for the code in this repo in the confluence post. The methods in this PR are essentially identical with two exceptions. This PR provides sensible defaults given the results of the analysis, and this PR has comments/docstrings/tests.
With the default settings in this PR, I've run both methods for an exposure the F087 filter on SCA 7. Constructing a gridded PSF model takes 10 seconds. I ran the PSF model fit on a synthetic ImageModel, without supplying initial centroid or flux guesses. Of the 500 sources injected with
Agreed.
I'm happy either way. The forward-looking intention for putting it in |
Did you mean to close spacetelescope/romanisim#63 instead of this one? |
Yikes you're right! Thanks @schlafly! |
|
6b4a2b4
to
96483a8
Compare
339f3d1
to
1e15776
Compare
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.
Thanks. Two more minor comments. I don't think we have any regression tests here, so I can't see how this would have an effect there, but we usually require runs of the regression suite with the changes before merging.
@@ -19,7 +19,7 @@ dependencies = [ | |||
'gwcs >=0.18.1', | |||
'jsonschema >=4.8', | |||
'numpy >=1.22', | |||
'photutils >=1.6.0', | |||
'photutils @ git+https://github.com/astropy/photutils.git', |
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 looks to me like this is likely out now?
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.
The last remaining and necessary addition to photutils is from astropy/photutils#1617. I'll ask @larrybradley if the next release is likely to be soon.
fetch-depth: 0 | ||
- id: data | ||
run: | | ||
echo "webbpsf_url=https://stsci.box.com/shared/static/n1fealx9q0m6sdnass6wnyfikvxtc0zz.gz" >> $GITHUB_OUTPUT |
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.
No changes needed here, but for romanisim it's annoying that we have to update this each time a new webbpsf release happens. I haven't understood why this file can't have a name like webbpsf-latest-release-test.gz or something, and when a new version comes out the new test data file gets updated. That would mean that each new version doesn't require new CI updates.
8728716
to
3215966
Compare
3215966
to
eada0df
Compare
Description
This PR introduces methods for fitting model PSFs computed with WebbPSF to ImageModels in romancal.
Resolves RCAL-573
Closes #781
New dependencies
The model PSF is computed by
webbpsf
, and the model PSF is fit to Roman ImageModels using the newphotutils.psf
module refactor in astropy/photutils#1558 (and futher PRs that followed it). I've pinnedphotutils
to the dev version until the next release (expected within about a week), and pinned to the latest version ofwebbpsf
.Like CRDS, WebbPSF depends on several reference files which must be configured on a given machine before tests can be run. I've updated the CI setup so that GitHub Actions has access to those files. One limitation is that these WebbPSF reference files are versioned along with the software, so there are no dev files easily available to test against. For this reason, I've left WebbPSF out of the devdeps tests.
The last new dependency is
scikit-learn
. For crowded groups of sources, photutils has aSourceGrouper
class, which uses a clustering algorithm implemented inscikit-learn
to determine which sources are close enough to fit simultaneously with a joint model.Implementation
There are two public methods introduced in this PR:
create_gridded_psf_model
uses WebbPSF to construct an ePSF model that is compatible with the photutilspsf
module. The function primarily serves to provide the user with reasonable defaults based on previous testing.fit_psf_to_image_model
uses fits the PSF model to a Roman ImageModel. At this time, defaults have been optimized to give PSF fits with a good tradeoff between runtime and astrometric accuracy. Further tests should be done in the future to test photometric accuracy.Tests are included to ensure that the inferred centroids of bright, high S/N, synthetic point sources are within 3-sigma of their injected values.
Checklist
CHANGES.rst
under the corresponding subsection