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)
def do_AGD(meta, vecs, sc, g, niter): start = time.time() ang, u, v = g.shape g_vec = np.transpose(g.copy(), (2, 0, 1)) vox = 1024 // sc pix_size = meta['pix_size'] * sc src_rad = meta['s2o'] det_rad = meta['o2d'] magn = src_rad / (src_rad + det_rad) bounds = vox * pix_size * magn / 2 vol_geom = astra.create_vol_geom(vox, vox, vox, -bounds, bounds, -bounds, bounds, -bounds, bounds) proj_geom = astra.create_proj_geom('cone_vec', v, u, vecs) rec = np.zeros(astra.geom_size(vol_geom), dtype=np.float32) rec_id = astra.data3d.link('-vol', vol_geom, rec) # %% projector_id = astra.create_projector('cuda3d', proj_geom, vol_geom) # rec_id = astra.data3d.create('-vol', vol_geom) proj_id = astra.data3d.create('-proj3d', proj_geom, g_vec) astra.plugin.register(NesterovGradient.AcceleratedGradientPlugin) cfg_agd = astra.astra_dict('AGD-PLUGIN') cfg_agd['ProjectionDataId'] = proj_id cfg_agd['ReconstructionDataId'] = rec_id cfg_agd['ProjectorId'] = projector_id cfg_agd['option'] = {} cfg_agd['option']['MinConstraint'] = 0 alg_id = astra.algorithm.create(cfg_agd) # Run Nesterov Accelerated Gradient Descent algorithm with 'nb_iter' iterations astra.algorithm.run(alg_id, niter) rec = np.transpose(rec, (2, 1, 0)) # %% pylab.figure() pylab.imshow(rec[vox // 2, :, :]) pylab.figure() pylab.imshow(rec[:, vox // 2, :]) pylab.figure() pylab.imshow(rec[:, :, vox // 2]) # release memory allocated by ASTRA structures astra.algorithm.delete(alg_id) astra.data3d.delete(proj_id) astra.data3d.delete(rec_id) print((time.time() - start), 'Finished AGD 50 reconstructionn') return rec
def FDK_astra(g, filt, geom, reco_space, ang_freq=None): # %% Create geometry # Make a circular scanning geometry ang, u, v = g.shape minvox = reco_space.min_pt[0] maxvox = reco_space.max_pt[0] vol_geom = astra.create_vol_geom(v, v, v, minvox, maxvox, minvox, maxvox, minvox, maxvox) w_du, w_dv = (geom.detector.partition.max_pt \ -geom.detector.partition.min_pt) / np.array([u,v]) if ang_freq is not None: angles = np.linspace(np.pi / 500, (2 + 1 / 500) * np.pi, 500, False)[::ang_freq] else: angles = np.linspace(np.pi / ang, (2 + 1 / ang) * np.pi, ang, False) proj_geom = astra.create_proj_geom('cone', w_du, w_dv, v, u, angles, geom.src_radius, geom.det_radius) g = np.transpose(np.asarray(g.copy()), (2, 0, 1)) # %% # Create a data object for the reconstruction rec = np.zeros(astra.geom_size(vol_geom), dtype=np.float32) rec_id = astra.data3d.link('-vol', vol_geom, rec) # rec_id = astra.data3d.create('-vol', vol_geom) proj_id = astra.data3d.create('-proj3d', proj_geom, g) # rec_id = astra.data3d.link('-vol', vol_geom, rec) fullFilterSize = int(2**(np.ceil(np.log2(2 * u)))) halfFilterSize = fullFilterSize // 2 + 1 # %% Make the matrix columns of the matrix B filter2d = np.zeros((ang, halfFilterSize)) for i in range(ang): filter2d[i, :] = filt * 4 * w_du # %% Make a filter geometry filter_geom = astra.create_proj_geom('parallel', w_du, halfFilterSize, angles) filter_id = astra.data2d.create('-sino', filter_geom, filter2d) # cfg = astra.astra_dict('FDK_CUDA') cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = proj_id cfg['option'] = {'FilterSinogramId': filter_id} # Create the algorithm object from the configuration structure alg_id = astra.algorithm.create(cfg) # %% astra.algorithm.run(alg_id) rec = np.transpose(rec, (2, 1, 0)) # %% # 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.data2d.delete(filter_id) return rec
def NNFDK_astra(g, NW, geom, reco_space, w_du, Exp_op, node_output, ang_freq=None): # %% Create geometry # Make a circular scanning geometry ang, u, v = g.shape minvox = reco_space.min_pt[0] maxvox = reco_space.max_pt[0] vox = np.shape(reco_space)[0] vol_geom = astra.create_vol_geom(vox, vox, vox, minvox, maxvox, minvox, maxvox, minvox, maxvox) if type(geom) == np.ndarray: vecs = geom proj_geom = astra.create_proj_geom('cone_vec', v, u, vecs) elif type(geom) == odl.tomo.geometry.conebeam.ConeFlatGeometry: angles = np.linspace((1 / ang) * np.pi, (2 + 1 / ang) * np.pi, ang, False) w_du, w_dv = 2 * geom.detector.partition.max_pt / [u, v] proj_geom = astra.create_proj_geom('cone', w_dv, w_du, v, u, angles, geom.src_radius, geom.det_radius) g = np.transpose(np.asarray(g), (2, 0, 1)) # %% proj_id = astra.data3d.create('-proj3d', proj_geom, g) rec = np.zeros(astra.geom_size(vol_geom), dtype=np.float32) rec_tot = np.zeros(astra.geom_size(vol_geom), dtype=np.float32) rec_id = astra.data3d.link('-vol', vol_geom, rec) fullFilterSize = int(2**(np.ceil(np.log2(u)) + 1)) halfFilterSize = fullFilterSize // 2 + 1 filter2d = np.zeros((ang, halfFilterSize)) Resize_Op = odl.ResizingOperator(Exp_op.range, ran_shp=(fullFilterSize, )) # %% Make a filter geometry filter_geom = astra.create_proj_geom('parallel', w_du, halfFilterSize, np.zeros(ang)) cfg = astra.astra_dict('FDK_CUDA') cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = proj_id # Create the algorithm object from the configuration structure # %% # Set a container list for the learned filters h_e = [] if node_output: mid = v // 2 node_output_axis = [] for i in range(NW['nNodes']): h = NW['l1'][:-1, i] * 2 * NW['sc1'][0, :] h_e += [h] b = NW['l1'][-1, i] + np.sum( NW['l1'][:-1, i]) + 2 * np.dot(NW['l1'][:-1, i], NW['sc1'][1, :]) filter2d = Exp_op_FFT(Exp_op, h, filter2d, Resize_Op, w_du) filter_id = astra.data2d.create('-sino', filter_geom, filter2d) cfg['option'] = {'FilterSinogramId': filter_id} alg_id = astra.algorithm.create(cfg) astra.algorithm.run(alg_id) rec_tot = hidden_layer(rec, rec_tot, NW['l2'][i], b) if node_output: rec2 = hidden_layer(rec, 0, NW['l2'][i], b) node_output_axis += [ rec2[:, :, mid], rec2[:, mid, :], rec2[mid, :, :] ] # Make a numpy array of the filter list h_e = np.asarray(h_e) # b_o = self.network['l2'][-1] rec_tot = outer_layer(rec_tot, NW['l2'][-1], NW['sc2'][0], NW['sc2'][1]) rec_tot = np.transpose(rec_tot, (2, 1, 0)) # %% Make the matrix columns of the matrix B # %% # 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) if node_output: return rec_tot, h_e, node_output_axis else: return rec_tot, h_e
def FDK_astra(g, filt, geom, reco_space, w_du, ang_freq=None, ang_offset=0): # %% Create geometry # Make a circular scanning geometry ang, u, v = g.shape minvox = reco_space.min_pt[0] maxvox = reco_space.max_pt[0] vox = np.shape(reco_space)[0] vol_geom = astra.create_vol_geom(vox, vox, vox, minvox, maxvox, minvox, maxvox, minvox, maxvox) # Build the projection geometry, through vecs or odl geometry if type(geom) == np.ndarray: vecs = geom proj_geom = astra.create_proj_geom('cone_vec', v, u, vecs) elif type(geom) == odl.tomo.geometry.conebeam.ConeFlatGeometry: angles = np.linspace((1 / ang) * np.pi + ang_offset, (2 + 1 / ang) * np.pi + ang_offset, ang, False) w_du, w_dv = 2 * geom.detector.partition.max_pt / [u, v] proj_geom = astra.create_proj_geom('cone', w_dv, w_du, v, u, angles, geom.src_radius, geom.det_radius) elif geom == 'xHQ': ang = 1000 src_rad = 100 det_rad = 0 angles = np.linspace((1 / ang) * np.pi, (2 + 1 / ang) * np.pi, ang, False) # angles = np.linspace(0, (2) * np.pi, ang, # False) obj_size = 2 * reco_space.max_pt[0] w_du = 2 * obj_size / u w_dv = obj_size / v proj_geom = astra.create_proj_geom('cone', w_dv, w_du, v, u, angles, src_rad * obj_size, det_rad * obj_size) g = np.transpose(np.asarray(g.copy()), (2, 0, 1)) cfg = astra.astra_dict('FDK_CUDA') # %% # Create a data object for the reconstruction rec = np.zeros(astra.geom_size(vol_geom), dtype=np.float32) rec_id = astra.data3d.link('-vol', vol_geom, rec) # rec_id = astra.data3d.create('-vol', vol_geom) proj_id = astra.data3d.create('-proj3d', proj_geom, g) # rec_id = astra.data3d.link('-vol', vol_geom, rec) # if geom == 'xHQ': # cfg['option'] = { 'FilterType': 'hann' } # else: fullFilterSize = int(2**(np.ceil(np.log2(2 * u)))) halfFilterSize = fullFilterSize // 2 + 1 # %% Make the matrix columns of the matrix B filter2d = np.zeros((ang, halfFilterSize)) for i in range(ang): filter2d[i, :] = filt * 4 * w_du # %% Make a filter geometry filter_geom = astra.create_proj_geom('parallel', w_du, halfFilterSize, np.zeros((ang))) filter_id = astra.data2d.create('-sino', filter_geom, filter2d) cfg['option'] = {'FilterSinogramId': filter_id} cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = proj_id # Create the algorithm object from the configuration structure alg_id = astra.algorithm.create(cfg) # %% astra.algorithm.run(alg_id) rec = np.transpose(rec, (2, 1, 0)) # %% # 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) if geom == 'xHQ': pass else: astra.data2d.delete(filter_id) return rec
import astra import numpy as np import pygpu import pylab # Initialize pygpu ctx = pygpu.init('cuda') pygpu.set_default_context(ctx) vol_geom = astra.create_vol_geom(128, 128, 128) angles = np.linspace(0, 2 * np.pi, 180, False) proj_geom = astra.create_proj_geom('cone', 1.0, 1.0, 128, 192, angles, 1000, 0) # Create a simple hollow cube phantom, as a pygpu gpuarray vol_gpuarr = pygpu.gpuarray.zeros(astra.geom_size(vol_geom), dtype='float32') vol_gpuarr[17:113, 17:113, 17:113] = 1 vol_gpuarr[33:97, 33:97, 33:97] = 0 # Create a pygpu gpuarray for the output projection data proj_gpuarr = pygpu.gpuarray.zeros(astra.geom_size(proj_geom), dtype='float32') # Create the astra GPULink objects and create astra data3d objects from them z, y, x = proj_gpuarr.shape proj_data_link = astra.data3d.GPULink(proj_gpuarr.gpudata, x, y, z, proj_gpuarr.strides[-2]) z, y, x = vol_gpuarr.shape vol_link = astra.data3d.GPULink(vol_gpuarr.gpudata, x, y, z, vol_gpuarr.strides[-2]) proj_id = astra.data3d.link('-sino', proj_geom, proj_data_link)
def Create_dataset_ASTRA_sim(pix, phantom, angles, src_rad, noise, Exp_bin, bin_param, **kwargs): if phantom == 'Defrise': phantom = 'Defrise random' if phantom == 'Fourshape_test': phantom = 'Fourshape' if 'MaxVoxDataset' in kwargs: MaxVoxDataset = kwargs['MaxVoxDataset'] else: MaxVoxDataset = np.max([int(pix**3 * 0.005), 1 * 10**6]) # The size of the measured objects in voxels voxels = [pix, pix, pix] dpix = [voxels[0] * 2, voxels[1]] u, v = dpix # ! ! ! This will lead to some problems later on ! ! ! det_rad = 0 data_obj = ddf.phantom(voxels, phantom, angles, noise, src_rad, det_rad, compute_xHQ=True) WV_obj = ddf.support_functions.working_var_map() WV_path = WV_obj.WV_path data_obj.make_mask(WV_path) Smat = Make_Smat(voxels, MaxVoxDataset, WV_path) # %% saving tiffs for CNNs w_du = data_obj.w_detu filt = make_hann_filt(voxels, w_du) xFDK = ddf.FDK_ODL_astra_backend.FDK_astra(data_obj.g, filt, data_obj.geometry, data_obj.reco_space, None) # %% Create geometry # Make a circular scanning geometry minvox = data_obj.reco_space.min_pt[0] maxvox = data_obj.reco_space.max_pt[0] vox = np.shape(data_obj.reco_space)[0] vol_geom = astra.create_vol_geom(vox, vox, vox, minvox, maxvox, minvox, maxvox, minvox, maxvox) ang = np.linspace((1 / angles) * np.pi, (2 + 1 / angles) * np.pi, angles, False) w_du, w_dv = 2 * data_obj.geometry.detector.partition.max_pt / [u, v] proj_geom = astra.create_proj_geom('cone', w_dv, w_du, v, u, ang, data_obj.geometry.src_radius, data_obj.geometry.det_radius) filter_part = odl.uniform_partition(-data_obj.detecsize[0], data_obj.detecsize[0], u) filter_space = odl.uniform_discr_frompartition(filter_part, dtype='float64') spf_space, Exp_op = ddf.support_functions.ExpOp_builder(bin_param, filter_space, interp=Exp_bin) nParam = np.size(spf_space) fullFilterSize = int(2**(np.ceil(np.log2(dpix[0])) + 1)) halfFilterSize = fullFilterSize // 2 + 1 Resize_Op = odl.ResizingOperator(Exp_op.range, ran_shp=(fullFilterSize, )) # %% Create forward and backward projector # project_id = astra.create_projector('cuda3d', proj_geom, vol_geom) # W = astra.OpTomo(project_id) # %% Create data proj_data = np.transpose(np.asarray(data_obj.g), (2, 0, 1)).copy() # W.FP(np.transpose(np.asarray(data_obj.f), (2, 1, 0))) # ! ! ! wat is deze? ! ! ! # if noise is not None: # g = add_poisson_noise(proj_data, noise[1]) # else: g = proj_data proj_id = astra.data3d.link('-sino', proj_geom, g) rec = np.zeros(astra.geom_size(vol_geom), dtype=np.float32) rec_id = astra.data3d.link('-vol', vol_geom, rec) B = np.zeros((MaxVoxDataset, nParam + 1)) # %% Make the matrix columns of the matrix B for nP in range(nParam): unit_vec = spf_space.zero() unit_vec[nP] = 1 filt = Exp_op(unit_vec) rs_filt = Resize_Op(filt) f_filt = np.real(np.fft.rfft(np.fft.ifftshift(rs_filt))) filter2d = np.zeros((angles, halfFilterSize)) for i in range(angles): filter2d[i, :] = f_filt * 4 * w_du # %% Make a filter geometry filter_geom = astra.create_proj_geom('parallel', w_du, halfFilterSize, np.zeros((angles))) filter_id = astra.data2d.create('-sino', filter_geom, filter2d) # cfg = astra.astra_dict('FDK_CUDA') cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = proj_id cfg['option'] = {'FilterSinogramId': filter_id} # Create the algorithm object from the configuration structure alg_id = astra.algorithm.create(cfg) # %% astra.algorithm.run(alg_id) rec = np.transpose(rec, (2, 1, 0)) B[:, nP] = rec[Smat] # %% # Clean up. Note that GPU memory is tied up in the algorithm object, # and main RAM in the data objects. B[:, -1] = data_obj.xHQ[Smat] # B[:, -1] = data_obj.f[Smat] astra.algorithm.delete(alg_id) astra.data3d.delete(rec_id) astra.data3d.delete(proj_id) return B, data_obj.xHQ, xFDK
def Create_dataset_ASTRA_real(dataset, pix_size, src_rad, det_rad, ang_freq, Exp_bin, bin_param, vox=None, vecs=None): # ! ! ! We overide 'vox' and 'vecs' later on # The size of the measured objects in voxels data_obj = ddf.real_data(dataset, pix_size, src_rad, det_rad, ang_freq, vox=vox, vecs=vecs) g = np.ascontiguousarray(np.transpose(np.asarray(data_obj.g.copy()), (2, 0, 1)), dtype=np.float32) v, ang, u = g.shape if vox is None: voxels = data_obj.voxels else: voxels = [vox, vox, vox] MaxVoxDataset = np.max([int(voxels[0]**3 * 0.005), 5 * 10**6]) Smat = Make_Smat(voxels, MaxVoxDataset, '', real_data=dataset['mask']) # %% Create geometry geom = data_obj.geometry w_du = data_obj.pix_size dpix = [u, v] minvox = data_obj.reco_space.min_pt[0] maxvox = data_obj.reco_space.max_pt[0] vox = np.shape(data_obj.reco_space)[0] vol_geom = astra.create_vol_geom(vox, vox, vox, minvox, maxvox, minvox, maxvox, minvox, maxvox) # Build a vecs vector from the geometry, or load it if type(geom) == np.ndarray: vecs = geom proj_geom = astra.create_proj_geom('cone_vec', v, u, vecs) elif type(geom) == odl.tomo.geometry.conebeam.ConeFlatGeometry: angles = np.linspace((1 / ang) * np.pi, (2 + 1 / ang) * np.pi, ang, False) w_du, w_dv = 2 * data_obj.geometry.detector.partition.max_pt / [u, v] proj_geom = astra.create_proj_geom('cone', w_dv, w_du, v, u, angles, data_obj.geometry.src_radius, data_obj.geometry.det_radius) filter_part = odl.uniform_partition(-data_obj.detecsize[0], data_obj.detecsize[0], dpix[0]) filter_space = odl.uniform_discr_frompartition(filter_part, dtype='float64') spf_space, Exp_op = ddf.ExpOp_builder(bin_param, filter_space, interp=Exp_bin) nParam = np.size(spf_space) fullFilterSize = int(2**(np.ceil(np.log2(dpix[0])) + 1)) halfFilterSize = fullFilterSize // 2 + 1 Resize_Op = odl.ResizingOperator(Exp_op.range, ran_shp=(fullFilterSize, )) # %% Create projection and reconstion objects proj_id = astra.data3d.link('-proj3d', proj_geom, g) rec = np.zeros(astra.geom_size(vol_geom), dtype=np.float32) rec_id = astra.data3d.link('-vol', vol_geom, rec) B = np.zeros((MaxVoxDataset, nParam + 1)) # %% Make the matrix columns of the matrix B for nP in range(nParam): unit_vec = spf_space.zero() unit_vec[nP] = 1 filt = Exp_op(unit_vec) rs_filt = Resize_Op(filt) f_filt = np.real(np.fft.rfft(np.fft.ifftshift(rs_filt))) filter2d = np.zeros((ang, halfFilterSize)) for i in range(ang): filter2d[i, :] = f_filt * 4 * w_du # %% Make a filter geometry filter_geom = astra.create_proj_geom('parallel', w_du, halfFilterSize, np.zeros(ang)) filter_id = astra.data2d.create('-sino', filter_geom, filter2d) # cfg = astra.astra_dict('FDK_CUDA') cfg['ReconstructionDataId'] = rec_id cfg['ProjectionDataId'] = proj_id cfg['option'] = {'FilterSinogramId': filter_id} # Create the algorithm object from the configuration structure alg_id = astra.algorithm.create(cfg) # %% astra.algorithm.run(alg_id) rec = np.transpose(rec, (2, 1, 0)) B[:, nP] = rec[Smat] # %% # Clean up. Note that GPU memory is tied up in the algorithm object, # and main RAM in the data objects. B[:, -1] = data_obj.f[Smat] astra.algorithm.delete(alg_id) astra.data3d.delete(rec_id) astra.data3d.delete(proj_id) return B