Ejemplo n.º 1
0
def _transfer_ray_4x4_4(field,
                        wavenumbers,
                        layer,
                        beta=0,
                        phi=0,
                        nsteps=1,
                        dmat=None,
                        out=None):

    d, epsv, epsa = layer

    if dmat is None:
        kd = wavenumbers * d
    else:
        kd = wavenumbers * d / 2

    alpha, f, fi = alphaffi(beta, phi, epsv, epsa)
    p = phasem(alpha, kd[..., None, None])

    for j in range(nsteps):
        if dmat is None:
            field = dotmdmf(f, p, fi, field, out=out)
        else:
            field = dotmdmf(f, p, fi, field, out=out)
            field = diffract(field, dmat, out=field)
            field = dotmdmf(f, p, fi, field, out=field)

    return field
Ejemplo n.º 2
0
def _projected_field(field, wavenumbers, mode, n=1, betamax=BETAMAX, out=None):
    eps = refind2eps([n] * 3)
    pmat = projection_matrix(field.shape[-2:],
                             wavenumbers,
                             epsv=eps,
                             epsa=(0., 0., 0.),
                             mode=mode,
                             betamax=betamax)
    return diffract(field, pmat, out=out)
Ejemplo n.º 3
0
def _transfer_ray_4x4_2(field,
                        wavenumbers,
                        layer,
                        beta=0,
                        phi=0,
                        nsteps=1,
                        dmatpn=None,
                        out=None,
                        tmpdata=None):
    _out = {} if tmpdata is None else tmpdata

    d, epsv, epsa = layer

    if dmatpn is None:
        kd = wavenumbers * d
    else:
        dmatp, dmatn = dmatpn
        kd = wavenumbers * d / 2

    alpha, f, fi = alphaffi(beta, phi, epsv, epsa, out=_out.get("affi"))

    p = phasem(alpha, kd[..., None, None], out=_out.get("p"))
    if tmpdata is not None:
        tmpdata["affi"] = (alpha, f, fi)
        tmpdata["p"] = p

    if dmatpn is not None:
        e = E_mat(f, mode=None)
        ei = inv(e, out=_out.get("ei"))
        if tmpdata is not None:
            tmpdata["ei"] = ei

    for j in range(nsteps):
        if dmatpn is None:
            field = dotmdmf(f, p, fi, field, out=out)
        else:
            field = dotmdmf(e, p, fi, field, out=out)
            diffract(field[..., 0::2, :, :], dmatp, out=field[..., 0::2, :, :])
            diffract(field[..., 1::2, :, :], dmatn, out=field[..., 1::2, :, :])
            field = dotmdmf(f, p, ei, field, out=field)

    return field
Ejemplo n.º 4
0
def jones2H(jones, wavenumbers, n=1., betamax=BETAMAX, mode=+1, out=None):
    eps = refind2eps([n] * 3)
    shape = jones.shape[-2:]
    layer = np.asarray((0., 0., 0.), dtype=FDTYPE)
    alpha, f, fi = diffraction_alphaffi(shape,
                                        wavenumbers,
                                        epsv=eps,
                                        epsa=layer,
                                        betamax=betamax)
    #    A = f[...,::2,::2]
    #    B = f[...,1::2,::2]
    #    Ai = inv(A)
    #    D = dotmm(B,Ai)
    D = E2H_mat(f, mode=mode)
    return diffract(jones, D, out=out)
