Exemplo n.º 1
0
    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))
        self._data_.update({'projection_norm_data' : projdata3D})

       # 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.parameters['data_fidelity'],# data fidelity, choose LS
                    device_projector='gpu')

        # Run FISTA reconstrucion algorithm here
        recon = self.Rectools.FISTA(self._data_, self._algorithm_, self._regularisation_)
        recon = np.swapaxes(recon,0,1)
        return recon
Exemplo n.º 2
0
    def process_frames(self, data):
        cor, angles, self.vol_shape, init  = self.get_frame_params()
        sinogram = data[0].astype(np.float32)
        anglesTot, self.DetectorsDimH = np.shape(sinogram)
        half_det_width = 0.5*self.DetectorsDimH
        cor_astra = half_det_width - cor
        self.anglesRAD = np.deg2rad(angles.astype(np.float32))
        self._data_.update({'projection_norm_data' : sinogram})

        # if one selects PWLS or SWLS models then raw data is also required (2 inputs)
        if ((self.parameters['data_fidelity'] == 'PWLS') or (self.parameters['data_fidelity'] == 'SWLS')):
            rawdata = data[1].astype(np.float32)
            rawdata /= np.max(rawdata)
            self._data_.update({'projection_raw_data' : rawdata})
            self._data_.update({'beta_SWLS' : self.parameters['data_beta_SWLS']*np.ones(self.DetectorsDimH)})

        # set parameters and initiate the ToMoBAR class object
        self.Rectools = RecToolsIR(DetectorsDimH = self.DetectorsDimH,  # DetectorsDimH # detector dimension (horizontal)
                    DetectorsDimV = None,  # DetectorsDimV # detector dimension (vertical) for 3D case only
                    CenterRotOffset = cor_astra.item() - 0.5, # The center of rotation (CoR) scalar or a vector
                    AnglesVec = self.anglesRAD, # the vector of angles in radians
                    ObjSize = self.vol_shape[0] , # a scalar to define the reconstructed object dimensions
                    datafidelity=self.parameters['data_fidelity'],# data fidelity, choose LS, PWLS, SWLS
                    device_projector='gpu')

        # Run FISTA reconstrucion algorithm here
        recon = self.Rectools.FISTA(self._data_, self._algorithm_, self._regularisation_)
        return recon
Exemplo n.º 3
0
    def process_frames(self, data):
        centre_of_rotations, angles, self.vol_shape, init = self.get_frame_params(
        )
        sinogram = data[0].astype(np.float32)
        anglesTot, self.DetectorsDimH = np.shape(sinogram)
        self.anglesRAD = np.deg2rad(angles.astype(np.float32))
        self._data_.update({'projection_norm_data': sinogram})
        """
        # if one selects PWLS model and provides raw input data
        if (self.parameters['data_fidelity'] == 'PWLS'):
        rawdata = data[1].astype(np.float32)
        rawdata /= np.max(rawdata)
        self._data_.update({'projection_raw_data' : rawdata})
        """

        # set parameters and initiate the 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.
            parameters['data_fidelity'],  # data fidelity, choose LS, PWLS
            device_projector='gpu')

        # Run FISTA reconstrucion algorithm here
        recon = self.Rectools.FISTA(self._data_, self._algorithm_,
                                    self._regularisation_)
        return recon
Exemplo n.º 4
0
    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
Exemplo n.º 5
0
    def process_frames(self, data):
        cor, angles, self.vol_shape, init = self.get_frame_params()

        self.anglesRAD = np.deg2rad(angles.astype(np.float32))
        projdata3D = data[0].astype(np.float32)
        dim_tuple = np.shape(projdata3D)
        self.Horiz_det = dim_tuple[self.det_dimX_ind]
        half_det_width = 0.5 * self.Horiz_det
        cor_astra = half_det_width - cor[0]
        projdata3D[projdata3D > 10**15] = 0.0
        projdata3D = np.swapaxes(projdata3D, 0, 1)
        #print(f"Shape of projdata3D is {np.shape(projdata3D)}")
        self._data_.update({'projection_norm_data': projdata3D})

        # if one selects PWLS or SWLS models then raw data is also required (2 inputs)
        if ((self.parameters['data_fidelity'] == 'PWLS')
                or (self.parameters['data_fidelity'] == 'SWLS')):
            rawdata3D = data[1].astype(np.float32)
            rawdata3D[rawdata3D > 10**15] = 0.0
            rawdata3D = np.swapaxes(rawdata3D, 0, 1) / np.max(
                np.float32(rawdata3D))
            #print(f"Shape of rawdata3D is {np.shape(rawdata3D)}")
            self._data_.update({'projection_raw_data': rawdata3D})
            self._data_.update({
                'beta_SWLS':
                self.parameters['data_beta_SWLS'] * np.ones(self.Horiz_det)
            })

    # 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=cor_astra.item() -
            0.5,  # The center of rotation (CoR) scalar or a vector
            AnglesVec=self.anglesRAD,  # the vector of angles in radians
            ObjSize=self.
            output_size,  # a scalar to define the reconstructed object dimensions
            datafidelity=self.parameters[
                'data_fidelity'],  # data fidelity, choose LS, PWLS, SWLS
            device_projector='gpu')

        # Run FISTA reconstrucion algorithm here
        recon = self.Rectools.FISTA(self._data_, self._algorithm_,
                                    self._regularisation_)
        recon = np.swapaxes(recon, 0, 1)
        return recon
