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

Improve stability of SIP fitting. Fix constant term - CRPIX - in SIP #427

Merged
merged 3 commits into from
Dec 13, 2022

Conversation

mcara
Copy link
Member

@mcara mcara commented Nov 30, 2022

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.

@codecov
Copy link

codecov bot commented Nov 30, 2022

Codecov Report

Base: 86.84% // Head: 86.93% // Increases project coverage by +0.09% 🎉

Coverage data is based on head (9f57c17) compared to base (dfef3f1).
Patch coverage: 87.16% of modified lines in pull request are covered.

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     
Flag Coverage Δ
unit 86.93% <87.16%> (+0.09%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
gwcs/wcs.py 87.65% <83.18%> (-0.16%) ⬇️
gwcs/tests/utils.py 100.00% <100.00%> (ø)

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.
📢 Do you have feedback about the report comment? Let us know in this issue.

@mcara
Copy link
Member Author

mcara commented Nov 30, 2022

Here I will attach an ASDF file with two test WCS: NIRCAM and MIRI.
test_wcs.asdf.zip

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])

@mcara mcara force-pushed the sip-use-lu-solve-fix-crpix branch 3 times, most recently from 89baa8c to 5c37e28 Compare December 1, 2022 01:41
Copy link
Collaborator

@perrygreenfield perrygreenfield left a 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):
Copy link
Collaborator

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):
Copy link
Collaborator

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):
Copy link
Collaborator

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.

Copy link
Collaborator

@perrygreenfield perrygreenfield left a 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
Copy link
Collaborator

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?

Copy link
Member Author

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.

Copy link
Member Author

@mcara mcara Dec 12, 2022

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

Copy link
Collaborator

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.

Copy link
Collaborator

@perrygreenfield perrygreenfield left a 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.

@mcara
Copy link
Member Author

mcara commented Dec 12, 2022

test-dev (Python 3.8, ubuntu-latest) does not start at all no matter how long it takes. @zacharyburnett

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.

Multi-Issues with to_fits_sip: Detection of achieved accuracy, docs, fixing c0_0
2 participants