Source code for skcomponents.optics.rotators

import numpy as np
from skcomponents.optics.component import OpticalComponent


[docs]class LinearRetarder(OpticalComponent): def __init__(self, rotation, phase): """ Parameters ---------- rotation : float Angle between the fast and slow axis phase : phase difference between fast and slow axis """ self._phase_difference = phase self._rotation = rotation
[docs] def matrix(self, wavelength) -> np.array: theta = 2 * self._rotation * np.pi / 180 phase = self._phase_difference * np.pi / 180 m_22 = (np.cos(theta) ** 2) + (np.sin(theta) ** 2) * np.cos(phase) m_23 = np.cos(theta) * np.sin(theta) * (1 - np.cos(phase)) m_24 = np.sin(theta) * np.sin(phase) m_32 = m_23 m_33 = (np.cos(theta) ** 2) * np.cos(phase) + (np.sin(theta) ** 2) m_34 = -np.cos(theta) * np.sin(phase) m_42 = -m_24 m_43 = -m_34 m_44 = np.cos(phase) return np.array([[1, 0, 0, 0], [0, m_22, m_23, m_24], [0, m_32, m_33, m_34], [0, m_42, m_43, m_44]])
[docs]class HalfWavePlate(LinearRetarder): def __init__(self, rotation): super().__init__(rotation=rotation, phase=180)
[docs]class QuarterWavePlate(LinearRetarder): def __init__(self, rotation): super().__init__(rotation=rotation, phase=90)
[docs]class LiquidCrystalRotator(OpticalComponent): def __init__(self, twist_angle: float = 0.0, phase: float = 180.0, reference_wavelength: float = None): """ Liquid crystal rotator based on the principal of a twisted nematic cell. Parameters ---------- twist_angle : float Angle of twist in the cell in degrees. phase : float Retardance angle of the cell in degrees, 180 * d * dn / lambda. The birefringence, `dn`, is assumed to vary with 1/lambda so that the phase is independent of wavelength. Notes ----- S. T. Tang, H. W. Chiu, and H. S. Kwok , "Optically optimized transmittive and reflective bistable twisted nematic liquid crystal displays", Journal of Applied Physics 87, 632-637 (2000) https://doi.org/10.1063/1.371918 """ self._twist_angle = twist_angle self._phase = phase self.reference_wavelength = reference_wavelength @property def twist_angle(self): return self._twist_angle @twist_angle.setter def twist_angle(self, value): self._twist_angle = value @property def phase(self): return self._phase @phase.setter def phase(self, value): self._phase = value
[docs] def matrix(self, wavelength) -> np.array: if (self._phase == 0) and (self._twist_angle == 0): return np.eye(4) phi = self._twist_angle * np.pi / 180 if self.reference_wavelength is not None: delta = self._phase * np.pi / 180 * (self.reference_wavelength / wavelength) else: delta = self._phase * np.pi / 180 x = np.sqrt(phi ** 2 + delta ** 2) a = np.cos(phi) * np.cos(x) + phi / x * np.sin(phi) * np.sin(x) b = delta / x * np.cos(phi) * np.sin(x) c = np.sin(phi) * np.cos(x) - phi / x * np.cos(phi) * np.sin(x) d = delta / x * np.sin(phi) * np.sin(x) m22 = 1 - 2 * (c ** 2 + d ** 2) m23 = 2 * (b * d - a * c) m24 = -2 * (a * d + b * c) m32 = 2 * (a * c + b * d) m33 = 1 - 2 * (b ** 2 + c ** 2) m34 = 2 * (a * b - c * d) m42 = 2 * (a * d - b * c) m43 = -2 * (a * b + c * d) m44 = 1 - 2 * (b ** 2 + d ** 2) return np.array([[1, 0, 0, 0], [0, m22, m23, m24], [0, m32, m33, m34], [0, m42, m43, m44]])
[docs]class IdealLCR(LiquidCrystalRotator): def __init__(self, twist_angle: float = 0.0): """ Same as LiquidCrystalRotator, however, the phase is compensated such that the polarization rotation is always equal to `twist_angle` """ super().__init__(twist_angle=twist_angle, phase=np.sqrt(180 ** 2 - twist_angle ** 2)) @LiquidCrystalRotator.twist_angle.setter def twist_angle(self, value): self._twist_angle = value self._phase = np.sqrt(180 ** 2 - value ** 2)