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])
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])
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])
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()
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}
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])
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])
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])
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])
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 ])