示例#1
0
def _layers_list(optical_data, eff_data, nin, nout, nstep):
    """Build optical data layers list and effective data layers list.
    It appends/prepends input and output layers. A layer consists of
    a tuple of (n, thickness, epsv, epsa) where n is number of sublayers"""
    d, epsv, epsa = validate_optical_data(optical_data)
    n = len(d)
    substeps = np.broadcast_to(np.asarray(nstep), (n, ))
    layers = [(n, (t / n, ev, ea))
              for n, t, ev, ea in zip(substeps, d, epsv, epsa)]
    #add input and output layers
    layers.insert(0,
                  (1,
                   (0., np.broadcast_to(refind2eps([nin] * 3), epsv[0].shape),
                    np.broadcast_to(np.array(
                        (0., 0., 0.), dtype=FDTYPE), epsa[0].shape))))
    layers.append(
        (1, (0., np.broadcast_to(refind2eps([nout] * 3), epsv[0].shape),
             np.broadcast_to(np.array((0., 0., 0.), dtype=FDTYPE),
                             epsa[0].shape))))
    if eff_data is None:
        d_eff, epsv_eff, epsa_eff = _isotropic_effective_data(optical_data)
    else:
        d_eff, epsv_eff, epsa_eff = validate_optical_data(eff_data,
                                                          homogeneous=True)
    eff_layers = [(n, (t / n, ev, ea))
                  for n, t, ev, ea in zip(substeps, d_eff, epsv_eff, epsa_eff)]
    eff_layers.insert(
        0, (1, (0., refind2eps([nin] * 3), np.array(
            (0., 0., 0.), dtype=FDTYPE))))
    eff_layers.append(
        (1, (0., refind2eps([nout] * 3), np.array((0., 0., 0.),
                                                  dtype=FDTYPE))))
    return layers, eff_layers
示例#2
0
def E_cover_diffraction_matrix(shape,
                               ks,
                               n=1.,
                               d_cover=0,
                               n_cover=1.5,
                               mode=+1,
                               betamax=BETAMAX,
                               out=None):
    ks = np.asarray(ks, dtype=FDTYPE)
    epsv = np.asarray(refind2eps((n, ) * 3), CDTYPE)
    epsa = np.asarray((0., 0., 0.), dtype=FDTYPE)
    epsv_cover = np.asarray(refind2eps((n_cover, ) * 3), CDTYPE)
    epsa_cover = np.asarray((0., 0., 0.), dtype=FDTYPE)
    alpha, j = E_diffraction_alphaE(shape,
                                    ks,
                                    epsv=epsv,
                                    epsa=epsa,
                                    mode=mode,
                                    betamax=betamax)
    alpha0, j0, j0i = E_diffraction_alphaEEi(shape,
                                             ks,
                                             epsv=epsv_cover,
                                             epsa=epsa_cover,
                                             mode=mode,
                                             betamax=betamax)

    alphac = alpha0 - alpha * n / n_cover
    alphac = alphac - alphac[..., 0, 0, :][..., None, None, :]

    kd = ks * d_cover
    pmat = phase_matrix(alphac, kd)
    return dotmdm(j0, pmat, j0i, out=out)
示例#3
0
def ffi_iso(n, beta=0., phi=0.):
    """Returns field matrix and inverse of the field matrix for isotropic layer 
    of a given refractive index and beta, phi parameters"""
    epsv = refind2eps([n] * 3)
    epsa = np.zeros(shape=(3, ), dtype=FDTYPE)
    alpha, f, fi = alphaffi(beta, phi, epsv, epsa)
    return f, fi
示例#4
0
def transmitted_field_direct(field, beta, phi, n=1.):
    ev = refind2eps([n] * 3)
    ea = np.zeros_like(ev)
    alpha, fmat = alphaf(beta, phi, ev, ea)
    pmat = projection_mat(fmat)
    field0 = np.empty_like(field)
    dotmv(pmat, transpose(field), out=transpose(field0))
    return field0
示例#5
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)
示例#6
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)
示例#7
0
 def __init__(self,
              field,
              ks,
              cmf,
              mode=None,
              n=1.,
              polarization="normal",
              window=None,
              diffraction=True,
              betamax=BETAMAX):
     self.betamax = betamax
     self.diffraction = diffraction
     self.pmode = polarization
     self.mode = mode
     self.epsv = refind2eps([n, n, n])
     self.epsa = np.array([0., 0., 0.])
     self.ks = ks
     self.ifield = field
     self._ffield = None
     self.window = window
     self.cmf = cmf
     self.dmat = None
