Esempio n. 1
0
def create_dn_buffer(size,
                     units,
                     points,
                     dn_inner=.0,
                     rad_inner=0,
                     dn_outer=.1,
                     rad_outer=.4):

    Nx, Ny, Nz = size
    dx, dy, dz = units

    program = OCLProgram(absPath("kernels/bpm_3d_spheres.cl"))

    dn_g = OCLArray.empty((Nz, Ny, Nx), dtype=np.float32)

    # sort by z
    ps = np.array(points)
    ps = ps[np.argsort(ps[:, 2]), :]

    Np = ps.shape[0]

    pointsBuf = OCLArray.from_array(ps.flatten().astype(np.float32))

    program.run_kernel("fill_dn", (Nx, Ny, Nz), None, dn_g.data,
                       pointsBuf.data, np.int32(Np), np.float32(dx),
                       np.float32(dy), np.float32(dz), np.float32(dn_inner),
                       np.float32(rad_inner), np.float32(dn_outer),
                       np.float32(rad_outer))

    return dn_g
Esempio n. 2
0
    def setup(self, size, units, lam=0.5, n0=1.0, use_fresnel_approx=False):
        """
            sets up the internal variables e.g. propagators etc...

            :param size:  the size of the geometry in pixels (Nx,Ny,Nz)
            :param units: the phyiscal units of each voxel in microns (dx,dy,dz)
            :param lam: the wavelength of light in microns
            :param n0:  the refractive index of the surrounding media
            :param use_fresnel_approx:  if True, uses fresnel approximation for propagator


        """
        Bpm3d_Base.setup(self, size, units, lam=lam, n0=n0, use_fresnel_approx=use_fresnel_approx)

        # setting up the gpu buffers and kernels
        self.program = OCLProgram(absPath("kernels/bpm_3d_kernels.cl"))

        Nx, Ny = self.size[:2]
        plan = fft_plan(())
        self._H_g = OCLArray.from_array(self._H.astype(np.complex64))

        self.scatter_weights_g = OCLArray.from_array(self.scatter_weights.astype(np.float32))
        self.gfactor_weights_g = OCLArray.from_array(self.gfactor_weights.astype(np.float32))

        self.scatter_cross_sec_g = OCLArray.zeros(Nz, "float32")
        self.gfactor_g = OCLArray.zeros(Nz, "float32")

        self.reduce_kernel = OCLReductionKernel(
            np.float32,
            neutral="0",
            reduce_expr="a+b",
            map_expr="weights[i]*cfloat_abs(field[i]-(i==0)*plain)*cfloat_abs(field[i]-(i==0)*plain)",
            arguments="__global cfloat_t *field, __global float * weights,cfloat_t plain",
        )
Esempio n. 3
0
def create_dn_buffer(size, units,points,
                     dn_inner = .0, rad_inner = 0,
                     dn_outer = .1, rad_outer = .4):

    Nx, Ny, Nz = size
    dx, dy, dz = units

    program = OCLProgram(absPath("kernels/bpm_3d_spheres.cl"))


    dn_g = OCLArray.empty((Nz,Ny,Nx),dtype=np.float32)

    # sort by z
    ps = np.array(points)
    ps = ps[np.argsort(ps[:,2]),:]

    Np = ps.shape[0]

    pointsBuf = OCLArray.from_array(ps.flatten().astype(np.float32))

    program.run_kernel("fill_dn",(Nx,Ny,Nz),None,dn_g.data,
                       pointsBuf.data,np.int32(Np),
                       np.float32(dx),np.float32(dy),np.float32(dz),
                       np.float32(dn_inner),np.float32(rad_inner),
                       np.float32(dn_outer),np.float32(rad_outer))


    return dn_g
Esempio n. 4
0
    def _setup_impl(self):
        """setting up the gpu buffers and kernels
        """

        self.bpm_program = OCLProgram(absPath("kernels/bpm_3d_kernels.cl"))

        Nx, Ny, Nz = self.size

        self._plan = fft_plan((Ny, Nx))

        self._H_g = OCLArray.from_array(self._H.astype(np.complex64))

        if not self.dn is None and self.n_volumes == 1:
            self.dn_g = OCLArray.from_array(self.dn)

        self.scatter_weights_g = OCLArray.from_array(
            self.scatter_weights.astype(np.float32))
        self.gfactor_weights_g = OCLArray.from_array(
            self.gfactor_weights.astype(np.float32))

        self.scatter_cross_sec_g = OCLArray.zeros(Nz, "float32")
        self.gfactor_g = OCLArray.zeros(Nz, "float32")
