Esempio n. 1
0
def _transfer_ray_4x4_1(field,
                        wavenumbers,
                        layer,
                        dmat1,
                        dmat2,
                        beta=0,
                        phi=0,
                        nsteps=1,
                        betamax=BETAMAX,
                        out=None):

    d, epsv, epsa = layer

    kd = wavenumbers * d

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

    e = E_mat(f, mode=None)
    ei = inv(e)

    for j in range(nsteps):
        field = dotmf(dmat1, field, out=out)
        field = ifft2(field, out=field)
        field = dotmdmf(e, p, ei, field, out=field)
        field = fft2(field, out=field)
        field = dotmf(dmat2, field, out=out)

    return field
Esempio n. 2
0
def _transfer_ray_4x4_1_windows(windows, field, wavenumbers, layer, dmat1, dmat2, betas, phis,
                    nsteps = 1, out = None,
                    betamax = BETAMAX):
        
    d, epsv, epsa = layer

    kd = wavenumbers*d 
    
    if out is None:
        out = np.zeros_like(field)

    for j in range(nsteps):
        field = dotmf(dmat1,field)
        for window, beta, phi in zip(windows, betas, phis):
            alpha, f = alphaf(beta,phi,epsv,epsa)
            p = phasem(alpha,kd[...,None,None])
            
            e = E_mat(f, mode = None)
            ei = inv(e)
            
            f = field * window
            
            
            f = ifft2(f, out = f)
            f = dotmdmf(e,p,ei,f, out = f)  
            f = fft2(field, out = f)
            out += f
            
        out = dotmf(dmat2,out, out = out)
                  
    return out
Esempio n. 3
0
def Epn_correction_matrix(beta,
                          phi,
                          ks,
                          d=1.,
                          epsv=(1, 1, 1),
                          epsa=(0, 0, 0.),
                          out=None):
    alpha, f = alphaf(beta, phi, epsv, epsa)
    kd = -np.asarray(ks) * d
    pmat = phase_mat(alpha, kd[..., None, None])
    e = E_mat(f, mode=None)
    ei = inv(e)
    return dotmdm(e, pmat, ei, out=out)
Esempio n. 4
0
def first_Epn_diffraction_matrix(shape,
                                 ks,
                                 d=1.,
                                 epsv=(1, 1, 1),
                                 epsa=(0, 0, 0.),
                                 betamax=BETAMAX,
                                 out=None):
    ks = np.asarray(ks, dtype=FDTYPE)
    epsv = np.asarray(epsv, dtype=CDTYPE)
    epsa = np.asarray(epsa, dtype=FDTYPE)
    alpha, f, fi = diffraction_alphaffi(shape,
                                        ks,
                                        epsv=epsv,
                                        epsa=epsa,
                                        betamax=betamax)
    kd = ks * d
    e = E_mat(f, mode=None)
    pmat = phase_mat(alpha, kd[..., None, None])
    return dotmdm(e, pmat, fi, out=out)
