| @@ 30-115 (lines=86) @@ | ||
| 27 | from tomobar.methodsDIR import RecToolsDIR |
|
| 28 | import numpy as np |
|
| 29 | ||
| 30 | @register_plugin |
|
| 31 | class ForwardProjectorGpu(Plugin, GpuPlugin): |
|
| 32 | """ |
|
| 33 | This plugin uses ToMoBAR software and GPU Astra projector to generate parallel-beam projection data. |
|
| 34 | The plugin will project the given object using the available metadata OR user-provided geometry. |
|
| 35 | In case when angles set to None, the metadata projection geometry will be used. |
|
| 36 | ||
| 37 | :param angles_deg: Projection angles in degrees in a format [start, stop, step]. Default: None. |
|
| 38 | :param det_horiz: The size of the horizontal detector. Default: None. |
|
| 39 | :param centre_of_rotation: The centre of rotation. Default: None. |
|
| 40 | :param out_datasets: Default out dataset name. Default: ['forw_proj'] |
|
| 41 | """ |
|
| 42 | ||
| 43 | def __init__(self): |
|
| 44 | super(ForwardProjectorGpu, self).__init__('ForwardProjectorGpu') |
|
| 45 | ||
| 46 | def pre_process(self): |
|
| 47 | #getting metadata |
|
| 48 | in_meta_data = self.get_in_meta_data()[0] |
|
| 49 | self.cor = in_meta_data.get('centre_of_rotation') |
|
| 50 | self.cor=self.cor[0] |
|
| 51 | ||
| 52 | def setup(self): |
|
| 53 | in_dataset, out_dataset = self.get_datasets() |
|
| 54 | in_pData, out_pData = self.get_plugin_datasets() |
|
| 55 | in_pData[0].plugin_data_setup('VOLUME_XZ', 'single') |
|
| 56 | ||
| 57 | if (self.parameters['angles_deg'] is None): |
|
| 58 | # data extracted geometry parameters |
|
| 59 | in_meta_data=self.get_in_meta_data()[0] |
|
| 60 | angles_meta_deg = in_meta_data.get('rotation_angle') |
|
| 61 | self.angles_rad = np.deg2rad(angles_meta_deg) |
|
| 62 | self.detectors_horiz = in_meta_data.get('detector_x_length') |
|
| 63 | else: |
|
| 64 | # user-set parameters |
|
| 65 | angles_list=self.parameters['angles_deg'] |
|
| 66 | self.cor=self.parameters['centre_of_rotation'] |
|
| 67 | self.angles_rad = np.deg2rad(np.linspace(angles_list[0], angles_list[1], angles_list[2], dtype=np.float)) |
|
| 68 | self.detectors_horiz = self.parameters['det_horiz'] |
|
| 69 | ||
| 70 | self.det_horiz_half=0.5*self.detectors_horiz |
|
| 71 | self.angles_total = len(self.angles_rad) |
|
| 72 | ||
| 73 | out_shape_sino = self.new_shape(in_dataset[0].get_shape(), in_dataset[0]) |
|
| 74 | labels = ['rotation_angle.degrees', 'detector_y.pixel', 'detector_x.pixel'] |
|
| 75 | pattern = {'name': 'SINOGRAM', 'slice_dims': (1,), |
|
| 76 | 'core_dims': (2,0)} |
|
| 77 | out_dataset[0].create_dataset(axis_labels=labels, shape=out_shape_sino) |
|
| 78 | out_dataset[0].add_pattern(pattern['name'], |
|
| 79 | slice_dims=pattern['slice_dims'], |
|
| 80 | core_dims=pattern['core_dims']) |
|
| 81 | pattern2 = {'name': 'PROJECTION', 'slice_dims': (0,), |
|
| 82 | 'core_dims': (1,2)} |
|
| 83 | out_dataset[0].add_pattern(pattern2['name'], |
|
| 84 | slice_dims=pattern['slice_dims'], |
|
| 85 | core_dims=pattern['core_dims']) |
|
| 86 | out_pData[0].plugin_data_setup(pattern['name'], self.get_max_frames()) |
|
| 87 | out_dataset[0].meta_data.set('rotation_angle', angles_meta_deg) |
|
| 88 | ||
| 89 | def process_frames(self, data): |
|
| 90 | image = data[0].astype(np.float32) |
|
| 91 | image = np.where(np.isfinite(image), image, 0) |
|
| 92 | objsize_image = np.shape(image)[0] |
|
| 93 | RectoolsDIR = RecToolsDIR(DetectorsDimH = self.detectors_horiz, # DetectorsDimH # detector dimension (horizontal) |
|
| 94 | DetectorsDimV = None, # DetectorsDimV # detector dimension (vertical) for 3D case only |
|
| 95 | CenterRotOffset = -self.cor+self.det_horiz_half-0.5, # Center of Rotation (CoR) scalar |
|
| 96 | AnglesVec = self.angles_rad, # array of angles in radians |
|
| 97 | ObjSize = objsize_image, # a scalar to define reconstructed object dimensions |
|
| 98 | device_projector='gpu') |
|
| 99 | sinogram_new = RectoolsDIR.FORWPROJ(image) |
|
| 100 | return sinogram_new |
|
| 101 | ||
| 102 | def new_shape(self, full_shape, data): |
|
| 103 | # calculate a new output data shape based on the input data shape |
|
| 104 | new_shape_sino_orig = list(full_shape) |
|
| 105 | new_shape_sino= (self.angles_total, new_shape_sino_orig[1], self.detectors_horiz) |
|
| 106 | return tuple(new_shape_sino) |
|
| 107 | ||
| 108 | def get_max_frames(self): |
|
| 109 | return 'single' |
|
| 110 | ||
| 111 | def nInput_datasets(self): |
|
| 112 | return 1 |
|
| 113 | ||
| 114 | def nOutput_datasets(self): |
|
| 115 | return 1 |
|
| 116 | ||
| @@ 30-115 (lines=86) @@ | ||
| 27 | from tomobar.methodsDIR import RecToolsDIR |
|
| 28 | import numpy as np |
|
| 29 | ||
| 30 | @register_plugin |
|
| 31 | class ForwardProjectorCpu(Plugin, CpuPlugin): |
|
| 32 | ||
| 33 | def __init__(self): |
|
| 34 | super(ForwardProjectorCpu, self).__init__('ForwardProjectorCpu') |
|
| 35 | ||
| 36 | def pre_process(self): |
|
| 37 | #getting metadata |
|
| 38 | in_meta_data = self.get_in_meta_data()[0] |
|
| 39 | self.cor = in_meta_data.get('centre_of_rotation') |
|
| 40 | self.cor=self.cor[0] |
|
| 41 | ||
| 42 | def setup(self): |
|
| 43 | in_dataset, out_dataset = self.get_datasets() |
|
| 44 | in_pData, out_pData = self.get_plugin_datasets() |
|
| 45 | in_pData[0].plugin_data_setup('VOLUME_XZ', 'single') |
|
| 46 | ||
| 47 | if (self.parameters['angles_deg'] is None): |
|
| 48 | # data extracted geometry parameters |
|
| 49 | in_meta_data=self.get_in_meta_data()[0] |
|
| 50 | angles_meta_deg = in_meta_data.get('rotation_angle') |
|
| 51 | self.angles_rad = np.deg2rad(angles_meta_deg) |
|
| 52 | self.detectors_horiz = in_meta_data.get('detector_x_length') |
|
| 53 | else: |
|
| 54 | # user-set parameters |
|
| 55 | angles_list=self.parameters['angles_deg'] |
|
| 56 | self.cor=self.parameters['centre_of_rotation'] |
|
| 57 | self.angles_rad = np.deg2rad(np.linspace(angles_list[0], angles_list[1], angles_list[2], dtype=np.float)) |
|
| 58 | self.detectors_horiz = self.parameters['det_horiz'] |
|
| 59 | ||
| 60 | self.det_horiz_half=0.5*self.detectors_horiz |
|
| 61 | self.angles_total = len(self.angles_rad) |
|
| 62 | ||
| 63 | out_shape_sino = self.new_shape(in_dataset[0].get_shape(), in_dataset[0]) |
|
| 64 | labels = ['rotation_angle.degrees', 'detector_y.pixel', 'detector_x.pixel'] |
|
| 65 | pattern = {'name': 'SINOGRAM', 'slice_dims': (1,), |
|
| 66 | 'core_dims': (2,0)} |
|
| 67 | out_dataset[0].create_dataset(axis_labels=labels, shape=out_shape_sino) |
|
| 68 | out_dataset[0].add_pattern(pattern['name'], |
|
| 69 | slice_dims=pattern['slice_dims'], |
|
| 70 | core_dims=pattern['core_dims']) |
|
| 71 | pattern2 = {'name': 'PROJECTION', 'slice_dims': (0,), |
|
| 72 | 'core_dims': (1,2)} |
|
| 73 | out_dataset[0].add_pattern(pattern2['name'], |
|
| 74 | slice_dims=pattern['slice_dims'], |
|
| 75 | core_dims=pattern['core_dims']) |
|
| 76 | out_pData[0].plugin_data_setup(pattern['name'], self.get_max_frames()) |
|
| 77 | out_dataset[0].meta_data.set('rotation_angle', angles_meta_deg) |
|
| 78 | ||
| 79 | def process_frames(self, data): |
|
| 80 | image = data[0].astype(np.float32) |
|
| 81 | image = np.where(np.isfinite(image), image, 0) |
|
| 82 | objsize_image = np.shape(image)[0] |
|
| 83 | RectoolsDIR = RecToolsDIR(DetectorsDimH = self.detectors_horiz, # DetectorsDimH # detector dimension (horizontal) |
|
| 84 | DetectorsDimV = None, # DetectorsDimV # detector dimension (vertical) for 3D case only |
|
| 85 | CenterRotOffset = -self.cor+self.det_horiz_half-0.5, # Center of Rotation (CoR) scalar |
|
| 86 | AnglesVec = self.angles_rad, # array of angles in radians |
|
| 87 | ObjSize = objsize_image, # a scalar to define reconstructed object dimensions |
|
| 88 | device_projector='cpu') |
|
| 89 | sinogram_new = RectoolsDIR.FORWPROJ(image) |
|
| 90 | return sinogram_new |
|
| 91 | ||
| 92 | def new_shape(self, full_shape, data): |
|
| 93 | # calculate a new output data shape based on the input data shape |
|
| 94 | new_shape_sino_orig = list(full_shape) |
|
| 95 | new_shape_sino= (self.angles_total, new_shape_sino_orig[1], self.detectors_horiz) |
|
| 96 | return tuple(new_shape_sino) |
|
| 97 | ||
| 98 | def get_max_frames(self): |
|
| 99 | return 'single' |
|
| 100 | ||
| 101 | def nInput_datasets(self): |
|
| 102 | return 1 |
|
| 103 | ||
| 104 | def nOutput_datasets(self): |
|
| 105 | return 1 |
|
| 106 | ||