Esempio n. 5
0
    def _setup_impl(self):
        """setting up the gpu buffers and kernels
        """

        self.bpm_program = OCLProgram(absPath("kernels/bpm_3d_kernels.cl"))

        Nx, Ny, Nz  = self.size

        self._plan = fft_plan((Ny,Nx))


        self._H_g = OCLArray.from_array(self._H.astype(np.complex64))

        if not self.dn is None and self.n_volumes==1:
           self.dn_g = OCLArray.from_array(self.dn)


        self.scatter_weights_g = OCLArray.from_array(self.scatter_weights.astype(np.float32))
        self.gfactor_weights_g = OCLArray.from_array(self.gfactor_weights.astype(np.float32))

        self.scatter_cross_sec_g = OCLArray.zeros(Nz,"float32")
        self.gfactor_g = OCLArray.zeros(Nz,"float32")
Esempio n. 6
0
    def setup(self, size, units, lam = .5, n0 = 1.,
              use_fresnel_approx = False):
        """
            sets up the internal variables e.g. propagators etc...

            :param size:  the size of the geometry in pixels (Nx,Ny,Nz)
            :param units: the phyiscal units of each voxel in microns (dx,dy,dz)
            :param lam: the wavelength of light in microns
            :param n0:  the refractive index of the surrounding media
            :param use_fresnel_approx:  if True, uses fresnel approximation for propagator


        """
        Bpm3d_Base.setup(self,size, units, lam = lam, n0 = n0,
              use_fresnel_approx = use_fresnel_approx)

        #setting up the gpu buffers and kernels
        self.program = OCLProgram(absPath("kernels/bpm_3d_kernels.cl"))

        Nx, Ny  = self.size[:2]
        plan = fft_plan(())
        self._H_g = OCLArray.from_array(self._H.astype(np.complex64))


        self.scatter_weights_g = OCLArray.from_array(self.scatter_weights.astype(np.float32))
        self.gfactor_weights_g = OCLArray.from_array(self.gfactor_weights.astype(np.float32))

        self.scatter_cross_sec_g = OCLArray.zeros(Nz,"float32")
        self.gfactor_g = OCLArray.zeros(Nz,"float32")



        self.reduce_kernel = OCLReductionKernel(
        np.float32, neutral="0",
            reduce_expr="a+b",
            map_expr="weights[i]*cfloat_abs(field[i]-(i==0)*plain)*cfloat_abs(field[i]-(i==0)*plain)",
            arguments="__global cfloat_t *field, __global float * weights,cfloat_t plain")
Esempio n. 7
0
def bpm_3d_inverse(u, units, lam=.5, use_fresnel_approx=False):
    """
    size     -    the dimension of the image to be calulcated  in pixels (Nx,Ny,Nz)
    units    -    the unit lengths of each dimensions in microns
    lam      -    the wavelength
    u       -    the complex field distribution

    returns 
    dn       -    the refractive index of the medium (can be complex)

    """
    clock = StopWatch()

    clock.tic("setup")
    Nz, Ny, Nx = u.shape
    dx, dy, dz = units

    #setting up the propagator
    k0 = 2. * np.pi / lam

    kxs = np.arange(-Nx / 2., Nx / 2.) / Nx
    kys = np.arange(-Ny / 2., Ny / 2.) / Ny

    KY, KX = np.meshgrid(kxs, kys, indexing="ij")

    H0 = np.sqrt(0.j + (1. / lam)**2 - KX**2 / dx**2 - KY**2 / dy**2)

    if use_fresnel_approx:
        H0 = 1. / lam * (0.j + 1. - .5 * lam**2 *
                         (KX**2 / dx**2 + KY**2 / dy**2))

    outsideInds = np.isnan(H0)
    H = np.exp(2.j * np.pi * dz * H0)
    H[outsideInds] = 0.
    H0[outsideInds] = 0.

    H = np.fft.fftshift(H).astype(np.complex64)
    """
    setting up the gpu buffers and kernels
    """

    program = OCLProgram(absPath("kernels/bpm_3d_kernels.cl"))
    # program = OCLProgram(src_str = kernel_str)

    kernel_divide = OCLElementwiseKernel(
        "cfloat_t *a_g, cfloat_t *b_g,float kz, cfloat_t *res_g",
        "res_g[i] = (cfloat_t)(i,0.)", "divide")

    plan = ocl_fft_plan((Ny, Nx))
    plane_g = OCLArray.empty((Ny, Nx), np.complex64)
    plane0_g = OCLArray.empty((Ny, Nx), np.complex64)

    h_g = OCLArray.from_array(H.astype(np.complex64))
    u_g = OCLArray.from_array(u.astype(np.complex64))

    dn_g = OCLArray.empty((Nz, Ny, Nx), dtype=np.complex64)

    clock.toc("setup")
    clock.tic("run")

    for i in range(Nz - 1):
        program.run_kernel("copy_complex", (Nx * Ny, ), None, u_g.data,
                           plane_g.data, np.int32(i * Nx * Ny))

        #calculate the propagated plane
        ocl_fft(plane_g, inplace=True, plan=plan)

        program.run_kernel("mult", (Nx * Ny, ), None, plane_g.data, h_g.data)

        ocl_fft(plane_g, inplace=True, inverse=True, plan=plan)

        dn_g[i + 1, ...] = plane_g

        # program.run_kernel("copy_complex",(Nx*Ny,),None,
        #                    u_g.data,plane0_g.data,np.int32((i+1)*Nx*Ny))

        # program.run_kernel("divide_dn_complex",(Nx*Ny,),None,
        #                    plane0_g.data,plane_g.data,dn_g.data,
        #                    np.float32(k0*dz),
        #                    np.int32((i+1)*Nx*Ny))

    clock.toc("run")

    print clock
    return dn_g.get()