Ejemplo n.º 5
0
    def _calculate_specter_normal(self, recalc=False, **params):
        self.set_parameters(**params)
        if self.ofield is None:
            recalc = True  #first time only trigger calculation
        if recalc or "focus" in self._updated_parameters:
            if self.mode is None:
                self.ofield = self.ifield[self.focus]
            else:
                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.ofield = diffract(self.ifield[self.focus],
                                       dmat,
                                       window=self.window,
                                       out=self.ofield)
            recalc = True

        if recalc or "polarizer" in self._updated_parameters or "analyzer" in self._updated_parameters or "sample" in self._updated_parameters:
            sample = self.sample
            if sample is None:
                sample = 0.
            if self.polarizer is None:
                tmp = _redim(self.ofield, ndim=5)
                out = np.empty_like(tmp[0])
            else:
                angle = -np.pi / 180 * (self.polarizer - sample)
                c, s = np.cos(angle), np.sin(angle)
                tmp = _redim(self.ofield, ndim=6)
                out = np.empty_like(tmp[0, 0])
            if self.analyzer is not None:
                angle = -np.pi / 180 * (self.analyzer - sample)
                #pmat = linear_polarizer(angle)
                pmat = ray_polarizer((np.cos(angle), np.sin(angle)),
                                     epsv=self.epsv,
                                     epsa=self.epsa)

            for i, data in enumerate(tmp):
                if self.polarizer is not None:
                    x = data[0] * c
                    y = np.multiply(data[1], s, out=out)
                    ffield = np.add(
                        x, y, out=out)  #numexpr.evaluate("x*c+y*s", out = out)
                else:
                    ffield = data

                if self.analyzer is not None:
                    pfield = dotmf(pmat, ffield, out=out)
                else:
                    pfield = ffield
                if i == 0:
                    self.specter = field2specter(pfield)
                else:
                    self.specter += field2specter(pfield)
            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
Ejemplo n.º 6
0
    def _calculate_specter_normal(self, recalc=False, **params):
        """Calculates field specter.
        
        Parameters
        ----------
        recalc : bool, optional
            If specified, it forces recalculation. Otherwise, result is calculated
            only if calculation parameters have changed.
        params: kwargs, optional
            Any additional keyword arguments that are passed dirrectly to 
            set_parameters method.
        """
        self.set_parameters(**params)
        if self.ofield is None:
            recalc = True  #first time only trigger calculation
        if recalc or "focus" in self._updated_parameters:
            if self.diffraction == True or self.mode is not None:
                #if mode is selected, we need to project the filed using diffraction
                d = 0 if self.focus is None else self.focus
                dmat = field_diffraction_matrix(self.ifield.shape[-2:],
                                                self.ks,
                                                d=d,
                                                epsv=self.epsv,
                                                epsa=self.epsa,
                                                mode=self.mode,
                                                betamax=self.betamax)

                self.ofield = diffract(self.ifield,
                                       dmat,
                                       window=self.window,
                                       out=self.ofield)
            else:
                #no diffraction at all..
                if self.window is not None:
                    self.ofield = self.ifield * self.window
                else:
                    self.ofield = self.ifield.copy()
            recalc = True
        if recalc or "polarizer" in self._updated_parameters or "analyzer" in self._updated_parameters or "sample" in self._updated_parameters:
            sample = self.sample
            if sample is None:
                sample = 0.
            if self.polarizer is None:
                tmp = _redim(self.ofield, ndim=5)
                out = np.empty_like(tmp[0])
            else:
                angle = -np.pi / 180 * (self.polarizer - sample)
                c, s = np.cos(angle), np.sin(angle)
                tmp = _redim(self.ofield, ndim=6)
                out = np.empty_like(tmp[0, 0])
            if self.analyzer is not None:

                angle = -np.pi / 180 * (self.analyzer - sample)
                #pmat = linear_polarizer(angle)
                pmat = normal_polarizer((np.cos(angle), np.sin(angle)))
                #pmat = ray_polarizer((np.cos(angle),np.sin(angle)),epsv = self.epsv, epsa = self.epsa)

            for i, data in enumerate(tmp):
                if self.polarizer is not None:
                    x = data[0] * c
                    y = np.multiply(data[1], s, out=out)
                    ffield = np.add(
                        x, y, out=out)  #numexpr.evaluate("x*c+y*s", out = out)
                else:
                    ffield = data

                if self.analyzer is not None:
                    #pfield = apply_jones_matrix(pmat, ffield, out = out)
                    pfield = dotmf(pmat, ffield, out=out)
                else:
                    pfield = ffield
                if i == 0:
                    self.specter = field2specter(pfield)
                else:
                    self.specter += field2specter(pfield)
            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