示例#8
0
def illumination_data(shape,
                      wavelengths,
                      pixelsize=1.,
                      beta=0.,
                      phi=0.,
                      intensity=1.,
                      n=1.,
                      focus=0.,
                      window=None,
                      backdir=False,
                      jones=None,
                      diffraction=True,
                      betamax=BETAMAX):
    """Constructs forward (or backward) propagating input illumination field data.
    
    Parameters
    ----------
    shape : (int,int)
        Shape of the illumination
    wavelengths : array_like
        A list of wavelengths.
    pixelsize : float, optional
        Size of the pixel in nm.
    beta : float or array_like of floats, optional
        Beta parameter(s) of the illumination. (Default 0. - normal incidence) 
    phi : float or array_like of floats, optional
        Azimuthal angle(s) of the illumination. 
    n : float, optional
        Refractive index of the media that this illumination field is assumed to
        be propagating in (default 1.)
    focus : float, optional
        Focal plane of the field. By default it is set at z=0. 
    window : array or None, optional
        If None, no window function is applied. This window function
        is multiplied with the constructed plane waves to define field diafragm
        of the input light. See :func:`.window.aperture`.
    backdir : bool, optional
        Whether field is bacward propagating, instead of being forward
        propagating (default)
    jones : jones vector or None, optional
        If specified it has to be a valid jones vector that defines polarization
        of the light. If not given (default), the resulting field will have two
        polarization components. See documentation for details and examples.
    diffraction : bool, optional
        Specifies whether field is diffraction limited or not. By default, the 
        field is filtered so that it has only propagating waves. You can disable
        this by specifying diffraction = False.    
    betamax : float, optional
        The betamax parameter of the propagating field.
    """

    verbose_level = DTMMConfig.verbose
    if verbose_level > 0:
        print("Building illumination data.")
    wavelengths = np.asarray(wavelengths)
    wavenumbers = 2 * np.pi / wavelengths * pixelsize
    if wavenumbers.ndim not in (1, ):
        raise ValueError("Wavelengths should be 1D array")

    if jones is None:
        intensity = intensity / 2.

    waves = illumination_waves(shape,
                               wavenumbers,
                               beta=beta,
                               phi=phi,
                               window=window)
    #intensity = ((np.abs(waves)**2).sum((-2,-1)))* np.asarray(intensity)[...,None]#sum over pixels
    #intensity = intensity * intensity
    mode = -1 if backdir else +1
    _beta = np.asarray(beta, FDTYPE)
    _phi = np.asarray(phi, FDTYPE)
    _intensity = np.asarray(intensity, FDTYPE)

    nrays = len(_beta) if _beta.ndim > 0 else 1

    beta = _beta[..., None, None, None]
    phi = _phi[..., None, None, None]
    intensity = _intensity[..., None, None, None, None]

    epsa = np.asarray((0., 0., 0.), FDTYPE)
    alpha, fmat = alphaf(beta, phi, refind2eps([n] * 3), epsa)
    field = waves2field2(waves, fmat, jones=jones, phi=phi, mode=mode)
    intensity1 = field2intensity(field)
    norm = np.ones_like(intensity1)
    norm[:, ...] = (intensity / nrays)**0.5
    if diffraction == True:
        diffracted_field(field,
                         wavenumbers,
                         d=-focus,
                         n=n,
                         mode=mode,
                         betamax=betamax,
                         out=field)
        intensity2 = field2intensity(field)
        ratio = (intensity1.sum((-2, -1)) / intensity2.sum((-2, -1)))**0.5
        norm[...] = norm * ratio[..., None, None]

    np.multiply(norm[..., None, :, :], field, field)

    return (field, wavelengths, pixelsize)
