def test_equal(self):
        AG = AcquisitionGeometry.create_Parallel3D()
        AG.set_channels(4, ['a','b','c','d'])
        AG.set_panel([2,3])
        AG.set_angles([0,1,2,3,5])
        AG.set_labels(('horizontal','angle','vertical','channel'))

        AG2 = AcquisitionGeometry.create_Parallel3D()
        AG2.set_channels(4, ['a','b','c','d'])
        AG2.set_panel([2,3])
        AG2.set_angles([0,1,2,3,5])
        AG2.set_labels(('horizontal','angle','vertical','channel'))
        self.assertTrue(AG == AG2)

        #test not equal
        AG3 = AG2.copy()
        AG3.config.system.ray.direction = [1,0,0]
        self.assertFalse(AG == AG3)

        AG3 = AG2.copy()
        AG3.config.panel.num_pixels = [1,2]
        self.assertFalse(AG == AG3)

        AG3 = AG2.copy()
        AG3.config.channels.channel_labels = ['d','b','c','d']
        self.assertFalse(AG == AG3)

        AG3 = AG2.copy()
        AG3.config.angles.angle_unit ='radian'
        self.assertFalse(AG == AG3)

        AG3 = AG2.copy()
        AG3.config.angles.angle_data[0] = -1
        self.assertFalse(AG == AG3)
    def test_create_Parallel2D(self):

        #default
        AG = AcquisitionGeometry.create_Parallel2D()
        numpy.testing.assert_allclose(AG.config.system.ray.direction, [0,1], rtol=1E-6)
        numpy.testing.assert_allclose(AG.config.system.detector.position, [0,0], rtol=1E-6)
        numpy.testing.assert_allclose(AG.config.system.detector.direction_x, [1,0], rtol=1E-6)
        numpy.testing.assert_allclose(AG.config.system.rotation_axis.position, [0,0], rtol=1E-6)

        #values
        ray_direction = [0.1, 3.0]
        detector_position = [-1.3,1000.0]
        detector_direction_x = [1,0.2]
        rotation_axis_position = [0.1,2]

        AG = AcquisitionGeometry.create_Parallel2D(ray_direction, detector_position, detector_direction_x, rotation_axis_position)

        ray_direction = numpy.asarray(ray_direction)
        detector_direction_x = numpy.asarray(detector_direction_x)

        ray_direction /= numpy.sqrt((ray_direction**2).sum())
        detector_direction_x /= numpy.sqrt((detector_direction_x**2).sum())

        numpy.testing.assert_allclose(AG.config.system.ray.direction, ray_direction, rtol=1E-6)
        numpy.testing.assert_allclose(AG.config.system.detector.position, detector_position, rtol=1E-6)
        numpy.testing.assert_allclose(AG.config.system.detector.direction_x, detector_direction_x, rtol=1E-6)
        numpy.testing.assert_allclose(AG.config.system.rotation_axis.position, rotation_axis_position, rtol=1E-6)
Пример #3
0
    def setUp(self):
        #%% Setup Geometry
        voxel_num_xy = 16
        voxel_num_z = 4

        pix_size = 0.2
        det_pix_x = voxel_num_xy
        det_pix_y = voxel_num_z

        num_projections = 36
        angles = np.linspace(0, 360, num=num_projections, endpoint=False)

        self.ag = AcquisitionGeometry.create_Parallel2D()\
                                           .set_angles(angles)\
                                           .set_panel(det_pix_x, pix_size)\
                                           .set_labels(['angle','horizontal'])

        self.ig = self.ag.get_ImageGeometry()

        self.ag3D = AcquisitionGeometry.create_Parallel3D()\
                                     .set_angles(angles)\
                                     .set_panel((det_pix_x,det_pix_y), (pix_size,pix_size))\
                                     .set_labels(['angle','vertical','horizontal'])
        self.ig3D = self.ag3D.get_ImageGeometry()

        self.ad3D = self.ag3D.allocate('random')
        self.ig3D = self.ag3D.get_ImageGeometry()
Пример #4
0
    def test_AcquisitionData(self):
        ag = AcquisitionGeometry.create_Parallel3D().set_panel(
            [5, 4]).set_angles([0, 1, 2]).set_channels(2).set_labels(
                ['channel', 'angle', 'vertical', 'horizontal'])
        data = ag.allocate(None)
        data_new = data.get_slice(angle=2)
        self.assertEquals(data_new.shape, (2, 4, 5))
        self.assertEquals(data_new.geometry.dimension_labels,
                          ('channel', 'vertical', 'horizontal'))

        #won't return a geometry for un-reconstructable slice
        ag = AcquisitionGeometry.create_Cone3D(
            [0, -200, 0], [0, 200, 0]).set_panel([5, 4]).set_angles(
                [0, 1, 2]).set_channels(2).set_labels(
                    ['channel', 'angle', 'vertical', 'horizontal'])
        data = ag.allocate('random')
        data_new = data.get_slice(vertical=1, force=True)
        self.assertEquals(data_new.shape, (2, 3, 5))
        self.assertTrue(isinstance(data_new, (DataContainer)))
        self.assertIsNone(data_new.geometry)
        self.assertEquals(data_new.dimension_labels,
                          ('channel', 'angle', 'horizontal'))

        #if 'centre' is between pixels interpolates
        data_new = data.get_slice(vertical='centre')
        self.assertEquals(data_new.shape, (2, 3, 5))
        self.assertEquals(data_new.geometry.dimension_labels,
                          ('channel', 'angle', 'horizontal'))
        numpy.testing.assert_allclose(
            data_new.array,
            (data.array[:, :, 1, :] + data.array[:, :, 2, :]) / 2)
    def test_get_ImageGeometry(self):

        AG = AcquisitionGeometry.create_Parallel2D()\
            .set_panel(num_pixels=[512,1],pixel_size=[0.1,0.1])      
        IG = AG.get_ImageGeometry()
        IG_gold = ImageGeometry(512,512,0,0.1,0.1,1,0,0,0,1)
        self.assertEqual(IG, IG_gold)

        AG = AcquisitionGeometry.create_Parallel3D()\
            .set_panel(num_pixels=[512,3],pixel_size=[0.1,0.2])
        IG = AG.get_ImageGeometry()
        IG_gold = ImageGeometry(512,512,3,0.1,0.1,0.2,0,0,0,1)
        self.assertEqual(IG, IG_gold)

        AG = AcquisitionGeometry.create_Cone2D(source_position=[0,-500], detector_position=[0.,500.])\
            .set_panel(num_pixels=[512,1],pixel_size=[0.1,0.2])
        IG = AG.get_ImageGeometry()
        IG_gold = ImageGeometry(512,512,0,0.05,0.05,1,0,0,0,1)
        self.assertEqual(IG, IG_gold)

        AG = AcquisitionGeometry.create_Cone3D(source_position=[0,-500,0], detector_position=[0.,500.,0])\
            .set_panel(num_pixels=[512,3],pixel_size=[0.1,0.2])
        IG = AG.get_ImageGeometry()
        IG_gold = ImageGeometry(512,512,3,0.05,0.05,0.1,0,0,0,1)
        self.assertEqual(IG, IG_gold)

        AG = AcquisitionGeometry.create_Cone3D(source_position=[0,-500,0], detector_position=[0.,500.,0])\
            .set_panel(num_pixels=[512,3],pixel_size=[0.1,0.2])
        IG = AG.get_ImageGeometry(resolution=0.5)
        IG_gold = ImageGeometry(256,256,2,0.025,0.025,0.05,0,0,0,1)
        self.assertEqual(IG, IG_gold)
    def test_system_description(self):
        AG = AcquisitionGeometry.create_Cone3D(source_position=[0, -50, 0],
                                               detector_position=[0, 100, 0])
        self.assertTrue(AG.system_description == 'simple')

        AG = AcquisitionGeometry.create_Cone3D(source_position=[-50, 0, 0],
                                               detector_position=[100, 0, 0],
                                               detector_direction_x=[0, -1, 0])
        self.assertTrue(AG.system_description == 'simple')

        AG = AcquisitionGeometry.create_Cone3D(
            source_position=[5, -50, 0],
            detector_position=[5, 100, 0],
            rotation_axis_position=[5, 0, 0])
        self.assertTrue(AG.system_description == 'simple')

        AG = AcquisitionGeometry.create_Cone3D(source_position=[5, -50, 0],
                                               detector_position=[0, 100, 0])
        self.assertTrue(AG.system_description == 'advanced')

        AG = AcquisitionGeometry.create_Cone3D(
            source_position=[0, -50, 0],
            detector_position=[0, 100, 0],
            rotation_axis_position=[5, 0, 0])
        self.assertTrue(AG.system_description == 'offset')
Пример #7
0
    def __init__(self, volume_geometry, sinogram_geometry):

        super(FBP_Flexible, self).__init__(volume_geometry=volume_geometry,
                                           sinogram_geometry=sinogram_geometry)

        #convert parallel geomerty to cone with large source to object
        sino_geom_cone = sinogram_geometry.copy()
        sino_geom_cone.config.system.update_reference_frame()

        #reverse ray direction unit-vector direction and extend to inf
        cone_source = -sino_geom_cone.config.system.ray.direction * sino_geom_cone.config.panel.pixel_size[
            1] * sino_geom_cone.config.panel.num_pixels[1] * 1e6
        detector_position = sino_geom_cone.config.system.detector.position
        detector_direction_x = sino_geom_cone.config.system.detector.direction_x

        if sinogram_geometry.dimension == '2D':
            tmp = AcquisitionGeometry.create_Cone2D(cone_source,
                                                    detector_position,
                                                    detector_direction_x)
        else:
            detector_direction_y = sino_geom_cone.config.system.detector.direction_y
            tmp = AcquisitionGeometry.create_Cone3D(cone_source,
                                                    detector_position,
                                                    detector_direction_x,
                                                    detector_direction_y)

        sino_geom_cone.config.system = tmp.config.system.copy()

        self.vol_geom_astra, self.proj_geom_astra = convert_geometry_to_astra_vec(
            volume_geometry, sino_geom_cone)
    def setUp(self): 

        N = 128
        angles = np.linspace(0, np.pi, 180, dtype='float32')

        ag = AcquisitionGeometry.create_Parallel2D()\
                                .set_angles(angles, angle_unit='radian')\
                                .set_panel(N, 0.1)\
                                .set_labels(['angle', 'horizontal'])
        
        ig = ag.get_ImageGeometry()

        
        ag3 = AcquisitionGeometry.create_Parallel3D()\
                                .set_angles(angles, angle_unit='radian')\
                                .set_panel((N, N), (0.1, 0.1))\
                                .set_labels(['vertical', 'angle', 'horizontal'])

        ig3 = ag3.get_ImageGeometry()

        self.ig = ig
        self.ag = ag
        self.ig3 = ig3
        self.ag3 = ag3
        self.norm = 14.85
    def test_calculate_magnification(self):
        AG = AcquisitionGeometry.create_Cone2D(source_position=[0,-500], detector_position=[0.,1000.])
        out = AG.config.system.calculate_magnification()
        self.assertEqual(out, [500, 1000, 3]) 

        AG = AcquisitionGeometry.create_Cone2D(source_position=[0,-500], detector_position=[0.,1000.], rotation_axis_position=[0.,250.])
        out = AG.config.system.calculate_magnification()
        self.assertEqual(out, [750, 750, 2]) 

        AG = AcquisitionGeometry.create_Cone2D(source_position=[0,-500], detector_position=[0.,1000.], rotation_axis_position=[5.,0.])
        out = AG.config.system.calculate_magnification()
        source_to_object = numpy.sqrt(5.0**2 + 500.0**2)
        theta = math.atan2(5.0,500.0)
        source_to_detector = 1500.0/math.cos(theta)
        self.assertEqual(out, [source_to_object, source_to_detector - source_to_object, source_to_detector/source_to_object]) 

        AG = AcquisitionGeometry.create_Cone2D(source_position=[0,-500], detector_position=[0.,1000.], rotation_axis_position=[5.,0.],detector_direction_x=[math.sqrt(5),math.sqrt(5)])
        out = AG.config.system.calculate_magnification()
        source_to_object = numpy.sqrt(5.0**2 + 500.0**2)

        ab = (AG.config.system.rotation_axis.position - AG.config.system.source.position).astype(numpy.float64)/source_to_object

        #source_position + d * ab = detector_position + t * detector_direction_x
        #x: d *  ab[0] =  t * detector_direction_x[0]
        #y: -500 + d *  ab[1] = 1000 + t * detector_direction_x[1] 

        # t = (d *  ab[0]) / math.sqrt(5)
        # d = 1500 / (ab[1]  - ab[0])

        source_to_detector = 1500 / (ab[1]  - ab[0])

        self.assertEqual(out, [source_to_object, source_to_detector - source_to_object, source_to_detector/source_to_object]) 
Пример #10
0
    def test_AcquisitionDataSubset(self):
        sgeometry = AcquisitionGeometry(dimension=2, angles=numpy.linspace(0, 180, num=10),
                                        geom_type='parallel', pixel_num_v=3,
                                        pixel_num_h=5, channels=2)
        # expected dimension_labels
        
        self.assertListEqual([AcquisitionGeometry.CHANNEL ,
                 AcquisitionGeometry.ANGLE , AcquisitionGeometry.VERTICAL ,
                 AcquisitionGeometry.HORIZONTAL],
                              list(sgeometry.dimension_labels))
        sino = sgeometry.allocate()

        # test reshape
        new_order = [AcquisitionGeometry.HORIZONTAL ,
                 AcquisitionGeometry.CHANNEL , AcquisitionGeometry.VERTICAL ,
                 AcquisitionGeometry.ANGLE]
        sino.reorder(new_order)

        self.assertListEqual(new_order, list(sino.geometry.dimension_labels))

        ss1 = sino.get_slice(vertical = 0)
        self.assertListEqual([AcquisitionGeometry.HORIZONTAL ,
                 AcquisitionGeometry.CHANNEL  ,
                 AcquisitionGeometry.ANGLE], list(ss1.geometry.dimension_labels))
        ss2 = sino.get_slice(vertical = 0, channel=0)
        self.assertListEqual([AcquisitionGeometry.HORIZONTAL ,
                 AcquisitionGeometry.ANGLE], list(ss2.geometry.dimension_labels))
Пример #11
0
    def setUp(self):
        #%% Setup Geometry
        voxel_num_xy = 255
        voxel_num_z = 15

        mag = 2
        src_to_obj = 50
        src_to_det = src_to_obj * mag

        pix_size = 0.2
        det_pix_x = voxel_num_xy
        det_pix_y = voxel_num_z

        num_projections = 1000
        angles = np.linspace(0, 360, num=num_projections, endpoint=False)

        self.ag = AcquisitionGeometry.create_Cone2D([0,-src_to_obj],[0,src_to_det-src_to_obj])\
                                           .set_angles(angles)\
                                           .set_panel(det_pix_x, pix_size)\
                                           .set_labels(['angle','horizontal'])

        self.ig = self.ag.get_ImageGeometry()

        self.ag3D = AcquisitionGeometry.create_Cone3D([0,-src_to_obj,0],[0,src_to_det-src_to_obj,0])\
                                     .set_angles(angles)\
                                     .set_panel((det_pix_x,det_pix_y), (pix_size,pix_size))\
                                     .set_labels(['angle','vertical','horizontal'])
        self.ig3D = self.ag3D.get_ImageGeometry()

        self.ad3D = self.ag3D.allocate('random')
        self.ig3D = self.ag3D.get_ImageGeometry()
Пример #12
0
    def setUp(self):
        #%% Setup Geometry
        voxel_num_xy = 255
        voxel_num_z = 15
        cs_ind = (voxel_num_z - 1) // 2

        mag = 2
        src_to_obj = 50
        src_to_det = src_to_obj * mag

        pix_size = 0.2
        det_pix_x = voxel_num_xy
        det_pix_y = voxel_num_z

        num_projections = 1000
        angles = np.linspace(0, 360, num=num_projections, endpoint=False)

        self.ag = AcquisitionGeometry.create_Cone2D([0,-src_to_obj],[0,src_to_det-src_to_obj])\
                                           .set_angles(angles)\
                                           .set_panel(det_pix_x, pix_size)\
                                           .set_labels(['angle','horizontal'])

        self.ig = self.ag.get_ImageGeometry()

        self.ag3D = AcquisitionGeometry.create_Cone3D([0,-src_to_obj,0],[0,src_to_det-src_to_obj,0])\
                                     .set_angles(angles)\
                                     .set_panel((det_pix_x,det_pix_y), (pix_size,pix_size))\
                                     .set_labels(['angle','vertical','horizontal'])
        self.ig3D = self.ag3D.get_ImageGeometry()

        #%% Create phantom
        kernel_size = voxel_num_xy
        kernel_radius = (kernel_size - 1) // 2
        y, x = np.ogrid[-kernel_radius:kernel_radius + 1,
                        -kernel_radius:kernel_radius + 1]

        circle1 = [5, 0, 0]  #r,x,y
        dist1 = ((x - circle1[1])**2 + (y - circle1[2])**2)**0.5

        circle2 = [5, 80, 0]  #r,x,y
        dist2 = ((x - circle2[1])**2 + (y - circle2[2])**2)**0.5

        circle3 = [25, 0, 80]  #r,x,y
        dist3 = ((x - circle3[1])**2 + (y - circle3[2])**2)**0.5

        mask1 = (dist1 - circle1[0]).clip(0, 1)
        mask2 = (dist2 - circle2[0]).clip(0, 1)
        mask3 = (dist3 - circle3[0]).clip(0, 1)
        phantom = 1 - np.logical_and(np.logical_and(mask1, mask2), mask3)

        self.golden_data = self.ig3D.allocate(0)
        for i in range(4):
            self.golden_data.fill(array=phantom, vertical=7 + i)

        self.golden_data_cs = self.golden_data.get_slice(vertical=cs_ind,
                                                         force=True)

        self.Op = ProjectionOperator(self.ig3D, self.ag3D)
        self.fp = self.Op.direct(self.golden_data)
Пример #13
0
    def read(self):
        '''
        Reads projections and return AcquisitionData container
        '''
        # the import will raise an ImportError if dxchange is not installed
        import dxchange
        # Load projections and most metadata
        data, metadata = dxchange.read_txrm(self.txrm_file)
        number_of_images = data.shape[0]
        
        # Read source to center and detector to center distances
        with olefile.OleFileIO(self.txrm_file) as ole:
            StoRADistance = dxchange.reader._read_ole_arr(ole, \
                    'ImageInfo/StoRADistance', "<{0}f".format(number_of_images))
            DtoRADistance = dxchange.reader._read_ole_arr(ole, \
                    'ImageInfo/DtoRADistance', "<{0}f".format(number_of_images))
            
        dist_source_center   = np.abs( StoRADistance[0] )
        dist_center_detector = np.abs( DtoRADistance[0] )
        
        # normalise data by flatfield
        data = data / metadata['reference']
        
        # circularly shift data by rounded x and y shifts
        for k in range(number_of_images):
            data[k,:,:] = np.roll(data[k,:,:], \
                (int(metadata['x-shifts'][k]),int(metadata['y-shifts'][k])), \
                axis=(1,0))
        
        # Pixelsize loaded in metadata is really the voxel size in um.
        # We can compute the effective detector pixel size as the geometric
        # magnification times the voxel size.
        d_pixel_size = ((dist_source_center+dist_center_detector)/dist_source_center)*metadata['pixel_size']
        
        # convert angles to requested unit measure, Zeiss stores in radians
        if self.angle_unit == AcquisitionGeometry.DEGREE:
            angles = np.degrees(metadata['thetas'])
        else:
            angles = np.asarray(metadata['thetas'])

        self._ag = AcquisitionGeometry(geom_type = 'cone', 
                                       dimension = '3D', 
                                       angles = angles, 
                                       pixel_num_h = metadata['image_width'], 
                                       pixel_size_h = d_pixel_size/1000, 
                                       pixel_num_v = metadata['image_height'], 
                                       pixel_size_v = d_pixel_size/1000, 
                                       dist_source_center =  dist_source_center, 
                                       dist_center_detector = dist_center_detector, 
                                       channels = 1,
                                       angle_unit = self.angle_unit,
                                       dimension_labels = ['angle', \
                                                           'vertical', \
                                                           'horizontal'])
        acq_data = self._ag.allocate(None)
        acq_data.fill(data)
        self._metadata = metadata
        return acq_data
    def test_get_centre_slice(self):
        AG = AcquisitionGeometry.create_Parallel3D(detector_direction_y=[0,1,1])
        AG.set_panel([1000,2000],[1,1])
        AG_cs = AG.get_centre_slice()

        AG2 = AcquisitionGeometry.create_Parallel2D()
        AG2.set_panel([1000,1],[1,math.sqrt(0.5)])

        self.assertEqual(AG2, AG_cs)
Пример #15
0
 def test_AcquisitionData(self):
     sgeometry = AcquisitionGeometry(dimension=2, angles=numpy.linspace(0, 180, num=10),
                                     geom_type='parallel', pixel_num_v=3,
                                     pixel_num_h=5, channels=2)
     #sino = AcquisitionData(geometry=sgeometry)
     sino = sgeometry.allocate()
     self.assertEqual(sino.shape, (2, 10, 3, 5))
     
     ag = AcquisitionGeometry (pixel_num_h=2,pixel_num_v=3,channels=4, dimension=2, angles=numpy.linspace(0, 180, num=10),
                                     geom_type='parallel', )
     print (ag.shape)
     print (ag.dimension_labels)
     
     data = ag.allocate()
     self.assertNumpyArrayEqual(numpy.asarray(data.shape), numpy.asarray(ag.shape))
     self.assertNumpyArrayEqual(numpy.asarray(data.shape), data.as_array().shape)
     
     print (data.shape, ag.shape, data.as_array().shape)
     
     ag2 = AcquisitionGeometry (pixel_num_h=2,pixel_num_v=3,channels=4, dimension=2, angles=numpy.linspace(0, 180, num=10),
                                             geom_type='parallel', 
                                             dimension_labels=[AcquisitionGeometry.VERTICAL ,
                      AcquisitionGeometry.ANGLE, AcquisitionGeometry.HORIZONTAL, AcquisitionGeometry.CHANNEL])
     
     data = ag2.allocate()
     print (data.shape, ag2.shape, data.as_array().shape)
     self.assertNumpyArrayEqual(numpy.asarray(data.shape), numpy.asarray(ag2.shape))
     self.assertNumpyArrayEqual(numpy.asarray(data.shape), data.as_array().shape)
Пример #16
0
 def test_AcquisitionGeometry_allocate_complex(self):
     ageometry = AcquisitionGeometry(dimension=2, 
                         angles=numpy.linspace(0, 180, num=10),
                         geom_type='parallel', pixel_num_v=3,
                         pixel_num_h=5, channels=2)
     sino = ageometry.allocate(0, dtype=numpy.complex64)
     shape = sino.shape
     print ("shape", shape)
     print ("dtype", sino.dtype)
     r = (1 + 1j*1)* numpy.ones(sino.shape, dtype=sino.dtype)
     sino.fill(r)
     self.assertAlmostEqual(sino.squared_norm(), sino.size*2)
Пример #17
0
    def setUp(self): 
        #%% Setup Geometry
        voxel_num_xy = 255
        voxel_num_z = 15
        self.cs_ind = (voxel_num_z-1)//2


        src_to_obj = 500
        src_to_det = src_to_obj

        pix_size = 0.2
        det_pix_x = voxel_num_xy
        det_pix_y = voxel_num_z

        num_projections = 360
        angles = np.linspace(0, 2*np.pi, num=num_projections, endpoint=False)

        self.ag_cone = AcquisitionGeometry.create_Cone3D([0,-src_to_obj,0],[0,src_to_det-src_to_obj,0])\
                                     .set_angles(angles, angle_unit='radian')\
                                     .set_panel((det_pix_x,det_pix_y), (pix_size,pix_size))\
                                     .set_labels(['vertical','angle','horizontal'])

        self.ag_parallel = AcquisitionGeometry.create_Parallel3D()\
                                     .set_angles(angles, angle_unit='radian')\
                                     .set_panel((det_pix_x,det_pix_y), (pix_size,pix_size))\
                                     .set_labels(['vertical','angle','horizontal'])

        self.ig_3D = self.ag_parallel.get_ImageGeometry()

        #%% Create phantom
        kernel_size = voxel_num_xy
        kernel_radius = (kernel_size - 1) // 2
        y, x = np.ogrid[-kernel_radius:kernel_radius+1, -kernel_radius:kernel_radius+1]

        circle1 = [5,0,0] #r,x,y
        dist1 = ((x - circle1[1])**2 + (y - circle1[2])**2)**0.5

        circle2 = [5,100,0] #r,x,y
        dist2 = ((x - circle2[1])**2 + (y - circle2[2])**2)**0.5

        circle3 = [25,0,100] #r,x,y
        dist3 = ((x - circle3[1])**2 + (y - circle3[2])**2)**0.5

        mask1 =(dist1 - circle1[0]).clip(0,1) 
        mask2 =(dist2 - circle2[0]).clip(0,1) 
        mask3 =(dist3 - circle3[0]).clip(0,1) 
        phantom = 1 - np.logical_and(np.logical_and(mask1, mask2),mask3)

        self.golden_data = self.ig_3D.allocate(0)
        for i in range(4):
            self.golden_data.fill(array=phantom, vertical=7+i)

        self.golden_data_cs = self.golden_data.subset(vertical=self.cs_ind)
Пример #18
0
    def test_size(self):
        print ("test size")
        ig = ImageGeometry(10,10)     
        d1 = ig.allocate(1)                                                     
                                                
        self.assertEqual( d1.size, 100 )
        
        sgeometry = AcquisitionGeometry(dimension=2, angles=numpy.linspace(0, 180, num=10),
                                        geom_type='parallel', pixel_num_v=3,
                                        pixel_num_h=5, channels=2)
        ad = sgeometry.allocate()

        self.assertEqual( ad.size, 3*5*10*2 )
Пример #19
0
    def setUp(self):
        self.ig = ImageGeometry(2, 3, 4, channels=5)
        angles = numpy.asarray([90., 0., -90.], dtype=numpy.float32)

        self.ag_cone = AcquisitionGeometry.create_Cone3D([0,-500,0],[0,500,0])\
                                    .set_panel((20,2))\
                                    .set_angles(angles)\
                                    .set_channels(4)

        self.ag = AcquisitionGeometry.create_Parallel3D()\
                                    .set_angles(angles)\
                                    .set_channels(4)\
                                    .set_panel((20,2))
    def test_system_description(self):
        AG = AcquisitionGeometry.create_Parallel3D()
        self.assertTrue(AG.system_description == 'simple')

        AG = AcquisitionGeometry.create_Parallel3D(
            detector_position=[5, 0, 0], rotation_axis_position=[5, 0, 0])
        self.assertTrue(AG.system_description == 'simple')

        AG = AcquisitionGeometry.create_Parallel3D(
            rotation_axis_position=[5, 0, 0])
        self.assertTrue(AG.system_description == 'offset')

        AG = AcquisitionGeometry.create_Parallel3D(ray_direction=[1, 1, 0])
        self.assertTrue(AG.system_description == 'advanced')
Пример #21
0
    def test_filtering(self):
        ag = AcquisitionGeometry.create_Parallel3D()\
            .set_panel([64,3],[0.1,0.1])\
            .set_angles([0,90])

        ad = ag.allocate('random', seed=0)

        reconstructor = FBP(ad)
        out1 = ad.copy()
        reconstructor._pre_filtering(out1)

        #by hand
        filter = reconstructor.get_filter_array()
        reconstructor._calculate_weights(ag)
        pad0 = (len(filter) - ag.pixel_num_h) // 2
        pad1 = len(filter) - ag.pixel_num_h - pad0

        out2 = ad.array.copy()
        out2 *= reconstructor._weights
        for i in range(2):
            proj_padded = np.zeros((ag.pixel_num_v, len(filter)))
            proj_padded[:, pad0:-pad1] = out2[i]
            filtered_proj = fft(proj_padded, axis=-1)
            filtered_proj *= filter
            filtered_proj = ifft(filtered_proj, axis=-1)
            out2[i] = np.real(filtered_proj)[:, pad0:-pad1]

        diff = (out1 - out2).abs().max()
        self.assertLess(diff, 1e-5)
Пример #22
0
def has_gpu_tigre():

    if not has_tigre:
        return False

    has_gpu = True
    if has_nvidia_smi():
        from cil.plugins.tigre import ProjectionOperator
        from tigre.utilities.errors import TigreCudaCallError

        N = 3
        angles = np.linspace(0, np.pi, 2, dtype='float32')

        ag = AcquisitionGeometry.create_Cone2D([0,-100],[0,200])\
                                .set_angles(angles, angle_unit='radian')\
                                .set_panel(N, 0.1)\
                                .set_labels(['angle', 'horizontal'])

        ig = ag.get_ImageGeometry()

        data = ig.allocate(1)

        Op = ProjectionOperator(ig, ag)

        try:
            Op.direct(data)
            has_gpu = True
        except TigreCudaCallError:
            has_gpu = False
    else:
        has_gpu = False

    print("has_gpu_tigre\t{}".format(has_gpu))
    return has_gpu
Пример #23
0
    def test_L1Norm_2D(self):
        model = 12 # select a model number from the library
        N = 400 # set dimension of the phantom
        path = os.path.dirname(tomophantom.__file__)
        path_library2D = os.path.join(path, "Phantom2DLibrary.dat")

        phantom_2D = TomoP2D.Model(model, N, path_library2D)    
        # data = ImageData(phantom_2D)
        ig = ImageGeometry(voxel_num_x=N, voxel_num_y=N)
        data = ig.allocate(None)
        data.fill(phantom_2D)

        # Create acquisition data and geometry
        detectors = N
        angles = np.linspace(0, 180, 120, dtype=np.float32)

        ag = AcquisitionGeometry.create_Parallel2D()\
            .set_angles(angles, angle_unit=AcquisitionGeometry.DEGREE)\
            .set_panel(detectors)
        sin = ag.allocate(None)
        sino = TomoP2D.ModelSino(model, detectors, detectors, angles, path_library2D)
        sin.fill(sino)
        sin_stripe = sin.copy()
        #        sin_stripe = sin
        tmp = sin_stripe.as_array()
        tmp[:,::27]=tmp[:,::28]
        sin_stripe.fill(tmp)

        ring_recon = RingRemover(20, "db15", 21, info = True)(sin_stripe)

        error = (ring_recon - sin).abs().as_array().mean()
        print ("L1Norm ", error)
        np.testing.assert_almost_equal(error, 83.20592, 4)
    def test_align_reference_frame_tigre(self):

        ag = AcquisitionGeometry.create_Cone2D(source_position=[0, 50],
                                               detector_position=[0., -100.],
                                               rotation_axis_position=[5., 2])
        ag.set_panel(100)

        ag_align = ag.copy()
        ag_align.config.system.align_reference_frame('tigre')

        numpy.testing.assert_allclose(ag_align.config.system.source.position,
                                      [0, -ag.dist_source_center],
                                      atol=1E-6)
        numpy.testing.assert_allclose(
            ag_align.config.system.rotation_axis.position, [0, 0], rtol=1E-6)

        cos_theta = abs(
            ag.config.system.source.position[1] -
            ag.config.system.rotation_axis.position[1]) / ag.dist_source_center
        sin_theta = math.sin(math.acos(cos_theta))

        vec = ag.config.system.detector.position - ag.config.system.source.position
        tmp = abs(vec[1]) * cos_theta
        det_y = tmp - ag.dist_source_center
        det_x = numpy.sqrt(vec[1]**2 - tmp**2)

        numpy.testing.assert_allclose(ag_align.config.system.detector.position,
                                      [det_x, det_y],
                                      rtol=1E-6)

        dir_x = -ag.config.system.detector.direction_x[0] * cos_theta
        dir_y = ag.config.system.detector.direction_x[0] * sin_theta
        numpy.testing.assert_allclose(
            ag_align.config.system.detector.direction_x, [dir_x, dir_y],
            rtol=1E-6)
    def test_get_centre_slice(self):
        AG = AcquisitionGeometry.create_Cone2D(source_position=[0, -500],
                                               detector_position=[0., 1000.])
        AG2 = AG.copy()

        AG2.config.system.get_centre_slice()
        self.assertEqual(AG.config.system, AG2.config.system)
Пример #26
0
    def test_fill_dimension_AcquisitionData(self):
        ag = AcquisitionGeometry.create_Parallel3D()
        ag.set_channels(4)
        ag.set_panel([2,3])
        ag.set_angles([0,1,2,3,5])
        ag.set_labels(('horizontal','angle','vertical','channel'))
        u = ag.allocate(0)
        print (u.shape)
        # (2, 5, 3, 4)
        a = numpy.ones((2,5))
        # default_labels = [ImageGeometry.VERTICAL, ImageGeometry.HORIZONTAL_Y, ImageGeometry.HORIZONTAL_X]
        b = u.subset(channel=0, vertical=0)
        print(b.shape)
        data = u.as_array()
        
        u.fill(a, channel=0, vertical=0)
        print(u.shape)
        numpy.testing.assert_array_equal(u.subset(channel=0, vertical=0).as_array(), a)

        u.fill(2, channel=0, vertical=0)
        numpy.testing.assert_array_equal(u.subset(channel=0, vertical=0).as_array(), 2 * a)

        u.fill(2, channel=0, vertical=0)
        numpy.testing.assert_array_equal(u.subset(channel=0, vertical=0).as_array(), 2 * a)
        
        b = u.subset(channel=0, vertical=0)
        b.fill(3)
        u.fill(b, channel=1, vertical=1)
        numpy.testing.assert_array_equal(u.subset(channel=1, vertical=1).as_array(), 3 * a)
Пример #27
0
    def test_fill_dimension_AcquisitionData(self):
        ag = AcquisitionGeometry.create_Parallel3D()
        ag.set_channels(4)
        ag.set_panel([2,3])
        ag.set_angles([0,1,2,3,5])
        ag.set_labels(('horizontal','angle','vertical','channel'))
        u = ag.allocate(0)
        a = numpy.ones((4,2))
        # default_labels = [ImageGeometry.VERTICAL, ImageGeometry.HORIZONTAL_Y, ImageGeometry.HORIZONTAL_X]
        
        data = u.as_array()
        axis_number = u.get_dimension_axis('horizontal_y')
        
        u.fill(a, horizontal_y=0)
        numpy.testing.assert_array_equal(u.subset(horizontal_y=0).as_array(), a)

        u.fill(2, horizontal_y=1)
        numpy.testing.assert_array_equal(u.subset(horizontal_y=0).as_array(), 2 * a)

        u.fill(2, horizontal_y=1)
        numpy.testing.assert_array_equal(u.subset(horizontal_y=1).as_array(), 2 * a)
        
        b = u.subset(horizontal_y=2)
        b.fill(3)
        u.fill(b, horizontal_y=2)
        numpy.testing.assert_array_equal(u.subset(horizontal_y=2).as_array(), 3 * a)

        # slice with 2 axis
        a = numpy.ones((2,))
        u.fill(a, horizontal_y=1, vertical=0)
        numpy.testing.assert_array_equal(u.subset(horizontal_y=1, vertical=0).as_array(), a)
    def test_align_reference_frame_tigre(self):
        AG = AcquisitionGeometry.create_Cone3D(
            source_position=[5, 500, 0],
            detector_position=[5., -1000., 0],
            rotation_axis_position=[5, 0, 0],
            rotation_axis_direction=[0, 0, -1])
        AG.config.system.align_reference_frame('tigre')

        numpy.testing.assert_allclose(AG.config.system.source.position,
                                      [0, -500, 0],
                                      rtol=1E-6)
        numpy.testing.assert_allclose(AG.config.system.detector.position,
                                      [0, 1000, 0],
                                      rtol=1E-6)
        numpy.testing.assert_allclose(AG.config.system.detector.direction_x,
                                      [1, 0, 0],
                                      rtol=1E-6)
        numpy.testing.assert_allclose(AG.config.system.detector.direction_y,
                                      [0, 0, -1],
                                      rtol=1E-6)
        numpy.testing.assert_allclose(AG.config.system.rotation_axis.position,
                                      [0, 0, 0],
                                      rtol=1E-6)
        numpy.testing.assert_allclose(AG.config.system.rotation_axis.direction,
                                      [0, 0, 1],
                                      rtol=1E-6)
Пример #29
0
    def test_cone3D_simple(self):
        ag = AcquisitionGeometry.create_Cone3D(source_position=[0,-2,0], detector_position=[0,1,0])\
                                      .set_angles(self.angles_deg, angle_unit='degree')\
                                      .set_labels(['vertical', 'angle','horizontal'])\
                                      .set_panel((self.num_pixels_x,self.num_pixels_y), (self.pixel_size_x,self.pixel_size_y))

        ig = ag.get_ImageGeometry()
        ig.voxel_num_y = 50
        ig.voxel_size_y /= 2

        angles_rad = np.array([-np.pi / 2, -np.pi, -3 * np.pi / 2])

        tg_geometry, tg_angles = CIL2TIGREGeometry.getTIGREGeometry(ig, ag)

        np.testing.assert_allclose(
            tg_geometry.DSD, ag.dist_center_detector + ag.dist_source_center)
        np.testing.assert_allclose(tg_geometry.DSO, ag.dist_source_center)
        np.testing.assert_allclose(tg_angles, angles_rad)
        np.testing.assert_allclose(tg_geometry.dDetector,
                                   ag.config.panel.pixel_size[::-1])
        np.testing.assert_allclose(tg_geometry.nDetector,
                                   ag.config.panel.num_pixels[::-1])
        np.testing.assert_allclose(
            tg_geometry.sDetector,
            tg_geometry.dDetector * tg_geometry.nDetector)
        np.testing.assert_allclose(tg_geometry.rotDetector, 0)
        np.testing.assert_allclose(tg_geometry.offDetector, 0)
        np.testing.assert_allclose(tg_geometry.offOrigin, 0)

        mag = ag.magnification
        np.testing.assert_allclose(tg_geometry.nVoxel, [3, 50, 128])
        np.testing.assert_allclose(tg_geometry.dVoxel,
                                   [0.2 / mag, 0.05 / mag, 0.1 / mag])
Пример #30
0
    def test_weights(self):
        ag = AcquisitionGeometry.create_Cone3D([0,-1,0],[0,2,0])\
            .set_panel([3,4],[0.1,0.2])\
            .set_angles([0,90])
        ad = ag.allocate(0)

        reconstructor = FDK(ad)
        reconstructor._calculate_weights(ag)
        weights = reconstructor._weights

        scaling = 7.5 * np.pi
        weights_new = np.ones_like(weights)

        det_size_x = ag.pixel_size_h * ag.pixel_num_h
        det_size_y = ag.pixel_size_v * ag.pixel_num_v

        ray_length_z = 3
        for j in range(4):
            ray_length_y = -det_size_y / 2 + ag.pixel_size_v * (j + 0.5)
            for i in range(3):
                ray_length_x = -det_size_x / 2 + ag.pixel_size_h * (i + 0.5)
                ray_length = (ray_length_x**2 + ray_length_y**2 +
                              ray_length_z**2)**0.5
                weights_new[j, i] = scaling * ray_length_z / ray_length

        diff = np.max(np.abs(weights - weights_new))
        self.assertLess(diff, 1e-5)