DetectorsDimH=detectorHoriz, # Horizontal detector dimension DetectorsDimV=None, # Vertical detector dimension (3D case) CenterRotOffset=92, # Center of Rotation scalar AnglesVec=angles_rad, # A vector of projection angles in radians ObjSize=N_size, # Reconstructed object dimensions (scalar) datafidelity='PWLS', # Data fidelity, choose from LS, KL, PWLS device_projector='gpu') # prepare dictionaries with parameters: _data_ = { 'projection_norm_data': data_norm, 'projection_raw_data': data_raw, 'OS_number': 6 } # data dictionary lc = Rectools.powermethod( _data_) # calculate Lipschitz constant (run once to initialise) _algorithm_ = {'iterations': 20, 'lipschitz_const': lc} # Run CGLS reconstrucion algorithm RecCGLS = Rectools.CGLS(_data_, _algorithm_) plt.figure() plt.imshow(RecCGLS, vmin=0, vmax=0.3, cmap="gray") plt.title('CGLS reconstruction') plt.show() #%% print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%") print("Reconstructing with FISTA PWLS-OS-TV method % %%%%%%%%%%%%%%") print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%") # adding regularisation
print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%") from tomobar.methodsIR import RecToolsIR # set parameters and initiate a class object Rectools = RecToolsIR(DetectorsDimH = P, # DetectorsDimH # detector dimension (horizontal) DetectorsDimV = None, # DetectorsDimV # detector dimension (vertical) for 3D case only CenterRotOffset = None, # Center of Rotation (CoR) scalar (for 3D case only) AnglesVec = angles_rad, # array of angles in radians ObjSize = N_size, # a scalar to define reconstructed object dimensions datafidelity='LS',# data fidelity, choose LS, PWLS (wip), GH (wip), Student (wip) nonnegativity='ENABLE', # enable nonnegativity constraint (set to 'ENABLE') OS_number = None, # the number of subsets, NONE/(or > 1) ~ classical / ordered subsets tolerance = 1e-06, # tolerance to stop outer iterations earlier device='gpu') lc = Rectools.powermethod() # calculate Lipschitz constant (run once to initilise) # Run FISTA reconstrucion algorithm without regularisation RecFISTA = Rectools.FISTA(noisy_sino, iterationsFISTA = 200, lipschitz_const = lc) # Run FISTA reconstrucion algorithm with regularisation RecFISTA_reg = Rectools.FISTA(noisy_sino, iterationsFISTA = 30, \ regularisation = 'ROF_TV', \ initialise = FBPrec,\ regularisation_parameter = 0.05,\ regularisation_iterations = 100,\ lipschitz_const = lc) plt.figure() plt.subplot(121) plt.imshow(RecFISTA, vmin=0, vmax=1, cmap="gray")
detectorHoriz, # DetectorsDimH # detector dimension (horizontal) DetectorsDimV= None, # DetectorsDimV # detector dimension (vertical) for 3D case only CenterRotOffset=None, # Center of Rotation (CoR) scalar (for 3D case only) AnglesVec=angles_rad, # array of angles in radians ObjSize=N_size, # a scalar to define reconstructed object dimensions datafidelity= 'PWLS', # data fidelity, choose LS, PWLS, GH (wip), Student (wip) nonnegativity='ENABLE', # enable nonnegativity constraint (set to 'ENABLE') OS_number= 12, # the number of subsets, NONE/(or > 1) ~ classical / ordered subsets tolerance=1e-08, # tolerance to stop outer iterations earlier device='gpu') lc = Rectools.powermethod( dataRaw[:, :, slice_to_recon] ) # calculate Lipschitz constant (run once to initilise) RecFISTA_os_pwls = Rectools.FISTA(data_norm[:,:,slice_to_recon], \ dataRaw[:,:,slice_to_recon], \ iterationsFISTA = 15, \ lipschitz_const = lc) fig = plt.figure() plt.imshow(RecFISTA_os_pwls[150:550, 150:550], vmin=0, vmax=0.003, cmap="gray") #plt.imshow(RecFISTA_os_pwls, vmin=0, vmax=0.004, cmap="gray") plt.title('FISTA PWLS-OS reconstruction') plt.show() #fig.savefig('dendr_PWLS.png', dpi=200) #%% print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
#%% print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%") print ("Reconstructing with FISTA-OS method using tomobar") print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%") # initialise tomobar ITERATIVE reconstruction class ONCE from tomobar.methodsIR import RecToolsIR RectoolsIR = RecToolsIR(DetectorsDimH = Horiz_det, # DetectorsDimH # detector dimension (horizontal) DetectorsDimV = Vert_det, # DetectorsDimV # detector dimension (vertical) for 3D case only AnglesVec = angles_rad, # array of angles in radians ObjSize = N_size, # a scalar to define reconstructed object dimensions datafidelity='LS',# data fidelity, choose LS, PWLS (wip), GH (wip), Student (wip) nonnegativity='ENABLE', # enable nonnegativity constraint (set to 'ENABLE') OS_number = 12, # the number of subsets, NONE/(or > 1) ~ classical / ordered subsets tolerance = 1e-07, # tolerance to stop outer iterations earlier device='gpu') lc = RectoolsIR.powermethod() # calculate Lipschitz constant #%% # Run FISTA reconstrucion algorithm without regularisation #RecFISTA = RectoolsIR.FISTA(projData3D_norm, iterationsFISTA = 5, lipschitz_const = lc) # Run FISTA reconstrucion algorithm with 3D regularisation RecFISTA_reg = RectoolsIR.FISTA(projData3D_norm, iterationsFISTA = 8, regularisation = 'FGP_TV', regularisation_parameter = 0.0007, regularisation_iterations = 200, lipschitz_const = lc) sliceSel = int(0.5*N_size) max_val = 1 plt.figure()
class TomobarRecon(BaseRecon, GpuPlugin): """ A Plugin to reconstruct full-field tomographic projection data using state-of-the-art regularised iterative algorithms from \ the ToMoBAR package. ToMoBAR includes FISTA and ADMM iterative methods and depends on the ASTRA toolbox and the CCPi RGL toolkit: \ https://github.com/vais-ral/CCPi-Regularisation-Toolkit. :param output_size: Number of rows and columns in the \ reconstruction. Default: 'auto'. :param iterations: Number of outer iterations for FISTA (default) or ADMM methods. Default: 20. :param datafidelity: Data fidelity, Least Squares only at the moment. Default: 'LS'. :param nonnegativity: Nonnegativity constraint, choose Enable or None. Default: 'ENABLE'. :param ordersubsets: The number of ordered-subsets to accelerate reconstruction. Default: 6. :param converg_const: Lipschitz constant, can be set to a value or automatic calculation. Default: 'power'. :param regularisation: To regularise choose methods ROF_TV, FGP_TV, SB_TV, LLT_ROF,\ NDF, Diff4th. Default: 'FGP_TV'. :param regularisation_parameter: Regularisation (smoothing) value, higher \ the value stronger the smoothing effect. Default: 0.0001. :param regularisation_iterations: The number of regularisation iterations. Default: 350. :param time_marching_parameter: Time marching parameter, relevant for \ (ROF_TV, LLT_ROF, NDF, Diff4th) penalties. Default: 0.0025. :param edge_param: Edge (noise) related parameter, relevant for NDF and Diff4th. Default: 0.01. :param regularisation_parameter2: Regularisation (smoothing) value for LLT_ROF method. Default: 0.005. :param NDF_penalty: NDF specific penalty type Huber, Perona, Tukey. Default: 'Huber'. :param tolerance: Tolerance to stop outer iterations earlier. Default: 5e-10. :param ring_variable: Regularisation variable for ring removal. Default: 0.0. :param ring_accelerator: Acceleration constant for ring removal (use with care). Default: 50.0. """ def __init__(self): super(TomobarRecon, self).__init__("TomobarRecon") def _shift(self, sinogram, centre_of_rotation): centre_of_rotation_shift = (sinogram.shape[0]/2) - centre_of_rotation result = ndimage.interpolation.shift(sinogram, (centre_of_rotation_shift, 0)) return result def pre_process(self): # extract given parameters self.iterationsFISTA = self.parameters['iterations'] self.datafidelity = self.parameters['datafidelity'] self.nonnegativity = self.parameters['nonnegativity'] self.ordersubsets = self.parameters['ordersubsets'] self.converg_const = self.parameters['converg_const'] self.regularisation = self.parameters['regularisation'] self.regularisation_parameter = self.parameters['regularisation_parameter'] self.regularisation_parameter2 = self.parameters['regularisation_parameter2'] self.ring_variable = self.parameters['ring_variable'] self.ring_accelerator = self.parameters['ring_accelerator'] self.time_marching_parameter = self.parameters['time_marching_parameter'] self.edge_param = self.parameters['edge_param'] self.NDF_penalty = self.parameters['NDF_penalty'] self.output_size = self.parameters['output_size'] self.tolerance = self.parameters['tolerance'] self.RecToolsIR = None if (self.ordersubsets > 1): self.regularisation_iterations = (int)(self.parameters['regularisation_iterations']/self.ordersubsets) + 1 else: self.regularisation_iterations = self.parameters['regularisation_iterations'] def process_frames(self, data): centre_of_rotations, angles, self.vol_shape, init = self.get_frame_params() sino = data[0].astype(np.float32) anglesTot, self.DetectorsDimH = np.shape(sino) self.anglesRAD = np.deg2rad(angles.astype(np.float32)) # check if the reconstruction class has been initialised and calculate # Lipschitz constant if not given explicitly self.setup_Lipschitz_constant() # Run FISTA reconstrucion algorithm here recon = self.Rectools.FISTA(sino,\ iterationsFISTA = self.iterationsFISTA,\ regularisation = self.regularisation,\ regularisation_parameter = self.regularisation_parameter,\ regularisation_iterations = self.regularisation_iterations,\ regularisation_parameter2 = self.regularisation_parameter2,\ time_marching_parameter = self.time_marching_parameter,\ lambdaR_L1 = self.ring_variable,\ alpha_ring = self.ring_accelerator,\ NDF_penalty = self.NDF_penalty,\ tolerance_regul = 0.0,\ edge_param = self.edge_param,\ lipschitz_const = self.Lipschitz_const) return recon def setup_Lipschitz_constant(self): if self.RecToolsIR is not None: return # set parameters and initiate a TomoBar class object self.Rectools = RecToolsIR(DetectorsDimH = self.DetectorsDimH, # DetectorsDimH # detector dimension (horizontal) DetectorsDimV = None, # DetectorsDimV # detector dimension (vertical) for 3D case only CenterRotOffset = None, # Center of Rotation (CoR) scalar (for 3D case only) AnglesVec = self.anglesRAD, # array of angles in radians ObjSize = self.vol_shape[0] , # a scalar to define the reconstructed object dimensions datafidelity=self.datafidelity,# data fidelity, choose LS, PWLS nonnegativity=self.nonnegativity, # enable nonnegativity constraint (set to 'on') OS_number = self.ordersubsets, # the number of subsets, NONE/(or > 1) ~ classical / ordered subsets tolerance = self.tolerance , # tolerance to stop outer iterations earlier device='gpu') if (self.parameters['converg_const'] == 'power'): self.Lipschitz_const = self.Rectools.powermethod() # calculate Lipschitz constant else: self.Lipschitz_const = self.parameters['converg_const'] return def get_max_frames(self): return 'single' def get_citation_information(self): cite_info1 = CitationInformation() cite_info1.name = 'citation1' cite_info1.description = \ ("First-order optimisation algorithm for linear inverse problems.") cite_info1.bibtex = \ ("@article{beck2009,\n" + "title={A fast iterative shrinkage-thresholding algorithm for linear inverse problems},\n" + "author={Amir and Beck, Mark and Teboulle},\n" + "journal={SIAM Journal on Imaging Sciences},\n" + "volume={2},\n" + "number={1},\n" + "pages={183--202},\n" + "year={2009},\n" + "publisher={SIAM}\n" + "}") cite_info1.endnote = \ ("%0 Journal Article\n" + "%T A fast iterative shrinkage-thresholding algorithm for linear inverse problems\n" + "%A Beck, Amir\n" + "%A Teboulle, Mark\n" + "%J SIAM Journal on Imaging Sciences\n" + "%V 2\n" + "%N 1\n" + "%P 183--202\n" + "%@ --\n" + "%D 2009\n" + "%I SIAM\n") cite_info1.doi = "doi: " return cite_info1
class TomobarRecon3d(BaseRecon, MultiThreadedPlugin): """ A Plugin to reconstruct full-field tomographic projection data using state-of-the-art regularised iterative algorithms from \ the ToMoBAR package. ToMoBAR includes FISTA and ADMM iterative methods and depends on the ASTRA toolbox and the CCPi RGL toolkit: \ https://github.com/vais-ral/CCPi-Regularisation-Toolkit. :param output_size: The dimension of the reconstructed volume (only X-Y dimension). Default: 'auto'. :param iterations: Number of outer iterations for FISTA method. Default: 20. :param datafidelity: Data fidelity, Least Squares (LS) or PWLS. Default: 'LS'. :param nonnegativity: Nonnegativity constraint, choose Enable or None. Default: 'ENABLE'. :param ordersubsets: The number of ordered-subsets to accelerate reconstruction. Default: 6. :param converg_const: Lipschitz constant, can be set to a scalar value or automatic calculation using power methods. Default: 'power'. :param regularisation: To regularise choose methods ROF_TV, FGP_TV, SB_TV, LLT_ROF,\ NDF, Diff4th. Default: 'ROF_TV'. :param regularisation_parameter: Regularisation (smoothing) value, higher \ the value stronger the smoothing effect. Default: 0.0001. :param regularisation_iterations: The number of regularisation iterations. Default: 400. :param time_marching_parameter: Time marching parameter, relevant for \ (ROF_TV, LLT_ROF, NDF, Diff4th) penalties. Default: 0.002. :param edge_param: Edge (noise) related parameter, relevant for NDF and Diff4th. Default: 0.01. :param regularisation_parameter2: Regularisation (smoothing) value for LLT_ROF method. Default: 0.005. :param NDF_penalty: NDF specific penalty type Huber, Perona, Tukey. Default: 'Huber'. :param tolerance: Tolerance to stop outer iterations earlier. Default: 1e-9. :param ring_variable: Regularisation variable for ring removal. Default: 0.0. :param ring_accelerator: Acceleration constant for ring removal (use with care). Default: 50.0. """ def __init__(self): super(TomobarRecon3d, self).__init__("TomobarRecon3d") def _get_output_size(self, in_data): sizeX = self.parameters['output_size'] shape = in_data.get_shape() if sizeX == 'auto': detX = in_data.get_data_dimension_by_axis_label('detector_x') sizeX = shape[detX] detY = in_data.get_data_dimension_by_axis_label('detector_y') sizeY = shape[detY] return (sizeX, sizeY) def setup(self): in_dataset, out_dataset = self.get_datasets() # reduce the data as per data_subset parameter self.preview_flag = \ self.set_preview(in_dataset[0], self.parameters['preview']) axis_labels = in_dataset[0].data_info.get('axis_labels')[0] dim_volX, dim_volY, dim_volZ = \ self.map_volume_dimensions(in_dataset[0]) axis_labels = { in_dataset[0]: [ str(dim_volX) + '.voxel_x.voxels', str(dim_volY) + '.voxel_y.voxels', str(dim_volZ) + '.voxel_z.voxels' ] } # specify reconstructed volume dimensions (self.output_size, self.Vert_det) = self._get_output_size(in_dataset[0]) shape = [0] * len(in_dataset[0].get_shape()) shape[0] = self.output_size shape[1] = self.Vert_det shape[2] = self.output_size # if there are only 3 dimensions then add a fourth for slicing if len(shape) == 3: axis_labels = [0] * 4 axis_labels[dim_volX] = 'voxel_x.voxels' axis_labels[dim_volY] = 'voxel_y.voxels' axis_labels[dim_volZ] = 'voxel_z.voxels' axis_labels[3] = 'scan.number' shape.append(1) if self.parameters['vol_shape'] == 'fixed': shape[dim_volX] = shape[dim_volZ] else: shape[dim_volX] = self.parameters['vol_shape'] shape[dim_volZ] = self.parameters['vol_shape'] if 'resolution' in self.parameters.keys(): shape[dim_volX] /= self.parameters['resolution'] shape[dim_volZ] /= self.parameters['resolution'] out_dataset[0].create_dataset(axis_labels=axis_labels, shape=tuple(shape)) out_dataset[0].add_volume_patterns(dim_volX, dim_volY, dim_volZ) ndims = range(len(shape)) core_dims = (dim_volX, dim_volY, dim_volZ) slice_dims = tuple(set(ndims).difference(set(core_dims))) out_dataset[0].add_pattern('VOLUME_3D', core_dims=core_dims, slice_dims=slice_dims) # set information relating to the plugin data in_pData, out_pData = self.get_plugin_datasets() dim = in_dataset[0].get_data_dimension_by_axis_label('rotation_angle') nSlices = in_dataset[0].get_shape()[dim] in_pData[0].plugin_data_setup('PROJECTION', nSlices, slice_axis='rotation_angle') # in_pData[1].plugin_data_setup('PROJECTION', nSlices) # (for PWLS) # set pattern_name and nframes to process for all datasets out_pData[0].plugin_data_setup('VOLUME_3D', 'single') def pre_process(self): # extract given parameters self.iterationsFISTA = self.parameters['iterations'] self.datafidelity = self.parameters['datafidelity'] self.nonnegativity = self.parameters['nonnegativity'] self.ordersubsets = self.parameters['ordersubsets'] self.converg_const = self.parameters['converg_const'] self.regularisation = self.parameters['regularisation'] self.regularisation_parameter = self.parameters[ 'regularisation_parameter'] self.regularisation_parameter2 = self.parameters[ 'regularisation_parameter2'] self.ring_variable = self.parameters['ring_variable'] self.ring_accelerator = self.parameters['ring_accelerator'] self.time_marching_parameter = self.parameters[ 'time_marching_parameter'] self.edge_param = self.parameters['edge_param'] self.NDF_penalty = self.parameters['NDF_penalty'] self.tolerance = self.parameters['tolerance'] self.RecToolsIR = None if (self.ordersubsets > 1): self.regularisation_iterations = (int)( self.parameters['regularisation_iterations'] / self.ordersubsets) + 1 else: self.regularisation_iterations = self.parameters[ 'regularisation_iterations'] in_pData = self.get_plugin_in_datasets() self.det_dimX_ind = in_pData[0].get_data_dimension_by_axis_label( 'detector_x') self.det_dimY_ind = in_pData[0].get_data_dimension_by_axis_label( 'detector_y') def process_frames(self, data): centre_of_rotations, angles, self.vol_shape, init = self.get_frame_params( ) self.anglesRAD = np.deg2rad(angles.astype(np.float32)) self.centre_of_rotations = centre_of_rotations projdata3D = data[0].astype(np.float32) dim_tuple = np.shape(projdata3D) self.Horiz_det = dim_tuple[self.det_dimX_ind] #print(np.shape(projdata3D)) projdata3D = np.swapaxes(projdata3D, 0, 1) # WIP for PWLS fidelity # rawdata3D = data[1].astype(np.float32) # rawdata3D =np.swapaxes(rawdata3D,0,1)/np.max(np.float32(rawdata3D)) # check if the reconstruction class has been initialised and calculate # Lipschitz constant if not given explicitly self.setup_Lipschitz_constant() # Run FISTA reconstrucion algorithm here recon = self.Rectools.FISTA(projdata3D,\ iterationsFISTA = self.iterationsFISTA,\ regularisation = self.regularisation,\ regularisation_parameter = self.regularisation_parameter,\ regularisation_iterations = self.regularisation_iterations,\ regularisation_parameter2 = self.regularisation_parameter2,\ time_marching_parameter = self.time_marching_parameter,\ lambdaR_L1 = self.ring_variable,\ alpha_ring = self.ring_accelerator,\ NDF_penalty = self.NDF_penalty,\ tolerance_regul = 0.0,\ edge_param = self.edge_param,\ lipschitz_const = self.Lipschitz_const) recon = np.swapaxes(recon, 0, 1) # temporal fix! return recon def setup_Lipschitz_constant(self): if self.RecToolsIR is not None: return # set parameters and initiate a TomoBar class object self.Rectools = RecToolsIR( DetectorsDimH=self. Horiz_det, # DetectorsDimH # detector dimension (horizontal) DetectorsDimV=self. Vert_det, # DetectorsDimV # detector dimension (vertical) for 3D case only CenterRotOffset= 0.0, # Center of Rotation (CoR) scalar (for 3D case only) AnglesVec=self.anglesRAD, # array of angles in radians ObjSize=self. output_size, # a scalar to define the reconstructed object dimensions datafidelity=self.datafidelity, # data fidelity, choose LS nonnegativity=self. nonnegativity, # enable nonnegativity constraint (set to 'on') OS_number=self. ordersubsets, # the number of subsets, NONE/(or > 1) ~ classical / ordered subsets tolerance=self. tolerance, # tolerance to stop outer iterations earlier device='gpu') if (self.parameters['converg_const'] == 'power'): self.Lipschitz_const = self.Rectools.powermethod( ) # calculate Lipschitz constant else: self.Lipschitz_const = self.parameters['converg_const'] return def nInput_datasets(self): return 1 def nOutput_datasets(self): return 1 def get_citation_information(self): cite_info1 = CitationInformation() cite_info1.name = 'citation1' cite_info1.description = \ ("First-order optimisation algorithm for linear inverse problems.") cite_info1.bibtex = \ ("@article{beck2009,\n" + "title={A fast iterative shrinkage-thresholding algorithm for linear inverse problems},\n" + "author={Amir and Beck, Mark and Teboulle},\n" + "journal={SIAM Journal on Imaging Sciences},\n" + "volume={2},\n" + "number={1},\n" + "pages={183--202},\n" + "year={2009},\n" + "publisher={SIAM}\n" + "}") cite_info1.endnote = \ ("%0 Journal Article\n" + "%T A fast iterative shrinkage-thresholding algorithm for linear inverse problems\n" + "%A Beck, Amir\n" + "%A Teboulle, Mark\n" + "%J SIAM Journal on Imaging Sciences\n" + "%V 2\n" + "%N 1\n" + "%P 183--202\n" + "%@ --\n" + "%D 2009\n" + "%I SIAM\n") cite_info1.doi = "doi: " return cite_info1
# Initialise FISTA-type PWLS reconstruction (run once) from tomobar.methodsIR import RecToolsIR # set parameters and initiate a class object Rectools = RecToolsIR(DetectorsDimH = np.size(det_y_crop), # DetectorsDimH # detector dimension (horizontal) DetectorsDimV = None, # DetectorsDimV # detector dimension (vertical) for 3D case only CenterRotOffset = None, # Center of Rotation (CoR) scalar (for 3D case only) AnglesVec = angles_rad, # array of angles in radians ObjSize = N_size, # a scalar to define reconstructed object dimensions datafidelity='PWLS',# data fidelity, choose LS, PWLS, GH (wip), Student (wip) nonnegativity='ENABLE', # enable nonnegativity constraint (set to 'ENABLE') OS_number = 12, # the number of subsets, NONE/(or > 1) ~ classical / ordered subsets tolerance = 1e-08, # tolerance to stop outer iterations earlier device='gpu') lc = Rectools.powermethod(data_raw[:,det_y_crop]) # calculate Lipschitz constant (run once to initilise) #%% print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%") print ("Reconstructing with FISTA PWLS-OS-TV method % %%%%%%%%%%%%%%") print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%") RecFISTA_TV = Rectools.FISTA(data_norm[:,det_y_crop], \ data_raw[:,det_y_crop], \ iterationsFISTA = 10, \ regularisation = 'FGP_TV', \ regularisation_parameter = 0.0012,\ regularisation_iterations = 200,\ lipschitz_const = lc) plt.figure() plt.imshow(RecFISTA_TV, vmin=0, vmax=0.2, cmap="gray") plt.title('FISTA-PWLS-OS-TV reconstruction')
# Initialise FISTA-type PWLS reconstruction (run once) from tomobar.methodsIR import RecToolsIR # set parameters and initiate a class object Rectools = RecToolsIR(DetectorsDimH = np.size(det_y_crop), # DetectorsDimH # detector dimension (horizontal) DetectorsDimV = None, # DetectorsDimV # detector dimension (vertical) for 3D case only CenterRotOffset = None, # Center of Rotation (CoR) scalar (for 3D case only) AnglesVec = angles_rad, # array of angles in radians ObjSize = N_size, # a scalar to define reconstructed object dimensions datafidelity='PWLS',# data fidelity, choose LS, PWLS, GH (wip), Student (wip) nonnegativity='ENABLE', # enable nonnegativity constraint (set to 'ENABLE') OS_number = 12, # the number of subsets, NONE/(or > 1) ~ classical / ordered subsets tolerance = 1e-08, # tolerance to stop outer iterations earlier device='gpu') lc = Rectools.powermethod(np.transpose(data_raw[det_y_crop,:,0])) # calculate Lipschitz constant (run once to initilise) #%% print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%") print ("Reconstructing with FISTA PWLS-OS-TV method % %%%%%%%%%%%%%%") print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%") RecFISTA_TV = Rectools.FISTA(np.transpose(data_norm[det_y_crop,:,0]), \ np.transpose(data_raw[det_y_crop,:,0]), \ iterationsFISTA = 10, \ regularisation = 'FGP_TV', \ regularisation_parameter = 0.0012,\ regularisation_iterations = 200,\ lipschitz_const = lc) plt.figure() plt.imshow(RecFISTA_TV, vmin=0, vmax=0.2, cmap="gray") plt.title('FISTA-PWLS-OS-TV reconstruction')