Skip to content

Commit 36b6d35

Browse files
committed
mask_2d_elliptical_annular_from
1 parent a5544b4 commit 36b6d35

File tree

1 file changed

+37
-67
lines changed

1 file changed

+37
-67
lines changed

autoarray/mask/mask_2d_util.py

Lines changed: 37 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -130,44 +130,6 @@ def mask_2d_circular_annular_from(
130130
)
131131

132132

133-
@numba_util.jit()
134-
def elliptical_radius_from(
135-
y_scaled: float, x_scaled: float, angle: float, axis_ratio: float
136-
) -> float:
137-
"""
138-
Returns the elliptical radius of an ellipse from its (y,x) scaled centre, rotation angle `angle` defined in degrees
139-
counter-clockwise from the positive x-axis and its axis-ratio.
140-
141-
This is used by the function `mask_elliptical_from` to determine the radius of every (y,x) coordinate in elliptical
142-
units when deciding if it is within the mask.
143-
144-
Parameters
145-
----------
146-
y_scaled
147-
The scaled y coordinate in Cartesian coordinates which is converted to elliptical coordinates.
148-
x_scaled
149-
The scaled x coordinate in Cartesian coordinates which is converted to elliptical coordinates.
150-
angle
151-
The rotation angle in degrees counter-clockwise from the positive x-axis
152-
axis_ratio
153-
The axis-ratio of the ellipse (minor axis / major axis).
154-
155-
Returns
156-
-------
157-
float
158-
The radius of the input scaled (y,x) coordinate on the ellipse's ellipitcal coordinate system.
159-
"""
160-
r_scaled = np.sqrt(x_scaled**2 + y_scaled**2)
161-
162-
theta_rotated = np.arctan2(y_scaled, x_scaled) + np.radians(angle)
163-
164-
y_scaled_elliptical = r_scaled * np.sin(theta_rotated)
165-
x_scaled_elliptical = r_scaled * np.cos(theta_rotated)
166-
167-
return np.sqrt(x_scaled_elliptical**2.0 + (y_scaled_elliptical / axis_ratio) ** 2.0)
168-
169-
170-
171133
def mask_2d_elliptical_from(
172134
shape_native: Tuple[int, int],
173135
pixel_scales: Tuple[float, float],
@@ -209,7 +171,7 @@ def mask_2d_elliptical_from(
209171
"""
210172
centres_scaled = mask_2d_centres_from(shape_native, pixel_scales, centre)
211173

212-
y, x = np.ogrid[:shape_native[0], :shape_native[1]]
174+
y, x = np.ogrid[: shape_native[0], : shape_native[1]]
213175
y_scaled = (y - centres_scaled[0]) * pixel_scales[0]
214176
x_scaled = (x - centres_scaled[1]) * pixel_scales[1]
215177

@@ -223,15 +185,16 @@ def mask_2d_elliptical_from(
223185
x_scaled_elliptical = r_scaled * np.cos(theta_rotated)
224186

225187
# Compute the elliptical radius
226-
r_scaled_elliptical = np.sqrt(x_scaled_elliptical**2 + (y_scaled_elliptical / axis_ratio)**2)
188+
r_scaled_elliptical = np.sqrt(
189+
x_scaled_elliptical**2 + (y_scaled_elliptical / axis_ratio) ** 2
190+
)
227191

228192
return ~(r_scaled_elliptical <= major_axis_radius)
229193

230194

231-
@numba_util.jit()
232195
def mask_2d_elliptical_annular_from(
233196
shape_native: Tuple[int, int],
234-
pixel_scales: ty.PixelScales,
197+
pixel_scales: Tuple[float, float],
235198
inner_major_axis_radius: float,
236199
inner_axis_ratio: float,
237200
inner_phi: float,
@@ -277,38 +240,45 @@ def mask_2d_elliptical_annular_from(
277240
Examples
278241
--------
279242
mask = mask_elliptical_annuli_from(
280-
shape=(10, 10), pixel_scales=0.1,
281-
inner_major_axis_radius=0.5, inner_axis_ratio=0.5, inner_phi=45.0,
282-
outer_major_axis_radius=1.5, outer_axis_ratio=0.8, outer_phi=90.0,
283-
centre=(0.0, 0.0))
243+
shape=(10, 10), pixel_scales=(0.1, 0.1),
244+
inner_major_axis_radius=0.5, inner_axis_ratio=0.5, inner_phi=45.0,
245+
outer_major_axis_radius=1.5, outer_axis_ratio=0.8, outer_phi=90.0,
246+
centre=(0.0, 0.0))
284247
"""
248+
centres_scaled = mask_2d_centres_from(shape_native, pixel_scales, centre)
285249

286-
mask_2d = np.full(shape_native, True)
287-
288-
centres_scaled = mask_2d_centres_from(
289-
shape_native=mask_2d.shape, pixel_scales=pixel_scales, centre=centre
290-
)
250+
y, x = np.ogrid[: shape_native[0], : shape_native[1]]
251+
y_scaled = (y - centres_scaled[0]) * pixel_scales[0]
252+
x_scaled = (x - centres_scaled[1]) * pixel_scales[1]
291253

292-
for y in range(mask_2d.shape[0]):
293-
for x in range(mask_2d.shape[1]):
294-
y_scaled = (y - centres_scaled[0]) * pixel_scales[0]
295-
x_scaled = (x - centres_scaled[1]) * pixel_scales[1]
254+
# Rotate the coordinates for the inner annulus
255+
r_scaled_inner = np.sqrt(x_scaled**2 + y_scaled**2)
256+
theta_rotated_inner = np.arctan2(y_scaled, x_scaled) + np.radians(inner_phi)
257+
y_scaled_elliptical_inner = r_scaled_inner * np.sin(theta_rotated_inner)
258+
x_scaled_elliptical_inner = r_scaled_inner * np.cos(theta_rotated_inner)
296259

297-
inner_r_scaled_elliptical = elliptical_radius_from(
298-
y_scaled, x_scaled, inner_phi, inner_axis_ratio
299-
)
260+
# Compute the elliptical radius for the inner annulus
261+
r_scaled_elliptical_inner = np.sqrt(
262+
x_scaled_elliptical_inner**2
263+
+ (y_scaled_elliptical_inner / inner_axis_ratio) ** 2
264+
)
300265

301-
outer_r_scaled_elliptical = elliptical_radius_from(
302-
y_scaled, x_scaled, outer_phi, outer_axis_ratio
303-
)
266+
# Rotate the coordinates for the outer annulus
267+
r_scaled_outer = np.sqrt(x_scaled**2 + y_scaled**2)
268+
theta_rotated_outer = np.arctan2(y_scaled, x_scaled) + np.radians(outer_phi)
269+
y_scaled_elliptical_outer = r_scaled_outer * np.sin(theta_rotated_outer)
270+
x_scaled_elliptical_outer = r_scaled_outer * np.cos(theta_rotated_outer)
304271

305-
if (
306-
inner_r_scaled_elliptical >= inner_major_axis_radius
307-
and outer_r_scaled_elliptical <= outer_major_axis_radius
308-
):
309-
mask_2d[y, x] = False
272+
# Compute the elliptical radius for the outer annulus
273+
r_scaled_elliptical_outer = np.sqrt(
274+
x_scaled_elliptical_outer**2
275+
+ (y_scaled_elliptical_outer / outer_axis_ratio) ** 2
276+
)
310277

311-
return mask_2d
278+
return ~(
279+
(r_scaled_elliptical_inner >= inner_major_axis_radius)
280+
& (r_scaled_elliptical_outer <= outer_major_axis_radius)
281+
)
312282

313283

314284
def mask_2d_via_pixel_coordinates_from(

0 commit comments

Comments
 (0)