Skip to content

Masks

masks

Spatial optical elements that act on a Beam by multiplication.

SpatialMask produces a (Dy, Dx) array multiplied into the whole field (lenses, Zernike aberrations, apertures/slits).

Usage: beam = beam * Lens(f=0.2) * Iris(radius=1e-3)
# First a Lens is applyed then an Iris.

Mask

Bases: ABC

apply abstractmethod

apply(beam) -> object

Apply this mask to beam, and return a copy.

Source code in structured_optics\masks.py
24
25
26
27
@abstractmethod
def apply(self, beam) -> object:
    """Apply this mask to `beam`, and return a copy."""
    raise NotImplementedError

__rmul__

__rmul__(beam)

Enable beam * SomeMask(...) syntax.

Parameters:

Name Type Description Default
beam Beam

Left-hand operand of the multiplication.

required

Returns:

Type Description
object or NotImplemented

The result of self.apply(beam) if beam looks like a Beam (i.e. it has a .field attribute); otherwise NotImplemented, so Python can fall back to other multiplication behavior.

Source code in structured_optics\masks.py
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
def __rmul__(self, beam):
    """Enable `beam * SomeMask(...)` syntax.

    Parameters
    ----------
    beam : Beam
        Left-hand operand of the multiplication.

    Returns
    -------
    object or NotImplemented
        The result of ``self.apply(beam)`` if `beam` looks like a
        `Beam` (i.e. it has a `.field` attribute); otherwise
        `NotImplemented`, so Python can fall back to other
        multiplication behavior.
    """

    if hasattr(beam, "field"):
        return self.apply(beam)
    return NotImplemented

SpatialMask

Bases: Mask

A mask defined by a complex transmittance T(x, y), applied elementwise to the whole field.

array abstractmethod

array(beam) -> np.ndarray

Return an array broadcastable to beam.field.shape[-2:].

Source code in structured_optics\masks.py
58
59
60
61
@abstractmethod
def array(self, beam) -> np.ndarray:
    """Return an array broadcastable to beam.field.shape[-2:]."""
    raise NotImplementedError

apply

apply(beam)

Multiply this mask's transmittance into a copy of beam.

Parameters:

Name Type Description Default
beam Beam

The beam to apply the mask to.

required

Returns:

Type Description
Beam

A copy of beam whose .field has been multiplied elementwise by self.array(beam). The original beam is left unmodified.

Source code in structured_optics\masks.py
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
def apply(self, beam):
    """Multiply this mask's transmittance into a copy of `beam`.

    Parameters
    ----------
    beam : Beam
        The beam to apply the mask to.

    Returns
    -------
    Beam
        A copy of `beam` whose `.field` has been multiplied elementwise
        by `self.array(beam)`. The original `beam` is left unmodified.
    """
    result = beam.copy()
    result.field *= self.array(result)
    return result

Lens

Lens(f: float, f0: tuple = (0, 0))

Bases: SpatialMask

An ideal thin lens, applying a paraxial parabolic phase profile.

Parameters:

Name Type Description Default
f float

Focal length of the lens.

required
f0 tuple

(x, y) offset of the lens center relative to the beam's optical axis. Defaults to (0, 0).

(0, 0)
Reference
[1] Goodman, Joseph W., and Mary E. Cox. "Introduction to Fourier optics." (1969): 97-101.
Source code in structured_optics\masks.py
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
def __init__(self, f: float, f0: tuple = (0, 0)):
    """
    Parameters
    ----------
    f : float
        Focal length of the lens.
    f0 : tuple, optional
        (x, y) offset of the lens center relative to the beam's
        optical axis. Defaults to (0, 0).

    Reference
    ---------
        [1] Goodman, Joseph W., and Mary E. Cox. "Introduction to Fourier optics." (1969): 97-101.
    """

    self.f, self.f0 = f, f0

AstigmaticLens

