-
Notifications
You must be signed in to change notification settings - Fork 46
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
Improve stability of SIP fitting. Fix constant term - CRPIX - in SIP #427
Improve stability of SIP fitting. Fix constant term - CRPIX - in SIP #427
Conversation
Codecov ReportBase: 86.84% // Head: 86.93% // Increases project coverage by
Additional details and impacted files@@ Coverage Diff @@
## master #427 +/- ##
==========================================
+ Coverage 86.84% 86.93% +0.09%
==========================================
Files 24 25 +1
Lines 3769 3888 +119
==========================================
+ Hits 3273 3380 +107
- Misses 496 508 +12
Flags with carried forward coverage won't be shown. Click here to find out more.
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
Here I will attach an ASDF file with two test WCS: NIRCAM and MIRI. After unzipping, do the following: import asdf
with asdf.open('test_wcs.asdf') as af:
w_nircam = af["nircam_wcs"]
w_miri = af["miri_wcs"]
hdr = w_nircam.to_fits_sip(max_pix_error=0.001, degree=None, max_inv_pix_error=None, npoints=128, crpix=[500, 500]) |
89baa8c
to
5c37e28
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.
Discussion somewhere should explain why this technique is better (mathematically) than the numpy lsq fitter.
gwcs/wcs.py
Outdated
# 0 < i + j <= degree. | ||
pseudo_vander = np.empty((x.size, nterms), dtype=float) | ||
|
||
def crd_pwr(p, q): |
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 all this conditional logic really necessary? Why not just use the general expression?
a[i, j] = np.sum(coord_pq, dtype=flt_type) | ||
a[j, i] = a[i, j] | ||
|
||
with warnings.catch_warnings(record=True): |
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.
Should we add this fitter to astropy modeling?
gwcs/wcs.py
Outdated
@@ -2752,67 +2756,197 @@ def _calc_approx_inv(self, max_inv_pix_error=5, inv_degree=None, npoints=16): | |||
(Shift(crpix[0]) & Shift(crpix[1]))) | |||
|
|||
|
|||
def _fit_2D_poly(ntransform, npoints, degree, max_error, plate_scale, | |||
def _poly_fit_lu(xin, yin, xout, yout, degree): |
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 deserves a significant docstring.
34dbdc8
to
bfa163c
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.
I have a question about the memory consequences of caching powers, which depends on the maximum degree that might be encountered as well as the size of the image. Perhaps a worst case example should be cited for JWST?
# normal system proved to be significantly more accurate, efficient, | ||
# and stable than SVD. | ||
# | ||
# coord_pow - a dictionary used to store powers of coordinate arrays |
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 guess that this is not a significant memory issue for large arrays, but what is the highest power we envision?
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.
doesn't matter. memory caching cannot store/use more than 2x memory used for the pseudo-vandermonde matrix. Just an estimate, for 9th (highest) order SIP it will store 54*npoints**2 values in addition to the same number computed anyway. For 1024 points, it would require about 50-100MB extra depending on longdouble size.
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.
For an expected typical usage with npoints=256 and longdouble being 128 bits and SIP degree of 5, caching would require 20MB
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.
Right. Somehow I was thinking it was for every pixel.
cd12f32
to
b76d061
Compare
b76d061
to
a2960c3
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.
LGTM and the end of Mihai's torture.
a2960c3
to
9f57c17
Compare
|
Closes #426
Closes #425
This PR addresses most of the issues in #425 and replaces #426. It has simplified the logic on when to raise errors or warnings, fixes (constrains) the first (constant) term in the SIP polynomials being fitted to distortions, and most importantly, it uses a different method for solving equations for the polynomial fit that in my testing seem to significantly outperform
astropy.modeling.fitting.LinearLSQFitter
in accuracy and stability(and possibly timing - not tested)and time/performance.