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

Add Image.array setter (#1272) #1329

Merged
merged 1 commit into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions galsim/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,10 @@ def iscontiguous(self):
"""
return self._array.strides[1]//self._array.itemsize == 1

@array.setter
def array(self, other):
self._array[:] = self._safe_cast(other)

@lazy_property
def _image(self):
cls = self._cpp_type[self.dtype]
Expand Down
78 changes: 78 additions & 0 deletions tests/test_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -1734,6 +1734,19 @@ def test_Image_inplace_add():
err_msg="Inplace add in Image class does not match reference for dtypes = "
+str(types[i])+" and "+str(types[j]))

# Adding via array:
image4 = image2.copy()
image4.array += image2.array
np.testing.assert_allclose(image4.array, 2*image2.array)
image4.array[:] += image2.array
np.testing.assert_allclose(image4.array, 3*image2.array)
image4.array = image4.array + image2.array
np.testing.assert_allclose(image4.array, 4*image2.array)
with assert_raises(ValueError):
image4.array += image2.array[:2,:]
with assert_raises(ValueError):
image4.array = image4.array[:2,:] + image2.array[:2,:]

with assert_raises(ValueError):
image1 += image1.subImage(galsim.BoundsI(0,4,0,4))

Expand Down Expand Up @@ -1776,6 +1789,19 @@ def test_Image_inplace_subtract():
err_msg="Inplace subtract in Image class does not match reference for dtypes = "
+str(types[i])+" and "+str(types[j]))

# Subtracting via array:
image4 = 5*image2
image4.array -= image2.array
np.testing.assert_allclose(image4.array, 4*image2.array)
image4.array[:] -= image2.array
np.testing.assert_allclose(image4.array, 3*image2.array)
image4.array = image4.array - image2.array
np.testing.assert_allclose(image4.array, 2*image2.array)
with assert_raises(ValueError):
image4.array -= image2.array[:2,:]
with assert_raises(ValueError):
image4.array = image4.array[:2,:] - image2.array[:2,:]

with assert_raises(ValueError):
image1 -= image1.subImage(galsim.BoundsI(0,4,0,4))

Expand Down Expand Up @@ -1907,6 +1933,17 @@ def test_Image_inplace_scalar_add():
err_msg="Inplace scalar add in Image class does not match reference for dtype = "
+str(types[i]))

# Adding via array:
image4 = image1.copy()
image4.array += 1
np.testing.assert_allclose(image4.array, image1.array + 1)
image4.array[:] += 1
np.testing.assert_allclose(image4.array, image1.array + 2)
image4.array = image4.array + 1
np.testing.assert_allclose(image4.array, image1.array + 3)
with assert_raises(ValueError):
image4.array = image4.array[:2,:] + 1


@timer
def test_Image_inplace_scalar_subtract():
Expand Down Expand Up @@ -1961,6 +1998,17 @@ def test_Image_inplace_scalar_multiply():
err_msg="Inplace scalar multiply in Image class does"
+" not match reference for dtype = "+str(types[i]))

# Multiplying via array:
image4 = image2.copy()
image4.array *= 2
np.testing.assert_allclose(image4.array, 2*image2.array)
image4.array[:] *= 2
np.testing.assert_allclose(image4.array, 4*image2.array)
image4.array = image4.array * 2
np.testing.assert_allclose(image4.array, 8*image2.array)
with assert_raises(ValueError):
image4.array = image4.array[:2,:] * 2


@timer
def test_Image_inplace_scalar_divide():
Expand Down Expand Up @@ -1988,6 +2036,36 @@ def test_Image_inplace_scalar_divide():
err_msg="Inplace scalar divide in Image class does"
+" not match reference for dtype = "+str(types[i]))

# Dividing via array:
image4 = 16*image2
if simple_types[i] is int:
with assert_raises(TypeError):
image4.array /= 2
with assert_raises(TypeError):
image4.array[:] /= 2
np.testing.assert_array_equal(image4.array, 16*image2.array) # unchanged yet
image4.array //= 2
np.testing.assert_array_equal(image4.array, 8*image2.array)
image4.array[:] //= 2
np.testing.assert_array_equal(image4.array, 4*image2.array)
image4.array = image4.array // 2
np.testing.assert_array_equal(image4.array, 2*image2.array)
# The following works for integer by explicitly rounding and casting.
# The native numpy operation would use floor to cast to int, which is 1 smaller.
image4.array = (image4.array / 2.0001)
np.testing.assert_array_equal(image4.array, image2.array)
with assert_raises(ValueError):
image4.array = image4.array[:2,:] // 2
else:
image4.array /= 2
np.testing.assert_allclose(image4.array, 8*image2.array)
image4.array[:] /= 2
np.testing.assert_allclose(image4.array, 4*image2.array)
image4.array = image4.array / 2
np.testing.assert_allclose(image4.array, 2*image2.array)
with assert_raises(ValueError):
image4.array = image4.array[:2,:] / 2


@timer
def test_Image_inplace_scalar_pow():
Expand Down
Loading