def polarizer4x4(jones, fmat, out=None): """Returns a polarizer matrix from a given jones vector and field matrix. Numpy broadcasting rules apply. Parameters ---------- jones : array_like A length two array describing the jones vector. Jones vector should be normalized. fmat : array_like A field matrix array of the medium. out : ndarray, optional Output array Examples -------- >>> f = f_iso(n = 1.) >>> jvec = dtmm.jones.jonesvec((1,0)) >>> pol_mat = polarizer4x4(jvec, f) #x polarizer matrix """ jonesmat = polarizer2x2(jones) fmat = normalize_f(fmat) fmati = inv(fmat) pmat = as4x4(jonesmat) m = dotmm(fmat, dotmm(pmat, fmati, out=out), out=out) return m
def jonesmat4x4(jmat, fmat, out=None): """Returns a 4x4 jones matrix for applying in eigenframe. Numpy broadcasting rules apply. Parameters ---------- jmat : (...,2,2) array A 2x2 jones matrix in the eigenframe. Any of matrices in :mod:`dtmm.jones` can be used. fmat : (...,4,4) array A field matrix array of the isotropic medium. out : ndarray, optional Output array Returns ------- jmat : (...,4,4) array A 4x4 matrix for field vector manipulation in the eigenframe. See Also -------- ray_jonesmat4x4 : for applying the jones matrix in the laboratory frame. """ fmat = normalize_f(fmat) fmati = inv(fmat) pmat = as4x4(jmat) m = dotmm(fmat, dotmm(pmat, fmati, out=out), out=out) return m
def stack_mat(kd, epsv, epsa, beta=0, phi=0, method="4x4", out=None): """Computes a stack characteristic matrix M = M_1.M_2....M_n if method is 4x4, 4x2(2x4) and a characteristic matrix M = M_n...M_2.M_1 if method is 2x2. Note that this function calls :func:`layer_mat`, so numpy broadcasting rules apply to kd[i], epsv[i], epsa[], beta and phi. Parameters ---------- kd : array_like A sequence of phase values (layer thickness times wavenumber in vacuum). len(kd) must match len(epsv) and len(epsa). epsv : array_like A sequence of epsilon eigenvalues. epsa : array_like A sequence of optical axes orientation angles (psi, theta, phi). beta : float Beta angle of input light. phi : float Phi angle of input light. method : str One of `4x4` (4x4 berreman), `2x2` (2x2 jones) or `4x2` (4x4 single reflections) out : ndarray, optional Returns ------- cmat : ndarray Characteristic matrix of the stack. """ t0 = time.time() mat = None n = len(kd) indices = range(n) if method == "2x2": indices = reversed(indices) verbose_level = DTMMConfig.verbose if verbose_level > 1: print("Building stack matrix.") for pi, i in enumerate(range(n)): print_progress(pi, n, level=verbose_level) mat = layer_mat(kd[i], epsv[i], epsa[i], beta=beta, phi=phi, method=method, out=mat) if pi == 0: if out is None: out = mat.copy() else: out[...] = mat else: dotmm(out, mat, out) print_progress(n, n, level=verbose_level) t = time.time() - t0 if verbose_level > 1: print(" Done in {:.2f} seconds!".format(t)) return out
def second_corrected_Epn_diffraction_matrix(shape, ks, beta, phi, d=1., epsv=(1, 1, 1), epsa=(0, 0, 0.), window=None, betamax=BETAMAX): dmat = second_Epn_diffraction_matrix(shape, ks, d, epsv, epsa, betamax=betamax) if window is not None: cmats = Epn_correction_matrix(beta, phi, ks, d, epsv, epsa) out = np.zeros_like(dmat) for w, cmat in zip(window, cmats): out += dotmm(w * dmat, cmat) return out else: cmat = Epn_correction_matrix(beta, phi, ks, d, epsv, epsa) return dotmm(dmat, cmat, out=None)
def stack_mat3d(k, d, epsv, epsa, method="4x4", mask=None): n = len(d) verbose_level = DTMMConfig.verbose if verbose_level > 1: print("Building stack matrix.") for i in range(n): print_progress(i, n, level=verbose_level) mat = layer_mat3d(k, d[i], epsv[i], epsa[i], mask=mask, method=method) if i == 0: if isinstance(mat, tuple): out = tuple((m.copy() for m in mat)) else: out = mat.copy() else: if isinstance(mat, tuple): if method.startswith("2x2"): out = tuple((bdotmm(m, o) for o, m in zip(out, mat))) else: out = tuple((bdotmm(o, m) for o, m in zip(out, mat))) else: if method.startswith("2x2"): out = dotmm(mat, out) else: out = dotmm(out, mat) print_progress(n, n, level=verbose_level) return out
def system_mat(cmat, fmatin=None, fmatout=None, fmatini=None, out=None): """Computes a system matrix from a characteristic matrix Fin-1.C.Fout""" if fmatini is None: if fmatin is None: fmatin = f_iso(1, 0, 0) fmatini = inv(fmatin) if fmatout is None: fmatout = fmatin out = dotmm(fmatini, cmat, out=out) return dotmm(out, fmatout, out=out)
def Etri_mat(fin, fout, fini=None, overwrite_fin=False, mode=+1, out=None): out1, out2 = out if out is not None else (None, None) A = E_mat(fin, mode=mode, copy=False) Ai = inv(A, out=out1) St, Sr = S_mat(fin, fout, fini=fini, overwrite_fin=overwrite_fin, mode=mode) Sti = inv(St, out=St) ei = dotmm(Sti, Ai, out=Ai) return ei, dotmm(Sr, ei, out=out2)
def transmission_mat(fin, fout, fini=None, mode=+1, out=None): A, B = S_mat(fin, fout, fini=fini, mode=mode) if mode == +1: A1 = fin[..., ::2, ::2] A2 = fout[..., ::2, ::2] elif mode == -1: A1 = fin[..., 1::2, 1::2] A2 = fout[..., 1::2, 1::2] else: raise ValueError("Unknown propagation mode.") Ai = inv(A, out=out) A1i = inv(A1) return dotmm(dotmm(A2, Ai, out=Ai), A1i, out=Ai)
def tr_mat(fin, fout, fini=None, overwrite_fin=False, mode=+1, out=None): if overwrite_fin == True: er = E_mat(fin, mode=mode * (-1), copy=True) else: er = E_mat(fin, mode=mode * (-1), copy=False) et = E_mat(fout, mode=mode, copy=False) eti, eri = Etri_mat(fin, fout, fini=fini, overwrite_fin=overwrite_fin, mode=mode, out=out) return dotmm(et, eti, out=eti), dotmm(er, eri, out=eri)
def corrected_field_diffraction_matrix(shape, ks, beta, phi, d=1., epsv=(1, 1, 1), epsa=(0, 0, 0.), betamax=BETAMAX, out=None): dmat = field_diffraction_matrix(shape, ks, d, epsv, epsa, betamax=betamax) cmat = correction_matrix(beta, phi, ks, d / 2, epsv, epsa) dmat = dotmm(dmat, cmat, out=out) return dotmm(cmat, dmat, out=dmat)
def t_mat(fin, fout, fini=None, overwrite_fin=False, mode=+1, out=None): eti = Eti_mat(fin, fout, fini=fini, overwrite_fin=overwrite_fin, mode=mode, out=out) et = E_mat(fout, mode=mode, copy=False) return dotmm(et, eti, out=eti)
def corrected_E_diffraction_matrix(shape, ks, beta, phi, d=1., epsv=(1, 1, 1), epsa=(0, 0, 0.), mode=+1, betamax=BETAMAX, out=None): dmat = E_diffraction_matrix(shape, ks, d, epsv, epsa, mode=mode, betamax=betamax) cmat = E_correction_matrix(beta, phi, ks, d / 2., epsv, epsa, mode=mode) return dotmm(cmat, dotmm(dmat, cmat, out=out), out=out)
def Eti_mat(fin, fout, fini=None, overwrite_fin=False, mode=+1, out=None): A = E_mat(fin, mode=mode, copy=False) Ai = inv(A, out=out) St, Sr = S_mat(fin, fout, fini=fini, overwrite_fin=overwrite_fin, mode=mode) Sti = inv(St, out=St) return dotmm(Sti, Ai, out=Ai)
def E2H_mat(fmat, mode=+1, out=None): if mode == +1: A = fmat[..., ::2, ::2] B = fmat[..., 1::2, ::2] elif mode == -1: A = fmat[..., ::2, 1::2] B = fmat[..., 1::2, 1::2] else: raise ValueError("Unknown propagation mode.") Ai = inv(A, out=out) return dotmm(B, Ai, out=Ai)
def first_field_diffraction_matrix(shape, ks, beta, phi, d=1., epsv=(1, 1, 1), epsa=(0, 0, 0.), betamax=BETAMAX, out=None): dmat = field_diffraction_matrix(shape, ks, d, epsv, epsa, betamax=betamax) cmat = field_correction_matrix(beta, phi, ks, d, epsv, epsa) return dotmm(dmat, cmat, out=None)
def S_mat(fin, fout, fini=None, overwrite_fin=False, mode=+1): if overwrite_fin == True: out = fin else: out = None if fini is None: fini = inv(fin, out=out) S = dotmm(fini, fout, out=out) if mode == +1: return S[..., ::2, ::2], S[..., 1::2, 0::2] elif mode == -1: return S[..., 1::2, 1::2], S[..., 0::2, 1::2] else: raise ValueError("Unknown propagation mode.")
def reflection_mat(smat, out=None): """Computes a 4x4 reflection matrix. """ m1 = np.zeros_like(smat) m2 = np.zeros_like(smat) m1[..., 1, 1] = 1. m1[..., 3, 3] = 1. m1[..., :, 0] = -smat[..., :, 0] m1[..., :, 2] = -smat[..., :, 2] m2[..., 0, 0] = -1. m2[..., 2, 2] = -1. m2[..., :, 1] = smat[..., :, 1] m2[..., :, 3] = smat[..., :, 3] m1 = inv(m1) return dotmm(m1, m2, out=out)
def second_corrected_Epn_diffraction_matrix(shape, ks, beta, phi, d=1., epsv=(1, 1, 1), epsa=(0, 0, 0.), betamax=BETAMAX, out=None): dmat = second_Epn_diffraction_matrix(shape, ks, d, epsv, epsa, betamax=betamax) cmat = Epn_correction_matrix(beta, phi, ks, d, epsv, epsa) return dotmm(dmat, cmat, out=None)
def apply_jonesmat(pmat, field, out=None): """Multiplies a (2x2) or (4x4) jones matrix with field vector Parameters ---------- pmat : ndarray A 4x4 jones matrix of shape (...,4,4) for field data or 2x2 jones matrix of shape (...,2,2) for E-field data or field : array Field vector array of shape (...,4) or (...,2). out : array, optional If specified, the results are written here. Returns ------- out : ndarray Computed field array of shape (...,4). """ return dotmm(pmat, field, out=out)
def as2x2(pmat, fmat, mode=+1, out=None): """Converts jones 4x4 matrix to 2x2 E-field matrix""" H = E2H_mat(fmat, mode=mode) out = dotmm(pmat[..., ::2, 1::2], H, out) out += pmat[..., ::2, ::2] return out
def _calculate_specter_mode(self, recalc=False, **params): self.set_parameters(**params) if self.ofield is None: recalc = True #first time only trigger calculation if recalc or self._has_parameter_updated("analyzer", "sample"): sample = self.sample if self.sample is not None else 0. if self.analyzer is not None: angle = -np.pi / 180 * (self.analyzer - sample) c, s = np.cos(angle), np.sin(angle) self.pmat = mode_polarizer(self.ifield.shape[-2:], self.ks, jones=(c, s), epsv=self.epsv, epsa=self.epsa, betamax=self.betamax) if self.pmode != "mode": self.pmat = self.pmat[..., 0:1, 0:1, :, :] if recalc or self._has_parameter_updated("focus"): if self.mode is None: self.ffield = fft2(self.ifield[self.focus]) else: self.dmat = field_diffraction_matrix(self.ifield.shape[-2:], self.ks, d=0, epsv=self.epsv, epsa=self.epsa, mode=self.mode, betamax=self.betamax) self.ffield = fft2(self.ifield[self.focus]) recalc = True #trigger update of self.data if recalc or self._has_parameter_updated("sample", "polarizer"): sample = self.sample if self.sample is not None else 0. if self.polarizer is not None: angle = -np.pi / 180 * (self.polarizer - sample) c, s = np.cos(angle), np.sin(angle) self.data = _redim(self.ffield, ndim=6) x = c * self.data[:, 0] y = s * self.data[:, 1] self.data = x + y else: self.data = _redim(self.ffield, ndim=5) if recalc or self._has_parameter_updated( "analyzer", "sample", "polarizer", "focus", "intensity"): if self.dmat is not None: pmat = dotmm(self.pmat, self.dmat) else: pmat = self.pmat self.ofield = dotmf(pmat, self.data, out=self.ofield) self.ofield = ifft2(self.ofield, out=self.ofield) for i, data in enumerate(self.ofield): if i == 0: self.specter = field2specter(data) else: self.specter += field2specter(data) recalc = True if recalc or "intensity" in self._updated_parameters: self._updated_parameters.clear() self._updated_parameters.add( "intensity") #trigger calculate_image call else: self._updated_parameters.clear() return self.specter
def _calculate_specter_mode(self, recalc=False, **params): self.set_parameters(**params) if self.ofield is None: recalc = True #first time only trigger calculation if recalc or self._has_parameter_updated("sample", "polarizer"): sample = self.sample if self.sample is not None else 0. if self.polarizer is not None: if self.ffield is None: self.ffield = fft2(self.ifield) angle = -np.pi / 180 * (self.polarizer - sample) c, s = np.cos(angle), np.sin(angle) self.data = _redim(self.ffield, ndim=6) x = c * self.data[:, 0] y = s * self.data[:, 1] self.data = x + y else: self.data = _redim(self.ffield, ndim=5) if recalc or self._has_parameter_updated("focus"): if self.diffraction == True or self.mode is not None: #if mode is selected, we need to project the field using diffraction d = 0 if self.focus is None else self.focus self.dmat = field_diffraction_matrix(self.ifield.shape[-2:], self.ks, d=d, epsv=self.epsv, epsa=self.epsa, mode=self.mode, betamax=self.betamax) else: self.dmat = np.asarray(np.diag((1, 1, 1, 1)), CDTYPE) if recalc or self._has_parameter_updated("analyzer", "sample"): sample = self.sample if self.sample is not None else 0. if self.analyzer is not None: angle = -np.pi / 180 * (self.analyzer - sample) c, s = np.cos(angle), np.sin(angle) self.pmat = mode_polarizer(self.ifield.shape[-2:], self.ks, jones=(c, s), epsv=self.epsv, epsa=self.epsa, betamax=self.betamax) else: self.pmat = None if recalc or self._has_parameter_updated( "analyzer", "sample", "polarizer", "focus", "intensity"): tmat = None if self.pmat is not None and self.dmat is not None: tmat = dotmm(self.pmat, self.dmat) if self.pmat is None and self.dmat is not None: tmat = self.dmat if self.pmat is not None and self.dmat is None: tmat = self.pmat if tmat is not None: self.ofield = dotmf(tmat, self.data, out=self.ofield) self.ofield = ifft2(self.ofield, out=self.ofield) for i, data in enumerate(self.ofield): if i == 0: self.specter = field2specter(data) else: self.specter += field2specter(data) recalc = True if recalc or "intensity" in self._updated_parameters: self._updated_parameters.clear() self._updated_parameters.add( "intensity") #trigger calculate_image call else: self._updated_parameters.clear() return self.specter