AstigmaticLens(fx: float, fy: float, f0: tuple = (0, 0))

Bases: SpatialMask

A lens with independent focal lengths along x and y (astigmatism).

Parameters:

Name Type Description Default
fx float

Focal length along the x axis.

required
fy float

Focal length along the y axis.

required
f0 tuple

(x, y) offset of the lens center. Defaults to (0, 0).

(0, 0)
Source code in structured_optics\masks.py
109
110
111
112
113
114
115
116
117
118
119
120
121
def __init__(self, fx: float, fy: float, f0: tuple = (0, 0)):
    """
    Parameters
    ----------
    fx : float
        Focal length along the x axis.
    fy : float
        Focal length along the y axis.
    f0 : tuple, optional
        (x, y) offset of the lens center. Defaults to (0, 0).
    """

    self.fx, self.fy, self.f0 = fx, fy, f0

TiltedLens

TiltedLens(f: float, phi: float, f0: tuple = (0, 0), flip_axis: bool = False)

Bases: AstigmaticLens

A spherical lens viewed at an angle, modeled as an equivalent AstigmaticLens with effective (fx, fy) derived from the tilt angle.

Parameters:

Name Type Description Default
f float

Nominal (untilted) focal length of the lens.

required
phi float

Tilt angle, in radians.

required
f0 tuple

(x, y) offset of the lens center. Defaults to (0, 0).

(0, 0)
flip_axis bool

If True, swap the roles of the tilted/untilted axes. Defaults to False.

False
Source code in structured_optics\masks.py
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
def __init__(self, f: float, phi: float, f0: tuple = (0, 0), flip_axis: bool = False):
    """
    Parameters
    ----------
    f : float
        Nominal (untilted) focal length of the lens.
    phi : float
        Tilt angle, in radians.
    f0 : tuple, optional
        (x, y) offset of the lens center. Defaults to (0, 0).
    flip_axis : bool, optional
        If True, swap the roles of the tilted/untilted axes.
        Defaults to False.
    """

    fx, fy = f * np.cos(phi) ** 3, f * np.cos(phi)
    if flip_axis:
        fx, fy = fy, fx
    super().__init__(fx, fy, f0)

ZernikeMask

ZernikeMask(coefs: tuple, strengths: tuple)

Bases: SpatialMask

A phase mask built from a weighted sum of Zernike polynomials, used to model optical aberrations.

Parameters:

Name Type Description Default
coefs tuple

Zernike term identifiers (indices/orders) to include.

required
strengths tuple

Coefficient strengths corresponding to each term in coefs.

required
Reference
[1] https://en.wikipedia.org/wiki/Zernike_polynomials
Source code in structured_optics\masks.py
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
def __init__(self, coefs: tuple, strengths: tuple):
    """
    Parameters
    ----------
    coefs : tuple
        Zernike term identifiers (indices/orders) to include.
    strengths : tuple
        Coefficient strengths corresponding to each term in `coefs`.

    Reference
    ---------
        [1] https://en.wikipedia.org/wiki/Zernike_polynomials
    """

    self.coefs, self.strengths = coefs, strengths

BooleanMask

BooleanMask(complementary: bool = False)

Bases: SpatialMask

Base class for hard-edged apertures. Subclasses implement bool_array; complementary=True inverts the aperture.

Parameters:

Name Type Description Default
complementary bool

If True, invert the aperture (block where it would otherwise pass, and vice versa). Defaults to False.

False
Source code in structured_optics\masks.py
179
180
181
182
183
184
185
186
187
188
def __init__(self, complementary: bool = False):
    """
    Parameters
    ----------
    complementary : bool, optional
        If True, invert the aperture (block where it would otherwise
        pass, and vice versa). Defaults to False.
    """

    self.complementary = complementary

bool_array abstractmethod

bool_array(beam) -> np.ndarray

Return a boolean array, True where the aperture transmits.

