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
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
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)
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)
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
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
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
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