Exemplo n.º 6
0
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
Exemplo n.º 7
0
FBPrec = RectoolsDIR.FBP(data_norm[:,det_y_crop])

plt.figure()
#plt.imshow(FBPrec[500:1500,500:1500], vmin=0, vmax=1, cmap="gray")
plt.imshow(FBPrec, vmin=0, vmax=1, cmap="gray")
plt.title('FBP reconstruction')

#%%
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 = None, # the number of subsets, NONE/(or > 1) ~ classical / ordered subsets
                    tolerance = 1e-08, # tolerance to stop outer iterations earlier
                    device='gpu')


# Run CGLS reconstrucion algorithm 
RecCGLS = Rectools.CGLS(data_norm[:,det_y_crop], iterations = 7)

plt.figure()
plt.imshow(RecCGLS, vmin=0, vmax=0.3, cmap="gray")
plt.title('CGLS reconstruction')
plt.show()
#%%
# Initialise FISTA-type PWLS reconstruction (run once)
Exemplo n.º 8
0
class TomobarReconCpu(BaseRecon, CpuPlugin):
    """
    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 data_fidelity: Data fidelity, Least Squares only at the moment. Default: 'LS'.
    :param data_Huber_thresh: Threshold parameter for __Huber__ data fidelity . Default: None.
    :param data_any_rings: a parameter to suppress various artifacts including rings and streaks. Default: None.
    :param data_any_rings_winsizes: half window sizes to collect background information [detector, angles, num of projections]. Default: (9,7,0).
    :param data_any_rings_power: a power parameter for Huber model. Default: 1.5.
    :param data_full_ring_GH: Regularisation variable for full constant ring removal (GH model). Default: None.
    :param data_full_ring_accelerator_GH: Acceleration constant for GH ring removal. Default: 10.0.
    :param algorithm_iterations: Number of outer iterations for FISTA (default) or ADMM methods. Default: 20.
    :param algorithm_verbose: print iterations number and other messages ('off' by default). Default: 'off'.
    :param algorithm_ordersubsets: The number of ordered-subsets to accelerate reconstruction. Default: 6.
    :param algorithm_nonnegativity: ENABLE or DISABLE nonnegativity constraint. Default: 'ENABLE'.
    :param regularisation_method: To regularise choose methods ROF_TV, FGP_TV, PD_TV, SB_TV, LLT_ROF,\
                             NDF, TGV, NLTV, Diff4th. Default: 'FGP_TV'.
    :param regularisation_parameter: Regularisation (smoothing) value, higher \
                            the value stronger the smoothing effect. Default: 0.00001.
    :param regularisation_iterations: The number of regularisation iterations. Default: 80.
    :param regularisation_device: The number of regularisation iterations. Default: 'cpu'.
    :param regularisation_PD_lip: Primal-dual parameter for convergence. Default: 8.
    :param regularisation_methodTV:  0/1 - TV specific isotropic/anisotropic choice. Default: 0.
    :param regularisation_timestep: Time marching parameter, relevant for \
                    (ROF_TV, LLT_ROF, NDF, Diff4th) penalties. Default: 0.003.
    :param regularisation_edge_thresh: 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 regularisation_NDF_penalty: NDF specific penalty type Huber, Perona, Tukey. Default: 'Huber'.
    """

    def __init__(self):
        super(TomobarReconCpu, self).__init__("TomobarReconCpu")

    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 into dictionaries suitable for ToMoBAR input
        self._data_ = {'OS_number' : self.parameters['algorithm_ordersubsets'],
                       'huber_threshold' : self.parameters['data_Huber_thresh'],
                       'ring_weights_threshold' :  self.parameters['data_any_rings'],
                       'ring_tuple_halfsizes' :  self.parameters['data_any_rings_winsizes'],
                       'ring_huber_power' :  self.parameters['data_any_rings_power'],
                       'ringGH_lambda' :  self.parameters['data_full_ring_GH'],
                       'ringGH_accelerate' :  self.parameters['data_full_ring_accelerator_GH']}

        self._algorithm_ = {'iterations' : self.parameters['algorithm_iterations'],
       			    'nonnegativity' : self.parameters['algorithm_nonnegativity'],
                            'verbose' : self.parameters['algorithm_verbose']}

        self._regularisation_ = {'method' : self.parameters['regularisation_method'],
                                'regul_param' : self.parameters['regularisation_parameter'],
                                'iterations' : self.parameters['regularisation_iterations'],
                                'device_regulariser' : self.parameters['regularisation_device'],
                                'edge_threhsold' : self.parameters['regularisation_edge_thresh'],
                                'time_marching_step' : self.parameters['regularisation_timestep'],
                                'regul_param2' : self.parameters['regularisation_parameter2'],
                                'PD_LipschitzConstant' : self.parameters['regularisation_PD_lip'],
                                'NDF_penalty' : self.parameters['regularisation_NDF_penalty'],
                                'methodTV' : self.parameters['regularisation_methodTV']}

    def process_frames(self, data):
        centre_of_rotations, angles, self.vol_shape, init  = self.get_frame_params()
        sinogram = data[0].astype(np.float32)
        anglesTot, self.DetectorsDimH = np.shape(sinogram)
        self.anglesRAD = np.deg2rad(angles.astype(np.float32))
        self._data_.update({'projection_norm_data' : sinogram})

        # set parameters and initiate the 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.parameters['data_fidelity'],# data fidelity, choose LS, PWLS
                    device_projector='cpu')

        # Run FISTA reconstrucion algorithm here
        recon = self.Rectools.FISTA(self._data_, self._algorithm_, self._regularisation_)
        return recon

    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