Ejemplo n.º 7
0
def _transfer_ray_2x2_2(field,
                        wavenumbers,
                        in_layer,
                        out_layer,
                        dmat=None,
                        beta=0,
                        phi=0,
                        nsteps=1,
                        mode=+1,
                        reflection=True,
                        betamax=BETAMAX,
                        refl=None,
                        bulk=None,
                        out=None,
                        tmpdata=None):
    _out = {} if tmpdata is None else tmpdata
    if in_layer is not None:
        d, epsv, epsa = in_layer
        alpha, fmat_in = alphaf(beta, phi, epsv, epsa, out=_out.get("afin"))
        if tmpdata is not None:
            _out["afin"] = alpha, fmat_in
    d, epsv, epsa = out_layer
    alpha, fmat = alphaf(beta, phi, epsv, epsa, out=_out.get("afout"))
    e = E_mat(fmat, mode=mode, copy=False)  #2x2 E-only view of fmat
    #    if refl is not None:
    #        ein = E_mat(fmat_in, mode = mode * (-1)) #reverse direction
    #
    #    if reflection == 0:
    #        kd = wavenumbers * d
    #    else:
    kd = wavenumbers * d / 2
    p = phase_mat(alpha, kd[..., None, None], mode=mode, out=_out.get("p"))

    ei0 = inv(e, out=_out.get("ei0"))
    ei = ei0

    if tmpdata is not None:
        _out["afout"] = alpha, fmat
        _out["ei0"] = ei
        _out["p"] = p

    for j in range(nsteps):
        #reflect only at the beginning
        if j == 0 and reflection != 0:
            #if we need to track reflections (multipass)
            if refl is not None:
                #ei,eri = Etri_mat(fmat_in, fmat, mode = mode, out = _out.get("eieri"))
                tmat, rmat = tr_mat(fmat_in,
                                    fmat,
                                    mode=mode,
                                    out=_out.get("eieri"))
                if tmpdata is not None:
                    #_out["eieri"] = ei,eri
                    _out["eieri"] = tmat, rmat
                trans = refl.copy()
                #refl = dotmf(eri, field, out = refl)
                refl = dotmf(rmat, field, out=refl)
                #field = dotmf(ei,field, out = out)
                field = dotmf(tmat, field, out=out)
                field = np.add(field, trans, out=field)

                if mode == -1 and bulk is not None:
                    #tmp_field = dotmf(e,field)
                    tmp_field = field
                    e2h = E2H_mat(fmat, mode=mode)
                    bulk[..., ::2, :, :] += tmp_field
                    bulk[..., 1::2, :, :] += dotmf(e2h, tmp_field)

                field = dotmf(ei, field, out=field)

                if d != 0.:
                    field = dotmf(dotmd(e, p), field, out=field)

                else:
                    field = dotmf(e, field, out=field)
                out = field

                #                rmat = dotmm(ein, eri, out = eri)
                #                trans = refl.copy()
                #                refl = dotmf(rmat, field, out = refl)
                #                ei0 = inv(e)
                #                field = dotmf(ei,field, out = out)
                #                field = dotmf(e,field) + trans
                #                if d != 0.:
                #                    field = dotmdmf(e,p,ei0,field, out = out)

                ei = ei0
            else:
                ei = Eti_mat(fmat_in, fmat, mode=mode, out=_out.get("eti"))
                field = dotmdmf(e, p, ei, field, out=out)
                out = field
                if tmpdata is not None:
                    _out["eti"] = ei
                ei = ei0
        else:
            #no need to compute if d == 0!.. identity
            if d != 0.:
                field = dotmdmf(e, p, ei, field, out=out)
                out = field
        if dmat is not None:
            field = diffract(field, dmat, out=out)
            out = field
        #no need to compute if d == 0!.. identity
        if d != 0.:
            field = dotmdmf(e, p, ei, field, out=out)

    if mode == +1 and bulk is not None:
        e2h = E2H_mat(fmat, mode=mode)
        bulk[..., 1::2, :, :] += dotmf(e2h, field)
        bulk[..., ::2, :, :] += field

    return field, refl