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
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", )
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
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")
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")
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")
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()
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()