Exemplo n.º 1
0
    def value(self, x, y, z):
        """
        Value of complex amplitude at coordinates (x,y,z).
        (x,y,z) is a cartesian coordinate frame centered at the waist.
        z lies along the propagation axis.
        
        ========Input=========
        
        x : Radial horizontal distance from z axis
        y : Radial vertical distance from z axis
        z : Axial distance from waist
    
        ========Output========
        
        u : Complex amplitude of beam at coordinates (x,y,z)
        
        """

        q = self.q(z)
        W = self.width(z)
        env = 1j * self.zO * self.A * tl.exp(-0.5j * self.k *
                                             (x**2 + y**2) / q) / q
        env *= tl.eval_hermite(self.l,
                               tl.sqrt(2) * x / W) * tl.eval_hermite(
                                   self.m,
                                   tl.sqrt(2) * y / W) * tl.exp(
                                       1j *
                                       (self.l + self.m) * self.gouy_phase(z))
        u = env * tl.exp(-1j * self.k * z)

        return u
Exemplo n.º 2
0
def SigmoidNormal(f, new_min=0., new_max=1.):
    """
    ~ Normalizes f to interval [new_min,new_max] using a sigmoid function
    ~ If the input array is complex, only affects its norm
    
    ========Input=========
    
    f : Input array
    new_min : Minimum value in normalization interval (default 0)
    new_max : Maximum value in normalization interval (default 1)
    
    ========Output========
    
    g : Normalized input array
    
    """

    if tl.iscomplex(f).any():
        g = 1 / (1 + tl.exp(-(abs(f) - tl.mean(abs(f))) /
                            (tl.maxx(abs(f)) - tl.minn(abs(f))))) * (
                                new_max - new_min) + new_min
        g *= tl.exp(1j * tl.angle(f))

    else:
        g = 1 / (1 + tl.exp(-(f - tl.mean(f)) /
                            (tl.maxx(f) - tl.minn(f)))) * (new_max -
                                                           new_min) + new_min

    return g
Exemplo n.º 3
0
    def value(self, r, p, z):
        """
        Value of complex amplitude at coordinates (r,p,z).
        (r,p,z) is a cylindrical coordinate frame centered at the waist.
        z lies along the propagation axis.
        
        ========Input=========
        
        r : Radial distance from z axis
        p : Azimuth angle
        z : Axial distance from waist
    
        ========Output========
        
        u : Complex amplitude of beam at coordinates (r,p,z)
        
        """

        q = self.q(z)
        W = self.width(z)
        env = 1j * self.zO * self.A * tl.exp(-0.5j * self.k * r**2 / q) / q
        env *= (r / W)**self.l * tl.eval_genlaguerre(
            self.m, self.l, 2 *
            (r / W)**2) * tl.exp(1j *
                                 (self.l + 2 * self.m) * self.gouy_phase(z) -
                                 1j * self.l * p)
        u = env * tl.exp(-1j * self.k * z)

        return u
Exemplo n.º 4
0
def Fresnel2S(f, z, wl, L1, L2):
    """
    ~ Propagates input 2D array in free space using the two-step Fresnel propagator
    Voelz D. Computational Fourier Optics: A MATLAB Tutorial. 2011.
    
    ========Input=========
    
    f :     Input complex amplitude profile (2D complex array)
    z :     Propagation distance
    wl :    Central wavelenght of the field
    L1 :    Input sample plane side lenght
    L2 :    Output sample plane side lenght
    
    ========Output========
    
    h :     Propagated complex amplitude profile (2D complex array)
    
    """

    if (tl.ndim(f) != 2):
        raise TypeError("Input array must be a 2D square array")

    m, n = tl.shape(f)

    if (m != n):
        raise ValueError("Input array must be a 2D square array")

    k = 2 * tl.pi / wl

    # Source plane
    dx1 = L1 / m
    x1 = tl.arange(-L1 / 2., L1 / 2., dx1)
    X, Y = tl.meshgrid(x1, x1)
    F = f * tl.exp(1j * k / (2. * z * L1) * (L1 - L2) * (X**2 + Y**2))
    F = tl.fft.fft2(tl.fft.fftshift(F))

    # Dummy plane
    fx1 = tl.arange(-1. / (2 * dx1), 1. / (2 * dx1), 1. / L1)
    fx1 = tl.fft.fftshift(fx1)
    FX1, FY1 = tl.meshgrid(fx1, fx1)
    G = F * tl.exp(-1j * tl.pi * wl * z * L1 / L2 * (FX1**2 + FY1**2))
    g = tl.fft.ifftshift(tl.fft.ifft2(G))

    # Observation plane
    dx2 = L2 / m
    x2 = tl.arange(-L2 / 2., L2 / 2., dx2)
    X, Y = tl.meshgrid(x2, x2)
    g = (L2 / L1) * g * tl.exp(-1j * k / (2. * z * L2) * (L1 - L2) *
                               (X**2 + Y**2))
    g = g * (dx1 / dx2)**2

    return g
