Skip to content

Commit bf6868f

Browse files
refactor: clean up Jones functionalities (#507)
1 parent 9a1342c commit bf6868f

File tree

2 files changed

+60
-179
lines changed

2 files changed

+60
-179
lines changed

optiland/jones.py

Lines changed: 39 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -117,38 +117,21 @@ def calculate_matrix(
117117
return jones_matrix
118118

119119

120-
class JonesPolarizerH(BaseJones):
121-
"""Class representing the Jones matrix for a horizontal polarizer."""
122-
123-
def calculate_matrix(
124-
self,
125-
rays: RealRays,
126-
reflect: bool = False,
127-
aoi: be.ndarray = None,
128-
):
129-
"""Calculate the Jones matrix for the given rays.
130-
131-
Args:
132-
rays (RealRays): Object representing the rays.
133-
reflect (bool, optional): Indicates whether the rays are reflected
134-
or not. Defaults to False.
135-
aoi (be.ndarray, optional): Array representing the angle of
136-
incidence. Defaults to None.
137-
138-
Returns:
139-
be.ndarray: The calculated Jones matrix.
140-
141-
"""
142-
jones_matrix = be.to_complex(be.zeros((be.size(rays.x), 3, 3)))
143-
jones_matrix[:, 0, 0] = 1
144-
jones_matrix[:, 1, 1] = 0
145-
jones_matrix[:, 2, 2] = 1
120+
class ConstantJones(BaseJones):
121+
"""Base class for constant Jones matrices.
146122
147-
return jones_matrix
123+
Args:
124+
j00 (complex): The (0, 0) element of the Jones matrix.
125+
j01 (complex): The (0, 1) element of the Jones matrix.
126+
j10 (complex): The (1, 0) element of the Jones matrix.
127+
j11 (complex): The (1, 1) element of the Jones matrix.
128+
"""
148129

149-
150-
class JonesPolarizerV(BaseJones):
151-
"""Class representing the Jones matrix for a vertical polarizer."""
130+
def __init__(self, j00: complex, j01: complex, j10: complex, j11: complex):
131+
self.j00 = j00
132+
self.j01 = j01
133+
self.j10 = j10
134+
self.j11 = j11
152135

153136
def calculate_matrix(
154137
self,
@@ -170,139 +153,55 @@ def calculate_matrix(
170153
171154
"""
172155
jones_matrix = be.to_complex(be.zeros((be.size(rays.x), 3, 3)))
173-
jones_matrix[:, 0, 0] = 0
174-
jones_matrix[:, 1, 1] = 1
156+
jones_matrix[:, 0, 0] = self.j00
157+
jones_matrix[:, 0, 1] = self.j01
158+
jones_matrix[:, 1, 0] = self.j10
159+
jones_matrix[:, 1, 1] = self.j11
175160
jones_matrix[:, 2, 2] = 1
176161

177162
return jones_matrix
178163

179164

180-
class JonesPolarizerL45(BaseJones):
181-
"""Class representing the Jones matrix for a linear polarizer at 45 degrees."""
182-
183-
def calculate_matrix(
184-
self,
185-
rays: RealRays,
186-
reflect: bool = False,
187-
aoi: be.ndarray = None,
188-
):
189-
"""Calculate the Jones matrix for the given rays.
190-
191-
Args:
192-
rays (RealRays): Object representing the rays.
193-
reflect (bool, optional): Indicates whether the rays are reflected
194-
or not. Defaults to False.
195-
aoi (be.ndarray, optional): Array representing the angle of
196-
incidence. Defaults to None.
165+
class JonesPolarizerH(ConstantJones):
166+
"""Class representing the Jones matrix for a horizontal polarizer."""
197167

198-
Returns:
199-
be.ndarray: The calculated Jones matrix.
168+
def __init__(self):
169+
super().__init__(1, 0, 0, 0)
200170

201-
"""
202-
jones_matrix = be.to_complex(be.zeros((be.size(rays.x), 3, 3)))
203-
jones_matrix[:, 0, 0] = 0.5
204-
jones_matrix[:, 0, 1] = 0.5
205-
jones_matrix[:, 1, 0] = 0.5
206-
jones_matrix[:, 1, 1] = 0.5
207-
jones_matrix[:, 2, 2] = 1
208171

209-
return jones_matrix
172+
class JonesPolarizerV(ConstantJones):
173+
"""Class representing the Jones matrix for a vertical polarizer."""
210174

175+
def __init__(self):
176+
super().__init__(0, 0, 0, 1)
211177

212-
class JonesPolarizerL135(BaseJones):
213-
"""Class representing the Jones matrix for a linear polarizer at 135 degrees."""
214178

215-
def calculate_matrix(
216-
self,
217-
rays: RealRays,
218-
reflect: bool = False,
219-
aoi: be.ndarray = None,
220-
):
221-
"""Calculate the Jones matrix for the given rays.
179+
class JonesPolarizerL45(ConstantJones):
180+
"""Class representing the Jones matrix for a linear polarizer at 45 degrees."""
222181

223-
Args:
224-
rays (RealRays): Object representing the rays.
225-
reflect (bool, optional): Indicates whether the rays are reflected
226-
or not. Defaults to False.
227-
aoi (be.ndarray, optional): Array representing the angle of
228-
incidence. Defaults to None.
182+
def __init__(self):
183+
super().__init__(0.5, 0.5, 0.5, 0.5)
229184

230-
Returns:
231-
be.ndarray: The calculated Jones matrix.
232185

233-
"""
234-
jones_matrix = be.to_complex(be.zeros((be.size(rays.x), 3, 3)))
235-
jones_matrix[:, 0, 0] = 0.5
236-
jones_matrix[:, 0, 1] = -0.5
237-
jones_matrix[:, 1, 0] = -0.5
238-
jones_matrix[:, 1, 1] = 0.5
239-
jones_matrix[:, 2, 2] = 1
186+
class JonesPolarizerL135(ConstantJones):
187+
"""Class representing the Jones matrix for a linear polarizer at 135 degrees."""
240188

241-
return jones_matrix
189+
def __init__(self):
190+
super().__init__(0.5, -0.5, -0.5, 0.5)
242191

243192

244-
class JonesPolarizerRCP(BaseJones):
193+
class JonesPolarizerRCP(ConstantJones):
245194
"""Class representing the Jones matrix for a right circular polarizer."""
246195

247-
def calculate_matrix(
248-
self,
249-
rays: RealRays,
250-
reflect: bool = False,
251-
aoi: be.ndarray = None,
252-
):
253-
"""Calculate the Jones matrix for the given rays.
254-
255-
Args:
256-
rays (RealRays): Object representing the rays.
257-
reflect (bool, optional): Indicates whether the rays are reflected
258-
or not. Defaults to False.
259-
aoi (be.ndarray, optional): Array representing the angle of
260-
incidence. Defaults to None.
261-
262-
Returns:
263-
be.ndarray: The calculated Jones matrix.
264-
265-
"""
266-
jones_matrix = be.to_complex(be.zeros((be.size(rays.x), 3, 3)))
267-
jones_matrix[:, 0, 0] = 0.5
268-
jones_matrix[:, 0, 1] = 1j * 0.5
269-
jones_matrix[:, 1, 0] = -1j * 0.5
270-
jones_matrix[:, 1, 1] = 0.5
271-
jones_matrix[:, 2, 2] = 1
272-
273-
return jones_matrix
196+
def __init__(self):
197+
super().__init__(0.5, 1j * 0.5, -1j * 0.5, 0.5)
274198

275199

276-
class JonesPolarizerLCP(BaseJones):
200+
class JonesPolarizerLCP(ConstantJones):
277201
"""Class representing the Jones matrix for a left circular polarizer."""
278202

279-
def calculate_matrix(
280-
self,
281-
rays: RealRays,
282-
reflect: bool = False,
283-
aoi: be.ndarray = None,
284-
):
285-
"""Calculate the Jones matrix for the given rays.
286-
287-
Args:
288-
rays (RealRays): Object representing the rays.
289-
reflect (bool, optional): Indicates whether the rays are reflected
290-
or not. Defaults to False.
291-
aoi (be.ndarray, optional): Array representing the angle of
292-
incidence. Defaults to None.
293-
294-
Returns:
295-
be.ndarray: The calculated Jones matrix.
296-
297-
"""
298-
jones_matrix = be.to_complex(be.zeros((be.size(rays.x), 3, 3)))
299-
jones_matrix[:, 0, 0] = 0.5
300-
jones_matrix[:, 0, 1] = -1j * 0.5
301-
jones_matrix[:, 1, 0] = 1j * 0.5
302-
jones_matrix[:, 1, 1] = 0.5
303-
jones_matrix[:, 2, 2] = 1
304-
305-
return jones_matrix
203+
def __init__(self):
204+
super().__init__(0.5, -1j * 0.5, 1j * 0.5, 0.5)
306205

307206

308207
class JonesLinearDiattenuator(BaseJones):

optiland/rays/polarization_state.py

Lines changed: 21 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -101,44 +101,26 @@ def create_polarization(pol_type: str):
101101
"""
102102
if pol_type == "unpolarized":
103103
return PolarizationState(is_polarized=False)
104-
if pol_type == "H":
105-
Ex = 1
106-
Ey = 0
107-
phase_x = 0
108-
phase_y = 0
109-
elif pol_type == "V":
110-
Ex = 0
111-
Ey = 1
112-
phase_x = 0
113-
phase_y = 0
114-
elif pol_type == "L+45":
115-
Ex = 1
116-
Ey = 1
117-
phase_x = 0
118-
phase_y = 0
119-
elif pol_type == "L-45":
120-
Ex = 1
121-
Ey = -1
122-
phase_x = 0
123-
phase_y = 0
124-
elif pol_type == "RCP":
125-
Ex = be.sqrt(2) / 2
126-
Ey = be.sqrt(2) / 2
127-
phase_x = 0
128-
phase_y = -be.pi / 2
129-
elif pol_type == "LCP":
130-
Ex = be.sqrt(2) / 2
131-
Ey = be.sqrt(2) / 2
132-
phase_x = 0
133-
phase_y = be.pi / 2
134-
else:
135-
raise ValueError(
136-
"Invalid polarization type. Must be H, V, L+45, L-45, RCP or LCP.",
104+
105+
pol_map = {
106+
"H": (1.0, 0.0, 0.0, 0.0),
107+
"V": (0.0, 1.0, 0.0, 0.0),
108+
"L+45": (1.0, 1.0, 0.0, 0.0),
109+
"L-45": (1.0, -1.0, 0.0, 0.0),
110+
"RCP": (be.sqrt(2) / 2, be.sqrt(2) / 2, 0.0, -be.pi / 2),
111+
"LCP": (be.sqrt(2) / 2, be.sqrt(2) / 2, 0.0, be.pi / 2),
112+
}
113+
114+
if pol_type in pol_map:
115+
Ex, Ey, phase_x, phase_y = pol_map[pol_type]
116+
return PolarizationState(
117+
is_polarized=True,
118+
Ex=Ex,
119+
Ey=Ey,
120+
phase_x=phase_x,
121+
phase_y=phase_y,
137122
)
138-
return PolarizationState(
139-
is_polarized=True,
140-
Ex=Ex,
141-
Ey=Ey,
142-
phase_x=phase_x,
143-
phase_y=phase_y,
123+
124+
raise ValueError(
125+
"Invalid polarization type. Must be H, V, L+45, L-45, RCP or LCP.",
144126
)

0 commit comments

Comments
 (0)