Incorrect behavior in vectorized `wcs.world_to_pixel()` with TPV
See original GitHub issueDescription
The wcs.world_to_pixel()
function can give incorrect results when run in vectorized mode with TPV.
Expected behavior
Results from vectorized mode are the same as in scalar mode.
Actual behavior
In my vectorized test case, outputs are mostly bogus.
Steps to Reproduce
Here is a reproduction case — apologies for the length:
from astropy.coordinates import SkyCoord
from astropy import units as u
from astropy.wcs import WCS
import numpy as np
# Create a WCS with a base TAN projection
hdr = {
"WCSAXES": 2,
"CRPIX1": 9019.3448,
"CRPIX2": 9822.9018,
"PC1_1": -0.00116096,
"PC1_2": 0.000330426,
"PC2_1": 0.000330397,
"PC2_2": 0.00116203,
"CDELT1": 1.0,
"CDELT2": 1.0,
"CUNIT1": "deg",
"CUNIT2": "deg",
"CTYPE1": "RA---TAN",
"CTYPE2": "DEC--TAN",
"CRVAL1": 337.103834,
"CRVAL2": 90.0,
"EQUINOX": 2000.0,
}
wcs_tan = WCS(hdr)
# Create a WCS with TPV distortion terms
hdr.update(
**{
"CTYPE1": "RA---TPV",
"CTYPE2": "DEC--TPV",
"PV1_0": -0.004862344579,
"PV1_1": 0.9988506351,
"PV1_2": 0.0003631415552,
"PV1_4": -0.000151807543,
"PV1_5": 0.0003264940806,
"PV1_6": 1.054162749e-05,
"PV1_7": 3.71399551e-05,
"PV1_8": -4.673290603e-06,
"PV1_9": -8.221049725e-06,
"PV1_10": -2.048430933e-05,
"PV1_12": 3.850243018e-06,
"PV1_13": -3.850788487e-06,
"PV1_14": -4.402412681e-07,
"PV1_15": -1.261618912e-06,
"PV1_16": -3.483007815e-07,
"PV1_17": -2.971533523e-07,
"PV1_18": 1.807889219e-07,
"PV1_19": -2.141983906e-07,
"PV1_20": 1.168331168e-07,
"PV1_21": 1.762917378e-07,
"PV1_22": 1.134792701e-07,
"PV2_0": -0.005101922485,
"PV2_1": 1.000314578,
"PV2_2": 0.0009117987251,
"PV2_4": 5.178903105e-05,
"PV2_5": -0.0001677371386,
"PV2_6": 0.0003132549032,
"PV2_7": -1.196471938e-05,
"PV2_8": -2.031118482e-05,
"PV2_9": 1.334272569e-05,
"PV2_10": -1.92055231e-05,
"PV2_12": -3.595935319e-07,
"PV2_13": 1.634133749e-07,
"PV2_14": -1.36746203e-06,
"PV2_15": 1.684772597e-06,
"PV2_16": -3.050997407e-06,
"PV2_17": 8.867628883e-08,
"PV2_18": 1.641951829e-07,
"PV2_19": -6.17124982e-08,
"PV2_20": -2.511534806e-08,
"PV2_21": -5.634176609e-08,
"PV2_22": 1.882567755e-07,
}
)
wcs_tpv = WCS(hdr)
# Vector of lats and lons that demonstrate the problem
lats = np.linspace(1.0453819570955787, 1.2938789521827248, 256)
lons = np.linspace(3.7637488459848645, 4.709526042452718, 256)
INDEX = 230
def do_scalar(wcs):
"Calculate the pixel coordinate of a particular position with scalar evaluation"
c = SkyCoord(lons[INDEX] * u.rad, lats[INDEX] * u.rad, frame="icrs")
idx = wcs.world_to_pixel(c)
return (idx[0].item(), idx[1].item())
def do_vector(wcs):
"Calculate the pixel coordinate of a particular pixel with vector evaluation"
c = SkyCoord(lons * u.rad, lats * u.rad, frame="icrs")
idx = wcs.world_to_pixel(c)
return (idx[0][INDEX], idx[1][INDEX])
# Without distortions, results are consistent as you would hope:
print("TAN scalar:", do_scalar(wcs_tan))
print("TAN vector:", do_vector(wcs_tan))
# With distortions, results are not consistent:
print("TPV scalar:", do_scalar(wcs_tpv))
print("TPV vector:", do_vector(wcs_tpv))
Comparing the result of wcs.world_to_pixel()
for the scalar versus vector inputs here, it looks like the 0’th element of the array is correct, but the rest are garbage. So, perhaps something is trying to vectorize but not actually initializing anything past the 0’th element?
Update: If I run the test repeatedly, the results from the vector-TPV case vary, although they are always around -1. So there is probably some uninitialized memory being read here.
System Details
Linux-5.18.13-200.fc36.x86_64-x86_64-with-glibc2.35
Python 3.9.13 | packaged by conda-forge | (main, May 27 2022, 16:56:21)
[GCC 10.3.0]
Numpy 1.23.1
pyerfa 2.0.0.1
astropy 5.1
Scipy 1.8.1
Matplotlib 3.5.2
CC @imbasimba
Issue Analytics
- State:
- Created a year ago
- Comments:11 (6 by maintainers)
Top Results From Across the Web
World Coordinate System (astropy.wcs)
astropy.wcs contains utilities for managing World Coordinate System (WCS) ... Perform just the core WCS transformation from world to pixel coordinates.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Thanks for digging into this! I’ll see if I can create a pure-WCSLIB reproduction case and report it to Mark if so. In the meantime I’d advocate for keeping this issue open until we retire that last 0.01% of uncertainty about where the bug lies. I’ll post follow-up comments as I dig in.
Noting for posterity: I sent Mark an email about this, CC’ing @mcara. I think that I’ve identified an issue in how WCSLIB handles errors in the situation created by this test case.