Exemplo n.º 9
0
class TomobarRecon3d(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: The dimension of the reconstructed volume (only X-Y dimension). Default: 'auto'.
    :param padding: The amount of pixels to pad each slab of the cropped projection data. Default: 17.
    :param data_fidelity: Data fidelity, choose LS, PWLS, SWLS or KL. Default: 'LS'.
    :param data_Huber_thresh: Threshold parameter for __Huber__ data fidelity . Default: None.
    :param data_beta_SWLS: A parameter for stripe-weighted model. Default: 0.1.
    :param data_full_ring_GH: Regularisation variable for full constant ring removal (GH model). Default: None.
    :param data_full_ring_accelerator_GH: Acceleration constant for GH ring removal. Default: 10.0.
    :param algorithm_iterations: Number of outer iterations for FISTA (default) or ADMM methods. Default: 20.
    :param algorithm_verbose: print iterations number and other messages ('off' by default). Default: 'off'.
    :param algorithm_mask: set to 1.0 to enable a circular mask diameter or < 1.0 to shrink the mask. Default: 1.0.
    :param algorithm_ordersubsets: The number of ordered-subsets to accelerate reconstruction. Default: 6.
    :param algorithm_nonnegativity: ENABLE or DISABLE nonnegativity constraint. Default: 'ENABLE'.
    :param regularisation_method: To regularise choose methods ROF_TV, FGP_TV, PD_TV, SB_TV, LLT_ROF,\
                             NDF, TGV, NLTV, Diff4th. Default: 'FGP_TV'.
    :param regularisation_parameter: Regularisation (smoothing) value, higher \
                            the value stronger the smoothing effect. Default: 0.00001.
    :param regularisation_iterations: The number of regularisation iterations. Default: 80.
    :param regularisation_device: The number of regularisation iterations. Default: 'gpu'.
    :param regularisation_PD_lip: Primal-dual parameter for convergence. Default: 8.
    :param regularisation_methodTV:  0/1 - TV specific isotropic/anisotropic choice. Default: 0.
    :param regularisation_timestep: Time marching parameter, relevant for \
                    (ROF_TV, LLT_ROF, NDF, Diff4th) penalties. Default: 0.003.
    :param regularisation_edge_thresh: 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 regularisation_NDF_penalty: NDF specific penalty type Huber, Perona, Tukey. Default: 'Huber'.
    """
    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]
        return sizeX

    def set_filter_padding(self, in_pData, out_pData):
        self.pad = self.parameters['padding']
        in_data = self.get_in_datasets()[0]
        det_y = in_data.get_data_dimension_by_axis_label('detector_y')
        pad_det_y = '%s.%s' % (det_y, self.pad)
        pad_dict = {'pad_directions': [pad_det_y], 'pad_mode': 'edge'}
        in_pData[0].padding = pad_dict
        out_pData[0].padding = pad_dict

    def setup(self):
        in_dataset = self.get_in_datasets()[0]
        self.parameters['vol_shape'] = self.parameters['output_size']
        procs = self.exp.meta_data.get("processes")
        procs = len([i for i in procs if 'GPU' in i])
        dim = in_dataset.get_data_dimension_by_axis_label('detector_y')
        nSlices = int(np.ceil(in_dataset.get_shape()[dim] / float(procs)))
        self._set_max_frames(nSlices)
        super(TomobarRecon3d, self).setup()

    def pre_process(self):
        in_pData = self.get_plugin_in_datasets()[0]
        out_pData = self.get_plugin_out_datasets()[0]
        detY = in_pData.get_data_dimension_by_axis_label('detector_y')
        # ! padding vertical detector !
        self.Vert_det = in_pData.get_shape()[detY] + 2 * self.pad

        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')
        self.output_size = out_pData.get_shape()[self.det_dimX_ind]

        # extract given parameters into dictionaries suitable for ToMoBAR input
        self._data_ = {
            'OS_number': self.parameters['algorithm_ordersubsets'],
            'huber_threshold': self.parameters['data_Huber_thresh'],
            'ringGH_lambda': self.parameters['data_full_ring_GH'],
            'ringGH_accelerate':
            self.parameters['data_full_ring_accelerator_GH']
        }

        self._algorithm_ = {
            'iterations': self.parameters['algorithm_iterations'],
            'nonnegativity': self.parameters['algorithm_nonnegativity'],
            'mask_diameter': self.parameters['algorithm_mask'],
            'verbose': self.parameters['algorithm_verbose']
        }

        self._regularisation_ = {
            'method': self.parameters['regularisation_method'],
            'regul_param': self.parameters['regularisation_parameter'],
            'iterations': self.parameters['regularisation_iterations'],
            'device_regulariser': self.parameters['regularisation_device'],
            'edge_threhsold': self.parameters['regularisation_edge_thresh'],
            'time_marching_step': self.parameters['regularisation_timestep'],
            'regul_param2': self.parameters['regularisation_parameter2'],
            'PD_LipschitzConstant': self.parameters['regularisation_PD_lip'],
            'NDF_penalty': self.parameters['regularisation_NDF_penalty'],
            'methodTV': self.parameters['regularisation_methodTV']
        }

    def process_frames(self, data):
        cor, angles, self.vol_shape, init = self.get_frame_params()

        self.anglesRAD = np.deg2rad(angles.astype(np.float32))
        projdata3D = data[0].astype(np.float32)
        dim_tuple = np.shape(projdata3D)
        self.Horiz_det = dim_tuple[self.det_dimX_ind]
        half_det_width = 0.5 * self.Horiz_det
        cor_astra = half_det_width - cor[0]
        projdata3D[projdata3D > 10**15] = 0.0
        projdata3D = np.swapaxes(projdata3D, 0, 1)
        #print(f"Shape of projdata3D is {np.shape(projdata3D)}")
        self._data_.update({'projection_norm_data': projdata3D})

        # if one selects PWLS or SWLS models then raw data is also required (2 inputs)
        if ((self.parameters['data_fidelity'] == 'PWLS')
                or (self.parameters['data_fidelity'] == 'SWLS')):
            rawdata3D = data[1].astype(np.float32)
            rawdata3D[rawdata3D > 10**15] = 0.0
            rawdata3D = np.swapaxes(rawdata3D, 0, 1) / np.max(
                np.float32(rawdata3D))
            #print(f"Shape of rawdata3D is {np.shape(rawdata3D)}")
            self._data_.update({'projection_raw_data': rawdata3D})
            self._data_.update({
                'beta_SWLS':
                self.parameters['data_beta_SWLS'] * np.ones(self.Horiz_det)
            })

    # 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=cor_astra.item() -
            0.5,  # The center of rotation (CoR) scalar or a vector
            AnglesVec=self.anglesRAD,  # the vector of angles in radians
            ObjSize=self.
            output_size,  # a scalar to define the reconstructed object dimensions
            datafidelity=self.parameters[
                'data_fidelity'],  # data fidelity, choose LS, PWLS, SWLS
            device_projector='gpu')

        # Run FISTA reconstrucion algorithm here
        recon = self.Rectools.FISTA(self._data_, self._algorithm_,
                                    self._regularisation_)
        recon = np.swapaxes(recon, 0, 1)
        return recon

    def nInput_datasets(self):
        return max(len(self.parameters['in_datasets']), 1)

    def nOutput_datasets(self):
        return 1

    def _set_max_frames(self, frames):
        self._max_frames = frames

    def get_max_frames(self):
        return self._max_frames

    def get_slice_axis(self):
        return 'detector_y'

    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
Exemplo n.º 10
0
plt.subplot(133)
plt.imshow(FBPrec[:, :, sliceSel], vmin=0, vmax=max_val)
plt.title('3D FBP Reconstruction, sagittal view')
plt.show()
#%%
print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print("Reconstructing with FISTA method (ASTRA used for projection)")
print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
from tomobar.methodsIR import RecToolsIR

# set parameters and initiate a class object
Rectools = RecToolsIR(
    DetectorsDimH=Horiz_det,  # DetectorsDimH # detector dimension (horizontal)
    DetectorsDimV=
    Vert_det,  # 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 or PWLS
    device_projector='gpu')

_data_ = {'projection_norm_data': projData3D_analyt_noise}  # data dictionary

lc = Rectools.powermethod(
    _data_)  # calculate Lipschitz constant (run once to initialise)

# Run FISTA reconstrucion algorithm without regularisation
_algorithm_ = {'iterations': 200, 'lipschitz_const': lc}
# Run FISTA reconstrucion algorithm without regularisation
RecFISTA = Rectools.FISTA(_data_, _algorithm_, {})
Exemplo n.º 11
0
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
Exemplo n.º 12
0
# calculate errors 
Qtools = QualityTools(phantom_tm, recNumerical)
RMSE = Qtools.rmse()
print("Root Mean Square Error is {}".format(RMSE))
#%%
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
                    CenterRotOffset = 0.0, # 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 = 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_analyt_noisy, iterationsFISTA = 5, lipschitz_const = lc)

# Run FISTA reconstrucion algorithm with 3D regularisation
#RecFISTA_reg = RectoolsIR.FISTA(projData3D_analyt_noisy, iterationsFISTA = 5, regularisation = 'ROF_TV', lipschitz_const = lc)

sliceSel = int(0.5*N_size)
max_val = 1
Exemplo n.º 13
0
plt.figure()
#plt.imshow(FBPrec[500:1500,500:1500], vmin=0, vmax=1, cmap="gray")
plt.imshow(FBPrec, vmin=0, vmax=1, cmap="gray")
plt.title('FBP reconstruction')

#%%
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)
    device_projector='gpu')

# prepare dictionaries with parameters:
_data_ = {
    'projection_norm_data': data_norm[:, det_y_crop],
    'projection_raw_data': data_raw[:, det_y_crop],
    'OS_number': 6
}  # data dictionary

lc = Rectools.powermethod(
    _data_)  # calculate Lipschitz constant (run once to initialise)
Exemplo n.º 14
0
plt.subplot(133)
plt.imshow(FBPrec[:,:,sliceSel],vmin=0, vmax=max_val)
plt.title('3D FBP Reconstruction, sagittal view')
plt.show()
#%%
print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print ("Reconstructing with FISTA method (ASTRA used for projection)")
print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
from tomobar.methodsIR import RecToolsIR

# set parameters and initiate a class object
Rectools = RecToolsIR(DetectorsDimH = Horiz_det,     # Horizontal detector dimension
                    DetectorsDimV = Vert_det,        # Vertical detector dimension (3D case)
                    CenterRotOffset = None,          # Center of Rotation scalar or a vector 
                    AnglesVec = angles_rad,          # A vector of projection angles in radians
                    ObjSize = N_size,                # Reconstructed object dimensions (scalar)
                    datafidelity='LS',               # Data fidelity, choose from LS, KL, PWLS
                    device_projector='gpu')

_data_ = {'projection_norm_data' : projData3D_analyt_noise} # data dictionary

lc = Rectools.powermethod(_data_) # calculate Lipschitz constant (run once to initialise)

# Run FISTA reconstrucion algorithm without regularisation
_algorithm_ = {'iterations' : 200,
               'lipschitz_const' : lc}
# Run FISTA reconstrucion algorithm without regularisation
RecFISTA = Rectools.FISTA(_data_, _algorithm_, {})

# adding regularisation using the CCPi regularisation toolkit
Exemplo n.º 15
0
    tiff.close()
"""
#%%
print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print("Reconstructing with ADMM method using tomobar software")
print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
# initialise tomobar ITERATIVE reconstruction class ONCE
from tomobar.methodsIR import RecToolsIR

RectoolsIR = RecToolsIR(
    DetectorsDimH=np.size(
        det_y_crop),  # DetectorsDimH # detector dimension (horizontal)
    DetectorsDimV=
    100,  # 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, GH (wip), Students t (wip)
    nonnegativity='ENABLE',  # enable nonnegativity constraint (set to 'ENABLE')
    OS_number=
    None,  # the number of subsets, NONE/(or > 1) ~ classical / ordered subsets
    tolerance=0.0,  # tolerance to stop inner (regularisation) iterations earlier
    device='gpu')
#%%
print("Reconstructing with ADMM method using SB-TV penalty")
RecADMM_reg_sbtv = RectoolsIR.ADMM(data_norm[0:100,:,det_y_crop],
                              rho_const = 2000.0, \
                              iterationsADMM = 15, \
                              regularisation = 'SB_TV', \
                              regularisation_parameter = 0.00085,\
                              regularisation_iterations = 50)
Exemplo n.º 16
0
plt.colorbar(ticks=[0, 0.5, 1], orientation='vertical')
plt.title('Misaligned noisy FBP Reconstruction')
plt.show()

plt.figure()
plt.imshow(abs(FBPrec_ideal - FBPrec_error), vmin=0, vmax=1, cmap="gray")
plt.colorbar(ticks=[0, 0.5, 1], orientation='vertical')
plt.title('FBP reconsrtuction differences')
#%%
# initialise tomobar ITERATIVE reconstruction class ONCE
from tomobar.methodsIR import RecToolsIR
RectoolsIR = 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)
    device_projector='gpu')
#%%
print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print("Reconstructing analytical sinogram using SIRT (tomobar)...")
print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
# prepare dictionaries with parameters:
_data_ = {'projection_norm_data': sino_an}  # data dictionary
_algorithm_ = {'iterations': 250}
SIRTrec_ideal = RectoolsIR.SIRT(_data_, _algorithm_)  # ideal reconstruction
_data_ = {'projection_norm_data': noisy_zing_stripe}  # data dictionary
SIRTrec_error = RectoolsIR.SIRT(_data_, _algorithm_)  # error reconstruction
Exemplo n.º 17
0
plt.show()

plt.figure()
plt.imshow(abs(FBPrec_ideal - FBPrec_error), vmin=0, vmax=2, cmap="gray")
plt.colorbar(ticks=[0, 0.5, 2], orientation='vertical')
plt.title('FBP reconsrtuction differences')
#%%
print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print("Reconstructing using FISTA method (tomobar)")
print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
from tomobar.methodsIR import RecToolsIR
RectoolsIR = 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=P,  # a scalar to define reconstructed object dimensions
    datafidelity='LS',  #data fidelity, choose LS
    device_projector='gpu')

# prepare dictionaries with parameters:
_data_ = {'projection_norm_data': noisy_zing_stripe}  # data dictionary
lc = RectoolsIR.powermethod(
    _data_)  # calculate Lipschitz constant (run once to initialise)
