예제 #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
예제 #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 _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
예제 #4
0
def diffract(fieldv, dmat, window=None, out=None):
    f = fft2(fieldv, out=out)
    f2 = dotmf(dmat, f, out=f)
    out = ifft2(f2, out=out)
    if window is not None:
        out = np.multiply(out, window, out=out)
    return out
예제 #5
0
def diffract(field,
             dmat,
             window=None,
             input_fft=False,
             output_fft=False,
             out=None):
    """Takes input field vector and diffracts it
    
    Parameters
    ----------
    field : (...,4,:,:) array
        Input field array.
    dmat : array
        Diffraction matrix. Use :func:`field_diffraction_matrix`to create one
    window : array, optional
        A window function applied to the result
    input_fft : bool
        Specifies whether input field array is the Fourier transform of the field.
        By default, input is assumed to be in real space.
    output_fft : bool
        Specifies whether the computed field array is the Fourier transform.
        By default, output is assumed to be in real space.
    out : ndarray, optional
        If specified, store the results here.
        
    Returns
    -------
    field : (...,4,:,:) array
        Diffracted field in real space (if output_fft == False )or in fft spaace
        (if output_fft == True).
            
    """
    if not input_fft:
        field = fft2(field, out=out)
        out = field
    if dmat is not None:
        out = dotmf(dmat, field, out=out)
    else:
        #make it work for dmat = None input... so just copy data
        if out is None:
            out = field.copy()
        else:
            if out is not field:
                out[...] = field
    if not output_fft:
        out = ifft2(out, out=out)
    if window is not None:
        if output_fft:
            raise ValueError(
                "Cannot use window function if ouput is fft field.")
        out = np.multiply(out, window, out=out)
    return out
예제 #6
0
def normalize_total(field, dmat, window=None, ref=None, out=None):
    if ref is not None:
        i1 = total_intensity(ref)
    else:
        i1 = total_intensity(field)

    f2 = dotmf(dmat, field, out=out)
    i2 = total_intensity(out)

    out = normalize_field_total(out, i1, i2, out=f2)

    if window is not None:
        out = np.multiply(out, window, out=out)
    return out
예제 #7
0
def project_normalized_fft(field, dmat, window=None, ref=None, out=None):
    if ref is not None:
        fref = fft2(ref, out=out)
        intensity1 = field2intensity(fref)
        f1 = fft2(field, out=out)
    else:
        f1 = fft2(field, out=out)
        intensity1 = field2intensity(f1)
    f2 = dotmf(dmat, f1, out=f1)
    intensity2 = field2intensity(f2)
    f3 = normalize_field(f2, intensity1, intensity2, out=f2)
    out = ifft2(f3, out=out)
    if window is not None:
        out = np.multiply(out, window, out=out)
    return out
예제 #8
0
def project_normalized_total(field, dmat, window=None, ref=None, out=None):
    if ref is not None:
        i1 = total_intensity(ref)
    else:
        i1 = total_intensity(field)
    f1 = fft2(field, out=out)

    f2 = dotmf(dmat, f1, out=f1)
    out = ifft2(f2, out=out)
    i2 = total_intensity(out)

    out = normalize_field_total(out, i1, i2, out=out)

    if window is not None:
        out = np.multiply(out, window, out=out)
    return out
예제 #9
0
def apply_ray_jonesmat(pmat, field, out=None):
    """Multiplies matrix with field data in real space.
    
    Parameters
    ----------
    pmat : array
        A 4x4 jones matrix of shape (...,4,4) for field data or
        2x2 jones matrix of shape (...,2,2) for E-field data or
    field : array
        Field data array of shape (...,4,:,:) or (...,2,:,:).
    out : array, optional
        If specified, the results are written here.
        
    Returns
    -------
    out : ndarray
        Computed field array of shape (...,4,:,:) or (...,2,:,:).
    """
    return dotmf(pmat, field, out=out)
예제 #10
0
def apply_mode_polarizer(pmat, field, out=None):
    """Multiplies mode polarizer with field data in fft space."""
    fft = fft2(field, out=out)
    pfft = dotmf(pmat, fft, out=fft)
    return ifft2(fft, out=pfft)
예제 #11
0
                                             beta=beta,
                                             phi=phi,
                                             diffraction=False,
                                             pixelsize=step)
#: transfer input light through stack
field_data_out = dtmm.transfer_field(field_data_in,
                                     optical_data,
                                     beta=beta,
                                     phi=phi,
                                     method="2x2",
                                     reflection=2,
                                     diffraction=False)
f, w, p = field_data_out

Txx2 = field2poynting(dotmf(
    x_polarizer,
    f[0]))[..., 0,
           0] * 2  #times two, because field_data_in[0][0] has intensity of 0.5
Tyx2 = field2poynting(dotmf(y_polarizer, f[0]))[..., 0, 0] * 2
Txy2 = field2poynting(dotmf(
    x_polarizer,
    f[1]))[..., 0,
           0] * 2  #times two, because field_data_in[0][1] has intensity of 0.5
Tyy2 = field2poynting(dotmf(y_polarizer, f[1]))[..., 0, 0] * 2

# uncomment below to see how the viewer calculates.. it is same for beta = 0,
# but slightly different for beta > 0