Esempio n. 8
0
def bpm_3d_inverse(u,units, lam = .5,
           use_fresnel_approx = False):
    """
    size     -    the dimension of the image to be calulcated  in pixels (Nx,Ny,Nz)
    units    -    the unit lengths of each dimensions in microns
    lam      -    the wavelength
    u       -    the complex field distribution

    returns 
    dn       -    the refractive index of the medium (can be complex)

    """
    clock = StopWatch()

    clock.tic("setup")
    Nz, Ny, Nx = u.shape
    dx, dy, dz = units

    

    #setting up the propagator
    k0 = 2.*np.pi/lam

    kxs = np.arange(-Nx/2.,Nx/2.)/Nx
    kys = np.arange(-Ny/2.,Ny/2.)/Ny

    KY, KX = np.meshgrid(kxs,kys, indexing= "ij")

    H0 = np.sqrt(0.j+(1./lam)**2-KX**2/dx**2-KY**2/dy**2)

    if use_fresnel_approx:
        H0  = 1./lam*(0.j+1.-.5*lam**2*(KX**2/dx**2+KY**2/dy**2))

        
    outsideInds = np.isnan(H0)
    H = np.exp(2.j*np.pi*dz*H0)
    H[outsideInds] = 0.
    H0[outsideInds] = 0.

    H = np.fft.fftshift(H).astype(np.complex64)


    """
    setting up the gpu buffers and kernels
    """

    program = OCLProgram(absPath("kernels/bpm_3d_kernels.cl"))
    # program = OCLProgram(src_str = kernel_str)

    kernel_divide = OCLElementwiseKernel(
        "cfloat_t *a_g, cfloat_t *b_g,float kz, cfloat_t *res_g",
        "res_g[i] = (cfloat_t)(i,0.)",
    "divide")
    
    plan = ocl_fft_plan((Ny,Nx))
    plane_g = OCLArray.empty((Ny,Nx),np.complex64)
    plane0_g = OCLArray.empty((Ny,Nx),np.complex64)

    h_g = OCLArray.from_array(H.astype(np.complex64))
    u_g = OCLArray.from_array(u.astype(np.complex64))

    dn_g = OCLArray.empty((Nz,Ny,Nx),dtype=np.complex64)

 
    clock.toc("setup")
    clock.tic("run")

    for i in range(Nz-1):
        program.run_kernel("copy_complex",(Nx*Ny,),None,
                           u_g.data,plane_g.data,np.int32(i*Nx*Ny))

        #calculate the propagated plane
        ocl_fft(plane_g,inplace = True, plan  = plan)

        program.run_kernel("mult",(Nx*Ny,),None,
                           plane_g.data,h_g.data)

        
        ocl_fft(plane_g,inplace = True, inverse = True,  plan  = plan)

        dn_g[i+1,...] = plane_g
        
        # program.run_kernel("copy_complex",(Nx*Ny,),None,
        #                    u_g.data,plane0_g.data,np.int32((i+1)*Nx*Ny))

        
        # program.run_kernel("divide_dn_complex",(Nx*Ny,),None,
        #                    plane0_g.data,plane_g.data,dn_g.data,
        #                    np.float32(k0*dz),
        #                    np.int32((i+1)*Nx*Ny))


 


    clock.toc("run")

    print clock
    return dn_g.get()