Пример #1
0
def waves2field2(waves, fmat, jones=None, phi=0, mode=+1):
    """Converts scalar waves to vector field data."""
    if jones is None:
        fvec1 = field4(fmat,
                       jones=jonesvec((1, 0), phi),
                       amplitude=waves,
                       mode=mode)
        fvec2 = field4(fmat,
                       jones=jonesvec((0, 1), phi),
                       amplitude=waves,
                       mode=mode)
        field1 = itranspose(fvec1)
        field2 = itranspose(fvec2)

        shape = list(field1.shape)
        shape.insert(-4, 2)
        out = np.empty(shape=shape, dtype=field1.dtype)
        out[..., 0, :, :, :, :] = field1
        out[..., 1, :, :, :, :] = field2
    else:
        #fvec = field4(fmat, jones = jonesvec((1,0),phi), amplitude = waves, mode = mode)
        fvec = field4(fmat,
                      jones=jonesvec(jones, phi),
                      amplitude=waves,
                      mode=mode)
        out = itranspose(fvec).copy()
    return out
Пример #2
0
def project_normalized_local(field, dmat, window=None, ref=None, out=None):
    f1 = fft2(field)
    f2 = dotmf(dmat, f1, out=f1)
    f = ifft2(f2, out=f2)
    pmat1 = normal_polarizer(jonesvec(transpose(f[..., ::2, :, :])))
    pmat2 = -pmat1
    pmat2[..., 0, 0] += 1
    pmat2[..., 1, 1] += 1  #pmat1 + pmat2 = identity by definition
    pmat2[..., 2, 2] += 1  #pmat1 + pmat2 = identity by definition
    pmat2[..., 3, 3] += 1  #pmat1 + pmat2 = identity by definition

    if ref is not None:
        intensity1 = field2intensity(dotmf(pmat1, ref))
        ref = dotmf(pmat2, ref)

    else:
        intensity1 = field2intensity(dotmf(pmat1, field))
        ref = dotmf(pmat2, field)

    intensity2 = field2intensity(f)

    f = normalize_field(f, intensity1, intensity2)

    out = np.add(f, ref, out=out)
    if window is not None:
        out = np.multiply(out, window, out=out)
    return out
Пример #3
0
def normal_polarizer(jones=(1, 0)):
    """A 4x4 polarizer for normal incidence light. It works reasonably well also
    for off-axis light, but it introduces weak reflections and depolarization.
    
    For off-axis planewaves you should use ray_polarizer instead of this."""
    p = polarizer(jonesvec(jones))
    pmat = np.zeros(shape=p.shape[:-2] + (4, 4), dtype=p.dtype)
    pmat[..., ::2, ::2] = p
    pmat[..., 1, 1] = p[..., 0, 0]
    pmat[..., 3, 3] = p[..., 1, 1]
    pmat[..., 1, 3] = -p[..., 0, 1]
    pmat[..., 3, 1] = -p[..., 1, 0]
    return pmat
Пример #4
0
def ray_polarizer(
        jones=(1, 0),
        beta=0,
        phi=0,
        epsv=(1., 1., 1.),
        epsa=(0., 0., 0.),
):
    """Returns a ray polarizer that should be applied in real space. Good for
    beams that can be approximated with a single wave vector and with a direction of 
    ray propagation beta and phi parameters.
    
    See also mode_polarizer, which is for non-planewave field data."""
    epsv = np.asarray(epsv, CDTYPE)
    epsa = np.asarray(epsa, FDTYPE)
    beta = np.asarray(beta, FDTYPE)
    phi = np.asarray(phi, FDTYPE)

    alpha, f = alphaf(beta, phi, epsv, epsa)
    jones = jonesvec(jones, phi)
    pmat = polarizer4x4(jones, f)
    return pmat
Пример #5
0
def mode_polarizer(shape,
                   ks,
                   jones=(1, 0),
                   epsv=(1., 1., 1.),
                   epsa=(0., 0., 0.),
                   betamax=BETAMAX):
    """Returns a mode polarizer that should be applied in fft space. This is the 
    most general polarizer that does not introduce any reflections for any kind
    of nonhomogeneous or homogeneous field."""
    ks = np.asarray(ks, FDTYPE)
    ks = abs(ks)
    epsv = np.asarray(epsv, CDTYPE)
    epsa = np.asarray(epsa, FDTYPE)
    beta, phi = betaphi(shape, ks)
    alpha, f = diffraction_alphaf(shape,
                                  ks,
                                  epsv=epsv,
                                  epsa=epsa,
                                  betamax=betamax)

    beta, phi = betaphi(shape, ks)
    jones = jonesvec(jones, phi)
    pmat = polarizer4x4(jones, f)
    return pmat
