예제 #1
0
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
예제 #2
0
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
예제 #3
0
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
예제 #4
0
파일: matrix.py 프로젝트: xj361685640/dtmm
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)
예제 #5
0
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
예제 #6
0
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)
예제 #7
0
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)
예제 #8
0
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)
예제 #9
0
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)
예제 #10
0
파일: matrix.py 프로젝트: xj361685640/dtmm
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)
예제 #11
0
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)
예제 #12
0
파일: matrix.py 프로젝트: xj361685640/dtmm
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)
예제 #13
0
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)
예제 #14
0
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)
예제 #15
0
파일: matrix.py 프로젝트: xj361685640/dtmm
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)
예제 #16
0
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.")
예제 #17
0
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)
예제 #18
0
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)
예제 #19
0
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)
예제 #20
0
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
예제 #21
0
    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
예제 #22
0
    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