def __init__(self, data_obj, data_struct=True, **kwargs): # %% Store the input in the object # BE F*****G CONSISTENT WITH RENAMING ETC. self.pix = data_obj.voxels[0] self.angles = data_obj.angles self.src_rad = data_obj.src_rad self.det_rad = data_obj.det_rad self.magn = self.src_rad / (self.src_rad + self.det_rad) self.data_struct = data_struct self.rec_methods = [] # %% Set up the geometry self.phantom = data_obj # Make the reconstruction space self.reco_space = self.phantom.reco_space voxels = self.phantom.voxels factor = 2 dpix = [int(factor * voxels[0]), voxels[1]] self.w_detu = (2 * self.phantom.detecsize[0]) / dpix[0] self.w_detv = (2 * self.phantom.detecsize[1]) / dpix[1] if self.phantom.data_type == 'simulated': self.PH = data_obj.PH self.noise = data_obj.noise # Do we need a mask? src_radius = self.src_rad * self.phantom.volumesize[0] * 2 det_radius = self.det_rad * self.phantom.volumesize[0] * 2 # Make a circular scanning geometry angle_partition = odl.uniform_partition(0, 2 * np.pi, self.angles) self.angle_space = odl.uniform_discr_frompartition(angle_partition) # Make a flat detector space det_partition = odl.uniform_partition(-self.phantom.detecsize, self.phantom.detecsize, dpix) self.det_space = odl.uniform_discr_frompartition(det_partition, dtype='float32') # Create geometry self.geometry = odl.tomo.ConeFlatGeometry(angle_partition, det_partition, src_radius=src_radius, det_radius=det_radius, axis=[0, 0, 1]) else: src_radius = self.phantom.src_rad det_radius = self.phantom.det_rad self.pix_size = self.phantom.pix_size self.angle_space = self.phantom.angle_space self.angles = np.size(self.angle_space) self.det_space = self.phantom.det_space self.geometry = self.phantom.geometry # %% Create the FP and BP and the data # Forward Projection self.FwP = odl.tomo.RayTransform(self.reco_space, self.geometry, use_cache=False) self.rs_detu = int(2**(np.ceil(np.log2(dpix[0])) + 1)) self.g = self.phantom.g
def test_astra_cpu_projector_fanflat(): """ASTRA CPU forward and back projection for fanflat geometry.""" # Create reco space and a phantom reco_space = odl.uniform_discr([-4, -5], [4, 5], (4, 5), dtype='float32') phantom = odl.phantom.cuboid(reco_space, min_pt=[0, 0], max_pt=[4, 5]) # Create fan beam geometry with flat detector angle_part = odl.uniform_partition(0, 2 * np.pi, 8) det_part = odl.uniform_partition(-6, 6, 6) src_rad = 100 det_rad = 10 geom = odl.tomo.FanFlatGeometry(angle_part, det_part, src_rad, det_rad) # Make projection space proj_space = odl.uniform_discr_frompartition(geom.partition, dtype='float32') # Forward evaluation proj_data = astra_cpu_forward_projector(phantom, geom, proj_space) assert proj_data.shape == proj_space.shape assert proj_data.norm() > 0 # Backward evaluation backproj = astra_cpu_back_projector(proj_data, geom, reco_space) assert backproj.shape == reco_space.shape assert backproj.norm() > 0
def test_astra_cpu_projector_parallel2d(): """ASTRA CPU forward and back projection for 2d parallel geometry.""" # Create reco space and a phantom reco_space = odl.uniform_discr([-4, -5], [4, 5], (4, 5), dtype='float32') phantom = odl.phantom.cuboid(reco_space, min_pt=[0, 0], max_pt=[4, 5]) # Create parallel geometry angle_part = odl.uniform_partition(0, 2 * np.pi, 8) det_part = odl.uniform_partition(-6, 6, 6) geom = odl.tomo.Parallel2dGeometry(angle_part, det_part) # Make projection space proj_space = odl.uniform_discr_frompartition(geom.partition, dtype='float32') # Forward evaluation proj_data = astra_cpu_forward_projector(phantom, geom, proj_space) assert proj_data.shape == proj_space.shape assert proj_data.norm() > 0 # Backward evaluation backproj = astra_cpu_back_projector(proj_data, geom, reco_space) assert backproj.shape == reco_space.shape assert backproj.norm() > 0
def test_scikit_radon_projector_parallel2d(): """Parallel 2D forward and backward projectors on the GPU.""" # Create reco space and a phantom reco_space = odl.uniform_discr([-5, -5], [5, 5], (5, 5), dtype='float32') phantom = odl.phantom.cuboid(reco_space, begin=[0, 0], end=[5, 5]) # Create parallel geometry angle_part = odl.uniform_partition(0, 2 * np.pi, 8) det_part = odl.uniform_partition(-6, 6, 6) geom = odl.tomo.Parallel2dGeometry(angle_part, det_part) # Make projection space proj_space = odl.uniform_discr_frompartition(geom.partition, dtype='float32') # Forward evaluation proj_data = scikit_radon_forward(phantom, geom, proj_space) assert proj_data.shape == proj_space.shape assert proj_data.norm() > 0 # Backward evaluation backproj = scikit_radon_back_projector(proj_data, geom, reco_space) assert backproj.shape == reco_space.shape assert backproj.norm() > 0
def test_astra_cuda_projector_parallel3d(): """Test 3D forward and backward projection functions on the GPU.""" # Create reco space and a phantom reco_space = odl.uniform_discr([-4, -5, -6], [4, 5, 6], (4, 5, 6), dtype='float32') phantom = odl.phantom.cuboid(reco_space, begin=[0, 0, 0], end=[4, 5, 6]) # Create parallel geometry angle_part = odl.uniform_partition(0, 2 * np.pi, 8) det_part = odl.uniform_partition([-7, -8], [7, 8], (7, 8)) geom = odl.tomo.Parallel3dAxisGeometry(angle_part, det_part) # Make projection space proj_space = odl.uniform_discr_frompartition(geom.partition, dtype='float32') # Forward evaluation proj_data = astra_cuda_forward_projector(phantom, geom, proj_space) assert proj_data.shape == proj_space.shape assert proj_data.norm() > 0 # Backward evaluation backproj = astra_cuda_back_projector(proj_data, geom, reco_space) assert backproj.shape == reco_space.shape assert backproj.norm() > 0
def test_astra_cuda_projector(space_and_geometry, use_cache): """Test ASTRA CUDA projector.""" # Create reco space and a phantom reco_space, geom = space_and_geometry phantom = odl.phantom.cuboid(reco_space) # Make projection space proj_space = odl.uniform_discr_frompartition(geom.partition, dtype=reco_space.dtype) # Forward evaluation projector = AstraCudaProjectorImpl(geom, reco_space, proj_space, use_cache=use_cache) proj_data = projector.call_forward(phantom) assert proj_data in proj_space assert proj_data.norm() > 0 assert np.all(proj_data.asarray() >= 0) # Backward evaluation back_projector = AstraCudaBackProjectorImpl(geom, reco_space, proj_space, use_cache=use_cache) backproj = back_projector.call_backward(proj_data) assert backproj in reco_space assert backproj.norm() > 0 assert np.all(proj_data.asarray() >= 0)
def test_scikit_radon_projector_parallel2d(): """Parallel 2D forward and backward projectors on the GPU.""" # Create reco space and a phantom reco_space = odl.uniform_discr([-5, -5], [5, 5], (5, 5), dtype='float32') phantom = odl.util.phantom.cuboid(reco_space, begin=0.5, end=1) # Create parallel geometry angle_part = odl.uniform_partition(0, 2 * np.pi, 8) det_part = odl.uniform_partition(-6, 6, 6) geom = odl.tomo.Parallel2dGeometry(angle_part, det_part) # Make projection space proj_space = odl.uniform_discr_frompartition(geom.partition, dtype='float32') # Forward evaluation proj_data = scikit_radon_forward(phantom, geom, proj_space) assert proj_data.shape == proj_space.shape assert proj_data.norm() > 0 # Backward evaluation backproj = scikit_radon_back_projector(proj_data, geom, reco_space) assert backproj.shape == reco_space.shape assert backproj.norm() > 0
def test_astra_cuda_projector_parallel3d(): """Test 3D forward and backward projection functions on the GPU.""" # Create reco space and a phantom reco_space = odl.uniform_discr([-4, -5, -6], [4, 5, 6], (4, 5, 6), dtype='float32') phantom = odl.phantom.cuboid(reco_space, min_pt=[0, 0, 0], max_pt=[4, 5, 6]) # Create parallel geometry angle_part = odl.uniform_partition(0, np.pi, 8) det_part = odl.uniform_partition([-7, -8], [7, 8], (7, 8)) geom = odl.tomo.Parallel3dAxisGeometry(angle_part, det_part) # Make projection space proj_space = odl.uniform_discr_frompartition(geom.partition, dtype='float32') # Forward evaluation proj_data = astra_cuda_forward_projector(phantom, geom, proj_space) assert proj_data.shape == proj_space.shape assert proj_data.norm() > 0 # Backward evaluation backproj = astra_cuda_back_projector(proj_data, geom, reco_space) assert backproj.shape == reco_space.shape assert backproj.norm() > 0
def test_astra_cuda_projector_helical_conebeam(): """Test 3D forward and backward projection functions on the GPU.""" # Create reco space and a phantom reco_space = odl.uniform_discr([-4, -5, -6], [4, 5, 6], (4, 5, 6), dtype='float32') phantom = odl.phantom.cuboid(reco_space, min_pt=[0, 0, 0], max_pt=[4, 5, 6]) # Create circular cone beam geometry with flat detector angle_part = odl.uniform_partition(0, 2 * np.pi, 8) det_part = odl.uniform_partition([-7, -8], [7, 8], (7, 8)) src_rad = 1000 det_rad = 100 pitch = 0.5 geom = odl.tomo.HelicalConeFlatGeometry(angle_part, det_part, src_rad, det_rad, pitch) # Make projection space proj_space = odl.uniform_discr_frompartition(geom.partition, dtype='float32') # Forward evaluation proj_data = astra_cuda_forward_projector(phantom, geom, proj_space) assert proj_data.shape == proj_space.shape assert proj_data.norm() > 0 # Backward evaluation backproj = astra_cuda_back_projector(proj_data, geom, reco_space) assert backproj.shape == reco_space.shape assert backproj.norm() > 0
def test_astra_cpu_projector_parallel2d(): """ASTRA CPU forward and back projection for 2d parallel geometry.""" # Create reco space and a phantom reco_space = odl.uniform_discr([-4, -5], [4, 5], (4, 5), dtype='float32') phantom = odl.phantom.cuboid(reco_space, begin=[0, 0], end=[4, 5]) # Create parallel geometry angle_part = odl.uniform_partition(0, 2 * np.pi, 8) det_part = odl.uniform_partition(-6, 6, 6) geom = odl.tomo.Parallel2dGeometry(angle_part, det_part) # Make projection space proj_space = odl.uniform_discr_frompartition(geom.partition, dtype='float32') # Forward evaluation proj_data = astra_cpu_forward_projector(phantom, geom, proj_space) assert proj_data.shape == proj_space.shape assert proj_data.norm() > 0 # Backward evaluation backproj = astra_cpu_back_projector(proj_data, geom, reco_space) assert backproj.shape == reco_space.shape assert backproj.norm() > 0
def test_astra_cpu_projector_fanflat(): """ASTRA CPU forward and back projection for fanflat geometry.""" # Create reco space and a phantom reco_space = odl.uniform_discr([-4, -5], [4, 5], (4, 5), dtype='float32') phantom = odl.phantom.cuboid(reco_space, begin=[0, 0], end=[4, 5]) # Create fan beam geometry with flat detector angle_part = odl.uniform_partition(0, 2 * np.pi, 8) det_part = odl.uniform_partition(-6, 6, 6) src_rad = 100 det_rad = 10 geom = odl.tomo.FanFlatGeometry(angle_part, det_part, src_rad, det_rad) # Make projection space proj_space = odl.uniform_discr_frompartition(geom.partition, dtype='float32') # Forward evaluation proj_data = astra_cpu_forward_projector(phantom, geom, proj_space) assert proj_data.shape == proj_space.shape assert proj_data.norm() > 0 # Backward evaluation backproj = astra_cpu_back_projector(proj_data, geom, reco_space) assert backproj.shape == reco_space.shape assert backproj.norm() > 0
def test_astra_cuda_projector_helical_conebeam(): """Test 3D forward and backward projection functions on the GPU.""" # Create reco space and a phantom reco_space = odl.uniform_discr([-4, -5, -6], [4, 5, 6], (4, 5, 6), dtype='float32') phantom = odl.phantom.cuboid(reco_space, begin=[0, 0, 0], end=[4, 5, 6]) # Create circular cone beam geometry with flat detector angle_part = odl.uniform_partition(0, 2 * np.pi, 8) det_part = odl.uniform_partition([-7, -8], [7, 8], (7, 8)) src_rad = 1000 det_rad = 100 pitch = 0.5 geom = odl.tomo.HelicalConeFlatGeometry(angle_part, det_part, src_rad, det_rad, pitch) # Make projection space proj_space = odl.uniform_discr_frompartition(geom.partition, dtype='float32') # Forward evaluation proj_data = astra_cuda_forward_projector(phantom, geom, proj_space) assert proj_data.shape == proj_space.shape assert proj_data.norm() > 0 # Backward evaluation backproj = astra_cuda_back_projector(proj_data, geom, reco_space) assert backproj.shape == reco_space.shape assert backproj.norm() > 0
def test_astra_cuda_projector(space_and_geometry): """Test ASTRA CUDA projector.""" # Create reco space and a phantom vol_space, geom = space_and_geometry phantom = odl.phantom.cuboid(vol_space) # Make projection space proj_space = odl.uniform_discr_frompartition(geom.partition, dtype=vol_space.dtype) # create RayTransform implementation astra_cuda = AstraCudaImpl(geom, vol_space, proj_space) # Forward evaluation proj_data = astra_cuda.call_forward(phantom) assert proj_data in proj_space assert proj_data.norm() > 0 assert np.all(proj_data.asarray() >= 0) # Backward evaluation backproj = astra_cuda.call_backward(proj_data) assert backproj in vol_space assert backproj.norm() > 0 assert np.all(proj_data.asarray() >= 0)
def fan_to_fan_flat(geometry, data): tmp_space = odl.uniform_discr_frompartition(geometry.partition, interp='linear') rot_angles = tmp_space.meshgrid[0] fan_angles = tmp_space.meshgrid[1] data = tmp_space.element(data) source_to_detector = geometry.src_radius + geometry.det_radius fan_dist = source_to_detector * np.arctan(fan_angles / source_to_detector) data = data.interpolation((rot_angles, fan_dist), bounds_check=False) data = data[::-1] return data
def ExpOp_builder(bin_param, filter_space, interp): # Create binning scheme if interp == 'Full': spf_space = filter_space Exp_op = odl.IdentityOperator(filter_space) elif interp == 'uniform': # Create binning scheme dpix = np.size(filter_space) dsize = filter_space.max_pt filt_bin_space = odl.uniform_discr(-dsize, dsize, dpix // (bin_param)) spf_space = odl.uniform_discr(0, dsize, dpix // (2 * bin_param)) resamp = odl.Resampling(filt_bin_space, filter_space) sym = SymOp(spf_space, filt_bin_space) Exp_op = resamp * sym else: if interp == 'constant': interp = 'nearest' elif interp == 'linear': pass else: raise ValueError('unknown `expansion operator type` ({})' ''.format(interp)) B = ExpBin(bin_param, np.size(filter_space)) * \ filter_space.weighting.const B[-1] -= 1 / 2 * filter_space.weighting.const # Create sparse filter space spf_part = odl.nonuniform_partition(B, min_pt=0, max_pt=B[-1]) spf_weight = np.ravel( np.multiply.reduce(np.meshgrid(*spf_part.cell_sizes_vecs))) spf_fspace = odl.FunctionSpace(spf_part.set) spf_space = odl.DiscreteLp(spf_fspace, spf_part, odl.rn(spf_part.size, weighting=spf_weight), interp=interp) filt_pos_part = odl.uniform_partition(0, B[-1], int(np.size(filter_space) / 2)) filt_pos_space = odl.uniform_discr_frompartition(filt_pos_part, dtype='float64') lin_interp = odl.Resampling(spf_space, filt_pos_space) # Create symmetry operator sym = SymOp(filt_pos_space, filter_space) # Create sparse filter operator Exp_op = sym * lin_interp return spf_space, Exp_op
def test_scikit_radon_projector_parallel2d(): """Parallel 2D forward and backward projectors with scikit.""" # Create reco space and a phantom reco_space = odl.uniform_discr([-5, -5], [5, 5], (5, 5)) phantom = odl.phantom.cuboid(reco_space, min_pt=[0, 0], max_pt=[5, 5]) # Create parallel geometry angle_part = odl.uniform_partition(0, np.pi, 5) det_part = odl.uniform_partition(-6, 6, 6) geom = odl.tomo.Parallel2dGeometry(angle_part, det_part) # Make projection space proj_space = odl.uniform_discr_frompartition(geom.partition) # Forward evaluation proj_data = scikit_radon_forward(phantom, geom, proj_space) assert proj_data.shape == proj_space.shape assert proj_data.norm() > 0 # Backward evaluation backproj = scikit_radon_back_projector(proj_data, geom, reco_space) assert backproj.shape == reco_space.shape assert backproj.norm() > 0
def test_skimage_radon_projector_parallel2d(): """Parallel 2D forward and backward projectors with skimage.""" # Create reco space and a phantom reco_space = odl.uniform_discr([-5, -5], [5, 5], (5, 5)) phantom = odl.phantom.cuboid(reco_space, min_pt=[0, 0], max_pt=[5, 5]) # Create parallel geometry angle_part = odl.uniform_partition(0, np.pi, 5) det_part = odl.uniform_partition(-6, 6, 6) geom = odl.tomo.Parallel2dGeometry(angle_part, det_part) # Make projection space proj_space = odl.uniform_discr_frompartition(geom.partition) # Forward evaluation proj_data = skimage_radon_forward(phantom, geom, proj_space) assert proj_data.shape == proj_space.shape assert proj_data.norm() > 0 # Backward evaluation backproj = skimage_radon_back_projector(proj_data, geom, reco_space) assert backproj.shape == reco_space.shape assert backproj.norm() > 0
def __init__(self, dataset, pix_size, src_rad, det_rad, ang_freq, vox=None, vecs=None, zoom=False, offset=0): self.data_type = 'real' # %% load data self.vecs = vecs self.ang_freq = ang_freq self.dataset = dataset self.offset = offset if type(dataset) == dict: g_vec = np.load(dataset['g']) # %% adapt data self.angles_in = np.shape(g_vec)[0] g_vec = g_vec[::ang_freq, :, :] rs_detu = np.min(np.shape(g_vec)[1:]) * 2 diff = int((rs_detu - np.size(g_vec, 1)) / 2) g_vec = np.concatenate((np.zeros(( np.size(g_vec, 0), diff, np.size(g_vec, 2))), g_vec, np.zeros((np.size(g_vec, 0), diff, np.size(g_vec, 2)))), 1) else: g_vec = dataset # Define the dimensions of the problem in cm self.pix_size = pix_size self.angles = g_vec.shape[0] self.src_rad = src_rad self.det_rad = det_rad if zoom: self.magn = 1 else: self.magn = self.src_rad / (self.src_rad + self.det_rad) self.dpix = [np.size(g_vec, 1), np.size(g_vec, 2)] u_size = self.dpix[0] * pix_size / 2 v_size = self.dpix[1] * pix_size / 2 self.detecsize = np.array([u_size, v_size]) if vox is None: self.voxels = [self.dpix[1], self.dpix[1], self.dpix[1]] self.volumesize = np.array([self.detecsize[1] * self.magn, self.detecsize[1] * self.magn, self.detecsize[1] * self.magn], dtype='float32') else: self.voxels = [vox, vox, vox] volsize = vox * self.pix_size * self.magn / 2 self.volumesize = np.array([volsize, volsize, volsize], dtype='float32') # %% # Make the reconstruction space self.reco_space = odl.uniform_discr(min_pt=-self.volumesize, max_pt=self.volumesize, shape=self.voxels, dtype='float32') if 'ground_truth' in dataset: self.f = self.reco_space.element(np.load(dataset['ground_truth'])) self.mask_name = dataset['mask'] # Make a circular scanning geometry angle_partition = odl.uniform_partition(offset, 2 * np.pi + offset, self.angles) # Make a flat detector space det_partition = odl.uniform_partition(-self.detecsize, self.detecsize, self.dpix) self.det_space = odl.uniform_discr_frompartition(det_partition, dtype='float32') # Create geometry self.geometry = odl.tomo.ConeFlatGeometry( angle_partition, det_partition, src_radius=self.src_rad, det_radius=self.det_rad, axis=[0, 0, 1]) self.angle_space = odl.uniform_discr_frompartition( self.geometry.motion_partition) # Forward Projection self.FwP = odl.tomo.RayTransform(self.reco_space, self.geometry, use_cache=False) # Backward Projection self.BwP = odl.tomo.RayBackProjection(self.reco_space, self.geometry, use_cache=False) if self.vecs is None: self.g = self.BwP.domain.element(g_vec) else: self.g = g_vec self.geometry = vecs gc.collect()
def __init__(self, data_obj, data_struct=True, **kwargs): # %% Store the input in the object # BE F*****G CONSISTENT WITH RENAMING ETC. self.pix = data_obj.voxels[0] self.angles = data_obj.angles self.src_rad = data_obj.src_rad self.det_rad = data_obj.det_rad self.magn = self.src_rad / (self.src_rad + self.det_rad) self.data_struct = data_struct self.rec_methods = [] if hasattr(data_obj, 'offset'): self.offset = data_obj.offset # %% If we need a data structure, make one: self.WV_obj = sup.working_var_map() self.WV_path = self.WV_obj.WV_path # %% Set up the geometry self.phantom = data_obj self.g = self.phantom.g # Make the reconstruction space self.reco_space = self.phantom.reco_space voxels = self.phantom.voxels dpix = [np.shape(self.g)[1], np.shape(self.g)[2]] self.w_detu = (2 * self.phantom.detecsize[0]) / dpix[0] self.w_detv = (2 * self.phantom.detecsize[1]) / dpix[1] if self.phantom.data_type == 'simulated': self.PH = data_obj.PH self.noise = data_obj.noise # Do we need a mask? if data_struct: self.phantom.make_mask(self.WV_path) else: pass src_radius = self.src_rad * self.phantom.volumesize[0] * 2 det_radius = self.det_rad * self.phantom.volumesize[0] * 2 # Make a circular scanning geometry angle_partition = odl.uniform_partition(0, 2 * np.pi, self.angles) self.angle_space = odl.uniform_discr_frompartition(angle_partition) # Make a flat detector space det_partition = odl.uniform_partition(-self.phantom.detecsize, self.phantom.detecsize, dpix) self.det_space = odl.uniform_discr_frompartition(det_partition, dtype='float32') # Create geometry self.geometry = odl.tomo.ConeFlatGeometry(angle_partition, det_partition, src_radius=src_radius, det_radius=det_radius, axis=[0, 0, 1]) else: src_radius = self.phantom.src_rad det_radius = self.phantom.det_rad self.pix_size = self.phantom.pix_size self.angle_space = self.phantom.angle_space self.angles = np.size(self.angle_space) self.det_space = self.phantom.det_space self.geometry = self.phantom.geometry # Create filter space, same size as the detector, because stability filter_part = odl.uniform_partition(-self.phantom.detecsize[0], self.phantom.detecsize[0], dpix[0]) # filter_part = odl.uniform_partition(-2 * self.phantom.detecsize[0], # 2 * self.phantom.detecsize[0], # 2 * dpix[0]) self.filter_space = odl.uniform_discr_frompartition(filter_part, dtype='float64') # %% Create the FP and BP # Create fourier filter space self.rs_detu = int(2**(np.ceil(np.log2(self.filter_space.size)) + 1)) # set =filter.size if filter is twice the detector self.frs_detu = self.rs_detu // 2 + 1 fourier_filter_part = odl.uniform_partition(0, np.pi, (self.frs_detu)) self.fourier_filter_space = odl.uniform_discr_frompartition( fourier_filter_part, dtype='complex64') if self.phantom.vecs is None: # Forward Projection self.FwP = odl.tomo.RayTransform(self.reco_space, self.geometry, use_cache=False) # Backward Projection self.BwP = odl.tomo.RayBackProjection(self.reco_space, self.geometry, use_cache=False) # %% Create the operators for the FDK framework # Create the FDK weighting for the data w_FDK = sup.FDK_weighting(dpix, self.det_space, self.w_detu, self.w_detv, src_radius) # Scale the data according to the FDK weighting self.g_scl = np.asarray(self.g.copy()) for a in range(self.angles): self.g_scl[a, :, :] *= w_FDK self.conv_op = sup.ConvolutionOp(self.filter_space, self.FwP.range, self.det_space, self.w_detv, self.g_scl, self.angle_space.weighting.const) # Create FDK operator which takes filter self.FDK_op = self.BwP * self.conv_op
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
def test_fourier_trafo_completely(): # Complete explicit test of all FT components on two small examples # Discretization with 4 points discr = odl.uniform_discr(-2, 2, 4, dtype="complex") # Interval boundaries -2, -1, 0, 1, 2 assert np.allclose(discr.partition.cell_boundary_vecs[0], [-2, -1, 0, 1, 2]) # Grid points -1.5, -0.5, 0.5, 1.5 assert np.allclose(discr.grid.coord_vectors[0], [-1.5, -0.5, 0.5, 1.5]) # First test function, symmetric. Can be represented exactly in the # discretization. def f(x): return (x >= -1) & (x <= 1) def fhat(x): return np.sqrt(2 / np.pi) * sinc(x) # Discretize f, check values f_discr = discr.element(f) assert np.allclose(f_discr, [0, 1, 1, 0]) # "s" = shifted, "n" = not shifted # Reciprocal grids recip_s = reciprocal_grid(discr.grid, shift=True) recip_n = reciprocal_grid(discr.grid, shift=False) assert np.allclose(recip_s.coord_vectors[0], np.linspace(-np.pi, np.pi / 2, 4)) assert np.allclose(recip_n.coord_vectors[0], np.linspace(-3 * np.pi / 4, 3 * np.pi / 4, 4)) # Range range_part_s = odl.uniform_partition_fromgrid(recip_s) range_s = odl.uniform_discr_frompartition(range_part_s, dtype="complex") range_part_n = odl.uniform_partition_fromgrid(recip_n) range_n = odl.uniform_discr_frompartition(range_part_n, dtype="complex") # Pre-processing preproc_s = [1, -1, 1, -1] preproc_n = [np.exp(1j * 3 / 4 * np.pi * k) for k in range(4)] fpre_s = dft_preprocess_data(f_discr, shift=True) fpre_n = dft_preprocess_data(f_discr, shift=False) assert np.allclose(fpre_s, f_discr * discr.element(preproc_s)) assert np.allclose(fpre_n, f_discr * discr.element(preproc_n)) # FFT step, replicating the _call_numpy method fft_s = np.fft.fftn(fpre_s, s=discr.shape, axes=[0]) fft_n = np.fft.fftn(fpre_n, s=discr.shape, axes=[0]) assert np.allclose(fft_s, [0, -1 + 1j, 2, -1 - 1j]) assert np.allclose( fft_n, [np.exp(1j * np.pi * (3 - 2 * k) / 4) + np.exp(1j * np.pi * (3 - 2 * k) / 2) for k in range(4)] ) # Interpolation kernel FT interp_s = np.sinc(np.linspace(-1 / 2, 1 / 4, 4)) / np.sqrt(2 * np.pi) interp_n = np.sinc(np.linspace(-3 / 8, 3 / 8, 4)) / np.sqrt(2 * np.pi) assert np.allclose(interp_s, _interp_kernel_ft(np.linspace(-1 / 2, 1 / 4, 4), interp="nearest")) assert np.allclose(interp_n, _interp_kernel_ft(np.linspace(-3 / 8, 3 / 8, 4), interp="nearest")) # Post-processing postproc_s = np.exp(1j * np.pi * np.linspace(-3 / 2, 3 / 4, 4)) postproc_n = np.exp(1j * np.pi * np.linspace(-9 / 8, 9 / 8, 4)) fpost_s = dft_postprocess_data( range_s.element(fft_s), real_grid=discr.grid, recip_grid=recip_s, shift=[True], axes=(0,), interp="nearest" ) fpost_n = dft_postprocess_data( range_n.element(fft_n), real_grid=discr.grid, recip_grid=recip_n, shift=[False], axes=(0,), interp="nearest" ) assert np.allclose(fpost_s, fft_s * postproc_s * interp_s) assert np.allclose(fpost_n, fft_n * postproc_n * interp_n) # Comparing to the known result sqrt(2/pi) * sinc(x) assert np.allclose(fpost_s, fhat(recip_s.coord_vectors[0])) assert np.allclose(fpost_n, fhat(recip_n.coord_vectors[0])) # Doing the exact same with direct application of the FT operator ft_op_s = FourierTransform(discr, shift=True) ft_op_n = FourierTransform(discr, shift=False) assert ft_op_s.range.grid == recip_s assert ft_op_n.range.grid == recip_n ft_f_s = ft_op_s(f) ft_f_n = ft_op_n(f) assert np.allclose(ft_f_s, fhat(recip_s.coord_vectors[0])) assert np.allclose(ft_f_n, fhat(recip_n.coord_vectors[0])) # Second test function, asymmetric. Can also be represented exactly in the # discretization. def f(x): return (x >= 0) & (x <= 1) def fhat(x): return np.exp(-1j * x / 2) * sinc(x / 2) / np.sqrt(2 * np.pi) # Discretize f, check values f_discr = discr.element(f) assert np.allclose(f_discr, [0, 0, 1, 0]) # Pre-processing fpre_s = dft_preprocess_data(f_discr, shift=True) fpre_n = dft_preprocess_data(f_discr, shift=False) assert np.allclose(fpre_s, [0, 0, 1, 0]) assert np.allclose(fpre_n, [0, 0, -1j, 0]) # FFT step fft_s = np.fft.fftn(fpre_s, s=discr.shape, axes=[0]) fft_n = np.fft.fftn(fpre_n, s=discr.shape, axes=[0]) assert np.allclose(fft_s, [1, -1, 1, -1]) assert np.allclose(fft_n, [-1j, 1j, -1j, 1j]) fpost_s = dft_postprocess_data( range_s.element(fft_s), real_grid=discr.grid, recip_grid=recip_s, shift=[True], axes=(0,), interp="nearest" ) fpost_n = dft_postprocess_data( range_n.element(fft_n), real_grid=discr.grid, recip_grid=recip_n, shift=[False], axes=(0,), interp="nearest" ) assert np.allclose(fpost_s, fft_s * postproc_s * interp_s) assert np.allclose(fpost_n, fft_n * postproc_n * interp_n) # Comparing to the known result exp(-1j*x/2) * sinc(x/2) / sqrt(2*pi) assert np.allclose(fpost_s, fhat(recip_s.coord_vectors[0])) assert np.allclose(fpost_n, fhat(recip_n.coord_vectors[0])) # Doing the exact same with direct application of the FT operator ft_f_s = ft_op_s(f) ft_f_n = ft_op_n(f) assert np.allclose(ft_f_s, fhat(recip_s.coord_vectors[0])) assert np.allclose(ft_f_n, fhat(recip_n.coord_vectors[0]))
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 test_fourier_trafo_completely(): # Complete explicit test of all FT components on two small examples # Discretization with 4 points discr = odl.uniform_discr(-2, 2, 4, dtype='complex') # Interval boundaries -2, -1, 0, 1, 2 assert np.allclose(discr.partition.cell_boundary_vecs[0], [-2, -1, 0, 1, 2]) # Grid points -1.5, -0.5, 0.5, 1.5 assert np.allclose(discr.grid.coord_vectors[0], [-1.5, -0.5, 0.5, 1.5]) # First test function, symmetric. Can be represented exactly in the # discretization. def f(x): return (x >= -1) & (x <= 1) def fhat(x): return np.sqrt(2 / np.pi) * sinc(x) # Discretize f, check values f_discr = discr.element(f) assert np.allclose(f_discr, [0, 1, 1, 0]) # "s" = shifted, "n" = not shifted # Reciprocal grids recip_s = reciprocal_grid(discr.grid, shift=True) recip_n = reciprocal_grid(discr.grid, shift=False) assert np.allclose(recip_s.coord_vectors[0], np.linspace(-np.pi, np.pi / 2, 4)) assert np.allclose(recip_n.coord_vectors[0], np.linspace(-3 * np.pi / 4, 3 * np.pi / 4, 4)) # Range range_part_s = odl.uniform_partition_fromgrid(recip_s) range_s = odl.uniform_discr_frompartition(range_part_s, dtype='complex') range_part_n = odl.uniform_partition_fromgrid(recip_n) range_n = odl.uniform_discr_frompartition(range_part_n, dtype='complex') # Pre-processing preproc_s = [1, -1, 1, -1] preproc_n = [np.exp(1j * 3 / 4 * np.pi * k) for k in range(4)] fpre_s = dft_preprocess_data(f_discr, shift=True) fpre_n = dft_preprocess_data(f_discr, shift=False) assert np.allclose(fpre_s, f_discr * discr.element(preproc_s)) assert np.allclose(fpre_n, f_discr * discr.element(preproc_n)) # FFT step, replicating the _call_numpy method fft_s = np.fft.fftn(fpre_s, s=discr.shape, axes=[0]) fft_n = np.fft.fftn(fpre_n, s=discr.shape, axes=[0]) assert np.allclose(fft_s, [0, -1 + 1j, 2, -1 - 1j]) assert np.allclose(fft_n, [ np.exp(1j * np.pi * (3 - 2 * k) / 4) + np.exp(1j * np.pi * (3 - 2 * k) / 2) for k in range(4) ]) # Interpolation kernel FT interp_s = np.sinc(np.linspace(-1 / 2, 1 / 4, 4)) / np.sqrt(2 * np.pi) interp_n = np.sinc(np.linspace(-3 / 8, 3 / 8, 4)) / np.sqrt(2 * np.pi) assert np.allclose( interp_s, _interp_kernel_ft(np.linspace(-1 / 2, 1 / 4, 4), interp='nearest')) assert np.allclose( interp_n, _interp_kernel_ft(np.linspace(-3 / 8, 3 / 8, 4), interp='nearest')) # Post-processing postproc_s = np.exp(1j * np.pi * np.linspace(-3 / 2, 3 / 4, 4)) postproc_n = np.exp(1j * np.pi * np.linspace(-9 / 8, 9 / 8, 4)) fpost_s = dft_postprocess_data(range_s.element(fft_s), real_grid=discr.grid, recip_grid=recip_s, shift=[True], axes=(0, ), interp='nearest') fpost_n = dft_postprocess_data(range_n.element(fft_n), real_grid=discr.grid, recip_grid=recip_n, shift=[False], axes=(0, ), interp='nearest') assert np.allclose(fpost_s, fft_s * postproc_s * interp_s) assert np.allclose(fpost_n, fft_n * postproc_n * interp_n) # Comparing to the known result sqrt(2/pi) * sinc(x) assert np.allclose(fpost_s, fhat(recip_s.coord_vectors[0])) assert np.allclose(fpost_n, fhat(recip_n.coord_vectors[0])) # Doing the exact same with direct application of the FT operator ft_op_s = FourierTransform(discr, shift=True) ft_op_n = FourierTransform(discr, shift=False) assert ft_op_s.range.grid == recip_s assert ft_op_n.range.grid == recip_n ft_f_s = ft_op_s(f) ft_f_n = ft_op_n(f) assert np.allclose(ft_f_s, fhat(recip_s.coord_vectors[0])) assert np.allclose(ft_f_n, fhat(recip_n.coord_vectors[0])) # Second test function, asymmetric. Can also be represented exactly in the # discretization. def f(x): return (x >= 0) & (x <= 1) def fhat(x): return np.exp(-1j * x / 2) * sinc(x / 2) / np.sqrt(2 * np.pi) # Discretize f, check values f_discr = discr.element(f) assert np.allclose(f_discr, [0, 0, 1, 0]) # Pre-processing fpre_s = dft_preprocess_data(f_discr, shift=True) fpre_n = dft_preprocess_data(f_discr, shift=False) assert np.allclose(fpre_s, [0, 0, 1, 0]) assert np.allclose(fpre_n, [0, 0, -1j, 0]) # FFT step fft_s = np.fft.fftn(fpre_s, s=discr.shape, axes=[0]) fft_n = np.fft.fftn(fpre_n, s=discr.shape, axes=[0]) assert np.allclose(fft_s, [1, -1, 1, -1]) assert np.allclose(fft_n, [-1j, 1j, -1j, 1j]) fpost_s = dft_postprocess_data(range_s.element(fft_s), real_grid=discr.grid, recip_grid=recip_s, shift=[True], axes=(0, ), interp='nearest') fpost_n = dft_postprocess_data(range_n.element(fft_n), real_grid=discr.grid, recip_grid=recip_n, shift=[False], axes=(0, ), interp='nearest') assert np.allclose(fpost_s, fft_s * postproc_s * interp_s) assert np.allclose(fpost_n, fft_n * postproc_n * interp_n) # Comparing to the known result exp(-1j*x/2) * sinc(x/2) / sqrt(2*pi) assert np.allclose(fpost_s, fhat(recip_s.coord_vectors[0])) assert np.allclose(fpost_n, fhat(recip_n.coord_vectors[0])) # Doing the exact same with direct application of the FT operator ft_f_s = ft_op_s(f) ft_f_n = ft_op_n(f) assert np.allclose(ft_f_s, fhat(recip_s.coord_vectors[0])) assert np.allclose(ft_f_n, fhat(recip_n.coord_vectors[0]))
# writer.setup(fig, 'DogBones' + '.mp4', dpi=100) for i in range(data.shape[0]): plt.gca().clear() plt.imshow(data[i, :, 500:564].T) plt.pause(0.1) # writer.grab_frame() # writer.finish() exit() # Space variables vol = list(data.shape) vol[0] = vol[1] # recon same as each row width vol = odl.uniform_partition([-v / sqrt(128) for v in vol], [v / sqrt(128) for v in vol], vol) vol = odl.uniform_discr_frompartition(vol[:, :, 500:564], dtype='float32') data = ascontiguousarray(data[:, :, 500:564], dtype='float32') PSpace = (angles, odl.uniform_partition([-v / sqrt(128) for v in data.shape[1:]], [v / sqrt(128) for v in data.shape[1:]], data.shape[1:])) PSpace = odl.tomo.Parallel3dAxisGeometry(*PSpace, axis=[0, 0, 1]) # Operators Radon = odl.tomo.RayTransform(vol, PSpace) grad = odl.Gradient(vol) op = odl.BroadcastOperator(Radon, grad) g = odl.solvers.functional.default_functionals.IndicatorNonnegativity( op.domain) fidelity = odl.solvers.L2NormSquared(Radon.range).translated(data)
import odl from odl.contrib.datasets.ct import mayo mayo_dir = '' # replace with your local folder # Load reference reconstruction volume_folder = mayo_dir + '/Training Cases/L067/full_1mm_sharp' partition, volume = mayo.load_reconstruction(volume_folder) # Load a subset of the projection data data_folder = mayo_dir + '/Training Cases/L067/full_DICOM-CT-PD' geometry, proj_data = mayo.load_projections(data_folder, indices=slice(20000, 28000)) # Reconstruction space and ray transform space = odl.uniform_discr_frompartition(partition, dtype='float32') ray_trafo = odl.tomo.RayTransform(space, geometry) # Define FBP operator fbp = odl.tomo.fbp_op(ray_trafo, padding=True) # Tam-Danielsson window to handle redundant data td_window = odl.tomo.tam_danielson_window(ray_trafo, n_pi=3) # Calculate FBP reconstruction fbp_result = fbp(td_window * proj_data) # Compare the computed recon to reference reconstruction (coronal slice) ref = space.element(volume) fbp_result.show('Recon (coronal)', clim=[0.7, 1.3]) ref.show('Reference (coronal)', clim=[0.7, 1.3])
import odl from GaussDictCode.dictionary_def import VolSpace, ProjSpace, AtomSpace, ProjElement from matplotlib import pyplot as plt # # 2D comparison ASpace = AtomSpace(2, isotropic=False) atoms = ASpace.random(2, seed=1) angles = odl.uniform_partition(0, 2 * pi, 360, nodes_on_bdry=True) detector = odl.uniform_partition(-1, 1, 256) vol = odl.uniform_partition([-1] * 2, [1] * 2, [128] * 2) myPSpace = ProjSpace(angles, detector) myTomo = GaussTomo(ASpace, VolSpace(vol), myPSpace, device='GPU') mySino = myTomo(atoms) odlPSpace = odl.tomo.Parallel2dGeometry(angles, detector) odlTomo = odl.tomo.RayTransform( odl.uniform_discr_frompartition(vol), odlPSpace) odlSino = odlTomo(myTomo.discretise(atoms).asarray()) odlSino = ProjElement(myPSpace, odlSino.asarray()) mySino.plot(plt.subplot('211'), aspect='auto') plt.title('2D Atomic Sinogram (top) and volume-sinogram (bottom)') odlSino.plot(plt.subplot('212'), aspect='auto') # # 2.5D comparison ASpace = AtomSpace(3, isotropic=False) atoms = ASpace.random(3, seed=2) atoms.I[:] = 1 atoms.r[:, :3], atoms.r[:, 3:] = 7, 0 angles = odl.uniform_partition(0, pi, 4, nodes_on_bdry=True) detector = odl.uniform_partition([-1] * 2, [1] * 2, [128] * 2) vol = odl.uniform_partition([-1] * 3, [1] * 3, [256] * 3)
# angles = angles[2:-1] vol = vol[::4, ::4, ::4] # for i in range(0, len(angles)): # plt.gca().clear() # plt.imshow(data[i].T) # plt.title(str(i)) # plt.show(block=False) # plt.pause(.3) # plt.show() # exit() box = [vol.min_pt, vol.max_pt] PSpace = ProjSpace( angles, odl.uniform_partition(vol.min_pt[1:], vol.max_pt[1:], data.shape[1:])) vol = VolSpace(odl.uniform_discr_frompartition(vol, dtype='float32')) # Initiate Recon: ##### def newAtoms(n, seed=None): tmp = ASpace.random(n, seed=seed) c.set(tmp.r, 2, (slice(None), slice(None, 3))) c.set(tmp.r, 0, (slice(None), slice(3, None))) c.set(tmp.I[:], .1) return tmp nAtoms = 50 recon = newAtoms(nAtoms, 1) ##### Radon = GaussTomo(ASpace, vol, PSpace, device='GPU') data = ProjElement(PSpace, data / data.max())
from GaussDictCode.transport_loss import l2_squared_loss from GaussDictCode.regularisation import null from KL_GaussRadon import doKL_ProjGDStep_iso with mrc.FileReaderMRC(join('store', 'jasenko_1p8A_nonsharpened_absscale.mrc')) as f: _, gt = f.read() gt[gt < 0] = 0 gt /= gt.max() / 2 angles = odl.RectGrid(linspace(-pi / 2, pi / 2, 40), linspace(0, pi / 2, 20)) angles = odl.uniform_partition_fromgrid(angles) vol = list(gt.shape) vol = odl.uniform_partition([-1] * 3, [1] * 3, vol) vol = odl.uniform_discr_frompartition(vol, dtype='float32') gt = ascontiguousarray(gt, dtype='float32') PSpace = (angles, odl.uniform_partition([-1] * 2, [1] * 2, [64] * 2)) PSpace = odl.tomo.Parallel3dEulerGeometry(*PSpace) # Operators Radon = odl.tomo.RayTransform(vol, PSpace) data = Radon(gt) with myManager(device='cpu', order='C', fType='float32', cType='complex64') as c: # Space settings: dim = 3 device = 'GPU' ASpace = AtomSpace(dim, isotropic=False)