Exemplo n.º 5
0
def Fraunhofer(f, z, wl, dx=1.):
    """
    ~ Propagates input 2D array in free space using the Fraunhofer propagator
    Voelz D. Computational Fourier Optics: A MATLAB Tutorial. 2011.
    
    ========Input=========
    
    f :     Input complex amplitude profile (2D complex array)
    z :     Propagation distance
    wl :    Central wavelenght of the field
    dx :    Sampling interval (default value is unit of measurement)
    
    ========Output========
    
    g  :    Propagated complex amplitude profile (2D complex array)
    oL :    Observation plane side lenght
    
    """

    n, m = tl.shape(f)
    oL = wl * z / dx  # Observation plane side lenght
    odx = oL / m
    ody = oL / n  # Observation plane sample interval
    x = tl.arange(-oL / 2, oL / 2, odx)
    y = tl.arange(-oL / 2, oL / 2, ody)
    X, Y = tl.meshgrid(x, y)

    g = -1j / (wl * z) * tl.exp(1j * tl.pi / (wl * z) * (X**2 + Y**2))
    g = g * FFT2(f) * dx * dx

    return g, oL
Exemplo n.º 6
0
def FresnelIR(f, z, wl, dx):
    """
    ~ Propagates f in free space sampling the Impulse Response
    Voelz D. Computational Fourier Optics: A MATLAB Tutorial. 2011.
    
    ========Input=========
    
    f :     Input complex amplitude profile (2D complex array)
    z :     Propagation distance
    wl :    Central wavelenght of the field
    dx :    Sampling interval (default value is unit of measurement)
    
    ========Output========
    
    h :     Propagated complex amplitude profile (2D complex array)
    
    """

    n, m = tl.shape(f)
    Lx = dx * n
    Ly = dx * m
    F = FFT2(f)
    x = tl.arange(-Lx / 2, Lx / 2, dx)
    y = tl.arange(-Ly / 2, Ly / 2, dx)
    X, Y = tl.meshgrid(x, y)
    g = tl.exp(1j * tl.pi / (wl * z) * (X**2 + Y**2)) / (1j * wl * z)
    G = FFT2(g) * dx * dx
    h = IFFT2(F * G)

    return h
Exemplo n.º 7
0
def Lens(F, R, wl, shape, dx=1.):
    """
    ~ Samples the trasmittance function of a thin lens with focal lenght f for a wave with central wavelenght wl with sampling interval dx
    
    ========Input=========
    
    F :         Focal lenght of thin lens
    R :         Radius of the lens
    wl :        Central wavelenght
    shape :     Array shape
    dx :        Sampling interval (default value is unit of measurement)
    
    ========Raises=========
    
    TypeError :     If f isn't a 2D array
    
    ========Output========
    
    t :     Thin lens complex transmittance
    
    """

    if (len(shape) != 2):
        raise TypeError('Shape must be 2D')

    n, m = shape
    x = tl.arange(-m * dx / 2, m * dx / 2, dx)
    y = tl.arange(-n * dx / 2, n * dx / 2, dx)
    X, Y = tl.meshgrid(x, y)
    t = tl.exp(-1j * (tl.pi / (wl * F)) * (X**2 + Y**2))
    t *= Pupil(R, shape, dx)

    return t
Exemplo n.º 8
0
def FresnelTF(f, z, wl, dx):
    """
    ~ Propagates f in free space sampling the Transfer Function
    Voelz D. Computational Fourier Optics: A MATLAB Tutorial. 2011.
    
    ========Input=========
    
    f :     Input complex amplitude profile (2D complex array)
    z :     Propagation distance
    wl :    Central wavelenght of the field
    dx :    Sampling interval (default value is unit of measurement)
    SBC :   Use the source bandwidth criterion for large propagation regime
    
    ========Output========
    
    h :     Propagated complex amplitude profile (2D complex array)
    """

    n, m = tl.shape(f)
    Lx = dx * n
    Ly = dx * m
    F = FFT2(f)
    fx = tl.arange(-1 / (2 * dx), 1 / (2 * dx), 1 / Lx)
    fy = tl.arange(-1 / (2 * dx), 1 / (2 * dx), 1 / Ly)
    FX, FY = tl.meshgrid(fx, fy)
    G = tl.exp((-1j * wl * tl.pi * z) * (FX**2 + FY**2))
    h = IFFT2(F * G)

    return h
