-
-
Notifications
You must be signed in to change notification settings - Fork 70
Open
Description
I’m seeing a deterministic size-dependent failure in reproject_adaptive when shape_out is very large (~1.8e9 pixels). Even with a trivial source plane (all ones) and clearly overlapping WCS, the function returns either:
- plane all-NaN and footprint all-false (sum=0), or
- plane all-zero and footprint has exactly 1 true pixel (sum=1)
No exception is raised.
This makes it hard to detect upstream because the output looks “valid” from an API perspective but is physically wrong.
Expected behavior
Either, A) a correct reprojection with nonzero footprint and finite plane values, or B) a raised exception indicating internal limitation (memory / indexing / shape limit)
Ideally A
Minimal verifiable complete example
This reproducer constructs a target WCS that clearly overlaps with source WCS, and uses an all-ones source plane.
import sys
import numpy as np
import astropy
from astropy import wcs
from reproject import reproject_adaptive
import reproject
def make_target_wcs(num_l: int, num_m: int, dl_deg: float, dm_deg: float, ra0_deg: float, dec0_deg: float):
# 4D WCS like our pipeline, then use .celestial
target_w = wcs.WCS(naxis=4)
target_w.wcs.ctype = ["RA---SIN", "DEC--SIN", "FREQ", "STOKES"]
target_w.wcs.cunit = ["deg", "deg", "Hz", ""]
# NOTE: reference pixel placement is intentional and matches our pipeline:
target_w.wcs.crpix = [num_l / 2.0, num_m / 2.0 + 1.0, 1.0, 1.0]
target_w.wcs.cdelt = [-abs(dl_deg), +abs(dm_deg), 1.0, 1.0]
target_w.wcs.crval = [ra0_deg, dec0_deg, 1.0, 1.0] # STOKES=I code is 1
return target_w.celestial
def make_source_wcs(num_l_src: int, num_m_src: int, dl_deg: float, dm_deg: float, ra0_deg: float, dec0_deg: float):
src_w = wcs.WCS(naxis=2)
src_w.wcs.ctype = ["RA---SIN", "DEC--SIN"]
src_w.wcs.cunit = ["deg", "deg"]
src_w.wcs.crpix = [(num_l_src + 1) / 2.0, (num_m_src + 1) / 2.0]
src_w.wcs.cdelt = [-abs(dl_deg), +abs(dm_deg)]
src_w.wcs.crval = [ra0_deg, dec0_deg]
return src_w
def run_case(num_l_out: int, num_m_out: int, label: str):
ra0_deg = 60.0
dec0_deg = 0.0
# ~1 arcsec/pixel
dl_deg = (1.009918463060501 / 3600.0)
dm_deg = (1.009918463060501 / 3600.0)
# Big-enough source plane so target overlap is guaranteed
num_l_src = 81920
num_m_src = 81920
src_wcs = make_source_wcs(num_l_src, num_m_src, dl_deg, dm_deg, ra0_deg, dec0_deg)
tgt_wcs = make_target_wcs(num_l_out, num_m_out, dl_deg, dm_deg, ra0_deg, dec0_deg)
# All ones input (dec, ra)
src_plane = np.ones((num_m_src, num_l_src), dtype=np.float32)
out_plane, footprint = reproject_adaptive(
(src_plane, src_wcs),
tgt_wcs,
kernel="gaussian",
conserve_flux=True,
shape_out=(num_m_out, num_l_out),
return_footprint=True,
parallel=False,
)
fp_sum = float(np.sum(footprint))
fp_size = int(footprint.size)
out_nan = int(np.isnan(out_plane).sum())
out_max = np.nanmax(out_plane)
out_min = np.nanmin(out_plane)
print(f"\n[{label}] shape_out=(num_m,num_l)=({num_m_out},{num_l_out})")
print(f" footprint sum/size: {fp_sum}/{fp_size}")
print(f" out NaN count: {out_nan} / {out_plane.size}")
print(f" out min/max: {out_min} / {out_max}")
def main():
print("Python:", sys.version)
print("astropy:", astropy.__version__)
print("reproject:", reproject.__version__)
# Control case: smaller (works)
run_case(17856, 17856, "small-square")
# Large cases: failures observed (either fp_sum==0 and NaNs, or fp_sum==1 and zeros)
run_case(43274, 42739, "large-nonsquare-odd")
run_case(43274, 42738, "large-nonsquare-even")
if __name__ == "__main__":
main()Output
Python: 3.11.14 (main, Dec 8 2025, 23:47:06) [GCC 12.2.0]
astropy: 7.2.0
reproject: 0.19.0
[small-square] shape_out=(num_m,num_l)=(17856,17856)
footprint sum/size: 318836736.0/318836736
out NaN count: 0 / 318836736
out min/max: 0.9999999998799467 / 1.0000000001127773
/tmp/ipykernel_1664238/1971168938.py:62: RuntimeWarning: All-NaN slice encountered
out_max = np.nanmax(out_plane)
/tmp/ipykernel_1664238/1971168938.py:63: RuntimeWarning: All-NaN slice encountered
out_min = np.nanmin(out_plane)
[large-nonsquare-odd] shape_out=(num_m,num_l)=(42739,43274)
footprint sum/size: 0.0/1849487486
out NaN count: 1849487486 / 1849487486
out min/max: nan / nan
[large-nonsquare-even] shape_out=(num_m,num_l)=(42738,43274)
footprint sum/size: 1.0/1849444212
out NaN count: 1849444211 / 1849444212
out min/max: 0.0 / 0.0
Observe
- small-square: nonzero footprint and finite values.
- large-nonsquare-odd: footprint sum == 0, output all NaNs.
- large-nonsquare-even: footprint sum == 1, output max == 0.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels