Beispiel #1
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])
Beispiel #2
0
    def test_parallel3D_offset(self):

        ag = AcquisitionGeometry.create_Parallel3D(detector_position=[2,0,0], rotation_axis_position=[3,0, 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))

        self.assertTrue(ag.system_description == 'offset')

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

        det_offset = np.array([0, -1, 0])
        np.testing.assert_allclose(tg_geometry.offDetector, det_offset)

        for i, ang in enumerate(tg_angles):
            ang2 = -(self.angles_rad[i] + np.pi / 2)
            self.compare_angles(ang, ang2, 1e-6)

        self.assertTrue(tg_geometry.mode == 'parallel')
        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.offOrigin, 0)

        np.testing.assert_allclose(
            tg_geometry.nVoxel,
            [self.ig.voxel_num_z, self.ig.voxel_num_y, self.ig.voxel_num_x])
        np.testing.assert_allclose(
            tg_geometry.dVoxel,
            [self.ig.voxel_size_z, self.ig.voxel_size_y, self.ig.voxel_size_x])
Beispiel #3
0
    def test_parallel3D_simple(self):
        ag = AcquisitionGeometry.create_Parallel3D()\
                                      .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))

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

        for i, ang in enumerate(tg_angles):
            ang2 = -(self.angles_rad[i] + np.pi / 2)
            self.compare_angles(ang, ang2, 1e-6)

        self.assertTrue(tg_geometry.mode == 'parallel')
        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)

        np.testing.assert_allclose(
            tg_geometry.nVoxel,
            [self.ig.voxel_num_z, self.ig.voxel_num_y, self.ig.voxel_num_x])
        np.testing.assert_allclose(
            tg_geometry.dVoxel,
            [self.ig.voxel_size_z, self.ig.voxel_size_y, self.ig.voxel_size_x])
Beispiel #4
0
    def __init__(self, volume_geometry, sinogram_geometry): 
        
        DataOrder.check_order_for_engine('tigre', volume_geometry)
        DataOrder.check_order_for_engine('tigre', sinogram_geometry) 

        tigre_geom, tigre_angles = CIL2TIGREGeometry.getTIGREGeometry(volume_geometry,sinogram_geometry)

        super(FBP, self).__init__(  volume_geometry = volume_geometry, sinogram_geometry = sinogram_geometry,\
                                    tigre_geom=tigre_geom, tigre_angles=tigre_angles)
    def __init__(self,
                 image_geometry,
                 aquisition_geometry,
                 direct_method='interpolated',
                 adjoint_weights='matched'):
        '''
        This class creates a configured TIGRE ProjectionOperator
        
        Please refer to the TIGRE documentation for futher descriptions
        https://github.com/CERN/TIGRE
        https://iopscience.iop.org/article/10.1088/2057-1976/2/5/055010
                        
        :param image_geometry: A description of the ImageGeometry of your data
        :type image_geometry: ImageGeometry
        :param aquisition_geometry: A description of the AcquisitionGeometry of your data
        :type aquisition_geometry: AcquisitionGeometry
        :param direct_method: The method used by the forward projector, 'Siddon' for ray-voxel intersection, 'interpolated' for interpolated projection
        :type direct_method: str, default 'interpolated'
        :param adjoint_weights: The weighting method used by the cone-beam backward projector, 'matched' for weights to approximatly match the 'interpolated' forward projector, 'FDK' for FDK weights, default 'matched'
        :type adjoint_weights: str    
        '''

        DataOrder.check_order_for_engine('tigre', image_geometry)
        DataOrder.check_order_for_engine('tigre', aquisition_geometry)

        super(ProjectionOperator,self).__init__(domain_geometry=image_geometry,\
             range_geometry=aquisition_geometry)

        if direct_method not in ['interpolated', 'Siddon']:
            raise ValueError(
                "direct_method expected 'interpolated' or 'Siddon' got {}".
                format(direct_method))

        if adjoint_weights not in ['matched', 'FDK']:
            raise ValueError(
                "adjoint_weights expected 'matched' or 'FDK' got {}".format(
                    adjoint_weights))

        self.method = {'direct': direct_method, 'adjoint': adjoint_weights}

        #set up TIGRE geometry
        tigre_geom, tigre_angles = CIL2TIGREGeometry.getTIGREGeometry(
            image_geometry, aquisition_geometry)

        #TIGRE bug workaround, when voxelgrid and panel are aligned ray tracing fails
        if direct_method == 'Siddon' and aquisition_geometry.geom_type == AcquisitionGeometry.PARALLEL:
            for i, angle in enumerate(tigre_angles):
                if abs(angle / np.pi) % 0.5 < 1e-4:
                    tigre_angles[i] += 1e-5

        tigre_geom.check_geo(tigre_angles)
        tigre_geom.cast_to_single()
        self.tigre_geom = tigre_geom

        #set up TIGRE GPU targets (from 2.2)
        if has_gpu_sel:
            self.gpuids = GpuIds()
Beispiel #6
0
    def __init__(self, image_geometry, aquisition_geometry, direct_method='Siddon',adjoint_method='matched'):
    
        DataOrder.check_order_for_engine('tigre', image_geometry)
        DataOrder.check_order_for_engine('tigre', aquisition_geometry) 

        super(ProjectionOperator,self).__init__(domain_geometry=image_geometry,\
             range_geometry=aquisition_geometry)
             
        self.tigre_geom, self.tigre_angles= CIL2TIGREGeometry.getTIGREGeometry(image_geometry,aquisition_geometry)

        self.method = {'direct':direct_method,'adjoint':adjoint_method}
Beispiel #7
0
    def test_cone3D_advanced(self):

        ag = AcquisitionGeometry.create_Cone3D(source_position=[0,-10,0], detector_position=[0,10,0], rotation_axis_position=[0,0, 0],rotation_axis_direction=[0,-1,1])\
                                      .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))

        self.assertTrue(ag.system_description == 'advanced')

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

        self.assertAlmostEqual(tg_geometry.DSO,
                               ag.dist_source_center * np.sin(np.pi / 4), 5)

        s2o = ag.dist_source_center * np.cos(np.pi / 4)
        np.testing.assert_allclose(tg_geometry.DSO, s2o)

        s2d = (ag.dist_center_detector + ag.dist_source_center) * np.cos(
            np.pi / 4)
        np.testing.assert_allclose(tg_geometry.DSD, s2d)

        det_rot = np.array([0, -np.pi / 4, 0])
        np.testing.assert_allclose(tg_geometry.rotDetector, det_rot)

        det_offset = np.array([-s2d, 0, 0])
        np.testing.assert_allclose(tg_geometry.offDetector, det_offset)

        for i, ang in enumerate(tg_angles):
            ang2 = -(self.angles_rad[i] + np.pi / 2)
            self.compare_angles(ang, ang2, 1e-6)

        self.assertTrue(tg_geometry.mode == 'cone')
        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)

        height = 10 / np.sqrt(2)
        np.testing.assert_allclose(tg_geometry.offOrigin, [-height, 0, 0])

        np.testing.assert_allclose(
            tg_geometry.nVoxel,
            [self.ig.voxel_num_z, self.ig.voxel_num_y, self.ig.voxel_num_x])
        np.testing.assert_allclose(
            tg_geometry.dVoxel,
            [self.ig.voxel_size_z, self.ig.voxel_size_y, self.ig.voxel_size_x])
Beispiel #8
0
    def test_cone3D_offset(self):

        #3, 4, 5 triangle for source + object
        ag = AcquisitionGeometry.create_Cone3D(source_position=[0,-4,0], detector_position=[0,4,0], rotation_axis_position=[3,0, 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))

        self.assertTrue(ag.system_description == 'offset')

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

        np.testing.assert_allclose(tg_geometry.DSO, ag.dist_source_center)

        yaw = np.arcsin(3. / 5.)
        det_rot = np.array([0, 0, yaw])
        np.testing.assert_allclose(tg_geometry.rotDetector, det_rot)

        offset = 4 * 6 / 5
        det_offset = np.array([0, -offset, 0])
        np.testing.assert_allclose(tg_geometry.offDetector, det_offset)

        s2d = ag.dist_center_detector + ag.dist_source_center - 6 * 3 / 5
        np.testing.assert_allclose(tg_geometry.DSD, s2d)

        for i, ang in enumerate(tg_angles):
            ang2 = -(self.angles_rad[i] + np.pi / 2 + yaw)
            self.compare_angles(ang, ang2, 1e-6)

        self.assertTrue(tg_geometry.mode == 'cone')
        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.offOrigin, 0)

        np.testing.assert_allclose(
            tg_geometry.nVoxel,
            [self.ig.voxel_num_z, self.ig.voxel_num_y, self.ig.voxel_num_x])
        np.testing.assert_allclose(
            tg_geometry.dVoxel,
            [self.ig.voxel_size_z, self.ig.voxel_size_y, self.ig.voxel_size_x])
Beispiel #9
0
    def test_cone3D_cofr(self):

        #3, 4, 5 triangle for source + object
        ag = AcquisitionGeometry.create_Cone3D(source_position=[0,-4,0], detector_position=[0,4,0], rotation_axis_position=[3,0, 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

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

        np.testing.assert_allclose(tg_geometry.DSO, ag.dist_source_center)

        yaw = np.arcsin(3. / 5.)
        det_rot = np.array([0, 0, yaw])
        np.testing.assert_allclose(tg_geometry.rotDetector, det_rot)

        offset = 4 * 6 / 5
        det_offset = np.array([0, -offset, 0])
        np.testing.assert_allclose(tg_geometry.offDetector, det_offset)

        s2d = ag.dist_center_detector + ag.dist_source_center - 6 * 3 / 5
        np.testing.assert_allclose(tg_geometry.DSD, s2d)

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

        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.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])
Beispiel #10
0
    def test_cone3D_simple(self):
        ag = AcquisitionGeometry.create_Cone3D(source_position=[0,-6,0], detector_position=[0,16,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))

        self.assertTrue(ag.system_description == 'simple')

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

        for i, ang in enumerate(tg_angles):
            ang2 = -(self.angles_rad[i] + np.pi / 2)
            self.compare_angles(ang, ang2, 1e-6)

        self.assertTrue(tg_geometry.mode == 'cone')
        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_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)

        np.testing.assert_allclose(
            tg_geometry.nVoxel,
            [self.ig.voxel_num_z, self.ig.voxel_num_y, self.ig.voxel_num_x])
        np.testing.assert_allclose(
            tg_geometry.dVoxel,
            [self.ig.voxel_size_z, self.ig.voxel_size_y, self.ig.voxel_size_x])
Beispiel #11
0
    def test_cone2D(self):

        ag = AcquisitionGeometry.create_Cone2D(source_position=[0,-6], detector_position=[0,16])\
                                     .set_angles(self.angles_rad, angle_unit='radian')\
                                     .set_labels(['angle','horizontal'])\
                                     .set_panel(self.num_pixels_x, self.pixel_size_x)

        #2D cone
        tg_geometry, tg_angles = CIL2TIGREGeometry.getTIGREGeometry(
            self.ig, ag)

        for i, ang in enumerate(tg_angles):
            ang2 = -(self.angles_rad[i] + np.pi / 2)
            self.compare_angles(ang, ang2, 1e-6)

        self.assertTrue(tg_geometry.mode == 'cone')
        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_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)

        np.testing.assert_allclose(
            tg_geometry.nVoxel, [1, self.ig.voxel_num_y, self.ig.voxel_num_x])
        np.testing.assert_allclose(tg_geometry.dVoxel, [
            ag.config.panel.pixel_size[1] / ag.magnification,
            self.ig.voxel_size_y, self.ig.voxel_size_x
        ])