Exemplo n.º 9
0
def Tilt(alpha, theta, wl, shape, dx=1.):
    """
    ~ Simulates the trasmittance function of a tilt (a prism for instance)
    
    ========Input=========
    
    alpha :     Tilt polar angle
    theta :     Tilt azimuth angle
    wl :        Central wavelenght
    shape :     Array shape
    dx :        Sampling interval (default value is unit of measurement)
    
    ========Raises=========
    
    TypeError:  If f isn't a 2D array
    
    ========Output========
    
    t :     Pinhole transmittance
    
    """

    if (len(shape) != 2):
        raise TypeError('f must be a 2D array')

    n, m = shape
    x = tl.arange(-m * dx / 2, m * dx / 2, dx)
    y = tl.arange(-n * dx / 2, n * dx / 2, dx)
    X, Y = tl.meshgrid(x, y)
    t = tl.exp(2j * tl.pi / wl * (X * tl.cos(theta) + Y * tl.sin(theta)) *
               tl.tan(alpha))

    return t
Exemplo n.º 10
0
def LinearNormal(f, new_min=0., new_max=1.):
    """
    ~ Linearly normalizes f to interval [new_min,new_max]
    ~ If the input array is complex, only affects its norm
    
    ========Input=========
    
    f : Input array
    new_min : Minimum value in normalization interval (default 0)
    new_max : Maximum value in normalization interval (default 1)
    
    ========Output========
    
    g : Normalized input array
    
    """

    if tl.iscomplex(f).any():
        fnorm = tl.abss(f)
        if ((fnorm == tl.mean(fnorm)).all()):
            g = 1.
        else:
            g = (fnorm - tl.minn(fnorm)) / (tl.maxx(fnorm) - tl.minn(fnorm)
                                            ) * (new_max - new_min) + new_min
        g *= tl.exp(1j * tl.angle(f))

    else:
        if ((f == tl.mean(f)).all()):
            g = tl.ones(tl.shape(f))
        else:
            g = (f - tl.minn(f)) / (tl.maxx(f) -
                                    tl.minn(f)) * (new_max - new_min) + new_min

    return g
Exemplo n.º 11
0
def FresnelCS(f, z, wl, dx=1., SBC=False):
    """
    ~ Propagates input 2D array in free space using the critical sampling criterion
    ~ Samples either the Impulse Response or the Transfer Function given the critic sampling criterion
    Voelz D. Computational Fourier Optics: A MATLAB Tutorial. 2011.
    
    ========Input=========
    
    f :     Input complex amplitude profile (2D complex array)
    z :     Propagation distance
    wl :    Central wavelenght of the field
    dx :    Sampling interval (default value is unit of measurement)
    SBC :   Use the source bandwidth criterion for large propagation regime
    
    ========Output========
    
    h :     Propagated complex amplitude profile (2D complex array)
    
    """

    n, m = tl.shape(f)  # Array dimensions
    Lx = dx * m
    Ly = dx * n  # Source plane side lenghts
    zc = dx * Lx / wl  # Critic sampling propagation distance
    F = FFT2(f)

    if (SBC):  # Check the source bandwidth criterion
        B = GetRBW(f, dx)
        SBC = B <= min([Lx, Ly]) / (wl * z)

    if (abs(z) > zc and not SBC):  # Propagating using Impulse Response
        x = tl.arange(-Lx / 2., Lx / 2., dx)
        y = tl.arange(-Ly / 2., Ly / 2., dx)
        X, Y = tl.meshgrid(x, y)
        g = tl.exp(1j * tl.pi / (wl * z) * (X**2 + Y**2)) / (1j * wl * z)
        G = FFT2(g) * dx * dx

    if (abs(z) <= zc):  # Propagating using Transfer Function
        F = 0.5 / dx  # Nyquist frequency
        fx = tl.arange(-F, F, 1. / Lx)
        fy = tl.arange(-F, F, 1. / Ly)
        FX, FY = tl.meshgrid(fx, fy)
        G = tl.exp((-1j * wl * tl.pi * z) * (FX**2 + FY**2))

    h = IFFT2(F * G)

    return h