Source code in structured_optics\masks.py
190
191
192
193
@abstractmethod
def bool_array(self, beam) -> np.ndarray:
    """Return a boolean array, True where the aperture transmits."""
    raise NotImplementedError

array

array(beam)

Build the (possibly inverted) boolean transmittance array.

Parameters:

Name Type Description Default
beam Beam

Beam whose spatial shape (beam.field.shape[-2:]) the mask must broadcast to.

required

Returns:

Type Description
ndarray

Boolean array broadcast to the beam's spatial shape. Equal to bool_array(beam), or its logical negation if self.complementary is True.

Raises:

Type Description
ValueError

If bool_array(beam) cannot be broadcast to the beam's spatial shape.

Source code in structured_optics\masks.py
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
def array(self, beam):
    """Build the (possibly inverted) boolean transmittance array.

    Parameters
    ----------
    beam : Beam
        Beam whose spatial shape (`beam.field.shape[-2:]`) the mask
        must broadcast to.

    Returns
    -------
    np.ndarray
        Boolean array broadcast to the beam's spatial shape. Equal to
        `bool_array(beam)`, or its logical negation if
        `self.complementary` is True.

    Raises
    ------
    ValueError
        If `bool_array(beam)` cannot be broadcast to the beam's
        spatial shape.
    """
    m = np.asarray(self.bool_array(beam), dtype=bool)
    spatial_shape = beam.field.shape[-2:]
    try:
        m = np.broadcast_to(m, spatial_shape)
    except ValueError:
        raise ValueError(f"Mask must be broadcastable to spatial shape {spatial_shape}, got {m.shape}")
    return ~m if self.complementary else m

Iris

Iris(radius=None, center=(0, 0), complementary=False)

Bases: BooleanMask

A circular aperture.

Parameters:

Name Type Description Default
radius float

Radius of the circular aperture.

None
center tuple

(x, y) center of the circle. Defaults to (0, 0).

(0, 0)
complementary bool

Invert the aperture. Defaults to False.

False
Source code in structured_optics\masks.py
228
229
230
231
232
233
234
235
236
237
238
239
240
def __init__(self, radius=None, center=(0, 0), complementary=False):
    """
    Parameters
    ----------
    radius : float, optional
        Radius of the circular aperture.
    center : tuple, optional
        (x, y) center of the circle. Defaults to (0, 0).
    complementary : bool, optional
        Invert the aperture. Defaults to False.
    """
    super().__init__(complementary)
    self.center, self.radius = center, radius

SquareAperture

SquareAperture(side_length=None, center=(0, 0), complementary=False)

Bases: BooleanMask

A square aperture.

Parameters:

Name Type Description Default
side_length float

Side length of the square aperture.

None
center tuple

(x, y) center of the square. Defaults to (0, 0).

(0, 0)
complementary bool

Invert the aperture. Defaults to False.

False
Source code in structured_optics\masks.py
248
249
250
251
252
253
254
255
256
257
258
259
260
261
def __init__(self, side_length=None, center=(0, 0), complementary=False):
    """
    Parameters
    ----------
    side_length : float, optional
        Side length of the square aperture.
    center : tuple, optional
        (x, y) center of the square. Defaults to (0, 0).
    complementary : bool, optional
        Invert the aperture. Defaults to False.
    """

    super().__init__(complementary)
    self.center, self.side_length = center, side_length

TriangleAperture

TriangleAperture(center=(0, 0), side_length=None, complementary=False)

Bases: BooleanMask

A triangular aperture.

Parameters:

Name Type Description Default
center tuple

(x, y) center of the triangle. Defaults to (0, 0).

(0, 0)
side_length float

Side length of the triangle.

None
complementary bool

Invert the aperture. Defaults to False.