_algorithm_ = {'iterations': 350, 'lipschitz_const': lc}

# adding regularisation using the CCPi regularisation toolkit
_regularisation_ = {
    'method': 'PD_TV',
    'regul_param': 0.001,
Exemplo n.º 18
0
# calculate errors
Qtools = QualityTools(phantom_tm, recNumerical_dynamic)
RMSE = Qtools.rmse()
print("Root Mean Square Error is {} for dynamic flat fields normalisation".
      format(RMSE))
#%%
print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print("Reconstructing with FISTA-OS method using tomobar")
print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
# initialise tomobar ITERATIVE reconstruction class ONCE
from tomobar.methodsIR import RecToolsIR
Rectools = RecToolsIR(
    DetectorsDimH=Horiz_det,  # DetectorsDimH # detector dimension (horizontal)
    DetectorsDimV=
    Vert_det,  # DetectorsDimV # detector dimension (vertical) for 3D case only
    CenterRotOffset=0.0,  # 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)
    device_projector='gpu')
#%%
# prepare dictionaries with parameters:
_data_ = {
    'projection_norm_data': projData3D_norm,
    'projection_raw_data': projData3D_noisy / np.max(projData3D_noisy),
    'OS_number': 10
}  # data dictionary
lc = Rectools.powermethod(
    _data_)  # calculate Lipschitz constant (run once to initialise)

# algorithm parameters
Exemplo n.º 19
0
plt.show()

plt.figure()
plt.imshow(abs(FBPrec_ideal - FBPrec_error), vmin=0, vmax=1, cmap="gray")
plt.colorbar(ticks=[0, 0.5, 1], orientation='vertical')
plt.title('FBP reconsrtuction differences')
#%%
# initialise tomobar ITERATIVE reconstruction class ONCE
from tomobar.methodsIR import RecToolsIR
RectoolsIR = 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')
#%%
print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print("Reconstructing analytical sinogram using SIRT (tomobar)...")
print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
iterationsSIRT = 250
SIRTrec_ideal = RectoolsIR.SIRT(sino_an,
                                iterationsSIRT)  # ideal reconstruction
SIRTrec_error = RectoolsIR.SIRT(noisy_zing_stripe,
                                iterationsSIRT)  # error reconstruction
Exemplo n.º 20
0
plt.figure()
plt.rcParams.update({'font.size': 20})
plt.imshow(FBPrec, vmin=0, vmax=1, cmap="gray")
plt.colorbar(ticks=[0, 0.5, 1], orientation='vertical')
plt.title('FBP reconstruction')
#%%
print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print ("Reconstructing with ADMM method (ASTRA used for projection)")
print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
from tomobar.methodsIR import RecToolsIR

# set parameters and initiate a class object
Rectools = RecToolsIR(DetectorsDimH = P, # Horizontal detector dimension
                    DetectorsDimV = None,            # Vertical detector dimension
                    CenterRotOffset = None,          # Center of Rotation scalar
                    AnglesVec = angles_rad,          # A vector of projection angles in radians
                    ObjSize = N_size,                # Reconstructed object dimensions (scalar)
                    datafidelity='LS',               # Data fidelity, choose from LS, KL, PWLS
                    device_projector='gpu')

# prepare dictionaries with parameters:
_data_ = {'projection_norm_data' : noisy_sino} # data dictionary
_algorithm_ = {'iterations' : 15,
               'ADMM_rho_const' : 4000.0}

# adding regularisation using the CCPi regularisation toolkit
_regularisation_ = {'method' : 'FGP_TV',
                    'regul_param' : 0.06,
                    'iterations' : 100,
                    'device_regulariser': 'gpu'}
Exemplo n.º 21
0
plt.subplot(133)
plt.imshow(FBPrec[:,:,sliceSel],vmin=0, vmax=max_val)
plt.title('3D FBP Reconstruction, sagittal view')
plt.show()
#%%
print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print ("Reconstructing with ADMM method (ASTRA used for projection)")
print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
from tomobar.methodsIR import RecToolsIR

# set parameters and initiate a class object
Rectools = RecToolsIR(DetectorsDimH = Horiz_det,  # DetectorsDimH # detector dimension (horizontal)
                    DetectorsDimV = Vert_det,  # 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, 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')

# Run ADMM reconstrucion algorithm with regularisation
RecADMM_reg = Rectools.ADMM(projData3D_analyt_noise,
                              rho_const = 2000.0, \
                              iterationsADMM = 20, \
                              regularisation = 'FGP_TV', \
                              regularisation_parameter = 0.0035,\
                              regularisation_iterations = 200)


sliceSel = int(0.5*N_size)
Exemplo n.º 22
0
plt.figure()
plt.imshow(abs(FBPrec_ideal - FBPrec_error), vmin=0, vmax=1, cmap="gray")
plt.colorbar(ticks=[0, 0.5, 1], orientation='vertical')
plt.title('FBP reconsrtuction differences')
#%%
print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print("Reconstructing using FISTA method (tomobar)")
print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
from tomobar.methodsIR import RecToolsIR
RectoolsIR = 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, 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 = RectoolsIR.powermethod()  # calculate Lipschitz constant

# Run FISTA reconstrucion algorithm with regularisation
RecFISTA_LS_reg = RectoolsIR.FISTA(noisy_zing_stripe,
                                   iterationsFISTA=350,
                                   regularisation='ROF_TV',
                                   regularisation_parameter=0.003,
                                   lipschitz_const=lc)
Exemplo n.º 23
0
# calculate errors
Qtools = QualityTools(phantom_tm, recNumerical)
RMSE = Qtools.rmse()
print("Root Mean Square Error is {}".format(RMSE))
#%%
print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print("Reconstructing with FISTA-OS method using tomobar")
print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
# initialise tomobar ITERATIVE reconstruction class ONCE
from tomobar.methodsIR import RecToolsIR
Rectools = RecToolsIR(
    DetectorsDimH=Horiz_det,  # DetectorsDimH # detector dimension (horizontal)
    DetectorsDimV=
    Vert_det,  # DetectorsDimV # detector dimension (vertical) for 3D case only
    CenterRotOffset=0.0,  # 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)
    device_projector='gpu')

_data_ = {
    'projection_norm_data': projData3D_analyt_noisy,
    'OS_number': 10
}  # data dictionary

lc = Rectools.powermethod(
    _data_)  # calculate Lipschitz constant (run once to initialise)

# Run FISTA reconstrucion algorithm without regularisation
_algorithm_ = {'iterations': 20, 'lipschitz_const': lc}
Exemplo n.º 24
0
FBPrec = RectoolsDIR.FBP(data_norm[:, :, slice_to_recon])

plt.figure()
plt.imshow(FBPrec[150:550, 150:550], vmin=0, vmax=0.005, cmap="gray")
plt.title('FBP reconstruction')

from tomobar.methodsIR import RecToolsIR
# set parameters and initiate a class object
Rectools = RecToolsIR(
    DetectorsDimH=
    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, \
Exemplo n.º 25
0
# calculate errors 
Qtools = QualityTools(phantom_tm, recNumerical)
RMSE = Qtools.rmse()
print("Root Mean Square Error is {}".format(RMSE))
#%%
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,
Exemplo n.º 26
0
plt.rcParams.update({'font.size': 20})
plt.imshow(FBPrec, vmin=0, vmax=1, cmap="gray")
plt.colorbar(ticks=[0, 0.5, 1], orientation='vertical')
plt.title('FBP reconstruction')
#%%
print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print("Reconstructing with ADMM method (ASTRA used for projection)")
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)
    device_projector='gpu')

# prepare dictionaries with parameters:
_data_ = {'projection_norm_data': noisy_sino}  # data dictionary
_algorithm_ = {'iterations': 15, 'ADMM_rho_const': 4000.0}

# adding regularisation using the CCPi regularisation toolkit
_regularisation_ = {
    'method': 'FGP_TV',
    'regul_param': 0.06,
    'iterations': 100,
    'device_regulariser': 'gpu'
Exemplo n.º 27
0
plt.rcParams.update({'font.size': 20})
plt.imshow(FBPrec, vmin=0, vmax=1, cmap="gray")
plt.colorbar(ticks=[0, 0.5, 1], orientation='vertical')
plt.title('FBP reconstruction')
#%%
print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print ("Reconstructing with FISTA method (ASTRA used for projection)")
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,\
Exemplo n.º 28
0
FBPrec_misalign = Rectools.FBP(
    sino_misalign)  # reconstruction with misalignment

plt.figure()
plt.imshow(FBPrec_misalign, vmin=0, vmax=1, cmap="gray")
plt.title('FBP reconstruction of misaligned data using known exact shifts')
#%%
print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print("Reconstructing using FISTA method (tomobar)")
print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
from tomobar.methodsIR import RecToolsIR
RectoolsIR = RecToolsIR(
    DetectorsDimH=P,  # Horizontal detector dimension
    DetectorsDimV=None,  # Vertical detector dimension (3D case)
    CenterRotOffset=None,  # 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, SWLS
    device_projector='gpu')

# prepare dictionaries with parameters
# data dictionary
_data_ = {
    'projection_norm_data': sino_artifacts,
    'projection_raw_data': sino_artifacts_raw / np.max(sino_artifacts_raw),
    'OS_number': 10
}
lc = RectoolsIR.powermethod(
    _data_)  # calculate Lipschitz constant (run once to initialise)

_algorithm_ = {'iterations': 30, 'mask_diameter': 0.9, 'lipschitz_const': lc}
Exemplo n.º 29
0
    ObjSize=N_size,  # Reconstructed object dimensions (scalar)
    device_projector='gpu')

FBPrec = RectoolsDIR.FBP(data_norm)

plt.figure()
#plt.imshow(FBPrec[500:1500,500:1500], vmin=0, vmax=1, cmap="gray")
plt.imshow(FBPrec, vmin=0, vmax=1, cmap="gray")
plt.title('FBP reconstruction')
#%%
from tomobar.methodsIR import RecToolsIR
# set parameters and initiate a class object
Rectools = RecToolsIR(
    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}
Exemplo n.º 30
0
class TomobarRecon3d(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: The dimension of the reconstructed volume (only X-Y dimension). Default: 'auto'.
    :param padding: The amount of pixels to pad each slab of the cropped projection data. Default: 17.
    :param data_fidelity: Data fidelity, Least Squares only at the moment. Default: 'LS'.
    :param data_Huber_thresh: Threshold parameter for __Huber__ data fidelity . Default: None.
    :param data_any_rings: a parameter to suppress various artifacts including rings and streaks. Default: None.
    :param data_any_rings_winsizes: half window sizes to collect background information [detector, angles, num of projections]. Default: (9,7,9).
    :param data_any_rings_power: a power parameter for Huber model. Default: 1.5.
    :param data_full_ring_GH: Regularisation variable for full constant ring removal (GH model). Default: None.
    :param data_full_ring_accelerator_GH: Acceleration constant for GH ring removal. Default: 10.0.
    :param algorithm_iterations: Number of outer iterations for FISTA (default) or ADMM methods. Default: 20.
    :param algorithm_verbose: print iterations number and other messages ('off' by default). Default: 'off'.
    :param algorithm_ordersubsets: The number of ordered-subsets to accelerate reconstruction. Default: 6.
    :param algorithm_nonnegativity: ENABLE or DISABLE nonnegativity constraint. Default: 'ENABLE'.
    :param regularisation_method: To regularise choose methods ROF_TV, FGP_TV, PD_TV, SB_TV, LLT_ROF,\
                             NDF, TGV, Diff4th. Default: 'FGP_TV'.
    :param regularisation_parameter: Regularisation (smoothing) value, higher \
                            the value stronger the smoothing effect. Default: 0.00001.
    :param regularisation_iterations: The number of regularisation iterations. Default: 80.
    :param regularisation_device: The number of regularisation iterations. Default: 'gpu'.
    :param regularisation_PD_lip: Primal-dual parameter for convergence. Default: 8.
    :param regularisation_methodTV:  0/1 - TV specific isotropic/anisotropic choice. Default: 0.
    :param regularisation_timestep: Time marching parameter, relevant for \
                    (ROF_TV, LLT_ROF, NDF, Diff4th) penalties. Default: 0.003.
    :param regularisation_edge_thresh: 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 regularisation_NDF_penalty: NDF specific penalty type Huber, Perona, Tukey. Default: 'Huber'.
    """

    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]
        return sizeX

    def set_filter_padding(self, in_pData, out_pData):
        self.pad = self.parameters['padding']
        in_data = self.get_in_datasets()[0]
        det_y = in_data.get_data_dimension_by_axis_label('detector_y')
        pad_det_y = '%s.%s' % (det_y, self.pad)
        pad_dict = {'pad_directions': [pad_det_y], 'pad_mode': 'edge'}
        in_pData[0].padding = pad_dict
        out_pData[0].padding = pad_dict

    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._get_output_size(in_dataset[0])
        shape = list(in_dataset[0].get_shape())
        rot_dim = in_dataset[0].get_data_dimension_by_axis_label(
                'rotation_angle')
        detX_dim = in_dataset[0].get_data_dimension_by_axis_label('detector_x')
        shape[rot_dim] = self.output_size
        shape[detX_dim] = self.output_size

        # if there are only 3 dimensions then add a fourth for slicing
#        if len(shape) == 2:
#            axis_labels = [0]*3
#            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()

    	procs = self.exp.meta_data.get("processes")
        procs = len([i for i in procs if 'GPU' in i])
        dim = in_dataset[0].get_data_dimension_by_axis_label('detector_y')
    	nSlices = int(np.ceil(shape[dim]/float(procs)))
    	
        in_pData[0].plugin_data_setup('SINOGRAM', nSlices, slice_axis='detector_y')

        # 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_XZ', nSlices)

    def pre_process(self):
        in_pData = self.get_plugin_in_datasets()[0]
        detY = in_pData.get_data_dimension_by_axis_label('detector_y')
        self.Vert_det = in_pData.get_shape()[detY] + 2*self.pad

        # extract given parameters into dictionaries suitable for ToMoBAR input
        self._data_ = {'OS_number' : self.parameters['algorithm_ordersubsets'],
                       'huber_threshold' : self.parameters['data_Huber_thresh'],
                       'ring_weights_threshold' :  self.parameters['data_any_rings'],
                       'ring_tuple_halfsizes' :  self.parameters['data_any_rings_winsizes'],
                       'ring_huber_power' :  self.parameters['data_any_rings_power'],
                       'ringGH_lambda' :  self.parameters['data_full_ring_GH'],
                       'ringGH_accelerate' :  self.parameters['data_full_ring_accelerator_GH']}

        self._algorithm_ = {'iterations' : self.parameters['algorithm_iterations'],
      			    'nonnegativity' : self.parameters['algorithm_nonnegativity'],
                            'verbose' : self.parameters['algorithm_verbose']}

        self._regularisation_ = {'method' : self.parameters['regularisation_method'],
                                'regul_param' : self.parameters['regularisation_parameter'],
                                'iterations' : self.parameters['regularisation_iterations'],
                                'device_regulariser' : self.parameters['regularisation_device'],
                                'edge_threhsold' : self.parameters['regularisation_edge_thresh'],
                                'time_marching_step' : self.parameters['regularisation_timestep'],
                                'regul_param2' : self.parameters['regularisation_parameter2'],
                                'PD_LipschitzConstant' : self.parameters['regularisation_PD_lip'],
                                'NDF_penalty' : self.parameters['regularisation_NDF_penalty'],
                                'methodTV' : self.parameters['regularisation_methodTV']}

        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))
        self._data_.update({'projection_norm_data' : projdata3D})

       # 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.parameters['data_fidelity'],# data fidelity, choose LS
                    device_projector='gpu')

        # Run FISTA reconstrucion algorithm here
        recon = self.Rectools.FISTA(self._data_, self._algorithm_, self._regularisation_)
        recon = np.swapaxes(recon,0,1)
        return recon

    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