Esempio n. 5
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
Esempio n. 6
0
def propagate_2x2_full(field,
                       wavenumbers,
                       layer,
                       input_layer=None,
                       nsteps=1,
                       mode=+1,
                       reflection=True,
                       betamax=BETAMAX,
                       refl=None,
                       bulk=None,
                       out=None):

    shape = field.shape[-2:]

    d, epsv, epsa = layer
    if input_layer is not None:
        d_in, epsv_in, epsa_in = input_layer

    kd = wavenumbers * d / nsteps

    if out is None:
        out = np.empty_like(field)

    ii, jj = np.meshgrid(range(shape[0]),
                         range(shape[1]),
                         copy=False,
                         indexing="ij")

    for step in range(nsteps):
        for i in range(len(wavenumbers)):
            ffield = fft2(field[..., i, :, :, :])
            ofield = np.zeros_like(out[..., i, :, :, :])

            b, p = betaphi(shape, wavenumbers[i])
            mask = b < betamax

            amplitude = ffield[..., mask]

            betas = b[mask]
            phis = p[mask]
            iind = ii[mask]
            jind = jj[mask]

            if bulk is not None:
                obulk = bulk[..., i, :, :, :]

            if refl is not None:
                tampl = fft2(refl[..., i, :, :, :])[..., mask]
                orefl = refl[..., i, :, :, :]
                orefl[...] = 0.

            for bp in sorted(zip(range(len(betas)), betas, phis, iind, jind),
                             key=lambda el: el[1],
                             reverse=False):
                #for j,bp in enumerate(zip(betas,phis,iind,jind)):

                j, beta, phi, ieig, jeig = bp

                out_af = alphaf(beta, phi, epsv, epsa)
                alpha, fmat_out = out_af
                e = E_mat(fmat_out, mode=mode)
                ei0 = inv(e)
                ei = ei0
                pm = phase_mat(alpha, kd[i, None, None], mode=mode)
                w = eigenwave(amplitude.shape[:-1] + shape,
                              ieig,
                              jeig,
                              amplitude=amplitude[..., j])
                if step == 0 and reflection != False:
                    alphain, fmat_in = alphaf(beta, phi, epsv_in, epsa_in)
                    if refl is not None:
                        ei, eri = Etri_mat(fmat_in, fmat_out, mode=mode)
                        ein = E_mat(fmat_in, mode=-1 * mode)
                        t = eigenwave(amplitude.shape[:-1] + shape,
                                      ieig,
                                      jeig,
                                      amplitude=tampl[..., j])
                        r = dotmf(eri, w)
                        r = dotmf(ein, r, out=r)
                        np.add(orefl, r, orefl)

                        w = dotmf(ei, w, out=w)
                        t = dotmf(ei0, t, out=t)
                        w = np.add(t, w, out=w)

                    else:
                        ei = Eti_mat(fmat_in, fmat_out, mode=mode)
                        w = dotmf(ei, w, out=w)
                    w = dotmf(dotmd(e, pm), w, out=w)
                    np.add(ofield, w, ofield)

                else:
                    w = dotmdmf(e, pm, ei, w, out=w)
                    np.add(ofield, w, ofield)

                if bulk is not None:
                    e2h = E2H_mat(fmat_out, mode=mode)
                    obulk[..., 1::2, :, :] += dotmf(e2h, w)
                    obulk[..., ::2, :, :] += w

            out[..., i, :, :, :] = ofield

        field = out
    return out, refl
Esempio n. 7
0
def _transfer_ray_2x2_1(fft_field,
                        wavenumbers,
                        layer,
                        effective_layer_in,
                        effective_layer_out,
                        dmat1,
                        dmat2,
                        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
    #fft_field = fft2(fft_field, out = out)
    shape = fft_field.shape[-2:]
    d_in, epsv_in, epsa_in = effective_layer_in

    d_out, epsv_out, epsa_out = effective_layer_out

    if reflection:
        tmat, rmat = E_tr_matrix(shape,
                                 wavenumbers,
                                 epsv_in=epsv_in,
                                 epsa_in=epsa_in,
                                 epsv_out=epsv_out,
                                 epsa_out=epsa_out,
                                 mode=mode,
                                 betamax=betamax)

    d, epsv, epsa = layer
    alpha, fmat = alphaf(beta, phi, epsv, epsa, out=_out.get("alphaf"))

    e = E_mat(fmat, mode=mode, copy=False)  #2x2 E-only view of fmat
    ei = inv(e, out=_out.get("ei"))
    #
    kd = wavenumbers * d
    p = phase_mat(alpha, kd[..., None, None], mode=mode, out=_out.get("p"))

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

    for j in range(nsteps):
        if j == 0 and reflection:
            #reflect only at the beginning
            if refl is not None:
                trans = refl.copy()
                refl = dotmf(rmat, fft_field, out=refl)
                fft_field = dotmf(tmat, fft_field, out=out)
                fft_field = np.add(fft_field, trans, out=fft_field)

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

                fft_field = dotmf(dmat1, fft_field, out=fft_field)
                out = fft_field
            else:
                fft_field = dotmf(tmat, fft_field, out=out)
                fft_field = dotmf(dmat1, fft_field, out=fft_field)
                out = fft_field
        else:
            if dmat1 is not None:
                fft_field = dotmf(dmat1, fft_field, out=out)
            out = fft_field
        field = ifft2(fft_field, out=out)
        field = dotmdmf(e, p, ei, field, out=field)
        fft_field = fft2(field, out=field)
        if dmat2 is not None:
            fft_field = dotmf(dmat2, fft_field, out=fft_field)
    #return fft_field, refl

    #out = ifft2(fft_field, out = out)

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

    return fft_field, refl
Esempio n. 8
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