#viewer = dtmm.field_viewer(field_data_out, diffraction = False)
#Txx2 = viewer.calculate_specter(polarizer = 0, analyzer = 0)[0,0]*2
#Tyy2 = viewer.calculate_specter(polarizer = 90, analyzer = 90)[0,0]*2
예제 #12
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
예제 #13
0
    def _calculate_specter_mode(self, recalc=False, **params):
        self.set_parameters(**params)

        if self.ofield is None:
            recalc = True  #first time only trigger calculation

        if recalc or self._has_parameter_updated("analyzer", "sample"):
            sample = self.sample if self.sample is not None else 0.
            if self.analyzer is not None:
                angle = -np.pi / 180 * (self.analyzer - sample)
                c, s = np.cos(angle), np.sin(angle)
                self.pmat = mode_polarizer(self.ifield.shape[-2:],
                                           self.ks,
                                           jones=(c, s),
                                           epsv=self.epsv,
                                           epsa=self.epsa,
                                           betamax=self.betamax)
                if self.pmode != "mode":
                    self.pmat = self.pmat[..., 0:1, 0:1, :, :]

        if recalc or self._has_parameter_updated("focus"):
            if self.mode is None:
                self.ffield = fft2(self.ifield[self.focus])
            else:
                self.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.ffield = fft2(self.ifield[self.focus])

            recalc = True  #trigger update of self.data

        if recalc or self._has_parameter_updated("sample", "polarizer"):
            sample = self.sample if self.sample is not None else 0.
            if self.polarizer is not None:
                angle = -np.pi / 180 * (self.polarizer - sample)
                c, s = np.cos(angle), np.sin(angle)

                self.data = _redim(self.ffield, ndim=6)
                x = c * self.data[:, 0]
                y = s * self.data[:, 1]
                self.data = x + y
            else:
                self.data = _redim(self.ffield, ndim=5)

        if recalc or self._has_parameter_updated(
                "analyzer", "sample", "polarizer", "focus", "intensity"):
            if self.dmat is not None:
                pmat = dotmm(self.pmat, self.dmat)
            else:
                pmat = self.pmat
            self.ofield = dotmf(pmat, self.data, out=self.ofield)
            self.ofield = ifft2(self.ofield, out=self.ofield)

            for i, data in enumerate(self.ofield):
                if i == 0:
                    self.specter = field2specter(data)
                else:
                    self.specter += field2specter(data)
            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
예제 #14
0
    def _calculate_specter_mode(self, recalc=False, **params):
        self.set_parameters(**params)
        if self.ofield is None:
            recalc = True  #first time only trigger calculation
        if recalc or self._has_parameter_updated("sample", "polarizer"):
            sample = self.sample if self.sample is not None else 0.
            if self.polarizer is not None:
                if self.ffield is None:
                    self.ffield = fft2(self.ifield)
                angle = -np.pi / 180 * (self.polarizer - sample)
                c, s = np.cos(angle), np.sin(angle)

                self.data = _redim(self.ffield, ndim=6)
                x = c * self.data[:, 0]
                y = s * self.data[:, 1]
                self.data = x + y
            else:
                self.data = _redim(self.ffield, ndim=5)

        if recalc or self._has_parameter_updated("focus"):
            if self.diffraction == True or self.mode is not None:
                #if mode is selected, we need to project the field using diffraction
                d = 0 if self.focus is None else self.focus
                self.dmat = field_diffraction_matrix(self.ifield.shape[-2:],
                                                     self.ks,
                                                     d=d,
                                                     epsv=self.epsv,
                                                     epsa=self.epsa,
                                                     mode=self.mode,
                                                     betamax=self.betamax)
            else:
                self.dmat = np.asarray(np.diag((1, 1, 1, 1)), CDTYPE)
        if recalc or self._has_parameter_updated("analyzer", "sample"):
            sample = self.sample if self.sample is not None else 0.
            if self.analyzer is not None:
                angle = -np.pi / 180 * (self.analyzer - sample)
                c, s = np.cos(angle), np.sin(angle)
                self.pmat = mode_polarizer(self.ifield.shape[-2:],
                                           self.ks,
                                           jones=(c, s),
                                           epsv=self.epsv,
                                           epsa=self.epsa,
                                           betamax=self.betamax)
            else:
                self.pmat = None

        if recalc or self._has_parameter_updated(
                "analyzer", "sample", "polarizer", "focus", "intensity"):
            tmat = None
            if self.pmat is not None and self.dmat is not None:
                tmat = dotmm(self.pmat, self.dmat)
            if self.pmat is None and self.dmat is not None:
                tmat = self.dmat
            if self.pmat is not None and self.dmat is None:
                tmat = self.pmat
            if tmat is not None:
                self.ofield = dotmf(tmat, self.data, out=self.ofield)
            self.ofield = ifft2(self.ofield, out=self.ofield)

            for i, data in enumerate(self.ofield):
                if i == 0:
                    self.specter = field2specter(data)
                else:
                    self.specter += field2specter(data)

            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
예제 #15
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
예제 #16
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
예제 #17
0
 def test_dotmf(self):
     out = linalg.dotmf(self.a,self.f)
     self.compare_results(out,[self.a, self.f])
예제 #18
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
예제 #19
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
예제 #20
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