def gpuGridrec(tomo,angles,center,input_params): """ Gridrec reconstruction using GPU based gridding Inputs: tomo : 3D numpy sinogram array with dimensions same as tomopy angles : Array of angles in radians center : Floating point center of rotation input_params : A dictionary with the keys 'gpu_device' : Device id of the gpu (For a 4 GPU cluster ; 0-3) 'oversamp_factor': A factor by which to pad the image/data for FFT 'fbp_filter_param' : A number between 0-1 for setting the filter cut-off for FBP """ print('Starting GPU NUFFT recon') #allocate space for final answer af.set_device(input_params['gpu_device']) #Set the device number for gpu based code #Change tomopy format new_tomo=np.transpose(tomo,(1,2,0)) #slice, columns, angles im_size = new_tomo.shape[1] num_slice = new_tomo.shape[0] num_angles=new_tomo.shape[2] pad_size=np.int16(im_size*input_params['oversamp_factor']) # nufft_scaling = (np.pi/pad_size)**2 #Initialize structures for NUFFT sino={} geom={} sino['Ns'] = pad_size#Sinogram size after padding sino['Ns_orig'] = im_size #size of original sinogram sino['center'] = center + (sino['Ns']/2 - sino['Ns_orig']/2) #for padded sinogram sino['angles'] = angles sino['filter'] = input_params['fbp_filter_param'] #Paramter to control strength of FBP filter normalized to [0,1] #Initialize NUFFT parameters nufft_params = init_nufft_params(sino,geom) rec_nufft = afnp.zeros((num_slice/2,sino['Ns_orig'],sino['Ns_orig']),dtype=afnp.complex64) Ax = afnp.zeros((sino['Ns'],num_angles),dtype=afnp.complex64) pad_idx = slice(sino['Ns']/2-sino['Ns_orig']/2,sino['Ns']/2+sino['Ns_orig']/2) rec_nufft_final=np.zeros((num_slice,sino['Ns_orig'],sino['Ns_orig']),dtype=np.float32) #Move all data to GPU slice_1=slice(0,num_slice,2) slice_2=slice(1,num_slice,2) gdata=afnp.array(new_tomo[slice_1]+1j*new_tomo[slice_2],dtype=afnp.complex64) x_recon = afnp.zeros((sino['Ns'],sino['Ns']),dtype=afnp.complex64) #loop over all slices for i in range(0,num_slice/2): Ax[pad_idx,:]=gdata[i] #filtered back-projection rec_nufft[i] = (back_project(Ax,nufft_params))[pad_idx,pad_idx] #Move to CPU #Rescale result to match tomopy rec_nufft=np.array(rec_nufft,dtype=np.complex64) #*nufft_scaling rec_nufft_final[slice_1]=np.array(rec_nufft.real,dtype=np.float32) rec_nufft_final[slice_2]=np.array(rec_nufft.imag,dtype=np.float32) return rec_nufft_final
def test_empty_ndarray(): a = afnumpy.zeros(()) b = numpy.zeros(()) iassert(a, b) a = afnumpy.ndarray(0) b = numpy.ndarray(0) iassert(a, b) a = afnumpy.ndarray((0, )) b = numpy.ndarray((0, )) iassert(a, b) a = afnumpy.zeros(3) b = numpy.zeros(3) iassert(a[0:0], b[0:0])
def test_empty_ndarray(): a = afnumpy.zeros(()) b = numpy.zeros(()) iassert(a,b) a = afnumpy.ndarray(0) b = numpy.ndarray(0) iassert(a,b) a = afnumpy.ndarray((0,)) b = numpy.ndarray((0,)) iassert(a,b) a = afnumpy.zeros(3) b = numpy.zeros(3) iassert(a[0:0],b[0:0])
def gpuGridrec(tomo, angles, center, input_params): print('Starting GPU NUFFT recon') #allocate space for final answer af.set_device( input_params['gpu_device']) #Set the device number for gpu based code #Change tomopy format new_tomo = np.transpose(tomo, (1, 2, 0)) #slice, columns, angles im_size = new_tomo.shape[1] num_slice = new_tomo.shape[0] num_angles = new_tomo.shape[2] pad_size = np.int16(im_size * input_params['oversamp_factor']) nufft_scaling = (np.pi / pad_size)**2 #Initialize structures for NUFFT sino = {} geom = {} sino['Ns'] = pad_size #Sinogram size after padding sino['Ns_orig'] = im_size #size of original sinogram sino['center'] = center + (sino['Ns'] / 2 - sino['Ns_orig'] / 2 ) #for padded sinogram sino['angles'] = angles sino['filter'] = input_params[ 'fbp_filter_param'] #Paramter to control strength of FBP filter normalized to [0,1] #Initialize NUFFT parameters nufft_params = init_nufft_params(sino, geom) rec_nufft = afnp.zeros((num_slice / 2, sino['Ns_orig'], sino['Ns_orig']), dtype=afnp.complex64) Ax = afnp.zeros((sino['Ns'], num_angles), dtype=afnp.complex64) pad_idx = slice(sino['Ns'] / 2 - sino['Ns_orig'] / 2, sino['Ns'] / 2 + sino['Ns_orig'] / 2) rec_nufft_final = np.zeros((num_slice, sino['Ns_orig'], sino['Ns_orig']), dtype=np.float32) #Move all data to GPU slice_1 = slice(0, num_slice, 2) slice_2 = slice(1, num_slice, 2) gdata = afnp.array(new_tomo[slice_1] + 1j * new_tomo[slice_2], dtype=afnp.complex64) x_recon = afnp.zeros((sino['Ns'], sino['Ns']), dtype=afnp.complex64) #loop over all slices for i in range(0, num_slice / 2): Ax[pad_idx, :] = gdata[i] #filtered back-projection rec_nufft[i] = (back_project(Ax, nufft_params))[pad_idx, pad_idx] #Move to CPU #Rescale result to match tomopy rec_nufft = np.array(rec_nufft, dtype=np.complex64) * nufft_scaling rec_nufft_final[slice_1] = np.array(rec_nufft.real, dtype=np.float32) rec_nufft_final[slice_2] = np.array(rec_nufft.imag, dtype=np.float32) return rec_nufft_final
def __init__(self, unitcell_size, det_shape, dtype=np.complex128): # only calculate the translations when they are needed self.translations = None self.unitcell_size = unitcell_size self.det_shape = det_shape # keep an array for the 4 symmetry related coppies of the solid unit self.syms = afnumpy.zeros((4,) + tuple(det_shape), dtype=dtype)
def __init__(self, unitcell_size, det_shape, dtype=np.complex128): # store the tranlation ramps # x = x T0 = 1 self.translations = afnumpy.array([T0]) # keep an array for the 1 symmetry related coppies of the solid unit self.syms = afnumpy.zeros((1,) + tuple(det_shape), dtype=dtype)
def imag(self): ret_type = numpy.real(numpy.zeros((), dtype=self.dtype)).dtype shape = list(self.shape) if not numpy.issubdtype(self.dtype, numpy.complexfloating): return afnumpy.zeros(self.shape) shape[-1] *= 2 dims = numpy.array(pu.c2f(shape), dtype=pu.dim_t) s = arrayfire.Array() arrayfire.backend.get().af_device_array( ctypes.pointer(s.arr), ctypes.c_void_p(self.d_array.device_ptr()), self.ndim, ctypes.c_void_p(dims.ctypes.data), pu.typemap(ret_type).value) arrayfire.backend.get().af_retain_array(ctypes.pointer(s.arr), s.arr) a = ndarray(shape, dtype=ret_type, af_array=s) ret = a[..., 1::2] ret._base = a ret._base_index = (Ellipsis, slice(1, None, 2)) return ret
def imag(self): ret_type = numpy.real(numpy.zeros((),dtype=self.dtype)).dtype shape = list(self.shape) if not numpy.issubdtype(self.dtype, numpy.complexfloating): return afnumpy.zeros(self.shape) shape[-1] *= 2 dims = numpy.array(pu.c2f(shape),dtype=pu.dim_t) s = arrayfire.Array() arrayfire.backend.get().af_device_array(ctypes.pointer(s.arr), ctypes.c_void_p(self.d_array.device_ptr()), self.ndim, ctypes.c_void_p(dims.ctypes.data), pu.typemap(ret_type).value) arrayfire.backend.get().af_retain_array(ctypes.pointer(s.arr),s.arr) a = ndarray(shape, dtype=ret_type, af_array=s) ret = a[...,1::2] ret._base = a ret._base_index = (Ellipsis, slice(1,None,2)) return ret
def test_cast(): a = afnumpy.zeros(25).astype(numpy.complex64) a[0] = 1. + 0.j assert(a[0] == 1. + 0j)
#! /usr/bin/env python import gnufft import afnumpy as afnp vol = afnp.ones((25,256,256), dtype='f') vol = vol + 1j * vol fcn = afnp.zeros((25,256,256), dtype='complex64') mrf_sigma = afnp.ones(1, dtype='f') gnufft.add_hessian(mrf_sigma[0], vol, fcn) print fcn[0,:10,:10] print fcn[0,:10,:10]
def test_zeros(): a = afnumpy.zeros(3) b = numpy.zeros(3) iassert(a, b)
import time import arrayfire as af af.set_device(2) nslice = 150 im_size = 2560 #obj = np.ones((nslice,im_size,im_size),dtype=np.float32) #obj=tomopy.shepp3d((nslice,im_size,im_size),dtype=np.float32) obj = np.random.rand(nslice, im_size, im_size).astype(np.float32) x = obj[::2] y = obj[1::2] print(x.shape) vol = x + 1j * y t = time.time() vol = afnp.array(vol.astype(np.complex64)) #255* fcn = afnp.zeros((nslice / 2, im_size, im_size), dtype=np.complex64) tvd_update(1.2, 1, vol, fcn) elapsed = time.time() - t print('Time taken for gradient %f' % (elapsed)) output = np.zeros((nslice, im_size, im_size), dtype=np.float32) output[::2] = np.array(fcn).real output[1::2] = np.array(fcn).imag print(output.max()) print(output.min()) del fcn fcn = afnp.zeros((nslice / 2, im_size, im_size), dtype=np.complex64) t = time.time() add_hessian(2, vol, fcn) elapsed = time.time() - t print('Time taken for Hessian %f' % (elapsed))
def gpuSIRT(tomo, angles, center, input_params): print('Starting GPU SIRT recon') #allocate space for final answer af.set_device( input_params['gpu_device']) #Set the device number for gpu based code #Change tomopy format new_tomo = np.transpose(tomo, (1, 2, 0)) #slice, columns, angles im_size = new_tomo.shape[1] num_slice = new_tomo.shape[0] num_angles = new_tomo.shape[2] pad_size = np.int16(im_size * input_params['oversamp_factor']) nufft_scaling = (np.pi / pad_size)**2 num_iter = input_params['num_iter'] #Initialize structures for NUFFT sino = {} geom = {} sino['Ns'] = pad_size #Sinogram size after padding sino['Ns_orig'] = im_size #size of original sinogram sino['center'] = center + (sino['Ns'] / 2 - sino['Ns_orig'] / 2 ) #for padded sinogram sino['angles'] = angles #Initialize NUFFT parameters nufft_params = init_nufft_params(sino, geom) temp_y = afnp.zeros((sino['Ns'], num_angles), dtype=afnp.complex64) temp_x = afnp.zeros((sino['Ns'], sino['Ns']), dtype=afnp.complex64) x_recon = afnp.zeros((num_slice / 2, sino['Ns_orig'], sino['Ns_orig']), dtype=afnp.complex64) pad_idx = slice(sino['Ns'] / 2 - sino['Ns_orig'] / 2, sino['Ns'] / 2 + sino['Ns_orig'] / 2) #allocate output array rec_sirt_final = np.zeros((num_slice, sino['Ns_orig'], sino['Ns_orig']), dtype=np.float32) #Pre-compute diagonal scaling matrices ; one the same size as the image and the other the same as data #initialize an image of all ones x_ones = afnp.ones((sino['Ns_orig'], sino['Ns_orig']), dtype=afnp.complex64) temp_x[pad_idx, pad_idx] = x_ones temp_proj = forward_project(temp_x, nufft_params) * (sino['Ns'] * afnp.pi / 2) R = 1 / afnp.abs(temp_proj) R[afnp.isnan(R)] = 0 R[afnp.isinf(R)] = 0 R = afnp.array(R, dtype=afnp.complex64) #Initialize a sinogram of all ones y_ones = afnp.ones((sino['Ns_orig'], num_angles), dtype=afnp.complex64) temp_y[pad_idx] = y_ones temp_backproj = back_project(temp_y, nufft_params) * nufft_scaling / 2 C = 1 / (afnp.abs(temp_backproj)) C[afnp.isnan(C)] = 0 C[afnp.isinf(C)] = 0 C = afnp.array(C, dtype=afnp.complex64) #Move all data to GPU slice_1 = slice(0, num_slice, 2) slice_2 = slice(1, num_slice, 2) gdata = afnp.array(new_tomo[slice_1] + 1j * new_tomo[slice_2], dtype=afnp.complex64) #loop over all slices for i in range(num_slice / 2): for iter_num in range(num_iter): #filtered back-projection temp_x[pad_idx, pad_idx] = x_recon[i] Ax = (np.pi / 2) * sino['Ns'] * forward_project( temp_x, nufft_params) temp_y[pad_idx] = gdata[i] x_recon[i] = x_recon[i] + ( C * back_project(R * (temp_y - Ax), nufft_params) * nufft_scaling / 2)[pad_idx, pad_idx] #Move to CPU #Rescale result to match tomopy rec_sirt = np.array(x_recon, dtype=np.complex64) rec_sirt_final[slice_1] = np.array(rec_sirt.real, dtype=np.float32) rec_sirt_final[slice_2] = np.array(rec_sirt.imag, dtype=np.float32) return rec_sirt_final
def test_cast(): a = afnumpy.zeros(25).astype(numpy.complex64) a[0] = 1. + 0.j assert (a[0] == 1. + 0j)
def test_gsm(self, beta = 1, nx = 10, ny = 1, pos = "end", export = False, outdir = ""): """ Initialise GSM beam as a container of multiple coherent modes Modes dictionary is setup by order {wfr, eigenvalue/weight} :param p_mu: rms width of the degree of coherence :param p_I: rms width of the intensity profile :param n: number of values for eigenvalue calculation (almost arb.) """ print("Initialising Gaussian-Schell Model Beam") self.log.info("Initialising Gaussian-Schell Model Beam") gauss_0 = primary_gaussian() # properties of gaussian N = nx*ny results = [] if export == True: os.mkdir(outdir) else: pass for itr in range(N): self.wfr.eigenval.append(eigenvaluePartCoh(1, beta,itr)) self.wfr.eigenval = self.wfr.eigenval[0:N] self.wfr.eigenfn = gen_modes(nx, ny) if pos == "start": gauss_0.d2waist = 0 elif pos == "end": gauss_0.d2waist = 2.012 else: assert("wavefront posn' should be 'start' or 'end'") print("Generating {} Coherent Modes".format(N)) self.log.info("Generating {} Coherent Modes".format(N)) eField = np.zeros((2048, 2048, 1)) if pos == "start": gauss_0.d2waist = 0 elif pos == "end": gauss_0.d2waist = 2.012 else: assert("wavefront posn' should be 'start' or 'end'") print(self.wfr.eigenfn) print("Generating {} Coherent Modes".format(N)) self.log.info("Generating {} Coherent Modes".format(N)) for itr in range(N): res = [] res.append(self.wfr.eigenfn[itr]) res.append(self.wfr.eigenval[itr]) if itr % 5 == 0: print("Generating Mode {}/{}".format(itr+1, N)) self.log.info("Generating Mode {}/{}".format(itr+1, N)) _mx = self.wfr.eigenfn[itr][0] _my = self.wfr.eigenfn[itr][1] M2x = (2*_mx)+1 M2y = (2*_my)+1 self.wfr.modes.append(Wavefront(build_gauss_wavefront_xy(gauss_0.nx ,gauss_0.ny, self.global_E*1e-03, gauss_0.xMin, gauss_0.xMax, gauss_0.yMin,gauss_0.yMax, gauss_0.sigX*M2x**-0.25, gauss_0.sigY*M2y**-0.25, gauss_0.d2waist, tiltX = 0, tiltY = 0, _mx = - _mx, ## NOTE NEGATIVE _my = _my, pulseEn = 2.51516e-2))) self.wfr.type = 'gsm' print("Coherent Modes Generated") self.log.info("Coherent Modes Generated") print("Testing Coherent Modes") self.log.info("Testing Coherent Modes") axis_x = np.linspace(-0.002, 0.002, 2048) axis_y = np.linspace(-0.002, 0.002, 2048) eField = np.zeros((2048,2048,1)) for itr in range(len(self.wfr.modes)): eField += self.wfr.modes[itr].data.arrEhor[:,:,:,0] * self.wfr.eigenval[itr] [cohx, cohy] = coherence_log(eField, axis_x, axis_y) self.log.info("**************************************************") self.log.info("Addition of Mode {}".format(itr)) self.log.info("Mode Weighting {}".format(self.wfr.eigenval[itr])) self.log.info("Mode Weighting {}".format(self.wfr.eigenfn[itr])) self.log.info("\n") self.log.info("Ix: {} m\nJx: {} m".format(cohx[2], cohx[3])) self.log.info("Iy: {} m\nJy: {} m".format(cohy[2], cohy[3])) self.log.info("x-beta: {} \n y-beta: {}".format(cohx[4], cohy[4])) res.append(cohx[2]) res.append(cohy[2]) res.append(cohx[3]) res.append(cohy[3]) res.append(cohx[4]) res.append(cohy[4]) results.append(res) return results
sino={} geom={} sino['Ns'] = 1024 #3624#im_size*2 #Sinogram size after padding sino['Ns_orig'] = im_size #size of original sinogram sino['center'] = sino_center + (sino['Ns']/2 - sino['Ns_orig']/2) #for padded sinogram sino['angles'] = ang sino['filter']=0.95 pad_size= sino['Ns'] params = init_nufft_params(sino,geom) ##Create a simulated object to test forward and back-projection routines pad_idx = slice(sino['Ns']/2-sino['Ns_orig']/2,sino['Ns']/2+sino['Ns_orig']/2) temp_x = afnp.zeros((sino['Ns'],sino['Ns']),dtype=afnp.complex64) print(temp_x.shape) Ax = afnp.zeros((num_slice/2,sino['Ns'],num_angles),dtype=afnp.complex64) y = afnp.zeros((num_slice/2,sino['Ns_orig'],sino['Ns_orig']),dtype=afnp.complex64) t=time.time() slice_1=slice(0,num_slice,2) slice_2=slice(1,num_slice,2) x=afnp.array(obj[slice_1]+1j*obj[slice_2],dtype=afnp.complex64) print(x.shape) for i in range(num_slice/2): temp_x[pad_idx,pad_idx]=x[i] Ax[i] = forward_project(temp_x,params) #(math.pi/2)*sino['Ns'] y[i] = (back_project(Ax[i],params)[pad_idx,pad_idx]) # elapsed_time = (time.time()-t) print('Time for Forward/Back-proj for %d slices: %f'% (num_slice,elapsed_time))
def gpuMBIR(tomo,angles,center,input_params): """ MBIR reconstruction using GPU based gridding operators Inputs: tomo : 3D numpy sinogram array with dimensions same as tomopy angles : Array of angles in radians center : Floating point center of rotation input_params : A dictionary with the keys 'gpu_device' : Device id of the gpu (For a 4 GPU cluster ; 0-3) 'oversamp_factor': A factor by which to pad the image/data for FFT 'num_iter' : Max number of MBIR iterations 'smoothness' : Regularization constant 'p': MRF shape param """ print('Starting GPU MBIR recon') #allocate space for final answer af.set_device(input_params['gpu_device']) #Set the device number for gpu based code #Change tomopy format new_tomo=np.transpose(tomo,(1,2,0)) #slice, columns, angles im_size = new_tomo.shape[1] num_slice = new_tomo.shape[0] num_angles=new_tomo.shape[2] pad_size=np.int16(im_size*input_params['oversamp_factor']) # nufft_scaling = (np.pi/pad_size)**2 num_iter = input_params['num_iter'] mrf_sigma = input_params['smoothness'] mrf_p = input_params['p'] print('MRF params p=%f sigma=%f' %(mrf_p,mrf_sigma)) #Initialize structures for NUFFT sino={} geom={} sino['Ns'] = pad_size#Sinogram size after padding sino['Ns_orig'] = im_size #size of original sinogram sino['center'] = center + (sino['Ns']/2 - sino['Ns_orig']/2) #for padded sinogram sino['angles'] = angles #Initialize NUFFT parameters print('Initialize NUFFT params') nufft_params = init_nufft_params(sino,geom) temp_y = afnp.zeros((sino['Ns'],num_angles),dtype=afnp.complex64) temp_x = afnp.zeros((sino['Ns'],sino['Ns']),dtype=afnp.complex64) x_recon = afnp.zeros((num_slice/2,sino['Ns_orig'],sino['Ns_orig']),dtype=afnp.complex64) pad_idx = slice(sino['Ns']/2-sino['Ns_orig']/2,sino['Ns']/2+sino['Ns_orig']/2) #allocate output array rec_mbir_final=np.zeros((num_slice,sino['Ns_orig'],sino['Ns_orig']),dtype=np.float32) #Move all data to GPU print('Moving data to GPU') slice_1=slice(0,num_slice,2) slice_2=slice(1,num_slice,2) gdata=afnp.array(new_tomo[slice_1]+1j*new_tomo[slice_2],dtype=afnp.complex64) gradient = afnp.zeros((num_slice/2,sino['Ns_orig'],sino['Ns_orig']), dtype=afnp.complex64)#temp array to store the derivative of cost func z_recon = afnp.zeros((num_slice/2,sino['Ns_orig'],sino['Ns_orig']),dtype=afnp.complex64)#Nesterov method variables t_nes = 1 #Compute Lipschitz of gradient print('Computing Lipschitz of gradient') x_ones= afnp.ones((1,sino['Ns_orig'],sino['Ns_orig']),dtype=afnp.complex64) temp_x[pad_idx,pad_idx]=x_ones[0] temp_proj=forward_project(temp_x,nufft_params) temp_backproj=(back_project(temp_proj,nufft_params))[pad_idx,pad_idx] print('Adding Hessian of regularizer') temp_backproj2=afnp.zeros((1,sino['Ns_orig'],sino['Ns_orig']),dtype=afnp.complex64) temp_backproj2[0]=temp_backproj add_hessian(mrf_sigma,x_ones, temp_backproj2) L = np.max([temp_backproj2.real.max(),temp_backproj2.imag.max()]) print('Lipschitz constant = %f' %(L)) del x_ones,temp_proj,temp_backproj,temp_backproj2 #loop over all slices for iter_num in range(num_iter): print('Iteration %d of %d'%(iter_num,num_iter)) #Derivative of the data fitting term for i in range(num_slice/2): temp_x[pad_idx,pad_idx]=x_recon[i] Ax = forward_project(temp_x,nufft_params) temp_y[pad_idx]=gdata[i] gradient[i] =(back_project((Ax-temp_y),nufft_params))[pad_idx,pad_idx] #nufft_scaling #Derivative of regularization term tvd_update(mrf_p,mrf_sigma,x_recon, gradient) #x_recon-=gradient/L x_recon,z_recon,t_nes=nesterovOGM2update(x_recon,z_recon,t_nes,gradient,L) #Move to CPU #Rescale result to match tomopy rec_mbir=np.array(x_recon,dtype=np.complex64) rec_mbir_final[slice_1]=np.array(rec_mbir.real,dtype=np.float32) rec_mbir_final[slice_2]=np.array(rec_mbir.imag,dtype=np.float32) return rec_mbir_final