コード例 #1
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
コード例 #2
0
ファイル: beams.py プロジェクト: santiagobusta/PyOptics
    def profile(self, z, f, dx=1.):
        """
        Beam's complex amplitude at an axial distance z from waist.
        Plane lies perpendicular to z axis and has the same shape as f.
        
        ========Input=========
    
        z : Axial distance from waist
        f : 2D Array defining the output array shape
        dx : Pixel pitch (default value is unit of measurement)
        
        ========Raises========
        
        TypeError: If f isn't a 2D array
        
        ========Output========
    
        g : 2D complex array (complex amplitude at an axial distance z from waist centered at z axis)
        
        """

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

        n, m = tl.shape(f)
        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)
        R = tl.sqrt(X**2 + Y**2)
        g = self.value(R, z)

        return g
コード例 #3
0
ファイル: beams.py プロジェクト: santiagobusta/PyOptics
    def profile(self, z, f, dx=1.):
        """
        Beam's complex amplitude at an axial distance z from waist.
        Plane lies perpendicular to z axis and has the same shape as f.
        
        ========Input=========
    
        z : Axial distance from waist
        f : 2D Array defining the output array shape
        dx : Pixel pitch (default value is unit of measurement)
        
        ========Raises========
    
        ========Output========
    
        g : 2D complex array (complex amplitude at an axial distance z from waist centered at z axis)
        
        """

        n, m = tl.shape(f)
        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)
        g = self.value(X, Y, z)
        return g
コード例 #4
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
コード例 #5
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
コード例 #6
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
コード例 #7
0
def Pupil(R, shape, dx=1.):
    """
    ~ Simulates the trasmittance function of a pinhole with radius R
    ~ This  is essentially a circ function
    
    ========Input=========
    
    R :         Radius of pinhole
    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 = (X**2 + Y**2 <= R**2) * 1.

    return t
コード例 #8
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
コード例 #9
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
コード例 #10
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
コード例 #11
0
def Rect(w, h, shape, x=0., y=0., angle=0., use_pxc=False):
    """
    ~ Creates a sampled 2D rectangular signal
    ~ (x,y) coordinates are given in a centered cartesian frame
    ~ angle is measured counterclockwise in radians

    ========Input=========
    
    w :         Width
    h :         Height
    shape :     Output array shape
    x :         Horizontal center of rectangle (Default for horizontally centered)
    y :         Vertical center of rectangle (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):
        w *= shape[1]
        h *= shape[0]
        x *= shape[1]
        y *= shape[0]

    w = w / 2
    h = h / 2
    X = range(shape[1])
    Y = range(shape[0])
    X, Y = tl.meshgrid(X, Y)

    f = ((X - x) * tl.cos(angle) - (Y - y) * tl.sin(angle) > -w) * (
        (X - x) * tl.cos(angle) - (Y - y) * tl.sin(angle) <= w) * (
            (Y - y) * tl.cos(angle) +
            (X - x) * tl.sin(angle) > -h) * ((Y - y) * tl.cos(angle) +
                                             (X - x) * tl.sin(angle) <= h) * 1.

    return f
コード例 #12
0
def Ellipse(a, b, shape, x=0., y=0., angle=0., use_pxc=False):
    """
    ~ Creates a sampled 2D ellipse signal
    ~ (x,y) coordinates are given in a centered cartesian frame
    ~ angle is measured counterclockwise in radians

    ========Input=========
    
    a :         Semi-major axis
    b :         Semi-minor axis
    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 major axis 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

    """

    if (not use_pxc):
        x += 0.5
        y += 0.5
        a *= shape[1]
        b *= shape[0]
        x *= shape[1]
        y *= shape[0]

    else:
        x += 0.5 * shape[1]
        y += 0.5 * shape[0]

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

    f = ((((X - x) * tl.cos(angle) - (Y - y) * tl.sin(angle)) / a)**2 +
         (((Y - y) * tl.cos(angle) + (X - x) * tl.sin(angle)) / b)**2 < 1) * 1.

    return f
コード例 #13
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