def test_norm_simple2D_cpu(self): # test exists # Create projection operator using Astra-Toolbox. Available CPU/CPU device = 'cpu' A = AstraProjectorSimple(self.ig, self.ag, device = device) n = A.norm() print ("norm A CPU", n) self.assertTrue(True) self.assertAlmostEqual(n, self.norm, places=2)
def calculate_norm(self): igtmp = self.domain_geometry().clone() # igtmp.shape = self.volume_geometry.shape[1:] # igtmp.dimension_labels = ['horizontal_y', 'horizontal_x'] # igtmp.channels = 1 agtmp = self.range_geometry().clone() # agtmp.shape = self.sinogram_geometry.shape[1:] # agtmp.dimension_labels = ['angle', 'horizontal'] # agtmp.channels = 1 Atmp = AstraProjectorSimple(igtmp, agtmp, device=self.device) return Atmp.norm()
def __init__(self, geomv, geomp, device='gpu'): super(ProjectionOperator, self).__init__(domain_geometry=geomv, range_geometry=geomp) self.volume_geometry = geomv self.sinogram_geometry = geomp sinogram_geometry_sc = geomp.subset(channel=0) volume_geometry_sc = geomv.subset(channel=0) if device is 'gpu': operator = AstraProjectorFlexible(volume_geometry_sc, sinogram_geometry_sc) else: UserWarning( "ASTRA projectors running on CPU will not make use of enhanced geometry parameters" ) if self.sinogram_geometry.dimension == '2D': operator = AstraProjectorSimple(volume_geometry_sc, sinogram_geometry_sc, device='cpu') else: raise NotImplementedError( "Cannot process 3D data without a GPU") if geomp.channels > 1: operator_full = ChannelwiseOperator( operator, self.sinogram_geometry.channels, dimension='prepend') self.operator = operator_full else: self.operator = operator
def test_consistency(self): # #%% AstraProjectorSimple cpu ig = self.ig_2D.copy() ag = self.ag_slice.copy() A = AstraProjectorSimple(ig, ag, device='cpu') fp = A.direct(self.golden_data_cs) bp = A.adjoint(fp) # #%% AstraProjectorFlexible ig = self.ig_3D.copy() ag = self.ag.copy() A = AstraProjector3DSimple(ig, ag) flex_fp = A.direct(self.golden_data) flex_bp = A.adjoint(flex_fp) #comparision foward projection fp_flex_0 = flex_fp.subset(vertical=self.cs_ind, force=True) fp_flex_1 = flex_fp.subset(vertical=self.cs_ind + 3, force=True) fp_flex_2 = flex_fp.subset(vertical=self.cs_ind - 3, force=True) zeros = self.ag_slice.allocate(0) np.testing.assert_allclose(fp_flex_0.as_array(), fp.as_array(), atol=0.8) np.testing.assert_allclose(fp_flex_1.as_array(), fp.as_array(), atol=0.8) np.testing.assert_allclose(fp_flex_2.as_array(), zeros.as_array()) #comparision back projection bp_flex_0 = flex_bp.subset(vertical=self.cs_ind, force=True) bp_flex_1 = flex_bp.subset(vertical=self.cs_ind + 3, force=True) bp_flex_2 = flex_bp.subset(vertical=self.cs_ind - 3, force=True) zeros = self.ig_2D.allocate(0) np.testing.assert_allclose(bp_flex_0.as_array(), bp.as_array(), atol=12) np.testing.assert_allclose(bp_flex_1.as_array(), bp.as_array(), atol=12) np.testing.assert_allclose(bp_flex_2.as_array(), zeros.as_array())
def test_SPDHG_vs_SPDHG_explicit_axpby(self): data = dataexample.SIMPLE_PHANTOM_2D.get(size=(128, 128)) if debug_print: print("test_SPDHG_vs_SPDHG_explicit_axpby here") ig = data.geometry ig.voxel_size_x = 0.1 ig.voxel_size_y = 0.1 detectors = ig.shape[0] angles = np.linspace(0, np.pi, 180) ag = AcquisitionGeometry('parallel', '2D', angles, detectors, pixel_size_h=0.1, angle_unit='radian') # Select device # device = input('Available device: GPU==1 / CPU==0 ') # if device=='1': # dev = 'gpu' # else: # dev = 'cpu' dev = 'cpu' Aop = AstraProjectorSimple(ig, ag, dev) sin = Aop.direct(data) # Create noisy data. Apply Gaussian noise noises = ['gaussian', 'poisson'] noise = noises[1] if noise == 'poisson': np.random.seed(10) scale = 5 eta = 0 noisy_data = AcquisitionData( np.random.poisson(scale * (eta + sin.as_array())) / scale, geometry=ag) elif noise == 'gaussian': np.random.seed(10) n1 = np.random.normal(0, 0.1, size=ag.shape) noisy_data = AcquisitionData(n1 + sin.as_array(), geometry=ag) else: raise ValueError('Unsupported Noise ', noise) #%% 'explicit' SPDHG, scalar step-sizes subsets = 10 size_of_subsets = int(len(angles) / subsets) # create GradientOperator operator op1 = GradientOperator(ig) # take angles and create uniform subsets in uniform+sequential setting list_angles = [ angles[i:i + size_of_subsets] for i in range(0, len(angles), size_of_subsets) ] # create acquisitioin geometries for each the interval of splitting angles list_geoms = [ AcquisitionGeometry('parallel', '2D', list_angles[i], detectors, pixel_size_h=0.1, angle_unit='radian') for i in range(len(list_angles)) ] # create with operators as many as the subsets A = BlockOperator(*[ AstraProjectorSimple(ig, list_geoms[i], dev) for i in range(subsets) ] + [op1]) ## number of subsets #(sub2ind, ind2sub) = divide_1Darray_equally(range(len(A)), subsets) # ## acquisisiton data ## acquisisiton data AD_list = [] for sub_num in range(subsets): for i in range(0, len(angles), size_of_subsets): arr = noisy_data.as_array()[i:i + size_of_subsets, :] AD_list.append( AcquisitionData(arr, geometry=list_geoms[sub_num])) g = BlockDataContainer(*AD_list) alpha = 0.5 ## block function F = BlockFunction(*[ *[KullbackLeibler(b=g[i]) for i in range(subsets)] + [alpha * MixedL21Norm()] ]) G = IndicatorBox(lower=0) prob = [1 / (2 * subsets)] * (len(A) - 1) + [1 / 2] algos = [] algos.append( SPDHG(f=F, g=G, operator=A, max_iteration=1000, update_objective_interval=200, prob=prob.copy(), use_axpby=True)) algos[0].run(1000, verbose=0) algos.append( SPDHG(f=F, g=G, operator=A, max_iteration=1000, update_objective_interval=200, prob=prob.copy(), use_axpby=False)) algos[1].run(1000, verbose=0) # np.testing.assert_array_almost_equal(algos[0].get_output().as_array(), algos[1].get_output().as_array()) from cil.utilities.quality_measures import mae, mse, psnr qm = (mae(algos[0].get_output(), algos[1].get_output()), mse(algos[0].get_output(), algos[1].get_output()), psnr(algos[0].get_output(), algos[1].get_output())) if debug_print: print("Quality measures", qm) assert qm[0] < 0.005 assert qm[1] < 3.e-05
def test_SPDHG_vs_PDHG_explicit(self): data = dataexample.SIMPLE_PHANTOM_2D.get(size=(128, 128)) ig = data.geometry ig.voxel_size_x = 0.1 ig.voxel_size_y = 0.1 detectors = ig.shape[0] angles = np.linspace(0, np.pi, 180) ag = AcquisitionGeometry('parallel', '2D', angles, detectors, pixel_size_h=0.1, angle_unit='radian') # Select device dev = 'cpu' Aop = AstraProjectorSimple(ig, ag, dev) sin = Aop.direct(data) # Create noisy data. Apply Gaussian noise noises = ['gaussian', 'poisson'] noise = noises[1] if noise == 'poisson': scale = 5 noisy_data = scale * applynoise.poisson(sin / scale, seed=10) # np.random.seed(10) # scale = 5 # eta = 0 # noisy_data = AcquisitionData(np.random.poisson( scale * (eta + sin.as_array()))/scale, ag) elif noise == 'gaussian': noisy_data = noise.gaussian(sin, var=0.1, seed=10) # np.random.seed(10) # n1 = np.random.normal(0, 0.1, size = ag.shape) # noisy_data = AcquisitionData(n1 + sin.as_array(), ag) else: raise ValueError('Unsupported Noise ', noise) #%% 'explicit' SPDHG, scalar step-sizes subsets = 10 size_of_subsets = int(len(angles) / subsets) # create Gradient operator op1 = GradientOperator(ig) # take angles and create uniform subsets in uniform+sequential setting list_angles = [ angles[i:i + size_of_subsets] for i in range(0, len(angles), size_of_subsets) ] # create acquisitioin geometries for each the interval of splitting angles list_geoms = [ AcquisitionGeometry('parallel', '2D', list_angles[i], detectors, pixel_size_h=0.1, angle_unit='radian') for i in range(len(list_angles)) ] # create with operators as many as the subsets A = BlockOperator(*[ AstraProjectorSimple(ig, list_geoms[i], dev) for i in range(subsets) ] + [op1]) ## number of subsets #(sub2ind, ind2sub) = divide_1Darray_equally(range(len(A)), subsets) # ## acquisisiton data ## acquisisiton data AD_list = [] for sub_num in range(subsets): for i in range(0, len(angles), size_of_subsets): arr = noisy_data.as_array()[i:i + size_of_subsets, :] AD_list.append( AcquisitionData(arr, geometry=list_geoms[sub_num])) g = BlockDataContainer(*AD_list) alpha = 0.5 ## block function F = BlockFunction(*[ *[KullbackLeibler(b=g[i]) for i in range(subsets)] + [alpha * MixedL21Norm()] ]) G = IndicatorBox(lower=0) prob = [1 / (2 * subsets)] * (len(A) - 1) + [1 / 2] spdhg = SPDHG(f=F, g=G, operator=A, max_iteration=1000, update_objective_interval=200, prob=prob) spdhg.run(1000, verbose=0) #%% 'explicit' PDHG, scalar step-sizes op1 = GradientOperator(ig) op2 = Aop # Create BlockOperator operator = BlockOperator(op1, op2, shape=(2, 1)) f2 = KullbackLeibler(b=noisy_data) g = IndicatorBox(lower=0) normK = operator.norm() sigma = 1 / normK tau = 1 / normK f1 = alpha * MixedL21Norm() f = BlockFunction(f1, f2) # Setup and run the PDHG algorithm pdhg = PDHG(f=f, g=g, operator=operator, tau=tau, sigma=sigma) pdhg.max_iteration = 1000 pdhg.update_objective_interval = 200 pdhg.run(1000, verbose=0) #%% show diff between PDHG and SPDHG # plt.imshow(spdhg.get_output().as_array() -pdhg.get_output().as_array()) # plt.colorbar() # plt.show() from cil.utilities.quality_measures import mae, mse, psnr qm = (mae(spdhg.get_output(), pdhg.get_output()), mse(spdhg.get_output(), pdhg.get_output()), psnr(spdhg.get_output(), pdhg.get_output())) if debug_print: print("Quality measures", qm) np.testing.assert_almost_equal(mae(spdhg.get_output(), pdhg.get_output()), 0.00150, decimal=3) np.testing.assert_almost_equal(mse(spdhg.get_output(), pdhg.get_output()), 1.68590e-05, decimal=3)
def test_SPDHG_vs_PDHG_implicit(self): data = dataexample.SIMPLE_PHANTOM_2D.get(size=(128, 128)) ig = data.geometry ig.voxel_size_x = 0.1 ig.voxel_size_y = 0.1 detectors = ig.shape[0] angles = np.linspace(0, np.pi, 90) ag = AcquisitionGeometry('parallel', '2D', angles, detectors, pixel_size_h=0.1, angle_unit='radian') # Select device dev = 'cpu' Aop = AstraProjectorSimple(ig, ag, dev) sin = Aop.direct(data) # Create noisy data. Apply Gaussian noise noises = ['gaussian', 'poisson'] noise = noises[1] noisy_data = ag.allocate() if noise == 'poisson': np.random.seed(10) scale = 20 eta = 0 noisy_data.fill( np.random.poisson(scale * (eta + sin.as_array())) / scale) elif noise == 'gaussian': np.random.seed(10) n1 = np.random.normal(0, 0.1, size=ag.shape) noisy_data.fill(n1 + sin.as_array()) else: raise ValueError('Unsupported Noise ', noise) # Create BlockOperator operator = Aop f = KullbackLeibler(b=noisy_data) alpha = 0.005 g = alpha * TotalVariation(50, 1e-4, lower=0) normK = operator.norm() #% 'implicit' PDHG, preconditioned step-sizes tau_tmp = 1. sigma_tmp = 1. tau = sigma_tmp / operator.adjoint( tau_tmp * operator.range_geometry().allocate(1.)) sigma = tau_tmp / operator.direct( sigma_tmp * operator.domain_geometry().allocate(1.)) # initial = operator.domain_geometry().allocate() # # Setup and run the PDHG algorithm pdhg = PDHG(f=f, g=g, operator=operator, tau=tau, sigma=sigma, max_iteration=1000, update_objective_interval=500) pdhg.run(verbose=0) subsets = 10 size_of_subsets = int(len(angles) / subsets) # take angles and create uniform subsets in uniform+sequential setting list_angles = [ angles[i:i + size_of_subsets] for i in range(0, len(angles), size_of_subsets) ] # create acquisitioin geometries for each the interval of splitting angles list_geoms = [ AcquisitionGeometry('parallel', '2D', list_angles[i], detectors, pixel_size_h=0.1, angle_unit='radian') for i in range(len(list_angles)) ] # create with operators as many as the subsets A = BlockOperator(*[ AstraProjectorSimple(ig, list_geoms[i], dev) for i in range(subsets) ]) ## number of subsets #(sub2ind, ind2sub) = divide_1Darray_equally(range(len(A)), subsets) # ## acquisisiton data AD_list = [] for sub_num in range(subsets): for i in range(0, len(angles), size_of_subsets): arr = noisy_data.as_array()[i:i + size_of_subsets, :] AD_list.append( AcquisitionData(arr, geometry=list_geoms[sub_num])) g = BlockDataContainer(*AD_list) ## block function F = BlockFunction(*[KullbackLeibler(b=g[i]) for i in range(subsets)]) G = alpha * TotalVariation(50, 1e-4, lower=0) prob = [1 / len(A)] * len(A) spdhg = SPDHG(f=F, g=G, operator=A, max_iteration=1000, update_objective_interval=200, prob=prob) spdhg.run(1000, verbose=0) from cil.utilities.quality_measures import mae, mse, psnr qm = (mae(spdhg.get_output(), pdhg.get_output()), mse(spdhg.get_output(), pdhg.get_output()), psnr(spdhg.get_output(), pdhg.get_output())) if debug_print: print("Quality measures", qm) np.testing.assert_almost_equal(mae(spdhg.get_output(), pdhg.get_output()), 0.000335, decimal=3) np.testing.assert_almost_equal(mse(spdhg.get_output(), pdhg.get_output()), 5.51141e-06, decimal=3)
def test_PDHG_vs_PDHG_explicit_axpby(self): data = dataexample.SIMPLE_PHANTOM_2D.get(size=(128, 128)) if debug_print: print("test_PDHG_vs_PDHG_explicit_axpby here") ig = data.geometry ig.voxel_size_x = 0.1 ig.voxel_size_y = 0.1 detectors = ig.shape[0] angles = np.linspace(0, np.pi, 180) ag = AcquisitionGeometry('parallel', '2D', angles, detectors, pixel_size_h=0.1, angle_unit='radian') dev = 'cpu' Aop = AstraProjectorSimple(ig, ag, dev) sin = Aop.direct(data) # Create noisy data. Apply Gaussian noise noises = ['gaussian', 'poisson'] noise = noises[1] if noise == 'poisson': np.random.seed(10) scale = 5 eta = 0 noisy_data = AcquisitionData( np.random.poisson(scale * (eta + sin.as_array())) / scale, geometry=ag) elif noise == 'gaussian': np.random.seed(10) n1 = np.random.normal(0, 0.1, size=ag.shape) noisy_data = AcquisitionData(n1 + sin.as_array(), geometry=ag) else: raise ValueError('Unsupported Noise ', noise) alpha = 0.5 op1 = GradientOperator(ig) op2 = Aop # Create BlockOperator operator = BlockOperator(op1, op2, shape=(2, 1)) f2 = KullbackLeibler(b=noisy_data) g = IndicatorBox(lower=0) normK = operator.norm() sigma = 1. / normK tau = 1. / normK f1 = alpha * MixedL21Norm() f = BlockFunction(f1, f2) # Setup and run the PDHG algorithm algos = [] algos.append( PDHG(f=f, g=g, operator=operator, tau=tau, sigma=sigma, max_iteration=1000, update_objective_interval=200, use_axpby=True)) algos[0].run(1000, verbose=0) algos.append( PDHG(f=f, g=g, operator=operator, tau=tau, sigma=sigma, max_iteration=1000, update_objective_interval=200, use_axpby=False)) algos[1].run(1000, verbose=0) from cil.utilities.quality_measures import mae, mse, psnr qm = (mae(algos[0].get_output(), algos[1].get_output()), mse(algos[0].get_output(), algos[1].get_output()), psnr(algos[0].get_output(), algos[1].get_output())) if debug_print: print("Quality measures", qm) np.testing.assert_array_less(qm[0], 0.005) np.testing.assert_array_less(qm[1], 3e-05)
def test_2D(self): # #%% AstraProjectorSimple cpu ig = self.ig_2D.copy() ag = self.ag_slice.copy() A = AstraProjectorSimple(ig, ag, device='cpu') fp = A.direct(self.golden_data_cs) bp = A.adjoint(fp) #%% AstraProjectorSimple gpu ig = self.ig_2D.copy() ag = self.ag_slice.copy() A = AstraProjectorSimple(ig, ag, device='gpu') fp_gpu = A.direct(self.golden_data_cs) bp_gpu = A.adjoint(fp_gpu) np.testing.assert_allclose(fp_gpu.as_array(), fp.as_array(), atol=0.8) np.testing.assert_allclose(bp_gpu.as_array(), bp.as_array(), atol=12) # #%% AstraProjectorFlexible as a 2D ig = self.ig_2D.copy() ag = self.ag_slice.copy() A = AstraProjectorFlexible(ig, ag) fp_flex = A.direct(self.golden_data_cs) bp_flex = A.adjoint(fp_flex) np.testing.assert_allclose(fp_flex.as_array(), fp.as_array(), atol=0.8) np.testing.assert_allclose(bp_flex.as_array(), bp.as_array(), atol=12)