def process(self, out=None): DATA = self.get_input() pad = False if len(DATA.shape) == 2: #for 2D cases pad = True data_temp = numpy.expand_dims(DATA.as_array(), axis=0) else: data_temp = DATA.as_array() rec_id, arr_out = astra.create_backprojection3d_gpu( data_temp, self.proj_geom, self.vol_geom) astra.data3d.delete(rec_id) if pad is True: arr_out = numpy.squeeze(arr_out, axis=0) if out is None: out = ImageData(arr_out, deep_copy=False, geometry=self.volume_geometry.copy(), suppress_warning=True) return out else: out.fill(arr_out)
def process(self): DATA = self.get_input() IM = ImageData(geometry=self.volume_geometry, dimension_labels=self.output_axes_order) rec_id, IM.array = astra.create_backprojection3d_gpu( DATA.as_array(), self.proj_geom, self.vol_geom) astra.data3d.delete(rec_id) # Scaling of 3D ASTRA backprojector, works both parallel and cone. scaling = 1 / self.volume_geometry.voxel_size_x**2 return scaling * IM
def backward(ctx, grad_out): astra.set_gpu_index([grad_out.device.index], memory=10 * 1024 * 1024 * 1024) grad_input = gradProjSize = gradVectors = None if ctx.needs_input_grad[0]: # permute here to handle opposite data layouts bproj_id, bproj_data = astra.create_backprojection3d_gpu( grad_out.squeeze(1).permute(2, 0, 1).data.cpu().numpy(), ctx.proj_geom, ctx.vol_geom) astra.data3d.delete(bproj_id) grad_input = Tensor(bproj_data).cuda(non_blocking=True).permute( 2, 1, 0) return grad_input, gradProjSize, gradVectors
def single_test_adjoint3D(self, geom_type, proj_type): for vg in VolumeGeometries(True, True): for pg in ProjectionGeometries(geom_type): for i in range(5): X = np.random.random(astra.geom_size(vg)) Y = np.random.random(astra.geom_size(pg)) proj_id, fX = astra.create_sino3d_gpu(X, pg, vg) bp_id, fTY = astra.create_backprojection3d_gpu(Y, pg, vg) astra.data3d.delete([proj_id, bp_id]) da = np.dot(fX.ravel(), Y.ravel()) db = np.dot(X.ravel(), fTY.ravel()) m = np.abs(da - db) TOL = 1e-1 if m / da >= TOL: print(vg) print(pg) print(m / da, da / db, da, db) self.assertTrue(m / da < TOL)
import numpy as np # Set up multi-GPU usage. # This only works for 3D GPU forward projection and back projection. astra.astra.set_gpu_index([0,1]) # Optionally, you can also restrict the amount of GPU memory ASTRA will use. # The line commented below sets this to 1GB. #astra.astra.set_gpu_index([0,1], memory=1024*1024*1024) vol_geom = astra.create_vol_geom(1024, 1024, 1024) angles = np.linspace(0, np.pi, 1024,False) proj_geom = astra.create_proj_geom('parallel3d', 1.0, 1.0, 1024, 1024, angles) # Create a simple hollow cube phantom cube = np.zeros((1024,1024,1024)) cube[128:895,128:895,128:895] = 1 cube[256:767,256:767,256:767] = 0 # Create projection data from this proj_id, proj_data = astra.create_sino3d_gpu(cube, proj_geom, vol_geom) # Backproject projection data bproj_id, bproj_data = astra.create_backprojection3d_gpu(proj_data, proj_geom, vol_geom) # Clean up. Note that GPU memory is tied up in the algorithm object, # and main RAM in the data objects. astra.data3d.delete(proj_id) astra.data3d.delete(bproj_id)
def backprojOS(self, proj_data, no_os): """Applying back-projection to a specific subset""" rec_id, object3D = astra.create_backprojection3d_gpu( proj_data, self.proj_geom_OS[no_os], self.vol_geom) astra.data3d.delete(rec_id) return object3D
def backproj(self, proj_data): """Applying backprojection""" rec_id, object3D = astra.create_backprojection3d_gpu( proj_data, self.proj_geom, self.vol_geom) astra.data3d.delete(rec_id) return object3D
# Set up multi-GPU usage. # This only works for 3D GPU forward projection and back projection. astra.set_gpu_index([0, 1]) # Optionally, you can also restrict the amount of GPU memory ASTRA will use. # The line commented below sets this to 1GB. #astra.set_gpu_index([0,1], memory=1024*1024*1024) vol_geom = astra.create_vol_geom(1024, 1024, 1024) angles = np.linspace(0, np.pi, 1024, False) proj_geom = astra.create_proj_geom('parallel3d', 1.0, 1.0, 1024, 1024, angles) # Create a simple hollow cube phantom cube = np.zeros((1024, 1024, 1024)) cube[128:895, 128:895, 128:895] = 1 cube[256:767, 256:767, 256:767] = 0 # Create projection data from this proj_id, proj_data = astra.create_sino3d_gpu(cube, proj_geom, vol_geom) # Backproject projection data bproj_id, bproj_data = astra.create_backprojection3d_gpu( proj_data, proj_geom, vol_geom) # Clean up. Note that GPU memory is tied up in the algorithm object, # and main RAM in the data objects. astra.data3d.delete(proj_id) astra.data3d.delete(bproj_id)
def recon_multi_part(algon,proj_data,proj_data_low,det_move,angles,x_sub_boundaries,y_sub_boundaries,z_sub_boundaries,vol_size,det_spacing_x,det_spacing_y,x_subvol_width,y_subvol_width,z_subvol_width,n_x,n_y,n_z,nr_iterations_high,source_origin, origin_det,relaxation): # this part performs the reconstruction of the subvolume. pro_proj = proj_data - proj_data_low # we only want to have the projection data that comes from the sub volume det_row_count= pro_proj.shape[0] det_col_count=pro_proj.shape[2] vectors_ROI = np.zeros((len(angles), 12)) # this vector will contain the information of the source and detector position. move_x,move_y,move_z=how_to_move(x_sub_boundaries,y_sub_boundaries,z_sub_boundaries,vol_size,x_subvol_width,y_subvol_width,z_subvol_width,n_x,n_y,n_z) for i in range(0,len(angles)): # source vectors_ROI[i,0] = np.sin(angles[i]) * (source_origin) +move_x vectors_ROI[i,1] = -np.cos(angles[i]) * (source_origin) + move_y vectors_ROI[i,2] = move_z # center of detector vectors_ROI[i,3] = -np.sin(angles[i]) * (origin_det) + move_x vectors_ROI[i,4] = np.cos(angles[i]) * (origin_det) + move_y vectors_ROI[i,5] = move_z +det_move # vector from detector pixel 0 to 1 vectors_ROI[i,6] = np.cos(angles[i]) *det_spacing_x vectors_ROI[i,7] = np.sin(angles[i])*det_spacing_x vectors_ROI[i,8] = 0 # vector from detector pixel (0,0) to (1,0) vectors_ROI[i,9] = 0 vectors_ROI[i,10] = 0 vectors_ROI[i,11] = det_spacing_y #ROI=cube[:,:,z_sub_boundaries[n_z,0]:z_sub_boundaries[n_z+1,0]] # mlab.figure() # mlab.contour3d(ROI) width_z=z_sub_boundaries[n_z+1,2]-z_sub_boundaries[n_z,1] width_y=y_sub_boundaries[n_y+1,2]-y_sub_boundaries[n_y,1] width_x=x_sub_boundaries[n_x+1,2]-x_sub_boundaries[n_x,1] vol_geom_ROI= astra.create_vol_geom(width_y.astype(int), width_z.astype(int), width_x.astype(int)) proj_geom_ROI = astra.create_proj_geom('cone_vec', det_row_count, det_col_count, vectors_ROI) if algon[0:4] != 'EGEN': # Create a data object for the reconstruction rec_id_ROI = astra.data3d.create('-vol', vol_geom_ROI) sinogram_id_ROI = astra.data3d.create('-proj3d', proj_geom_ROI, pro_proj) if algon=='SIRT': algon='SIRT3D_CUDA' elif algon=='CGLS': algon='CGLS3D_CUDA' # Set up the parameters for a reconstruction algorithm using the GPU cfg = astra.astra_dict(algon) cfg['ReconstructionDataId'] = rec_id_ROI cfg['ProjectionDataId'] = sinogram_id_ROI cfg['option']={} cfg['option']['MinConstraint'] = 0 #attenuation coefficient can't be negative #cfg['option']['VoxelSuperSampling'] = np.round(float(det_spacing_x)/vol_size,decimals=2) alg_id = astra.algorithm.create(cfg) print "startar algo" if algon == 'SIRT3D_CUDA' or algon=='CGLS3D_CUDA': astra.algorithm.run(alg_id,nr_iterations_high) elif algon=='EGEN_SART': rec_volume=(width_x.astype(int), width_y.astype(int), width_z.astype(int)) rec_volume=np.zeros(rec_volume,dtype= np.float16) sides=[rec_volume.shape[0],rec_volume.shape[1],rec_volume.shape[2]] max_side=np.max(sides) print max_side h=relaxation*float(1)/(max_side)#0.00001 change to max size of y o z vectors=np.matrix('0 0 0 0 0 0 0 0 0 0 0 0',dtype= np.float16) for ii in range(0,nr_iterations_high): angles_ind = np.linspace(0, len(angles), len(angles),False) np.random.shuffle(angles_ind) #shuffle the projection angles to get faster convergence for jj in angles_ind: #proj_geom = astra.create_proj_geom('cone', det_spacing, det_spacing, det_size[1], det_size[1], angles[jj], source_to_origin_pixels,origin_to_detector_pixels) vectors[:,:]=vectors_ROI[jj,:] proj_geom_SART = astra.create_proj_geom('cone_vec', det_row_count, det_col_count, vectors) sinogram_id, proj_it = astra.create_sino3d_gpu(rec_volume, proj_geom_SART,vol_geom_ROI) proj_it=proj_it[:,0,:] residual=np.zeros((det_row_count,1,det_col_count)) residual[:,0,:]=proj_it-pro_proj[:,jj,:] astra.data3d.store(sinogram_id, residual) #h=0.001 [id, rec_volume_it] = astra.create_backprojection3d_gpu(residual, proj_geom_SART, vol_geom_ROI) rec_volume= rec_volume -h*rec_volume_it rec_volume=rec_volume*(rec_volume>0) astra.data3d.delete(id) astra.data3d.delete(sinogram_id) else: print"algorithm is not supported" print "s**t algo" if algon[0:4] != 'EGEN': # Get the result rec_sub_vol=astra.data3d.get(rec_id_ROI) # Clean up. Note that GPU memory is tied up in the algorithm object, # and main RAM in the data objects. astra.algorithm.delete(alg_id) astra.data3d.delete(rec_id_ROI) astra.data3d.delete(sinogram_id_ROI) return rec_sub_vol else: return rec_volume
def make_reconsruction(proj_data,number_of_projections,vol_size_ratio,det_size,rec_volume,source_to_origin_pixels,origin_to_detector_pixels,nr_iterations,algo,relaxation,initializer): vol_geom = astra.create_vol_geom(rec_volume) angles = np.linspace(0, 2*np.pi, number_of_projections, False) det_spacing=np.round((float(det_size[0])/det_size[1])/vol_size_ratio,decimals=3) proj_geom = astra.create_proj_geom('cone', det_spacing, det_spacing, det_size[1], det_size[1], angles, source_to_origin_pixels,origin_to_detector_pixels) #np.round(float(rec_volume[0])/new_size[0],decimals=2) if algo[0:4] != 'EGEN': # Create projection data from this proj_id=4 # Create a data object for the reconstruction rec_id = astra.data3d.create('-vol', vol_geom,initializer) sinogram_id = astra.data3d.create('-proj3d', proj_geom, proj_data) #Set up the parameters for a reconstruction algorithm using the GPU cfg = astra.astra_dict(algo) cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = sinogram_id cfg['option']={} cfg['option']['MinConstraint'] = 0 #attenuation coefficient can't be negative # Create the algorithm object from the configuration structure alg_id = astra.algorithm.create(cfg) print "startar algo" if algo == 'SIRT3D_CUDA' or algo=='CGLS3D_CUDA': astra.algorithm.run(alg_id,nr_iterations) elif algo=='FDK_CUDA': astra.algorithm.run(alg_id) elif algo=='EGEN_SIRT': if isinstance( initializer, ( int, long ) ): rec_volume=np.zeros(rec_volume,dtype= np.float16) else: rec_volume=initializer for ii in range(0,nr_iterations): sinogram_id, proj_it = astra.create_sino3d_gpu(rec_volume, proj_geom,vol_geom) residual=proj_it-proj_data h=relaxation*float(1)/(rec_volume.shape[0]*number_of_projections) [id, rec_volume_it] = astra.create_backprojection3d_gpu(residual, proj_geom, vol_geom) rec_volume= rec_volume -h*rec_volume_it rec_volume=rec_volume*(rec_volume>0) astra.data3d.delete(id) astra.data3d.delete(sinogram_id) elif algo=='EGEN_SART': if isinstance( initializer, ( int, long ) ): rec_volume=np.zeros(rec_volume,dtype= np.float16) else: rec_volume=initializer #print rec_volume.shape[0] for ii in range(0,nr_iterations): angles_ind = np.linspace(0, number_of_projections, number_of_projections,False) np.random.shuffle(angles_ind) for jj in angles_ind: proj_geom = astra.create_proj_geom('cone', det_spacing, det_spacing, det_size[1], det_size[1], angles[jj], source_to_origin_pixels,origin_to_detector_pixels) #print np.min(sub_volume_high) sinogram_id, proj_it = astra.create_sino3d_gpu(rec_volume, proj_geom,vol_geom) proj_it=proj_it[:,0,:] residual=np.zeros((det_size[1],1,det_size[1])) residual[:,0,:]=proj_it-proj_data[:,jj,:] #print np.shape(proj_it),np.shape(residual),np.shape(proj_data[:,jj,:]) #astra.data3d.store(sinogram_id, residual) h=relaxation*float(1)/(rec_volume.shape[0])#0.00001 [id, rec_volume_it] = astra.create_backprojection3d_gpu(residual, proj_geom, vol_geom) rec_volume= rec_volume -h*rec_volume_it rec_volume=rec_volume*(rec_volume>0) astra.data3d.delete(id) astra.data3d.delete(sinogram_id) # pylab.figure() # pylab.gray() # pylab.imshow(rec_volume[:,:,128]) else: print"algorithm is not supported" print "s**t algo" if algo[0:4] != 'EGEN': # Get the result rec = astra.data3d.get(rec_id) # Clean up. Note that GPU memory is tied up in the algorithm object, # and main RAM in the data objects. astra.algorithm.delete(alg_id) astra.data3d.delete(rec_id) astra.data3d.delete(proj_id) astra.data3d.delete(sinogram_id) return rec else: return rec_volume