示例#9
0
def transfer_4x4(field_data,
                 optical_data,
                 beta=0.,
                 phi=0.,
                 eff_data=None,
                 nin=1.,
                 nout=1.,
                 npass=1,
                 nstep=1,
                 diffraction=True,
                 reflection=1,
                 multiray=False,
                 norm=DTMM_NORM_FFT,
                 smooth=SMOOTH,
                 betamax=BETAMAX,
                 ret_bulk=False,
                 out=None):
    """Transfers input field data through optical data. See transfer_field.
    """
    if reflection not in (1, 2, 3, 4):
        raise ValueError(
            "Invalid reflection. The 4x4 method is either reflection mode 1 or 2."
        )
    if smooth > 1.:
        pass
        #smooth =1.
    elif smooth < 0:
        smooth = 0.
    verbose_level = DTMMConfig.verbose
    if verbose_level > 1:
        print(" * Initializing.")

    calc_reference = bool(norm & DTMM_NORM_REF)

    if (norm & DTMM_NORM_FFT):
        norm = "fft"
    else:
        if calc_reference:
            norm = "local"
        else:
            norm = "total"

    #define optical data
    d, epsv, epsa = validate_optical_data(optical_data)

    layers, eff_layers = _layers_list(optical_data, eff_data, nin, nout, nstep)

    #define input field data
    field_in, wavelengths, pixelsize = field_data

    #define constants
    ks = k0(wavelengths, pixelsize)

    n = len(layers)

    if beta is None and phi is None:
        ray_tracing = False
        beta, phi = field2betaphi(field_in, ks, multiray)
    else:
        ray_tracing = False
    if diffraction != 1:
        ray_tracing = False
    beta, phi = _validate_betaphi(beta, phi, extendeddim=field_in.ndim - 2)

    #define output field
    if out is None:
        if ret_bulk == True:
            bulk_out = np.zeros((n, ) + field_in.shape, field_in.dtype)
            bulk_out[0] = field_in
            field_in = bulk_out[0]
            field_out = bulk_out[-1]
        else:
            bulk_out = None
            field_out = np.zeros_like(field_in)
    else:
        out[...] = 0.
        if ret_bulk == True:
            bulk_out = out
            bulk_out[0] = field_in
            field_in = bulk_out[0]
            field_out = bulk_out[-1]
        else:
            bulk_out = None
            field_out = out
    indices = list(range(1, n - 1))
    #if npass > 1:
    #    field0 = field_in.copy()

    field0 = field_in.copy()
    field = field_in.copy()

    field_in[...] = 0.

    if norm == 2:
        #make sure we take only the forward propagating part of the field
        transmitted_field(field,
                          ks,
                          n=nin,
                          betamax=min(betamax, nin),
                          out=field)

    if calc_reference:
        ref = field.copy()
    else:
        ref = None

    i0 = field2intensity(transmitted_field(field0, ks, n=nin, betamax=betamax))
    i0 = i0.sum(tuple(range(i0.ndim))[-2:])

    if reflection not in (2, 4) and 0 <= diffraction and diffraction < np.inf:
        work_in_fft = True
    else:
        work_in_fft = False

    if work_in_fft:
        field = fft2(field, out=field)
    _reuse = False
    tmpdata = {}

    #:projection matrices.. set when needed
    if npass > 1:
        pin_mat = projection_matrix(field.shape[-2:],
                                    ks,
                                    epsv=refind2eps([nin] * 3),
                                    mode=+1,
                                    betamax=betamax)
        pout_mat = projection_matrix(field.shape[-2:],
                                     ks,
                                     epsv=refind2eps([nout] * 3),
                                     mode=+1,
                                     betamax=betamax)

    for i in range(npass):
        if verbose_level > 0:
            prefix = " * Pass {:2d}/{}".format(i + 1, npass)
            suffix = ""
        else:
            prefix = ""
            suffix = "{}/{}".format(i + 1, npass)

        _bulk_out = bulk_out
        direction = (-1)**i
        _nstep, (thickness, ev, ea) = layers[indices[0]]

        if direction == 1:
            _betamax = betamax
        else:
            _betamax = betamax

        for pindex, j in enumerate(indices):
            print_progress(pindex,
                           n,
                           level=verbose_level,
                           suffix=suffix,
                           prefix=prefix)

            nstep, (thickness, ev, ea) = layers[j]
            output_layer = (thickness * direction, ev, ea)

            _nstep, output_layer_eff = eff_layers[j]

            d, e, a = output_layer_eff
            output_layer_eff = d * direction, e, a

            if ray_tracing == True:
                if work_in_fft:
                    beta, phi = field2betaphi(ifft2(field), ks, multiray)
                else:
                    beta, phi = field2betaphi(field, ks, multiray)
                beta, phi = _validate_betaphi(beta,
                                              phi,
                                              extendeddim=field_in.ndim - 2)

            if calc_reference and i % 2 == 0:
                _nstep, (thickness_in, ev_in, ea_in) = layers[j - 1]
                input_layer = (thickness_in, ev_in, ea_in)
                ref2, refl = propagate_2x2_effective_2(ref[..., ::2, :, :],
                                                       ks,
                                                       input_layer,
                                                       output_layer,
                                                       None,
                                                       output_layer_eff,
                                                       beta=beta,
                                                       phi=phi,
                                                       nsteps=nstep,
                                                       diffraction=diffraction,
                                                       reflection=0,
                                                       betamax=_betamax,
                                                       mode=direction,
                                                       out=ref[..., ::2, :, :])

            if bulk_out is not None:
                out_field = _bulk_out[j]
            else:
                out_field = field

            if diffraction >= 0 and diffraction < np.inf:
                if reflection == 4:
                    field = propagate_4x4_effective_4(field,
                                                      ks,
                                                      output_layer,
                                                      output_layer_eff,
                                                      beta=beta,
                                                      phi=phi,
                                                      nsteps=nstep,
                                                      diffraction=diffraction,
                                                      betamax=_betamax,
                                                      out=out_field)
                elif reflection == 3:
                    field = propagate_4x4_effective_3(field,
                                                      ks,
                                                      output_layer,
                                                      output_layer_eff,
                                                      beta=beta,
                                                      phi=phi,
                                                      nsteps=nstep,
                                                      diffraction=diffraction,
                                                      betamax=_betamax,
                                                      out=out_field)

                elif reflection == 2:
                    field = propagate_4x4_effective_2(field,
                                                      ks,
                                                      output_layer,
                                                      output_layer_eff,
                                                      beta=beta,
                                                      phi=phi,
                                                      nsteps=nstep,
                                                      diffraction=diffraction,
                                                      betamax=_betamax,
                                                      out=out_field,
                                                      tmpdata=tmpdata)
                else:
                    field = propagate_4x4_effective_1(field,
                                                      ks,
                                                      output_layer,
                                                      output_layer_eff,
                                                      beta=beta,
                                                      phi=phi,
                                                      nsteps=nstep,
                                                      diffraction=diffraction,
                                                      betamax=_betamax,
                                                      out=out_field,
                                                      _reuse=_reuse)
            else:
                field = propagate_4x4_full(field,
                                           ks,
                                           output_layer,
                                           nsteps=nstep,
                                           betamax=_betamax,
                                           out=out_field)
            _reuse = True
        if ref is not None:
            ref[..., 1::2, :, :] = jones2H(ref2, ks, betamax=_betamax, n=nout)
        print_progress(n, n, level=verbose_level, suffix=suffix, prefix=prefix)

        indices.reverse()

        if work_in_fft == True:
            field = ifft2(field)

        if npass > 1:
            #smooth = 1. - i/(npass-1.)
            if i % 2 == 0:
                if i != npass - 1:
                    if verbose_level > 1:
                        print(" * Normalizing transmissions.")
                    if calc_reference:
                        np.multiply(ref, (nin / nout)**0.5, ref)

                    sigma = smooth * (npass - i) / (npass)

                    if norm == "fft":
                        field = project_normalized_fft(field,
                                                       pout_mat,
                                                       ref=ref,
                                                       out=field)
                    elif norm == "local":
                        field = project_normalized_local(field,
                                                         pout_mat,
                                                         ref=ref,
                                                         out=field)
                    elif norm == "total":
                        field = project_normalized_total(field,
                                                         pout_mat,
                                                         ref=ref,
                                                         out=field)

                    field = denoise_field(field, ks, nin, sigma, out=field)

                np.add(field_out, field, field_out)
                field = field_out.copy()

            else:
                field_in[...] = field
                if i != npass - 1:
                    if verbose_level > 1:
                        print(" * Normalizing reflections.")

                    sigma = smooth * (npass - i) / (npass)

                    ffield = fft2(field, out=field)
                    ffield = dotmf(pin_mat, ffield, out=ffield)
                    ffield = denoise_fftfield(ffield,
                                              ks,
                                              nin,
                                              sigma,
                                              out=ffield)
                    field = ifft2(field, out=ffield)

                    i0f = total_intensity(field)
                    fact = ((i0 / i0f))
                    fact = fact[..., None, None, None]
                    np.multiply(field, fact, out=field)

                    np.multiply(field_out, fact, out=field_out)
                    np.multiply(field_in, fact, out=field_in)

                    np.subtract(field0, field, out=field)

                    np.add(field_in, field, field_in)

                    if calc_reference:
                        ref = field.copy()

            if work_in_fft == True:
                field = fft2(field, out=field)

        else:
            field_out[...] = field
            field_in[...] = field0
    #denoise(field_out, ks, nout, smooth*10, out = field_out)

    if ret_bulk == True:
        if work_in_fft:
            ifft2(bulk_out[1:-1], out=bulk_out[1:-1])
        return bulk_out, wavelengths, pixelsize
    else:
        return field_out, wavelengths, pixelsize