Skip to content

Commit 28c5245

Browse files
committed
Support 32-bit input/output
1 parent 62a0d3f commit 28c5245

File tree

3 files changed

+45
-5
lines changed

3 files changed

+45
-5
lines changed

reproject/adaptive/core.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,10 @@ def _reproject_adaptive_2d(
117117
"broadcast" across those images.
118118
"""
119119

120-
# Make sure image is floating point
121-
array_in = np.asarray(array, dtype=float)
120+
# Make sure image is floating point, but preserve the floating-point precision if it's floating point already
121+
array_in = np.asarray(array)
122+
if not np.issubdtype(array.dtype, np.floating):
123+
array_in = np.asarray(array, dtype=float)
122124
shape_out = tuple(shape_out)
123125

124126
# Check dimensionality of WCS and shape_out

reproject/adaptive/deforest.pyx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import numpy as np
3333

3434
cimport cython
3535
cimport numpy as np
36+
from cython cimport floating
3637
from libc.math cimport atan2, ceil, cos, exp, fabs, floor, round, sin, sqrt
3738
from libc.stdlib cimport qsort
3839

@@ -155,7 +156,7 @@ cdef double clip(double x, double vmin, double vmax, int cyclic,
155156
@cython.wraparound(False)
156157
@cython.nonecheck(False)
157158
@cython.cdivision(True)
158-
cdef bint sample_array(const double[:,:,:] source, double[:] dest,
159+
cdef bint sample_array(const floating[:,:,:] source, floating[:] dest,
159160
double x, double y, int x_cyclic, int y_cyclic,
160161
bint out_of_range_nearest) noexcept nogil:
161162
x = clip(x, 0, source.shape[2] - 1, x_cyclic, out_of_range_nearest)
@@ -352,7 +353,7 @@ BAD_VALUE_MODES['ignore'] = 3
352353
@cython.wraparound(False)
353354
@cython.nonecheck(False)
354355
@cython.cdivision(True)
355-
def map_coordinates(const double[:,:,:] source, double[:,:,:] target, Ci, int max_samples_width=-1,
356+
def map_coordinates(const floating[:,:,:] source, floating[:,:,:] target, Ci, int max_samples_width=-1,
356357
int conserve_flux=False, int progress=False, int singularities_nan=False,
357358
int x_cyclic=False, int y_cyclic=False, int out_of_range_nan=False,
358359
bint center_jacobian=False, bint despiked_jacobian=False,
@@ -492,7 +493,7 @@ def map_coordinates(const double[:,:,:] source, double[:,:,:] target, Ci, int ma
492493
cdef double[:] weight_sum = np.empty(source.shape[0])
493494
cdef double ignored_weight_sum
494495
cdef double weight
495-
cdef double[:] value = np.empty(source.shape[0])
496+
cdef floating[:] value = np.empty_like(source, shape=source.shape[0])
496497
cdef double[:] P1 = np.empty((2,))
497498
cdef double[:] P2 = np.empty((2,))
498499
cdef double[:] P3 = np.empty((2,))

reproject/adaptive/tests/test_core.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,43 @@ def test_reproject_adaptive_2d(wcsapi, center_jacobian, roundtrip_coords):
6262
return array_footprint_to_hdulist(array_out, footprint_out, header_out)
6363

6464

65+
def test_reproject_adaptive_dtypes():
66+
# Set up initial array with pattern
67+
data_in = np.zeros((256, 256))
68+
data_in[::20, :] = 1
69+
data_in[:, ::20] = 1
70+
data_in[10::20, 10::20] = 1
71+
72+
# Define a simple input WCS
73+
wcs_in = WCS(naxis=2)
74+
wcs_in.wcs.crpix = 128.5, 128.5
75+
wcs_in.wcs.cdelt = -0.01, 0.01
76+
77+
# Define a lower resolution output WCS
78+
wcs_out = WCS(naxis=2)
79+
wcs_out.wcs.crpix = 30.5, 30.5
80+
wcs_out.wcs.cdelt = -0.0427, 0.0427
81+
82+
header_out = wcs_out.to_header()
83+
84+
array_out, footprint_out = reproject_adaptive(
85+
(data_in, wcs_in),
86+
wcs_out,
87+
shape_out=(60, 60),
88+
)
89+
90+
array_out_32bit = np.empty_like(array_out, dtype=np.float32)
91+
_, footprint_out = reproject_adaptive(
92+
(data_in.astype(np.float32), wcs_in),
93+
wcs_out,
94+
shape_out=(60, 60),
95+
output_array=array_out_32bit,
96+
)
97+
98+
# Check that surface brightness is conserved in the unrotated case
99+
assert_allclose(array_out, array_out_32bit, rtol=0.1)
100+
101+
65102
@pytest.mark.parametrize("axis", ("x", "y"))
66103
@pytest.mark.parametrize("center_jacobian", (True, False))
67104
def test_reproject_adaptive_despike_jacobian(axis, center_jacobian):

0 commit comments

Comments
 (0)