False
Source code in structured_optics\masks.py
269
270
271
272
273
274
275
276
277
278
279
280
281
282
def __init__(self, center=(0, 0), side_length=None, complementary=False):
    """
    Parameters
    ----------
    center : tuple, optional
        (x, y) center of the triangle. Defaults to (0, 0).
    side_length : float, optional
        Side length of the triangle.
    complementary : bool, optional
        Invert the aperture. Defaults to False.
    """

    super().__init__(complementary)
    self.center, self.side_length = center, side_length

HSlit

HSlit(size, center=0, complementary=False)

Bases: BooleanMask

A horizontal slit: passes a vertical strip of width 2 * size centered at center along the x axis.

Parameters:

Name Type Description Default
size float

Half-width of the slit.

required
center float

Center position along x. Defaults to 0.

0
complementary bool

Invert the aperture. Defaults to False.

False
Source code in structured_optics\masks.py
292
293
294
295
296
297
298
299
300
301
302
303
304
305
def __init__(self, size, center=0, complementary=False):
    """
    Parameters
    ----------
    size : float
        Half-width of the slit.
    center : float, optional
        Center position along x. Defaults to 0.
    complementary : bool, optional
        Invert the aperture. Defaults to False.
    """

    super().__init__(complementary)
    self.size, self.center = size, center

VSlit

VSlit(size, center=0, complementary=False)

Bases: BooleanMask

A vertical slit: passes a horizontal strip of width 2 * size centered at center along the y axis.

Parameters:

Name Type Description Default
size float

Half-width of the slit.

required
center float

Center position along y. Defaults to 0.

0
complementary bool

Invert the aperture. Defaults to False.

False
Source code in structured_optics\masks.py
315
316
317
318
319
320
321
322
323
324
325
326
327
328
def __init__(self, size, center=0, complementary=False):
    """
    Parameters
    ----------
    size : float
        Half-width of the slit.
    center : float, optional
        Center position along y. Defaults to 0.
    complementary : bool, optional
        Invert the aperture. Defaults to False.
    """

    super().__init__(complementary)
    self.size, self.center = size, center

DoubleSlit

DoubleSlit(size, dis, center=0, complementary=False)

Bases: BooleanMask

Two parallel slits (double-slit experiment), each of half-width size, separated by distance dis, centered at center.

Parameters:

Name Type Description Default
size float

Half-width of each slit.

required
dis float

Center-to-center distance between the two slits.

required
center float

Midpoint of the two-slit pair along x. Defaults to 0.

0
complementary bool

Invert the aperture. Defaults to False.

False
Source code in structured_optics\masks.py
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
def __init__(self, size, dis, center=0, complementary=False):
    """
    Parameters
    ----------
    size : float
        Half-width of each slit.
    dis : float
        Center-to-center distance between the two slits.
    center : float, optional
        Midpoint of the two-slit pair along x. Defaults to 0.
    complementary : bool, optional
        Invert the aperture. Defaults to False.
    """

    super().__init__(complementary)
    self.size, self.dis, self.center = size, dis, center

CrossSlit

CrossSlit(size, hsize=None, complementary=False)

Bases: BooleanMask

A cross-shaped (plus-sign) aperture: the union of a vertical band and a horizontal band through the origin.

Parameters:

Name Type Description Default
size float

Half-width of the vertical band (along x). Also used as the default horizontal band half-width if hsize is omitted.

required
hsize float

Half-width of the horizontal band (along y). Defaults to size if not given.

None
complementary bool

Invert the aperture. Defaults to False.

False
Source code in structured_optics\masks.py
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
def __init__(self, size, hsize=None, complementary=False):
    """
    Parameters
    ----------
    size : float
        Half-width of the vertical band (along x). Also used as the
        default horizontal band half-width if `hsize` is omitted.
    hsize : float, optional
        Half-width of the horizontal band (along y). Defaults to
        `size` if not given.
    complementary : bool, optional
        Invert the aperture. Defaults to False.
    """

    super().__init__(complementary)
    self.size, self.hsize = size, hsize if hsize is not None else size