def test_ImageDataSubset(self): new_order = ['horizontal_x', 'channel', 'horizontal_y', ] vgeometry = ImageGeometry(voxel_num_x=4, voxel_num_y=3, channels=2, dimension_labels=new_order) # expected dimension_labels self.assertListEqual(new_order, vgeometry.dimension_labels) vol = vgeometry.allocate() # test reshape new_order = [ 'channel', 'horizontal_x','horizontal_y'] ss = vol.subset(new_order) self.assertListEqual(new_order, ss.geometry.dimension_labels) ss1 = ss.subset(horizontal_x = 0) self.assertListEqual([ 'channel', 'horizontal_y'], ss1.geometry.dimension_labels) vg = ImageGeometry(3,4,5,channels=2) self.assertListEqual([ImageGeometry.CHANNEL, ImageGeometry.VERTICAL, ImageGeometry.HORIZONTAL_Y, ImageGeometry.HORIZONTAL_X], vg.dimension_labels) ss2 = vg.allocate() ss3 = ss2.subset(vertical = 0, channel=0) self.assertListEqual([ImageGeometry.HORIZONTAL_Y, ImageGeometry.HORIZONTAL_X], ss3.geometry.dimension_labels)
def test_axpby(self): # test axpby between BlockDataContainers ig0 = ImageGeometry(2, 3, 4) ig1 = ImageGeometry(2, 3, 5) data0 = ig0.allocate(-1) data2 = ig0.allocate(1) data1 = ig0.allocate(2) data3 = ig0.allocate(3) cp0 = BlockDataContainer(data0, data2) cp1 = BlockDataContainer(data1, data3) out = cp0 * 0. - 10 cp0.axpby(3, -2, cp1, out, num_threads=4) # operation should be [ 3 * -1 + (-2) * 2 , 3 * 1 + (-2) * 3 ] # output should be [ -7 , -3 ] res0 = ig0.allocate(-7) res2 = ig0.allocate(-3) res = BlockDataContainer(res0, res2) print("res0", res0.as_array()) print("res2", res2.as_array()) print("###############################") print("out_0", out.get_item(0).as_array()) print("out_1", out.get_item(1).as_array()) self.assertBlockDataContainerEqual(out, res)
def test_ImageData(self): # create ImageData from geometry vgeometry = ImageGeometry(voxel_num_x=4, voxel_num_y=3, channels=2) #vol = ImageData(geometry=vgeometry) vol = vgeometry.allocate() self.assertEqual(vol.shape, (2, 3, 4)) vol1 = vol + 1 self.assertNumpyArrayEqual(vol1.as_array(), numpy.ones(vol.shape)) vol1 = vol - 1 self.assertNumpyArrayEqual(vol1.as_array(), -numpy.ones(vol.shape)) vol1 = 2 * (vol + 1) self.assertNumpyArrayEqual(vol1.as_array(), 2 * numpy.ones(vol.shape)) vol1 = (vol + 1) / 2 self.assertNumpyArrayEqual(vol1.as_array(), numpy.ones(vol.shape) / 2) vol1 = vol + 1 self.assertEqual(vol1.sum(), 2*3*4) vol1 = (vol + 2) ** 2 self.assertNumpyArrayEqual(vol1.as_array(), numpy.ones(vol.shape) * 4) self.assertEqual(vol.number_of_dimensions, 3) ig2 = ImageGeometry (voxel_num_x=2,voxel_num_y=3,voxel_num_z=4, dimension_labels=[ImageGeometry.HORIZONTAL_X, ImageGeometry.HORIZONTAL_Y, ImageGeometry.VERTICAL]) data = ig2.allocate() self.assertNumpyArrayEqual(numpy.asarray(data.shape), numpy.asarray(ig2.shape)) self.assertNumpyArrayEqual(numpy.asarray(data.shape), data.as_array().shape)
def skiptest_BlockDataContainerShapeArithmetic(self): print("test block data container") ig0 = ImageGeometry(2, 3, 4) ig1 = ImageGeometry(2, 3, 4) data0 = ImageData(geometry=ig0) data1 = ImageData(geometry=ig1) + 1 data2 = ImageData(geometry=ig0) + 2 data3 = ImageData(geometry=ig1) + 3 cp0 = BlockDataContainer(data0, data1) #cp1 = BlockDataContainer(data2,data3) cp1 = cp0 + 1 self.assertTrue(cp1.shape == cp0.shape) cp1 = cp0.T + 1 transpose_shape = (cp0.shape[1], cp0.shape[0]) self.assertTrue(cp1.shape == transpose_shape) cp1 = cp0.T - 1 transpose_shape = (cp0.shape[1], cp0.shape[0]) self.assertTrue(cp1.shape == transpose_shape) cp1 = (cp0.T + 1) * 2 transpose_shape = (cp0.shape[1], cp0.shape[0]) self.assertTrue(cp1.shape == transpose_shape) cp1 = (cp0.T + 1) / 2 transpose_shape = (cp0.shape[1], cp0.shape[0]) self.assertTrue(cp1.shape == transpose_shape) cp1 = cp0.T.power(2.2) transpose_shape = (cp0.shape[1], cp0.shape[0]) self.assertTrue(cp1.shape == transpose_shape) cp1 = cp0.T.maximum(3) transpose_shape = (cp0.shape[1], cp0.shape[0]) self.assertTrue(cp1.shape == transpose_shape) cp1 = cp0.T.abs() transpose_shape = (cp0.shape[1], cp0.shape[0]) self.assertTrue(cp1.shape == transpose_shape) cp1 = cp0.T.sign() transpose_shape = (cp0.shape[1], cp0.shape[0]) self.assertTrue(cp1.shape == transpose_shape) cp1 = cp0.T.sqrt() transpose_shape = (cp0.shape[1], cp0.shape[0]) self.assertTrue(cp1.shape == transpose_shape) cp1 = cp0.T.conjugate() transpose_shape = (cp0.shape[1], cp0.shape[0]) self.assertTrue(cp1.shape == transpose_shape)
def setUp(self): N, M = 20, 30 K = 20 C = 20 self.decimal = 1 self.iterations = 50 ########################################################################### # 2D geometry no channels self.ig = ImageGeometry(N, M) self.ig2 = ImageGeometry(N, M, channels = C) self.ig3 = ImageGeometry(N, M, K)
def skiptest_BlockDataContainerShape(self): print("test block data container") ig0 = ImageGeometry(12, 42, 55, 32) ig1 = ImageGeometry(12, 42, 55, 32) data0 = ImageData(geometry=ig0) data1 = ImageData(geometry=ig1) + 1 data2 = ImageData(geometry=ig0) + 2 data3 = ImageData(geometry=ig1) + 3 cp0 = BlockDataContainer(data0, data1) cp1 = BlockDataContainer(data2, data3) transpose_shape = (cp0.shape[1], cp0.shape[0]) self.assertTrue(cp0.T.shape == transpose_shape)
def test_NestedBlockDataContainer(self): ig0 = ImageGeometry(2, 3, 4) ig1 = ImageGeometry(2, 3, 5) data0 = ig0.allocate(0) data2 = ig0.allocate(1) cp0 = BlockDataContainer(data0, data2) #cp1 = BlockDataContainer(data2,data3) nested = BlockDataContainer(cp0, data2, data2) out = BlockDataContainer(BlockDataContainer(data0, data0), data0, data0) nested.divide(data2, out=out) self.assertBlockDataContainerEqual(out, nested)
def process(self): projections = self.get_input() projections_axes = projections.get_data_axes_order(new_order=self.default_acquisition_axes_order) if not projections_axes == [0,1,2]: projections.array = numpy.transpose(projections.array, projections_axes) pixel_per_voxel = 1 # should be estimated from image_geometry and acquisition_geometry image_geometry = ImageGeometry(voxel_num_x = self.acquisition_geometry.pixel_num_h, voxel_num_y = self.acquisition_geometry.pixel_num_h, voxel_num_z = self.acquisition_geometry.pixel_num_v) # input centered/padded acquisitiondata center_of_rotation = projections.get_dimension_size('horizontal') / 2 if self.acquisition_geometry.geom_type == 'parallel': back = pbalg.pb_backward_project( projections.as_array(), self.acquisition_geometry.angles, center_of_rotation, pixel_per_voxel ) out = ImageData(geometry=self.image_geometry, dimension_labels=self.default_image_axes_order) out_axes = out.get_data_axes_order(new_order=self.output_axes_order) if not out_axes == [0,1,2]: back = numpy.transpose(back, out_axes) out.fill(back) return out else: raise ValueError('Cannot process cone beam')
def test_GradientDescentArmijo(self): print ("Test GradientDescent") ig = ImageGeometry(12,13,14) x_init = ig.allocate() # b = x_init.copy() # fill with random numbers # b.fill(numpy.random.random(x_init.shape)) b = ig.allocate('random') identity = Identity(ig) norm2sq = LeastSquares(identity, b) rate = None alg = GradientDescent(x_init=x_init, objective_function=norm2sq, rate=rate) alg.max_iteration = 100 alg.run() self.assertNumpyArrayAlmostEqual(alg.x.as_array(), b.as_array()) alg = GradientDescent(x_init=x_init, objective_function=norm2sq, max_iteration=20, update_objective_interval=2) #alg.max_iteration = 20 self.assertTrue(alg.max_iteration == 20) self.assertTrue(alg.update_objective_interval==2) alg.run(20, verbose=True) self.assertNumpyArrayAlmostEqual(alg.x.as_array(), b.as_array())
def test_FISTA_catch_Lipschitz(self): print ("Test FISTA catch Lipschitz") ig = ImageGeometry(127,139,149) x_init = ImageData(geometry=ig) x_init = ig.allocate() b = x_init.copy() # fill with random numbers b.fill(numpy.random.random(x_init.shape)) x_init = ig.allocate(ImageGeometry.RANDOM) identity = Identity(ig) #### it seems FISTA does not work with Nowm2Sq norm2sq = LeastSquares(identity, b) print ('Lipschitz', norm2sq.L) norm2sq.L = None #norm2sq.L = 2 * norm2sq.c * identity.norm()**2 #norm2sq = FunctionOperatorComposition(L2NormSquared(b=b), identity) opt = {'tol': 1e-4, 'memopt':False} print ("initial objective", norm2sq(x_init)) try: alg = FISTA(x_init=x_init, f=norm2sq, g=ZeroFunction()) self.assertTrue(False) except ValueError as ve: print (ve) self.assertTrue(True)
def test_Gradient_linearity(self): nc, nz, ny, nx = 3, 4, 5, 6 ig = ImageGeometry(voxel_num_x=nx, voxel_num_y=ny, voxel_num_z=nz, channels=nc) grad = Gradient(ig, bnd_cond='Neumann', correlation='SpaceChannels', backend='c') self.assertTrue(LinearOperator.dot_test(grad)) grad = Gradient(ig, bnd_cond='Periodic', correlation='SpaceChannels', backend='c') self.assertTrue(LinearOperator.dot_test(grad)) grad = Gradient(ig, bnd_cond='Neumann', correlation='SpaceChannels', backend='numpy') self.assertTrue(LinearOperator.dot_test(grad)) grad = Gradient(ig, bnd_cond='Periodic', correlation='SpaceChannels', backend='numpy') self.assertTrue(LinearOperator.dot_test(grad))
def test_ScaledOperator(self): print ("test_ScaledOperator") ig = ImageGeometry(10,20,30) img = ig.allocate() scalar = 0.5 sid = scalar * Identity(ig) numpy.testing.assert_array_equal(scalar * img.as_array(), sid.direct(img).as_array())
def test_Function(self): N = 3 ig = ImageGeometry(N, N) ag = ig op1 = Gradient(ig) op2 = Identity(ig, ag) # Form Composite Operator operator = BlockOperator(op1, op2, shape=(2, 1)) # Create functions noisy_data = ag.allocate(ImageGeometry.RANDOM_INT) d = ag.allocate(ImageGeometry.RANDOM_INT) alpha = 0.5 # scaled function g = alpha * L2NormSquared(b=noisy_data) # Compare call of g a2 = alpha * (d - noisy_data).power(2).sum() #print(a2, g(d)) self.assertEqual(a2, g(d)) # Compare convex conjugate of g a3 = 0.5 * d.squared_norm() + d.dot(noisy_data) self.assertEqual(a3, g.convex_conjugate(d))
def test_Norm(self): print ("test_BlockOperator") ## numpy.random.seed(1) N, M = 200, 300 ig = ImageGeometry(N, M) G = Gradient(ig) t0 = timer() norm = G.norm() t1 = timer() norm2 = G.norm() t2 = timer() norm3 = G.norm(force=True) t3 = timer() print ("Norm dT1 {} dT2 {} dT3 {}".format(t1-t0,t2-t1, t3-t2)) self.assertLess(t2-t1, t1-t0) self.assertLess(t2-t1, t3-t2) numpy.random.seed(1) t4 = timer() norm4 = G.norm(iterations=50, force=True) t5 = timer() self.assertLess(t2-t1, t5-t4) numpy.random.seed(1) t4 = timer() norm5 = G.norm(x_init=ig.allocate('random'), iterations=50, force=True) t5 = timer() self.assertLess(t2-t1, t5-t4) for n in [norm, norm2, norm3, norm4, norm5]: print ("norm {}", format(n))
def test_axpby2(self): # test axpby with BlockDataContainer and DataContainer ig0 = ImageGeometry(2, 3, 4) # ig1 = ImageGeometry(2,3,5) data0 = ig0.allocate(-1) data2 = ig0.allocate(1) data1 = ig0.allocate(2) # data3 = ig1.allocate(3) cp0 = BlockDataContainer(data0, data2) # cp1 = BlockDataContainer(data1,data3) out = cp0 * 0. - 10 cp0.axpby(3, -2, data1, out) # operation should be [ 3 * -1 + (-2) * 2 , 3 * 1 + (-2) * 2 ] # output should be [ -7 , -1 ] res0 = ig0.allocate(-7) res2 = ig0.allocate(-1) res = BlockDataContainer(res0, res2) print("res0", res0.as_array()) print("res2", res2.as_array()) print("###############################") print("out_0", out.get_item(0).as_array()) print("out_1", out.get_item(1).as_array()) self.assertBlockDataContainerEqual(out, res)
def test_PowerMethod(self): print ("test_BlockOperator") N, M = 200, 300 niter = 10 ig = ImageGeometry(N, M) Id = Identity(ig) G = Gradient(ig) uid = Id.domain_geometry().allocate(ImageGeometry.RANDOM_INT, seed=1) a = LinearOperator.PowerMethod(Id, niter, uid) #b = LinearOperator.PowerMethodNonsquare(Id, niter, uid) b = LinearOperator.PowerMethod(Id, niter) print ("Edo impl", a[0]) print ("None impl", b[0]) #self.assertAlmostEqual(a[0], b[0]) self.assertNumpyArrayAlmostEqual(a[0],b[0],decimal=6) a = LinearOperator.PowerMethod(G, niter, uid) b = LinearOperator.PowerMethod(G, niter) #b = LinearOperator.PowerMethodNonsquare(G, niter, uid) print ("Edo impl", a[0]) #print ("old impl", b[0]) self.assertNumpyArrayAlmostEqual(a[0],b[0],decimal=2)
def test_mixedL12Norm(self): M, N, K = 2, 3, 5 ig = ImageGeometry(voxel_num_x=M, voxel_num_y=N) u1 = ig.allocate('random_int') u2 = ig.allocate('random_int') U = BlockDataContainer(u1, u2, shape=(2, 1)) # Define no scale and scaled f_no_scaled = MixedL21Norm() f_scaled = 1 * MixedL21Norm() # call a1 = f_no_scaled(U) a2 = f_scaled(U) self.assertNumpyArrayAlmostEqual(a1, a2) tmp = [el**2 for el in U.containers] self.assertBlockDataContainerEqual(BlockDataContainer(*tmp), U.power(2)) z1 = f_no_scaled.proximal_conjugate(U, 1) u3 = ig.allocate('random_int') u4 = ig.allocate('random_int') z3 = BlockDataContainer(u3, u4, shape=(2, 1)) f_no_scaled.proximal_conjugate(U, 1, out=z3) self.assertBlockDataContainerEqual(z3, z1)
def test_FISTA_Norm2Sq(self): print ("Test FISTA Norm2Sq") ig = ImageGeometry(127,139,149) b = ig.allocate(ImageGeometry.RANDOM) # fill with random numbers x_init = ig.allocate(ImageGeometry.RANDOM) identity = Identity(ig) #### it seems FISTA does not work with Nowm2Sq norm2sq = LeastSquares(identity, b) #norm2sq.L = 2 * norm2sq.c * identity.norm()**2 #norm2sq = FunctionOperatorComposition(L2NormSquared(b=b), identity) opt = {'tol': 1e-4, 'memopt':False} print ("initial objective", norm2sq(x_init)) alg = FISTA(x_init=x_init, f=norm2sq, g=ZeroFunction()) alg.max_iteration = 2 alg.run(20, verbose=True) self.assertNumpyArrayAlmostEqual(alg.x.as_array(), b.as_array()) alg = FISTA(x_init=x_init, f=norm2sq, g=ZeroFunction(), max_iteration=2, update_objective_interval=3) self.assertTrue(alg.max_iteration == 2) self.assertTrue(alg.update_objective_interval== 3) alg.run(20, verbose=True) self.assertNumpyArrayAlmostEqual(alg.x.as_array(), b.as_array())
def stest_NestedBlockDataContainer2(self): M, N = 2, 3 ig = ImageGeometry(voxel_num_x=M, voxel_num_y=N) ag = ig u = ig.allocate(1) op1 = Gradient(ig) op2 = Identity(ig, ag) operator = BlockOperator(op1, op2, shape=(2, 1)) d1 = op1.direct(u) d2 = op2.direct(u) d = operator.direct(u) dd = operator.domain_geometry() ww = operator.range_geometry() print(d.get_item(0).get_item(0).as_array()) print(d.get_item(0).get_item(1).as_array()) print(d.get_item(1).as_array()) c1 = d + d c2 = 2 * d c3 = d / (d + 0.0001) c5 = d.get_item(0).power(2).sum()
def test_CGLS(self): print ("Test CGLS") #ig = ImageGeometry(124,153,154) ig = ImageGeometry(10,2) numpy.random.seed(2) x_init = ig.allocate(0.) b = ig.allocate('random') # b = x_init.copy() # fill with random numbers # b.fill(numpy.random.random(x_init.shape)) # b = ig.allocate() # bdata = numpy.reshape(numpy.asarray([i for i in range(20)]), (2,10)) # b.fill(bdata) identity = Identity(ig) alg = CGLS(x_init=x_init, operator=identity, data=b) alg.max_iteration = 200 alg.run(20, verbose=True) self.assertNumpyArrayAlmostEqual(alg.x.as_array(), b.as_array()) alg = CGLS(x_init=x_init, operator=identity, data=b, max_iteration=200, update_objective_interval=2) self.assertTrue(alg.max_iteration == 200) self.assertTrue(alg.update_objective_interval==2) alg.run(20, verbose=True) self.assertNumpyArrayAlmostEqual(alg.x.as_array(), b.as_array())
def test_max(self): print ("test max") ig = ImageGeometry(10,10) a = numpy.asarray(numpy.linspace(-10,10, num=100, endpoint=True), dtype=numpy.float32) a = a.reshape((10,10)) d1 = ig.allocate(1) d1.fill(a) self.assertAlmostEqual(d1.max(), 10.)
def testwriteImageData(self): im_size = 5 ig = ImageGeometry(voxel_num_x = im_size, voxel_num_y = im_size) im = ig.allocate() writer = NEXUSDataWriter() writer.set_up(file_name = os.path.join(os.getcwd(), 'test_nexus_im.nxs'), data_container = im) writer.write_file() self.stestreadImageData()
def test_axpby(self): print ("test axpby") ig = ImageGeometry(10,10) d1 = ig.allocate(1) d2 = ig.allocate(2) out = ig.allocate(None) # equals to 2 * [1] + 1 * [2] = [4] d1.axpby(2,1,d2,out) res = numpy.ones_like(d1.as_array()) * 4. numpy.testing.assert_array_equal(res, out.as_array())
def test_Identity(self): print ("test_Identity") ig = ImageGeometry(10,20,30) img = ig.allocate() # img.fill(numpy.ones((30,20,10))) self.assertTrue(img.shape == (30,20,10)) #self.assertEqual(img.sum(), 2*float(10*20*30)) self.assertEqual(img.sum(), 0.) Id = Identity(ig) y = Id.direct(img) numpy.testing.assert_array_equal(y.as_array(), img.as_array())
def test_axpby4(self): # test axpby with nested BlockDataContainer ig0 = ImageGeometry(2, 3, 4) ig1 = ImageGeometry(2, 3, 5) data0 = ig0.allocate(-1) data2 = ig0.allocate(1) # data1 = ig0.allocate(2) data3 = ig1.allocate(3) cp0 = BlockDataContainer(data0, data2) cp1 = BlockDataContainer(cp0 * 0. + [2, -2], data3) print(cp1.get_item(0).get_item(0).as_array()) print(cp1.get_item(0).get_item(1).as_array()) print(cp1.get_item(1).as_array()) print("###############################") out = cp1 * 0. cp2 = out + [1, 3] print(cp2.get_item(0).get_item(0).as_array()) print(cp2.get_item(0).get_item(1).as_array()) print(cp2.get_item(1).as_array()) cp2.axpby(3, -2, cp1, out, num_threads=4) # output should be [ [ -1 , 7 ] , 3] res0 = ig0.allocate(-1) res2 = ig0.allocate(7) res3 = ig1.allocate(3) res = BlockDataContainer(BlockDataContainer(res0, res2), res3) # print ("res0", res0.as_array()) # print ("res2", res2.as_array()) print("###############################") # print ("out_0", out.get_item(0).as_array()) # print ("out_1", out.get_item(1).as_array()) self.assertBlockDataContainerEqual(out, res)
def setUp(self): self.ig = ImageGeometry(1, 2, 3, channels=4) angles = numpy.asarray([90., 0., -90.], dtype=numpy.float32) self.ag = AcquisitionGeometry('cone', 'edo', pixel_num_h=20, pixel_num_v=2, angles=angles, dist_source_center=312.2, dist_center_detector=123., channels=4)
def test_IndicatorBox(self): ig = ImageGeometry(10, 10) im = ig.allocate(-1) ib = IndicatorBox(lower=0) a = ib(im) numpy.testing.assert_equal(a, numpy.inf) ib = IndicatorBox(lower=-2) a = ib(im) numpy.testing.assert_array_equal(0, a) ib = IndicatorBox(lower=-5, upper=-2) a = ib(im) numpy.testing.assert_equal(a, numpy.inf)
def setUp(self): #wget.download('https://github.com/DiamondLightSource/Savu/raw/master/test_data/data/24737_fd.nxs') #self.filename = '24737_fd.nxs' # we use TomoIdentity as the operator and solve the simple least squares # problem for a random-valued ImageData or AcquisitionData b? # Then we know the minimiser is b itself # || I x -b ||^2 # create an ImageGeometry ig = ImageGeometry(12,13,14) pass
def __init__(self, geomv, geomp, default=False): super(CCPiProjectorSimple, self).__init__() # Store volume and sinogram geometries. self.acquisition_geometry = geomp self.volume_geometry = geomv if geomp.geom_type == "cone": raise TypeError('Can only handle parallel beam') # set-up the geometries if compatible geoms = setupCCPiGeometries(geomv, geomp, 0) vg = ImageGeometry(voxel_num_x=geoms['output_volume_x'], voxel_num_y=geoms['output_volume_y'], voxel_num_z=geoms['output_volume_z']) pg = AcquisitionGeometry('parallel', '3D', geomp.angles, geoms['n_h'], geomp.pixel_size_h, geoms['n_v'], geomp.pixel_size_v #2D in 3D is a slice 1 pixel thick ) if not default: # check if geometry is the same (on the voxels) if not ( vg.voxel_num_x == geomv.voxel_num_x and \ vg.voxel_num_y == geomv.voxel_num_y and \ vg.voxel_num_z == geomv.voxel_num_z ): msg = 'The required volume geometry will not work\nThe following would\n' msg += vg.__str__() raise ValueError(msg) if not (pg.pixel_num_h == geomp.pixel_num_h and \ pg.pixel_num_v == geomp.pixel_num_v and \ len( pg.angles ) == len( geomp.angles ) ) : msg = 'The required acquisition geometry will not work\nThe following would\n' msg += pg.__str__() raise ValueError(msg) self.fp = CCPiForwardProjector(image_geometry=vg, acquisition_geometry=pg, output_axes_order=['angle','vertical','horizontal']) self.bp = CCPiBackwardProjector(image_geometry=vg, acquisition_geometry=pg, output_axes_order=[ ImageGeometry.HORIZONTAL_X, ImageGeometry.HORIZONTAL_Y, ImageGeometry.VERTICAL]) # Initialise empty for singular value. self.s1 = None self.ag = pg self.vg = vg
def create_simple_ImageData(self): N = 64 ig = ImageGeometry(voxel_num_x=N, voxel_num_y=N) Phantom = ImageData(geometry=ig) x = Phantom.as_array() x[int(round(N/4)):int(round(3*N/4)), int(round(N/4)):int(round(3*N/4))] = 0.5 x[int(round(N/8)):int(round(7*N/8)), int(round(3*N/8)):int(round(5*N/8))] = 1 return (ig, Phantom)