Пример #6
0
nlayers = 100
#: which wavelengths to compute (in nanometers)
k = np.linspace(2 * np.pi / 700, 2 * np.pi / 400, 200)
wavelengths = 2 * np.pi / k
#:ordinary refractive index of LC
no = 1.5
#:extraordinary
ne = 1.62

#---------------
# implementation
#---------------

step = thickness * 1000 / nlayers  #in nanometers

x_jvec = jones.jonesvec((1, 0))
y_jvec = jones.jonesvec((0, 1))

phis = np.linspace(0, np.pi / 2, nlayers)  #twist rotation angle
phase = (ne - no) * k * step  #phase retardation in each of the layers

matrices = [jones.polarizer(x_jvec)]  #x polarizer

#add retarders... left handed TN
for phi in phis:
    matrices.append(jones.retarder(phase, phi))

#next, we multiply matrices together in reverse order ...tn2.tn1.tn0.x
jmat = jones.multi_dot(matrices, reverse=True)

normally_white_jmat = jones.dotmm(jones.polarizer(y_jvec),
Пример #7
0
#: substrate epsilon
eps_out = dtmm.refind2eps(nout)
#: ray beta parameters; beta is nin*np.sin(theta)
betas = np.array(
    np.linspace(0.0, 0.9999999, 1000), dtype="float32"
)  #in case we compiled for float32, this has to be float not duouble
#: phi angle of the input light - will make a diffference for anisotropic layer
phi = 0

_phi = 0

pol1 = (-np.sin(_phi), np.cos(_phi))
pol2 = (np.cos(_phi), np.sin(_phi))

#: we must view them in rotated frame, with respect to the ray phi value.
pol1 = jones.jonesvec(pol1, phi)
pol2 = jones.jonesvec(pol2, phi)

#build field matrices
a, f, fi = tmm.alphaffi(betas, phi, eps_layer, eps_angles)
aout, fout, g = tmm.alphaffi(
    betas, phi, eps_out,
    eps_angles)  #eps_angles does nothing because eps_out is isotropic
ain, fin, g = tmm.alphaffi(
    betas, phi, eps_in,
    eps_angles)  #eps_angles does nothing because eps_in is isotropic

dot = dtmm.linalg.dotmm
dotd = dtmm.linalg.dotmd
dotmdm = dtmm.linalg.dotmdm
dotmv = dtmm.linalg.dotmv
Пример #8
0
# the inverse, with reflections
eti = tmm.Eti_mat(f[:-1], f[1:], mode=+1)
p2 = tmm.phase_mat(a, kd, mode=+1)[:, 1:]

#2x2 characteristic matrix
m2 = dotmdm(e, p2, ei)  #no reflections
m2t = dotmdm(e, p2, eti)  #with reflections

# multiply matrices together over second axis (first axis is wavelenght, second are layers)
cmat = linalg.multi_dot(m, axis=1)

#the 2x2 matrices must be multiplied in reverse order... because we propagate forward
cmat2 = linalg.multi_dot(m2, axis=1, reverse=True)
cmat2t = linalg.multi_dot(m2t, axis=1, reverse=True)

jx = jones.jonesvec((1, 0), phi)
jy = jones.jonesvec((0, 1), phi)

#field projection matrices - used to take the forward propagating or backward propagating waves
pmat = tmm.projection_mat(fout, mode=+1)
mmat = tmm.projection_mat(fin, mode=-1)

fvec = tmm.field4(fin, jones=jx)
#fvec = tmm.field4old(fin,jones = jx)
fvec = np.array([fvec] * nwavelengths)

tfvec2 = tmm.transmit2x2(fvec, cmat2, fmatout=fout[None, ...])
tfvec2r = tmm.transmit2x2(fvec, cmat2t, fmatout=fout[None, ...])

tfvec4 = tmm.transmit(fvec,
                      cmat,