Exemplo n.º 12
0
    def value(self, r, z):
        """
        Value of complex amplitude at coordinates (r,z).
        (r,z) is a cylindrical coordinate frame centered at the waist.
        z lies along the propagation axis.
        
        ========Input=========
        
        r : Radial distance from z axis
        z : Axial distance from waist
    
        ========Output========
        
        u : Complex amplitude of beam at coordinates (r,z)
        
        """

        q = self.q(z)
        env = 1j * self.zO * self.A * tl.exp(-0.5j * self.k * r**2 / q) / q
        u = env * tl.exp(-1j * self.k * z)

        return u
Exemplo n.º 13
0
    def value(self, r, p, z):
        """
        Value of complex amplitude at coordinates (r,p,z).
        (r,p,z) is a cylindrical coordinate frame centered at the waist.
        z lies along the propagation axis.
        
        ========Input=========
        
        r : Radial distance from z axis
        p : Azimuth angle
        z : Axial distance from waist
    
        ========Output========
        
        u : Complex amplitude of beam at coordinates (r,z)
        
        """

        env = self.A * tl.jv(self.m, self.kT * r) * tl.exp(1j * self.m * p)
        u = env * tl.exp(-1j * self.b * z)

        return u
Exemplo n.º 14
0
    def value(self, r, z):
        """
        Value of complex amplitude at coordinates (r,z).
        (r,z) is a cylindrical coordinate frame centered at the waist.
        z lies along the propagation axis.
        
        ========Input=========
        
        r : Radial distance from z axis
        z : Axial distance from waist
    
        ========Output========
        
        u : Complex amplitude of beam at coordinates (r,z)
        
        """

        q = self.q(z)
        env = 1j * self.zO * self.A * tl.exp(
            -0.5j * self.k * (r**2 + (self.b * z / self.k)**2) / q) / q
        env *= tl.jv(0, self.b * r / (1. + 1j * z / self.zO))
        u = env * tl.exp(-1j * (self.k - self.b**2 / (2. * self.k)) * z)

        return u
Exemplo n.º 15
0
    def value(self, r):
        """
        Value of complex amplitude at a distance r from wave source.
        
        ========Input=========
        
        r : Radial coordinate centered at wave source
    
        ========Output========
        
        u : Complex amplitude of beam at coordinate r
        
        """

        u = tl.zeros_like(r, dtype='complex')
        u[r == 0.] = tl.inf
        u[r != 0.] = self.A * tl.exp(-1j * self.k * r[r != 0.]) / r[r != 0.]

        return u
Exemplo n.º 16
0
    def value(self, x, y, z):
        """
        Value of complex amplitude at coordinates (x,y,z).
        (x,y,z) is a cartesian coordinate frame.
        The wavevector defines the propagation axis.
        
        ========Input=========
        
        x : Horizontal cartesian coordinate
        y : Vertical cartesian coordinate
        z : Default axis cartesian coordinate
    
        ========Output========
        
        u : Complex amplitude of beam at coordinates (x,y,z)
        
        """

        u = self.A * tl.exp(-1j * (self.kx * x + self.ky * y + self.kz * z))

        return u
Exemplo n.º 17
0
def Gauss(sx, sy, shape, x=0., y=0., angle=0., use_pxc=False):
    """
    ~ Creates a sampled 2D Gaussian distribution signal
    ~ (x,y) coordinates are given in a centered cartesian frame

    ========Input=========
    
    sx :        Gaussian RMS width
    sy :        Gaussian RMS height
    shape:      Output array shape
    x :         Horizontal center of ellipse (Default for horizontally centered)
    y :         Vertical center of ellipse (Default for vertically centered)
    angle :     Angle defining the width direction (Default for horizontal direction)
    use_pxc :   Use pixel as unit of measurement (Default for shape as unit of measurement)
    
    ========Output========
    
    f : 2D float array

    """

    x += 0.5
    y += 0.5

    if (use_pxc == False):
        sx *= shape[1]
        sy *= shape[0]
        x *= shape[1]
        y *= shape[0]

    X = range(shape[1])
    Y = range(shape[0])
    X, Y = tl.meshgrid(X, Y)

    f = tl.exp(-0.5 * (((X - x) * tl.cos(angle) -
                        (Y - y) * tl.sin(angle)) / sx)**2 - 0.5 *
               (((Y - y) * tl.cos(angle) + (X - x) * tl.sin(angle)) / sy)**2)
    return f