Skip to content

Commit 9128fa8

Browse files
authored
Minor PSF refactor and more logs (#901)
2 parents 06e0769 + 84ab1d1 commit 9128fa8

3 files changed

Lines changed: 37 additions & 20 deletions

File tree

scopesim/effects/psfs/psf_base.py

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def __init__(self, **kwargs):
4949
"wave_key": "WAVE0",
5050
"normalise_kernel": True,
5151
"rounded_edges": True,
52-
"rotational_blur_angle": 0,
52+
"rotational_blur_angle": 0*u.deg,
5353
}
5454
self.meta.update(params)
5555
self.meta.update(kwargs)
@@ -76,7 +76,7 @@ def apply_to(self, obj, **kwargs):
7676

7777
# apply rotational blur for field-tracking observations
7878
rot_blur_angle = self.meta["rotational_blur_angle"]
79-
if abs(rot_blur_angle) > 0:
79+
if abs(rot_blur_angle << u.deg) > 0*u.deg:
8080
# makes a copy of kernel
8181
kernel = rotational_blur(kernel, rot_blur_angle)
8282

@@ -150,35 +150,41 @@ def plot(self, obj=None, **kwargs):
150150
return fig
151151

152152

153-
def rotational_blur(image, angle):
153+
@u.quantity_input
154+
def rotational_blur(image, angle: u.Quantity[u.deg]):
154155
"""
155156
Rotate and coadd an image over a given angle to imitate a blur.
156157
157158
Parameters
158159
----------
159-
image : array
160-
Image to blur
161-
angle : float
162-
[deg] Angle over which the image should be rotationally blurred
160+
image : array-like
161+
Image to blur.
162+
angle : u.Quantity["angle"]
163+
Angle over which the image should be rotationally blurred.
164+
165+
.. versionchanged:: PLACEHOLDER_NEXT_RELEASE_VERSION
166+
167+
Require `angle` to be a Quantity.
163168
164169
Returns
165170
-------
166-
image_rot : array
171+
image_rot : np.ndarray
167172
Blurred image
168173
169174
"""
170175
image_rot = np.copy(image)
171176

172-
n_angles = 1
173-
rad_to_deg = 57.29578
174-
edge_pixel_unit_angle = np.arctan2(1, (image.shape[0] // 2)) * rad_to_deg
175-
while abs(angle) > edge_pixel_unit_angle and n_angles < 25:
176-
angle /= 2.
177-
image_rot += rotate(image_rot, angle, reshape=False, order=1)
177+
edge_pixel_unit_angle = np.arctan2(1, (image.shape[0] // 2)) * u.rad
178+
n_steps = np.ceil(np.log2(abs(angle) / edge_pixel_unit_angle))
179+
n_steps = int(min(n_steps, 8)) # avoid overrun
180+
181+
current_angle = angle.copy()
182+
for _ in range(n_steps):
183+
current_angle /= 2.
184+
image_rot += rotate(image_rot, current_angle, reshape=False, order=3)
178185
# each time kernel is rotated and added, the frame total doubles
179-
n_angles *= 2
180186

181-
return image_rot / n_angles
187+
return image_rot / image_rot.sum() * image.sum()
182188

183189

184190
def get_bkg_level(obj, bg_w):

scopesim/effects/psfs/semianalytical.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,18 @@
1111

1212
from .. import ter_curves_utils as tu
1313
from ...optics.fov import FieldOfView
14-
from ...utils import (figure_factory, figure_grid_factory, from_currsys,
15-
quantify, check_keys)
14+
from ...utils import (
15+
figure_factory,
16+
figure_grid_factory,
17+
from_currsys,
18+
quantify,
19+
check_keys,
20+
get_logger,
21+
)
1622
from . import PSF
1723

24+
logger = get_logger(__name__)
25+
1826

1927
class SemiAnalyticalPSF(PSF):
2028
"""Base class for semianalytical PSFs."""
@@ -115,9 +123,11 @@ def get_kernel(self, fov):
115123

116124
n = self.meta["psf_side_length"]
117125
wave = self.wavelength
126+
logger.debug(" start AnisoCADO")
118127
self._psf_object = aniso.AnalyticalScaoPsf(pixelSize=pixel_scale,
119128
N=n, wavelength=wave,
120129
nmRms=self.nmRms)
130+
logger.debug(" done AnisoCADO")
121131
if np.any(self.meta["offset"]):
122132
self._psf_object.shift_off_axis(self.meta["offset"][0],
123133
self.meta["offset"][1])

scopesim/tests/tests_effects/test_PSF.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from pytest import approx
44
import numpy as np
55
from matplotlib import pyplot as plt
6+
from astropy import units as u
67

78
from scopesim.effects import PSF
89
from scopesim.effects.psfs.psf_base import get_bkg_level
@@ -56,7 +57,7 @@ def test_rescale_produces_odd_size_kernel(self, nkern, scale_factor):
5657
assert n_x % 2 == 1
5758

5859
class TestRotationBlur:
59-
@pytest.mark.parametrize("angle", ([1, 5, 15, 60]))
60+
@pytest.mark.parametrize("angle", ([1, 5, 15, 60]*u.deg))
6061
def test_returns_rotated_kernel_array_has_same_sum(self, angle):
6162
# Without blur
6263
implane = basic_image_plane()
@@ -169,7 +170,7 @@ def test_convolves_with_3D_cube(self):
169170
plt.subplot(231)
170171
plt.imshow(implane.data[1, :, :])
171172

172-
psf = PSF(rotational_blur_angle=15, bkg_width=5, rounded_edges=False)
173+
psf = PSF(rotational_blur_angle=15*u.deg, bkg_width=5, rounded_edges=False)
173174
psf.kernel = basic_kernel(n=63)
174175
implane = psf.apply_to(implane)
175176

0 commit comments

Comments
 (0)