Source code for skcomponents.optics.polarizers

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


[docs]class LinearPolarizer(OpticalComponent): def __init__(self, orientation: float, wavelength_nm: np.array = None, contrast_ratio: np.array = None, transmission: np.array = None): """ Linear polarizer Parameters ---------- orientation : float Orientation of the polarizer in degrees. 0 is horizontal, 90 is vertical """ self._theta = orientation if contrast_ratio is not None: if len(wavelength_nm) != len(contrast_ratio): raise ValueError('wavelength_nm and contrast_ratio must be the same length') self._k1 = contrast_ratio / (1 + contrast_ratio) self._k2 = 1 / (1 + contrast_ratio) if transmission is not None: if len(wavelength_nm) != len(transmission): raise ValueError('wavelength_nm and transmission must be the same length') self._transmission = transmission self._contrast_ratio = contrast_ratio self._wavelength_nm = wavelength_nm @property def orientation(self): return self._theta @orientation.setter def orientation(self, value): self._theta = value @property def wavelength_nm(self): return self._wavelength_nm def contrast_ratio(self, wavelength): if self._contrast_ratio is None: return np.inf else: return np.interp(wavelength, self._wavelength_nm, self._contrast_ratio) def transmission(self, wavelength): if self._transmission is None: return 1.0 else: return np.interp(wavelength, self._wavelength_nm, self._transmission, left=self._transmission[0], right=self._transmission[-1]) def px(self, wavelength): if self._contrast_ratio is None: return 1 else: return np.sqrt(np.interp(wavelength, self._wavelength_nm, self._k1, left=self._k1[0], right=self._k1[-1])) def py(self, wavelength): if self._contrast_ratio is None: return 0 else: return np.sqrt(np.interp(wavelength, self._wavelength_nm, self._k2, left=self._k2[0], right=self._k2[-1])) def _mueller_matrix(self, wavelength): px = self.px(wavelength) py = self.py(wavelength) m11 = px ** 2 + py ** 2 m12 = px ** 2 - py ** 2 m21 = m12 m22 = m11 m33 = 2 * px * py m44 = m33 t = self.transmission(wavelength) return t * 0.5 * np.array([[m11, m12, 0, 0], [m21, m22, 0, 0], [0, 0, m33, 0], [0, 0, 0, m44]])
[docs] def matrix(self, wavelength): return self.rotation_matrix(self._theta) @ self._mueller_matrix(wavelength) @ self.rotation_matrix(-self._theta)
@staticmethod def rotation_matrix(theta): theta = 2 * theta * np.pi / 180 return np.array([[1, 0, 0, 0], [0, np.cos(theta), np.sin(theta), 0], [0, -np.sin(theta), np.cos(theta), 0], [0, 0, 0, 1]])
[docs]class IdealLinearPolarizer(LinearPolarizer): def _mueller_matrix(self, wavelength): return 0.5 * np.array([[1, 1, 0, 0], [1, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]])
[docs]class VerticalPolarizer(LinearPolarizer): def __init__(self, **kwargs): super().__init__(90.0, **kwargs)
[docs]class HorizontalPolarizer(LinearPolarizer): def __init__(self, **kwargs): super().__init__(0.0, **kwargs)