From 415534f1e3a50569647fd0dd9c945adccc367bb5 Mon Sep 17 00:00:00 2001 From: dkazanc Date: Tue, 17 Dec 2024 16:45:00 +0000 Subject: [PATCH 1/7] fixing api build and updating sphinx --- .github/workflows/tomobar_docs.yml | 28 ++++++++++++++-------- docs/source/api/tomobar.astra_wrappers.rst | 20 +++++++++++++--- docs/source/api/tomobar.rst | 3 ++- docs/source/conf.py | 18 +++++++++++--- docs/source/doc-conda-requirements.yml | 7 ++---- 5 files changed, 54 insertions(+), 22 deletions(-) diff --git a/.github/workflows/tomobar_docs.yml b/.github/workflows/tomobar_docs.yml index 373ae7872..0a15eaf68 100644 --- a/.github/workflows/tomobar_docs.yml +++ b/.github/workflows/tomobar_docs.yml @@ -1,25 +1,29 @@ name: tomobar_docs on: - schedule: - # Run at midnight every day - - cron: '20 12 * * *' - + workflow_dispatch: + pull_request: + branches: + - main + push: + branches: + - main + jobs: - build-linux: + build-docs-publish: runs-on: ubuntu-latest defaults: run: shell: bash -el {0} steps: - name: Checkout repository code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - - name: Setup Python 3.9 - uses: actions/setup-python@v3 + - name: Setup Python 3.10 + uses: actions/setup-python@v4 with: - python-version: 3.9 - + python-version: '3.10' + - name: tomobar-docs uses: conda-incubator/setup-miniconda@v2 with: @@ -27,6 +31,10 @@ jobs: activate-environment: tomobar-docs environment-file: ./docs/source/doc-conda-requirements.yml + - name: pip install tomobar + run: | + pip install tomobar + - name: Build api docs run: sphinx-apidoc -feT -t=./docs/source/_templates -o ./docs/source/api ./tomobar diff --git a/docs/source/api/tomobar.astra_wrappers.rst b/docs/source/api/tomobar.astra_wrappers.rst index 94bfa7292..c8b858610 100644 --- a/docs/source/api/tomobar.astra_wrappers.rst +++ b/docs/source/api/tomobar.astra_wrappers.rst @@ -1,6 +1,20 @@ -:mod:`tomobar.astra_wrappers` -============================================ +tomobar.astra\_wrappers package +=============================== + +Submodules +---------- + +.. toctree:: + :maxdepth: 4 + + tomobar.astra_wrappers.astra_base + tomobar.astra_wrappers.astra_tools2d + tomobar.astra_wrappers.astra_tools3d + +Module contents +--------------- + .. automodule:: tomobar.astra_wrappers :members: :show-inheritance: - :undoc-members: \ No newline at end of file + :undoc-members: diff --git a/docs/source/api/tomobar.rst b/docs/source/api/tomobar.rst index 4a9af0525..a0f680f0e 100644 --- a/docs/source/api/tomobar.rst +++ b/docs/source/api/tomobar.rst @@ -7,6 +7,7 @@ Subpackages .. toctree:: :maxdepth: 4 + tomobar.astra_wrappers tomobar.cuda_kernels tomobar.supp @@ -16,7 +17,7 @@ Submodules .. toctree:: :maxdepth: 4 - tomobar.astra_wrappers + tomobar.fourier tomobar.methodsDIR tomobar.methodsDIR_CuPy tomobar.methodsIR diff --git a/docs/source/conf.py b/docs/source/conf.py index efe785ed2..f0c38d74d 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -21,9 +21,10 @@ MOCK_MODULES = [ "cupy", "astra", + "scipy", + "scipy.fftpack", ] - # MOCK_MODULES = [ # "cupy", # "skimage", @@ -35,6 +36,16 @@ for mod_name in MOCK_MODULES: sys.modules[mod_name] = mock.Mock() +autodoc_mock_imports = [ + "astra", + "cupy", + "scipy", + "scipy.fftpack", + "tomobar.astra_wrappers.astra_tools2d", + "tomobar.astra_wrappers.astra_tools3d", +] + + # ------------------------------------------------------------------------------ project = "Tomobar" @@ -61,14 +72,15 @@ # Add links to highlighted source code "sphinx.ext.viewcode", # Allows a grid layout and dropdown boxes - "sphinx_panels", + "sphinx_design", # copy to clipboard button "sphinx_copybutton", + # use jupyter notebooks + "nbsphinx", #'IPython.sphinxext.ipython_console_highlighting', "sphinx.ext.githubpages", # Generate .nojekyll file for git pages build ] - autosummary_generate = True numfig = True template_patterns = ["_templates"] diff --git a/docs/source/doc-conda-requirements.yml b/docs/source/doc-conda-requirements.yml index 2ba95fe82..5a1ad2300 100644 --- a/docs/source/doc-conda-requirements.yml +++ b/docs/source/doc-conda-requirements.yml @@ -1,18 +1,15 @@ name: tomobar-docs channels: - conda-forge - - defaults - - httomo dependencies: - - python=3.10 - - tomobar + - python>=3.10 - scipy - sphinx - sphinx-book-theme - nbsphinx - pandoc - jinja2 - - sphinx-panels + - sphinx-design - sphinx-copybutton - pyyaml - ipython From 08cb31a967d968bb0f091fcbcfa7356ccd2547bd Mon Sep 17 00:00:00 2001 From: dkazanc Date: Wed, 18 Dec 2024 11:24:10 +0000 Subject: [PATCH 2/7] work on RecToolsIRCuPy docs --- docs/source/conf.py | 12 +++++++++++ tomobar/methodsIR_CuPy.py | 45 ++++++++++++++++++++------------------- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index f0c38d74d..6e4b3a9fe 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -38,13 +38,25 @@ autodoc_mock_imports = [ "astra", + "astra.experimental", "cupy", "scipy", "scipy.fftpack", + "bm3d", + "skimage", + "tomobar.astra_wrappers.astra_base", "tomobar.astra_wrappers.astra_tools2d", "tomobar.astra_wrappers.astra_tools3d", ] +class CustomMock(mock.Mock): + def __repr__(self): + return "" + + +sys.modules["cupy"] = CustomMock() +sys.modules["numpy"] = CustomMock() + # ------------------------------------------------------------------------------ diff --git a/tomobar/methodsIR_CuPy.py b/tomobar/methodsIR_CuPy.py index d9783cbb8..6c8ea1610 100644 --- a/tomobar/methodsIR_CuPy.py +++ b/tomobar/methodsIR_CuPy.py @@ -1,8 +1,4 @@ """Reconstruction class for regularised iterative methods using CuPy library. - -* Regularised FISTA algorithm (A. Beck and M. Teboulle, A fast iterative - shrinkage-thresholding algorithm for linear inverse problems, - SIAM Journal on Imaging Sciences, vol. 2, no. 1, pp. 183–202, 2009.) """ import numpy as np @@ -25,13 +21,13 @@ class RecToolsIRCuPy(RecToolsIR): - """CuPy-enabled iterative reconstruction algorithms using ASTRA toolbox, CCPi-RGL toolkit. + """CuPy-enabled iterative reconstruction algorithms using ASTRA toolbox and CCPi-RGL toolkit (FISTA). Parameters for reconstruction algorithms are extracted from three dictionaries: - _data_, _algorithm_ and _regularisation_. See API for `tomobar.supp.dicts` function for all parameters - that are accepted. + _data_, _algorithm_ and _regularisation_. See `tomobar.supp.dicts `_ + function of ToMoBAR's :ref:`ref_api` for all parameters explained. If FISTA is used it will require CuPy-enabled routines of the CCPi-regularisation toolkit. - This implementation is typically >3 times faster than one in RecToolsIR, however + This implementation is typically more than times faster than the one in RecToolsIR, however, please note that the functionality of FISTA is limited compared to the version of FISTA in RecToolsIR. The work is in progress and the current FISTA version is experimental. @@ -41,8 +37,8 @@ class RecToolsIRCuPy(RecToolsIR): CenterRotOffset (float): The Centre of Rotation (CoR) scalar or a vector for each angle. AnglesVec (np.ndarray): Vector of projection angles in radians. ObjSize (int): Reconstructed object dimensions (a scalar). - datafidelity (str): Data fidelity, choose from LS, KL, PWLS or SWLS. - device_projector (int): Provide a GPU index (integer) of a specific GPU device. + datafidelity (str, optional): Data fidelity, choose from LS and PWLS. Defaults to LS. + device_projector (int, optional): Provide a GPU index of a specific GPU device. Defaults to 0. cupyrun (bool, optional): instantiate CuPy modules. """ @@ -53,7 +49,7 @@ def __init__( CenterRotOffset, # The Centre of Rotation scalar or a vector AnglesVec, # Array of projection angles in radians ObjSize, # Reconstructed object dimensions (scalar) - datafidelity="LS", # Data fidelity, choose from LS, KL, PWLS, SWLS + datafidelity="LS", # Data fidelity, choose from LS and PWLS device_projector=0, # provide a GPU index (integer) of a specific device cupyrun=True, ): @@ -75,7 +71,8 @@ def Landweber( self, _data_: dict, _algorithm_: Union[dict, None] = None ) -> cp.ndarray: """Using Landweber iterative technique to reconstruct projection data given as a CuPy array. - We perform the following iterations: x_k+1 = x_k - tau*A.T(A(x_k) - b) + We perform the following iterations: :math:`x^{k+1} = x^{k} + \\tau * \mathbf{A}^{\intercal}(\mathbf{A}x^{k} - b)`. + Args: _data_ (dict): Data dictionary, where projection data is provided. @@ -112,9 +109,9 @@ def Landweber( def SIRT(self, _data_: dict, _algorithm_: Union[dict, None] = None) -> cp.ndarray: """Using Simultaneous Iterations Reconstruction Technique (SIRT) iterative technique to - reconstruct projection data given as a CuPy array. - We perform the following iterations:: x_k+1 = C*A.T*R(b - A(x_k)) - + reconstruct projection data given as a CuPy array. + We perform the following iterations: :math:`x^{k+1} = \mathbf{C}\mathbf{A}^{\intercal}\mathbf{R}(b - \mathbf{A}x^{k})`. + Args: _data_ (dict): Data dictionary, where projection data is provided. _algorithm_ (dict, optional): Algorithm dictionary where algorithm parameters are provided. @@ -162,7 +159,8 @@ def SIRT(self, _data_: dict, _algorithm_: Union[dict, None] = None) -> cp.ndarra def CGLS(self, _data_: dict, _algorithm_: Union[dict, None] = None) -> cp.ndarray: """Conjugate Gradients Least Squares iterative technique to reconstruct projection data - given as a CuPy array. We aim to solve the system of normal equations A.T*A*x = A.T*b. + given as a CuPy array. The algorithm aim to solve the system of normal equations + :math:`\mathbf{A}^{\intercal}\mathbf{A}x = \mathbf{A}^{\intercal} b`. Args: _data_ (dict): Data dictionary, where projection data is provided. @@ -221,7 +219,7 @@ def CGLS(self, _data_: dict, _algorithm_: Union[dict, None] = None) -> cp.ndarra def powermethod(self, _data_: dict) -> float: """Power iteration algorithm to calculate the eigenvalue of the operator (projection matrix). - projection_raw_data is required for PWLS fidelity (self.datafidelity = PWLS), otherwise will be ignored. + projection_raw_data is required for the PWLS fidelity (self.datafidelity = PWLS), otherwise will be ignored. Args: _data_ (dict): Data dictionary, where input data as a cupy array is provided. @@ -239,11 +237,14 @@ def FISTA( _algorithm_: Union[dict, None] = None, _regularisation_: Union[dict, None] = None, ) -> cp.ndarray: - """A Fast Iterative Shrinkage-Thresholding Algorithm with various types regularisations. - The parameters for the algorithm should be provided in three dictionaries: - _data_, _algorithm_ and _regularisation_. See API for `tomobar.supp.dicts` function - for all parameters that are accepted. - Please note that not all of the functionality supported compared to FISTA from methodsIR. + """A Fast Iterative Shrinkage-Thresholding Algorithm [BT2009]_ with various types of regularisation from + the regularisation toolkit [KAZ2019]_. + + All parameters for the algorithm should be provided in three dictionaries: + _data_, _algorithm_, and _regularisation_. See `tomobar.supp.dicts `_ + function of ToMoBAR's :ref:`ref_api` for all parameters explained. + Please note that not all of the functionality supported in this CuPy implementation compared to FISTA from + `methodsIR `_. Args: _data_ (dict): Data dictionary, where input data is provided. From 02a207db6dec6842cfa9f90a15d990517e4d64af Mon Sep 17 00:00:00 2001 From: dkazanc Date: Thu, 19 Dec 2024 17:37:53 +0000 Subject: [PATCH 3/7] improving docs --- .github/workflows/tomobar_docs.yml | 10 ++++---- docs/source/howto/installation.rst | 9 +++++-- docs/source/introduction/references.rst | 32 ++++++++++++++----------- pyproject.toml | 2 -- tomobar/methodsDIR.py | 5 ++-- tomobar/methodsDIR_CuPy.py | 13 +++++----- tomobar/methodsIR.py | 10 +++----- tomobar/methodsIR_CuPy.py | 12 ++++++---- tomobar/regularisers.py | 5 ++-- tomobar/regularisersCuPy.py | 9 ++++--- 10 files changed, 55 insertions(+), 52 deletions(-) diff --git a/.github/workflows/tomobar_docs.yml b/.github/workflows/tomobar_docs.yml index 0a15eaf68..c4225f948 100644 --- a/.github/workflows/tomobar_docs.yml +++ b/.github/workflows/tomobar_docs.yml @@ -4,10 +4,10 @@ on: workflow_dispatch: pull_request: branches: - - main + - master push: branches: - - main + - master jobs: build-docs-publish: @@ -23,7 +23,7 @@ jobs: uses: actions/setup-python@v4 with: python-version: '3.10' - + - name: tomobar-docs uses: conda-incubator/setup-miniconda@v2 with: @@ -32,8 +32,8 @@ jobs: environment-file: ./docs/source/doc-conda-requirements.yml - name: pip install tomobar - run: | - pip install tomobar + run: | + pip install tomobar - name: Build api docs run: sphinx-apidoc -feT -t=./docs/source/_templates -o ./docs/source/api ./tomobar diff --git a/docs/source/howto/installation.rst b/docs/source/howto/installation.rst index 641cc9fa9..ee3f30436 100644 --- a/docs/source/howto/installation.rst +++ b/docs/source/howto/installation.rst @@ -3,7 +3,10 @@ Installation Guide ------------------ ToMoBAR is a Python package with several :ref:`ref_dependencies`. To ensure its full functionality it is recommended to install them. -It mostly relies on the GPU-enabled computations and therefore we suggest using a decent NVIDIA graphics card to support it. +It mostly relies on the GPU-enabled computations and therefore we suggest using a decent NVIDIA graphics card to support it. ToMoBAR +can run with `CuPy `_ or using normal routines using pre-built CUDA modules of the Regularisation Toolkit. + +.. note:: CuPy-enabled ToMoBAR is the development in progress. Methods like FISTA can normally run several times faster, however, not every variation is supported. .. _ref_python: @@ -22,6 +25,7 @@ or install with the dependencies into a new environment: .. code-block:: console $ conda install -c httomo -c conda-forge tomophantom tomobar astra-toolbox ccpi-regulariser pypwt + $ conda install conda-forge::cupy # install only if you need CuPy-enabled modules one can also try this installation, especially for other than Linux OSs: @@ -30,7 +34,8 @@ one can also try this installation, especially for other than Linux OSs: $ conda install -c httomo -c ccpi -c conda-forge tomophantom tomobar astra-toolbox ccpi-regulariser Install ToMoBAR from PyPi: -+++++++++++++++++++++++++++ +++++++++++++++++++++++++++ + One can install ToMoBAR from PyPi, however, not all dependencies might be at PyPi yet. .. code-block:: console diff --git a/docs/source/introduction/references.rst b/docs/source/introduction/references.rst index 07a84d672..664ef6ef2 100644 --- a/docs/source/introduction/references.rst +++ b/docs/source/introduction/references.rst @@ -3,39 +3,43 @@ References *********** -.. [CT2020] D. Kazantsev and N. Wadeson. 2020, Tomographic MOdel-BAsed Reconstruction (ToMoBAR) software for high resolution - synchrotron X-ray tomography, CT Meeting 2020. +.. [CT2020] D. Kazantsev and N. Wadeson. 2020, Tomographic MOdel-BAsed Reconstruction (ToMoBAR) software for high resolution + synchrotron X-ray tomography, CT Meeting 2020. Download `here `_. -.. [SX2022] D. Kazantsev, N. Wadeson, M. Basham, 2022. - High performance Savu software for fast 3D model-based +.. [SX2022] D. Kazantsev, N. Wadeson, M. Basham, 2022. + High performance Savu software for fast 3D model-based iterative reconstruction of large data at Diamond Light Source. SoftwareX, 19, p.101157. -.. [BT2009] A. Beck and M. Teboulle, A fast iterative shrinkage-thresholding - algorithm for linear inverse problems, SIAM Journal on Imaging Sciences, vol. 2, +.. [BT2009] A. Beck and M. Teboulle, A fast iterative shrinkage-thresholding + algorithm for linear inverse problems, SIAM Journal on Imaging Sciences, vol. 2, no. 1, pp. 183–202, 2009. -.. [PM2015] P. Paleo and A. Mirone 2015. Ring artifacts correction in +.. [Boyd2011] Boyd, N. Parikh, E. Chu, B. Peleato, J. Eckstein, "Distributed optimization and + statistical learning via the alternating direction method of multipliers", Found. Trends Mach. Learn., + vol. 3, no. 1, pp. 1-122, Jan. 2011 + +.. [PM2015] P. Paleo and A. Mirone 2015. Ring artifacts correction in compressed sensing tomographic reconstruction. Journal of synchrotron radiation, 22(5), pp.1268-1278. .. [HOA2017] H. Om Aggrawal et al. 2017. A Convex Reconstruction Model - for X-ray tomographic Imaging with Uncertain Flat-fields", IEEE + for X-ray tomographic Imaging with Uncertain Flat-fields", IEEE Transactions on Computational Imaging. -.. [KAZ1_2017] D. Kazantsev et al. 2017. A Novel +.. [KAZ1_2017] D. Kazantsev et al. 2017. A Novel Tomographic Reconstruction Method Based on the Robust - Student's t Function For Suppressing Data Outliers. + Student's t Function For Suppressing Data Outliers. IEEE TCI, 3(4), pp.682-693. -.. [KAZ2019] D. Kazantsev et al. 2019. CCPi-Regularisation +.. [KAZ2019] D. Kazantsev et al. 2019. CCPi-Regularisation toolkit for computed tomographic image reconstruction with proximal splitting algorithms. SoftwareX, 9, pp.317-323. -.. [GUO2018] E. Guo et al. 2018. The influence of nanoparticles on dendritic +.. [GUO2018] E. Guo et al. 2018. The influence of nanoparticles on dendritic grain growth in Mg alloys. Acta Materialia. -.. [KAZ2017] D. Kazantsev et al. 2017. Model-based iterative - reconstruction using higher-order regularization of dynamic +.. [KAZ2017] D. Kazantsev et al. 2017. Model-based iterative + reconstruction using higher-order regularization of dynamic synchrotron data. Measurement Science and Technology, 28(9), p.094004. \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index adc528dbf..f40857587 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,8 +66,6 @@ addopts = [ "-ra", "-q", "--tb=native", - "--cov-report=term", - "--cov-report=xml:cov.xml", ] testpaths = [ "tests", diff --git a/tomobar/methodsDIR.py b/tomobar/methodsDIR.py index 78e1f6f55..4236037e6 100644 --- a/tomobar/methodsDIR.py +++ b/tomobar/methodsDIR.py @@ -1,6 +1,6 @@ -"""Reconstruction class for direct reconstructon methods. +"""Reconstruction class for direct reconstruction methods. -* Fourier Slice Theorem reconstruction (adopted from Tim Day's code) +* Fourier Slice Theorem reconstruction (adopted from the Tim Day's code) * Forward/Backward projection (ASTRA) * Filtered Back Projection (ASTRA) """ @@ -8,7 +8,6 @@ import numpy as np import scipy.fftpack -from typing import Union from tomobar.astra_wrappers.astra_tools2d import AstraTools2D from tomobar.astra_wrappers.astra_tools3d import AstraTools3D from tomobar.supp.funcs import _data_dims_swapper, _parse_device_argument diff --git a/tomobar/methodsDIR_CuPy.py b/tomobar/methodsDIR_CuPy.py index 295990811..0f25b114a 100644 --- a/tomobar/methodsDIR_CuPy.py +++ b/tomobar/methodsDIR_CuPy.py @@ -1,9 +1,8 @@ """Reconstruction class for 3D direct methods using CuPy-library. * Forward/Backward projection (ASTRA with DirectLink and CuPy). -* Filtered Back Projection (ASTRA, Filter implemented in CuPy). -* Fourier direct reconstruction with classical polar to cartesian interpolation. -* Fourier direct reconstruction on unequally spaced grids (interpolation in image space). +* Filtered Back Projection (ASTRA, Filter implemented with CuPy). +* Fourier direct reconstruction on unequally spaced grids (interpolation in image space), aka log-polar method. """ import numpy as np @@ -31,7 +30,7 @@ class RecToolsDIRCuPy(RecToolsDIR): - """Reconstruction class using DIRect methods with CuPy API. + """Reconstruction class using direct methods with CuPy API. Args: DetectorsDimH (int): Horizontal detector dimension. @@ -120,7 +119,7 @@ def FBP(self, data: xp.ndarray, **kwargs) -> xp.ndarray: Returns: xp.ndarray: The FBP reconstructed volume as a CuPy array. """ - cutoff_freq = 0.6 # default value + cutoff_freq = 1.1 # default value for key, value in kwargs.items(): if key == "data_axes_labels_order" and value is not None: data = _data_dims_swapper(data, value, ["angles", "detY", "detX"]) @@ -139,8 +138,8 @@ def FBP(self, data: xp.ndarray, **kwargs) -> xp.ndarray: def FOURIER_INV(self, data: xp.ndarray, **kwargs) -> xp.ndarray: """Fourier direct inversion in 3D on unequally spaced (also called as NonUniform FFT/NUFFT) grids using CuPy array as an input. - This implementation follows V. Nikitin's CUDA-C implementation: - https://github.com/nikitinvv/radonusfft and TomoCuPy package. + This implementation follows V. Nikitin's CUDA-C implementation: + https://github.com/nikitinvv/radonusfft and TomoCuPy package. Args: diff --git a/tomobar/methodsIR.py b/tomobar/methodsIR.py index d9bbd9eed..75c494479 100644 --- a/tomobar/methodsIR.py +++ b/tomobar/methodsIR.py @@ -1,12 +1,8 @@ """Reconstruction class for regularised iterative methods. -* Regularised FISTA algorithm (A. Beck and M. Teboulle, A fast iterative - shrinkage-thresholding algorithm for linear inverse problems, - SIAM Journal on Imaging Sciences, vol. 2, no. 1, pp. 183–202, 2009.) -* Regularised ADMM algorithm (Boyd, N. Parikh, E. Chu, B. Peleato, J. Eckstein, "Distributed optimization and - statistical learning via the alternating direction method of multipliers", Found. Trends Mach. Learn., - vol. 3, no. 1, pp. 1-122, Jan. 2011) -* SIRT, CGLS algorithms wrapped directly from the ASTRA package +* Regularised FISTA algorithm [BT2009]_ +* Regularised ADMM algorithm [Boyd2011]_ +* SIRT and CGLS algorithms wrapped directly from the ASTRA package """ import numpy as xp diff --git a/tomobar/methodsIR_CuPy.py b/tomobar/methodsIR_CuPy.py index de2ccfe19..504b78144 100644 --- a/tomobar/methodsIR_CuPy.py +++ b/tomobar/methodsIR_CuPy.py @@ -1,4 +1,9 @@ """Reconstruction class for regularised iterative methods using CuPy library. + +* FISTA regularised algorithm [BT2009]_ . Implemented using ASTRA with DirectLink and CuPy, Regularisation Toolkit-CuPy. +* Landweber algorithm. +* SIRT algorithm. +* CGLS algorithm. """ import numpy as np @@ -55,7 +60,6 @@ def __init__( device_projector=0, # provide a GPU index (integer) of a specific device cupyrun=True, ): - if DetectorsDimV == 0 or DetectorsDimV is None: raise ValueError("2D CuPy reconstruction is not yet supported, only 3D is") @@ -146,7 +150,7 @@ def SIRT(self, _data_: dict, _algorithm_: Union[dict, None] = None) -> cp.ndarra """Using Simultaneous Iterations Reconstruction Technique (SIRT) iterative technique to reconstruct projection data given as a CuPy array. We perform the following iterations: :math:`x^{k+1} = \mathbf{C}\mathbf{A}^{\intercal}\mathbf{R}(b - \mathbf{A}x^{k})`. - + Args: _data_ (dict): Data dictionary, where projection data is provided. _algorithm_ (dict, optional): Algorithm dictionary where algorithm parameters are provided. @@ -194,7 +198,7 @@ def SIRT(self, _data_: dict, _algorithm_: Union[dict, None] = None) -> cp.ndarra def CGLS(self, _data_: dict, _algorithm_: Union[dict, None] = None) -> cp.ndarray: """Conjugate Gradients Least Squares iterative technique to reconstruct projection data - given as a CuPy array. The algorithm aim to solve the system of normal equations + given as a CuPy array. The algorithm aim to solve the system of normal equations :math:`\mathbf{A}^{\intercal}\mathbf{A}x = \mathbf{A}^{\intercal} b`. Args: @@ -357,7 +361,7 @@ def FISTA( All parameters for the algorithm should be provided in three dictionaries: _data_, _algorithm_, and _regularisation_. See `tomobar.supp.dicts `_ function of ToMoBAR's :ref:`ref_api` for all parameters explained. - Please note that not all of the functionality supported in this CuPy implementation compared to FISTA from + Please note that not all of the functionality supported in this CuPy implementation compared to FISTA from `methodsIR `_. Args: diff --git a/tomobar/regularisers.py b/tomobar/regularisers.py index 3d5ba0a37..dc4ec842f 100644 --- a/tomobar/regularisers.py +++ b/tomobar/regularisers.py @@ -1,7 +1,6 @@ """Adding regularisers from the CCPi-regularisation toolkit and -initiate proximity operator for iterative methods. +instantiate a proximal operator for iterative methods. -@author: Daniil Kazantsev: https://github.com/dkazanc """ import numpy as np @@ -36,7 +35,7 @@ def prox_regul(self, X: np.ndarray, _regularisation_: dict) -> Union[np.ndarray, Args: X (np.ndarray): 2D or 3D numpy array. - _regularisation_ (dict): Regularisation dictionary with parameters. + _regularisation_ (dict): Regularisation dictionary with parameters, see `tomobar.supp.dicts `_. Returns: np.ndarray or a tuple: Filtered 2D or 3D numpy array or a tuple. diff --git a/tomobar/regularisersCuPy.py b/tomobar/regularisersCuPy.py index 898bce7b7..0cbaae0eb 100644 --- a/tomobar/regularisersCuPy.py +++ b/tomobar/regularisersCuPy.py @@ -1,7 +1,6 @@ -"""Adding CuPy-enabled regularisers from the CCPi-regularisation toolkit and -initiate proximity operator for iterative methods. +"""Adding CuPy-enabled regularisers from the CCPi-regularisation toolkit and +instantiate a proximal operator for iterative methods. -@author: Daniil Kazantsev: https://github.com/dkazanc """ import cupy as cp @@ -16,11 +15,11 @@ def prox_regul(self, X: cp.ndarray, _regularisation_: dict) -> cp.ndarray: - """Enabling proximal operators step in interative reconstruction. + """Enabling proximal operators step in iterative reconstruction. Args: X (cp.ndarray): 2D or 3D CuPy array. - _regularisation_ (dict): Regularisation dictionary with parameters. + _regularisation_ (dict): Regularisation dictionary with parameters, see `tomobar.supp.dicts `_. Returns: cp.ndarray: Filtered 2D or 3D CuPy array. From 828b5884c11be9eaa7430a8d8e9a61824f3b37e5 Mon Sep 17 00:00:00 2001 From: dkazanc Date: Thu, 19 Dec 2024 17:43:16 +0000 Subject: [PATCH 4/7] removing pip install tomobar workflow --- .github/workflows/tomobar_docs.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/tomobar_docs.yml b/.github/workflows/tomobar_docs.yml index c4225f948..9ee3c4e64 100644 --- a/.github/workflows/tomobar_docs.yml +++ b/.github/workflows/tomobar_docs.yml @@ -31,10 +31,6 @@ jobs: activate-environment: tomobar-docs environment-file: ./docs/source/doc-conda-requirements.yml - - name: pip install tomobar - run: | - pip install tomobar - - name: Build api docs run: sphinx-apidoc -feT -t=./docs/source/_templates -o ./docs/source/api ./tomobar From 2121a729382ab30cf718c72be254003e70626f15 Mon Sep 17 00:00:00 2001 From: dkazanc Date: Fri, 20 Dec 2024 09:40:42 +0000 Subject: [PATCH 5/7] docs impr continues --- docs/source/howto/installation.rst | 13 +-- docs/source/introduction/references.rst | 14 ++- tests/conftest.py | 6 +- tests/test_RecToolsDIRCuPy.py | 135 ++++++++++++------------ tomobar/supp/dicts.py | 20 ++-- tomobar/supp/suppTools.py | 16 +-- 6 files changed, 103 insertions(+), 101 deletions(-) diff --git a/docs/source/howto/installation.rst b/docs/source/howto/installation.rst index ee3f30436..8ad7154b9 100644 --- a/docs/source/howto/installation.rst +++ b/docs/source/howto/installation.rst @@ -24,10 +24,11 @@ or install with the dependencies into a new environment: .. code-block:: console - $ conda install -c httomo -c conda-forge tomophantom tomobar astra-toolbox ccpi-regulariser pypwt + $ conda install -c httomo -c conda-forge tomophantom tomobar astra-toolbox ccpi-regulariser $ conda install conda-forge::cupy # install only if you need CuPy-enabled modules + $ pip install pypwt # if wavelet regularisation is to be used -one can also try this installation, especially for other than Linux OSs: +the installation above is tested on Linux and Windows, but one can also try: .. code-block:: console @@ -65,7 +66,8 @@ This sets the development environment to work in-place on the code. $ conda env create --name tomobar --file conda-recipe/environment/environment.yml $ conda activate tomobar $ pip install -e .[dev] # the editable environment - $ pytest tests/ # all tests should pass + $ pytest tests/test_RecToolsDIR.py tests/test_RecToolsIR.py + $ pytest tests/ # you'll need CuPy to run all tests Conda builds +++++++++++++ @@ -73,7 +75,7 @@ If one needs to conda-build the package, please follow the steps bellow: .. code-block:: console - $ export VERSION=$(date +%Y.%m) # OR set VERSION=2024.01 for Windows + $ export VERSION=$(date +%Y.%m) # OR set VERSION=2025.01 for Windows $ git clone git@github.com/dkazanc/ToMoBAR.git # clone the repo $ conda build conda-recipe/ $ conda install path/to/the/tarball @@ -82,6 +84,5 @@ If one needs to conda-build the package, please follow the steps bellow: Matlab ====== -Matlab part of ToMoBAR is not currently maintained and will be deprecated in future releases. -The code and Demos we provide have been tested with Matlab 2018 and ASTRA-Toolbox version v1.8.3. +.. warning:: Matlab's part of ToMoBAR is not currently maintained and will be deprecated in future releases. The code and demos were tested with Matlab 2018 and ASTRA-Toolbox version v1.8.3. diff --git a/docs/source/introduction/references.rst b/docs/source/introduction/references.rst index 664ef6ef2..1abceeccd 100644 --- a/docs/source/introduction/references.rst +++ b/docs/source/introduction/references.rst @@ -12,13 +12,13 @@ References iterative reconstruction of large data at Diamond Light Source. SoftwareX, 19, p.101157. -.. [BT2009] A. Beck and M. Teboulle, A fast iterative shrinkage-thresholding +.. [BT2009] A. Beck and M. Teboulle, 2009, A fast iterative shrinkage-thresholding algorithm for linear inverse problems, SIAM Journal on Imaging Sciences, vol. 2, - no. 1, pp. 183–202, 2009. + no. 1, pp. 183–202. -.. [Boyd2011] Boyd, N. Parikh, E. Chu, B. Peleato, J. Eckstein, "Distributed optimization and - statistical learning via the alternating direction method of multipliers", Found. Trends Mach. Learn., - vol. 3, no. 1, pp. 1-122, Jan. 2011 +.. [Boyd2011] Boyd, N. Parikh, E. Chu, B. Peleato, J. Eckstein, 2011, Distributed optimization and + statistical learning via the alternating direction method of multipliers, Found. Trends Mach. Learn., + vol. 3, no. 1, pp. 1-122 .. [PM2015] P. Paleo and A. Mirone 2015. Ring artifacts correction in compressed sensing tomographic reconstruction. Journal of synchrotron radiation, @@ -28,6 +28,10 @@ References for X-ray tomographic Imaging with Uncertain Flat-fields", IEEE Transactions on Computational Imaging. +.. [Xu2016] Q. Xu et al., 2016. Accelerated fast iterative shrinkage thresholding + algorithms for sparsity‐regularized cone‐beam CT image reconstruction. + Medical physics, 43(4), pp.1849-1872. + .. [KAZ1_2017] D. Kazantsev et al. 2017. A Novel Tomographic Reconstruction Method Based on the Robust Student's t Function For Suppressing Data Outliers. diff --git a/tests/conftest.py b/tests/conftest.py index 3e32b0e5b..1cd319250 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,7 +3,11 @@ import os import numpy as np import pytest -import cupy as cp + +try: + import cupy as cp +except ImportError: + print("Cupy library is a required to run some tests") CUR_DIR = os.path.abspath(os.path.dirname(__file__)) diff --git a/tests/test_RecToolsDIRCuPy.py b/tests/test_RecToolsDIRCuPy.py index 7b293d331..fbffc6576 100644 --- a/tests/test_RecToolsDIRCuPy.py +++ b/tests/test_RecToolsDIRCuPy.py @@ -4,7 +4,8 @@ from numpy.testing import assert_allclose from cupy import float32 import time -from cupy.cuda.nvtx import RangePush, RangePop + +# from cupy.cuda.nvtx import RangePush, RangePop from cupyx.profiler import time_range import pytest @@ -87,76 +88,76 @@ def test_Fourier3D_Z_odd(ensure_clean_memory): assert recon.shape == (3, N_size, N_size) -@pytest.mark.perf -def test_Fourier_inv3D_performance(ensure_clean_memory): - dev = cp.cuda.Device() - data_host = np.random.randint( - low=7515, high=37624, size=(1801, 6, 2560), dtype=np.uint16 - ).astype(np.float32) - data = cp.asarray(data_host) - detX = cp.shape(data)[2] - detY = cp.shape(data)[1] - angles = np.linspace(0, math.pi, data.shape[0]) - N_size = detX - RecToolsCP = RecToolsDIRCuPy( - DetectorsDimH=detX, # Horizontal detector dimension - DetectorsDimV=detY, # Vertical detector dimension (3D case) - CenterRotOffset=0.0, # Center of Rotation scalar or a vector - AnglesVec=angles, # A vector of projection angles in radians - ObjSize=N_size, # Reconstructed object dimensions (scalar) - device_projector="gpu", - ) - # cold run - RecToolsCP.FOURIER_INV(data, data_axes_labels_order=["angles", "detY", "detX"]) - start = time.perf_counter_ns() - RangePush("Core") - for _ in range(10): - RecToolsCP.FOURIER_INV(data, data_axes_labels_order=["angles", "detY", "detX"]) - RangePop() - dev.synchronize() - duration_ms = float(time.perf_counter_ns() - start) * 1e-6 / 10 +# @pytest.mark.perf +# def test_Fourier_inv3D_performance(ensure_clean_memory): +# dev = cp.cuda.Device() +# data_host = np.random.randint( +# low=7515, high=37624, size=(1801, 6, 2560), dtype=np.uint16 +# ).astype(np.float32) +# data = cp.asarray(data_host) +# detX = cp.shape(data)[2] +# detY = cp.shape(data)[1] +# angles = np.linspace(0, math.pi, data.shape[0]) +# N_size = detX +# RecToolsCP = RecToolsDIRCuPy( +# DetectorsDimH=detX, # Horizontal detector dimension +# DetectorsDimV=detY, # Vertical detector dimension (3D case) +# CenterRotOffset=0.0, # Center of Rotation scalar or a vector +# AnglesVec=angles, # A vector of projection angles in radians +# ObjSize=N_size, # Reconstructed object dimensions (scalar) +# device_projector="gpu", +# ) +# # cold run +# RecToolsCP.FOURIER_INV(data, data_axes_labels_order=["angles", "detY", "detX"]) +# start = time.perf_counter_ns() +# RangePush("Core") +# for _ in range(10): +# RecToolsCP.FOURIER_INV(data, data_axes_labels_order=["angles", "detY", "detX"]) +# RangePop() +# dev.synchronize() +# duration_ms = float(time.perf_counter_ns() - start) * 1e-6 / 10 - assert "performance in ms" == duration_ms +# assert "performance in ms" == duration_ms -@pytest.mark.perf -def test_FBP_performance(ensure_clean_memory): - dev = cp.cuda.Device() - data_host = np.random.randint( - low=7515, high=37624, size=(1801, 6, 2560), dtype=np.uint16 - ).astype(np.float32) - data = cp.asarray(data_host) - detX = cp.shape(data)[2] - detY = cp.shape(data)[1] - angles = np.linspace(0, math.pi, data.shape[0]) - N_size = detX - RecToolsCP = RecToolsDIRCuPy( - DetectorsDimH=detX, # Horizontal detector dimension - DetectorsDimV=detY, # Vertical detector dimension (3D case) - CenterRotOffset=0.0, # Center of Rotation scalar or a vector - AnglesVec=angles, # A vector of projection angles in radians - ObjSize=N_size, # Reconstructed object dimensions (scalar) - device_projector="gpu", - ) - # cold run - RecToolsCP.FBP( - data, - data_axes_labels_order=["angles", "detY", "detX"], - cutoff_freq=1.1, - ) - start = time.perf_counter_ns() - RangePush("Core") - for _ in range(10): - RecToolsCP.FBP( - data, - data_axes_labels_order=["angles", "detY", "detX"], - cutoff_freq=1.1, - ) - RangePop() - dev.synchronize() - duration_ms = float(time.perf_counter_ns() - start) * 1e-6 / 10 +# @pytest.mark.perf +# def test_FBP_performance(ensure_clean_memory): +# dev = cp.cuda.Device() +# data_host = np.random.randint( +# low=7515, high=37624, size=(1801, 6, 2560), dtype=np.uint16 +# ).astype(np.float32) +# data = cp.asarray(data_host) +# detX = cp.shape(data)[2] +# detY = cp.shape(data)[1] +# angles = np.linspace(0, math.pi, data.shape[0]) +# N_size = detX +# RecToolsCP = RecToolsDIRCuPy( +# DetectorsDimH=detX, # Horizontal detector dimension +# DetectorsDimV=detY, # Vertical detector dimension (3D case) +# CenterRotOffset=0.0, # Center of Rotation scalar or a vector +# AnglesVec=angles, # A vector of projection angles in radians +# ObjSize=N_size, # Reconstructed object dimensions (scalar) +# device_projector="gpu", +# ) +# # cold run +# RecToolsCP.FBP( +# data, +# data_axes_labels_order=["angles", "detY", "detX"], +# cutoff_freq=1.1, +# ) +# start = time.perf_counter_ns() +# RangePush("Core") +# for _ in range(10): +# RecToolsCP.FBP( +# data, +# data_axes_labels_order=["angles", "detY", "detX"], +# cutoff_freq=1.1, +# ) +# RangePop() +# dev.synchronize() +# duration_ms = float(time.perf_counter_ns() - start) * 1e-6 / 10 - assert "performance in ms" == duration_ms +# assert "performance in ms" == duration_ms def test_FBP3D(data_cupy, angles, ensure_clean_memory): diff --git a/tomobar/supp/dicts.py b/tomobar/supp/dicts.py index cbd971f45..66728a5ea 100644 --- a/tomobar/supp/dicts.py +++ b/tomobar/supp/dicts.py @@ -2,7 +2,6 @@ from tomobar.astra_wrappers.astra_tools2d import AstraTools2D from tomobar.astra_wrappers.astra_tools3d import AstraTools3D -import typing from typing import Union from tomobar.supp.funcs import _data_dims_swapper @@ -25,21 +24,20 @@ def dicts_check( _regularisation_: Union[dict, None] = None, method_run: str = "FISTA", ) -> tuple: - """This function checks the given _data_, _algorithm_, and _regularisation_ - dictionaries and populates parameters if required. Please note that the dictionaries are - required for iterative methods only as for direct methods the input is an array explicitly - given to the function as an argument. The most versatile method in terms of parametrisation - is currently FISTA, therefore most of the keywords arguments bellow are applicable to it. + """This function checks `_data_`, `_algorithm_`, and `_regularisation_` + dictionaries and populates parameters in them, if required. Please note that the dictionaries are + needed for iterative methods only. The most versatile methods that accept a variety of different parameters + are FISTA and ADMM. Args: - _data_ (dict): Data dictionary where data related items must be specified. - _algorithm_ (dict, optional): Algorithm dictionary. Defaults to {}. - _regularisation_ (dict, optional): Regularisation dictionary. Needed only for FISTA and ADMM algorithms. Defaults to {}. - method_run (str, optional): The name of the method to be run. Defaults to "FISTA". + _data_ (dict): *Data dictionary where data-related items must be specified.* + _algorithm_ (dict, optional): *Algorithm dictionary. Defaults to None.* + _regularisation_ (dict, optional): Regularisation dictionary. Needed only for FISTA and ADMM algorithms. Defaults to None. + method_run (str): The name of the method to be run. Defaults to "FISTA". Keyword Args: _data_['projection_norm_data'] (ndarray): The -log(normalised) projection data as a 2D sinogram or as a 3D data array. - _data_['projection_raw_data'] (ndarray): Raw data for PWLS and SWLS models. FISTA-related parameter. + _data_['projection_raw_data'] (ndarray): Raw data for PWLS and SWLS models. A FISTA-related parameter. _data_['data_axes_labels_order'] (list, None). The order of the axes labels for the input data, use the following labels: ["detY", "angles", "detX"]. _data_['OS_number'] (int): The number of ordered subsets, if None or 1 then the classical (full data) algorithm. Defaults to 1. _data_['huber_threshold'] (float): Parameter for the Huber data fidelity (to supress outliers). diff --git a/tomobar/supp/suppTools.py b/tomobar/supp/suppTools.py index 276986aa4..4ac265add 100644 --- a/tomobar/supp/suppTools.py +++ b/tomobar/supp/suppTools.py @@ -1,19 +1,13 @@ -"""Supplementary data tools: +"""Supplementary pre/post processing data tools: List of functions: -* normaliser - to normalise the raw data and take the negative log (if needed). Options are: 'mean', 'median' and 'dynamic'. +* normaliser - Projection data normalise the raw data and take the negative log (if needed). Options are: 'mean', 'median' and 'dynamic'. * autocropper - automatically crops the 3D projection data to reduce its size. -@authors: - Daniil Kazantsev: https://github.com/dkazanc - - Gerard Jover Pujol https://github.com/IararIV/ """ import numpy as np -import typing -from typing import Union try: import cupy as xp @@ -252,9 +246,9 @@ def normaliser( ) if method != "dynamic": denom = flats - darks - denom[(np.where(denom <= 0.0))] = ( - 1.0 # remove zeros/negatives in the denominator if any - ) + denom[ + (np.where(denom <= 0.0)) + ] = 1.0 # remove zeros/negatives in the denominator if any if axis == 1: denom = denom[:, np.newaxis, :] darks = darks[:, np.newaxis, :] From aed90900e57eb62725da2962088c436b86ceedbf Mon Sep 17 00:00:00 2001 From: dkazanc Date: Fri, 20 Dec 2024 15:22:12 +0000 Subject: [PATCH 6/7] finishing documentation corrections --- README.rst | 19 ++--- docs/source/conf.py | 17 +--- docs/source/howto/installation.rst | 2 + docs/source/howto/use.rst | 17 ++-- docs/source/introduction/about.rst | 44 +++++----- docs/source/introduction/dependencies.rst | 99 +++++++++++++---------- docs/source/introduction/references.rst | 13 ++- docs/source/reference/api.rst | 3 - tests/test_RecToolsIR.py | 4 +- tomobar/methodsDIR.py | 8 +- tomobar/methodsDIR_CuPy.py | 6 +- tomobar/methodsIR.py | 27 +++---- tomobar/methodsIR_CuPy.py | 22 ++--- tomobar/regularisers.py | 3 +- tomobar/regularisersCuPy.py | 3 +- tomobar/supp/dicts.py | 45 +++++------ tomobar/supp/suppTools.py | 10 +-- 17 files changed, 176 insertions(+), 166 deletions(-) diff --git a/README.rst b/README.rst index aeb946494..5aada0037 100644 --- a/README.rst +++ b/README.rst @@ -1,23 +1,16 @@ ToMoBAR's documentation ======================= -**ToMoBAR** (cite [CT2020]_, [SX2022]_) is a Python library of direct and model-based -regularised iterative reconstruction algorithms with a -plug-and-play capability. ToMoBAR offers you a selection -of various data models and regularisers resulting in complex +**ToMoBAR** (cite [CT2020]_, [SX2022]_) is a Python library of direct and model-based +regularised iterative reconstruction algorithms with a +plug-and-play capability. ToMoBAR offers you a selection +of various data models and regularisers resulting in complex objectives for tomographic reconstruction. ToMoBAR can operate in GPU device-to-device fashion on CuPy arrays therefore ensuring -a better computational efficiency. With GPU device controlling API +a better computational efficiency. With GPU device controlling API exposed it can also support multi-GPU parallel computing. -Although ToMoBAR does offer a variety of reconstruction methods, -the FISTA algorithm [BT2009]_ specifically provides various useful modifications, e.g.: -convergence acceleration with ordered-subsets, different -data fidelities: PWLS, Kullback-Leibler, Huber, Group-Huber [PM2015]_, -Students't [KAZ1_2017]_, and SWLS [HOA2017]_ to deal with noise and reconstruction artefacts -(rings, streaks). Together with the regularisers from the CCPi-Regularisation toolkit [KAZ2019]_ -one can construct up to a hundred of complex combinations for the objective function. - +See more in :ref:`intro_about` or go directly to :ref:`ref_installation` and try `Demos `_. .. figure:: _static/recsFISTA_stud.png :scale: 85 % diff --git a/docs/source/conf.py b/docs/source/conf.py index 6e4b3a9fe..5783a387b 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -1,6 +1,3 @@ -# -- General configuration ------------------------------------------------ -# https://www.sphinx-doc.org/en/master/usage/configuration.html - #!/usr/bin/env python import os import sys @@ -49,6 +46,7 @@ "tomobar.astra_wrappers.astra_tools3d", ] + class CustomMock(mock.Mock): def __repr__(self): return "" @@ -60,8 +58,9 @@ def __repr__(self): # ------------------------------------------------------------------------------ -project = "Tomobar" -# copyright = f"{date.today().year}, Diamond Light Source" +project = "ToMoBAR" +author = "Daniil Kazantsev" +copyright = f"{date.today().year}, Diamond Light Source and Manchester University, UK" # Specify a base language to help assistive technology language = "en" @@ -111,14 +110,6 @@ def __repr__(self): html_static_path = ["_static"] html_use_smartypants = True -""" -html_theme_options = { - "logo_only": True, - "display_version": False, - "githuburl": "https://github.com/dkazanc/ToMoBAR", -} -""" - html_theme_options = { "logo": { "image_dark": "_static/tomobar_logo_dark.png", diff --git a/docs/source/howto/installation.rst b/docs/source/howto/installation.rst index 8ad7154b9..bcc7b03a8 100644 --- a/docs/source/howto/installation.rst +++ b/docs/source/howto/installation.rst @@ -34,6 +34,8 @@ the installation above is tested on Linux and Windows, but one can also try: $ conda install -c httomo -c ccpi -c conda-forge tomophantom tomobar astra-toolbox ccpi-regulariser +.. warning:: Packages installed from the CCPi channel might be of different versions and incompatible with the demos. + Install ToMoBAR from PyPi: ++++++++++++++++++++++++++ diff --git a/docs/source/howto/use.rst b/docs/source/howto/use.rst index 3f55fb3d9..19a987735 100644 --- a/docs/source/howto/use.rst +++ b/docs/source/howto/use.rst @@ -2,13 +2,16 @@ Using ToMoBAR ------------------ -In :ref:`tutorials`, we provide few examples how to reconstruct tomographic data collected using parallel-beam geometry. -ToMoBAR offers direct and iterative reconstructors which are build around `ASTRA-Toolbox `_ projection/backprojection modules, see the ASTRA wrappers at :mod:`tomobar.astra_wrappers`. +In :ref:`tutorials`, we provide few examples how to reconstruct synthetic and real tomographic data collected with the parallel-beam geometry. -The very general recipe to perform reconstruction in Python with ToMoBAR follows: +The general recipe to perform reconstruction in Python with ToMoBAR is the following: -* 1. Import a module related to the reconstruction task chosen, e.g., direct (DIR), iterative (IR), or `CuPy `_-enabled. -* 2. Instantiate the reconstructor class, while providing parameters normally related to the parallel-beam 2D and 3D scanning geometry. -* 3. After class instantiation you will get an access to different reconstruction methods of that class. Run the selected reconstruction method providing data as an input and additional parameters, if needed. +* 1. Import a module related to the reconstruction task chosen, e.g., direct (:code:`DIR`) modules :mod:`tomobar.methodsDIR`, iterative (:code:`IR`) :mod:`tomobar.methodsIR`, + or `CuPy `_-enabled modules :mod:`tomobar.methodsDIR_CuPy` and :mod:`tomobar.methodsIR_CuPy`. +* 2. Instantiate a reconstructor class while providing parameters related to the parallel-beam 2D and 3D scanning geometries. +* 3. After instantiation you will get an access to different reconstruction methods of that class. Run selected reconstruction method providing data as an input and additional parameters. + For all :code:`DIR` methods parameters are passed directly, while for :code:`IR` methods you will need to form dictionaries: + :data:`_data_`, :data:`_algorithm_`, and :data:`_regularisation_`. See :mod:`tomobar.supp.dicts` for the list of parameters accepted. -As the main aim for ToMoBAR is to reconstruct the data from the synchrotron X-ray or neutron imaging instruments, where the radiation beam is approximately parallel. So far, we do not provide API for the divergent beam geometries, however ASTRA supports it and the wrappers at :mod:`tomobar.astra_wrappers` can be extended. + +.. note:: As the main aim for ToMoBAR is to reconstruct the data from the synchrotron X-ray or neutron imaging instruments, with the beam being approximately parallel. So far, we do not provide API for the divergent beam geometries, however as ASTRA supports it, the wrappers at :mod:`tomobar.astra_wrappers` can be extended. The contributions are welcome! diff --git a/docs/source/introduction/about.rst b/docs/source/introduction/about.rst index 6db0a6db8..7bef72284 100644 --- a/docs/source/introduction/about.rst +++ b/docs/source/introduction/about.rst @@ -1,15 +1,20 @@ +.. _intro_about: + About ToMoBAR -******************* +************** + +The general concept: +==================== +ToMoBAR is a Python library (Matlab is not currently supported) of direct and model-based +regularised iterative reconstruction algorithms with a plug-and-play capability. +ToMoBAR offers you a selection of various data models and regularisers resulting in +complex objectives for tomographic reconstruction. ToMoBAR uses ASTRA-Toolbox [VanAarle2015]_, +for projection-backprojection parallel-beam geometry routines, which is +a common geometry for X-ray synchrotron imaging [SX2022]_. -The general concept -===================== -ToMoBAR is a Python library (Matlab is not currently maintained) of direct and model-based -regularised iterative reconstruction algorithms with a plug-and-play capability. -ToMoBAR offers you a selection of various data models and regularisers resulting in -complex objectives for tomographic reconstruction. ToMoBAR can operate -in GPU device-to-device fashion on CuPy arrays therefore ensuring -a better computational efficiency. With GPU device controlling API -exposed it can also support multi-GPU parallel computing. +ToMoBAR can operate in GPU device-to-device fashion on CuPy arrays therefore ensuring +a better computational efficiency. With GPU device controlling :ref:`ref_api` +exposed it can also support multi-GPU parallel computing [CT2020]_ . .. figure:: ../_static/TomoRec_surf2.jpg :scale: 30 % @@ -18,13 +23,14 @@ exposed it can also support multi-GPU parallel computing. What ToMoBAR can do: ==================== -* Reconstruct parallel-beam projection data in 2D and 3D using GPU-accelerated routines from ASTRA-toolbox. -* Employ the basic direct and iterative schemes to perform reconstruction. -* Employ advanced model-based regularised iterative schemes such as FISTA and ADMM proximal splitting algorithms. -* The FISTA algorithm offers various modifications: - convergence acceleration with ordered-subsets method, - different data fidelities: PWLS, Kullback-Leibler, Huber, Group-Huber [PM2015]_, Students't [KAZ1_2017]_, and SWLS [HOA2017]_ - to deal with noise and imaging artefacts (rings, streaks). -* Together with regularisers from the CCPi-Regularisation Toolkit [KAZ2019]_ one can construct up to a hundred of complex combinations for the objective function. +* Reconstruct parallel-beam projection data in 2D and 3D using GPU-accelerated routines from ASTRA-toolbox [VanAarle2015]_. +* Employ fast GPU-accelerated direct methods, such as FBP method in :mod:`tomobar.methodsDIR` and CuPy accelerated Fourier + reconstruction :func:`FOURIER_INV` in :mod:`tomobar.methodsDIR_CuPy`. +* Use advanced model-based regularised iterative schemes such as FISTA and ADMM proximal splitting algorithms in :mod:`tomobar.methodsIR` or + even faster implementations with CuPy in :mod:`tomobar.methodsIR_CuPy`. +* The FISTA algorithm [BT2009]_, [Xu2016]_ offers various modifications: convergence acceleration with ordered-subsets, + different data fidelities: PWLS, Huber, Group-Huber [PM2015]_, Students't [KAZ1_2017]_, and SWLS [HOA2017]_ + to deal with noise and various imaging artefacts, such as, rings, streaks. +* Combine FISTA and ADMM methods with regularisers from the CCPi-Regularisation Toolkit [KAZ2019]_. It is possible to construct different combinations of the objective function. -See more on API of ToMoBAR in :ref:`ref_api`. +See more on ToMoBAR's API in :ref:`ref_api`. diff --git a/docs/source/introduction/dependencies.rst b/docs/source/introduction/dependencies.rst index c5be28348..df906d4e2 100644 --- a/docs/source/introduction/dependencies.rst +++ b/docs/source/introduction/dependencies.rst @@ -2,77 +2,92 @@ Dependencies ************ -ToMoBAR relies on several dependencies which we list bellow in the order of priority. -In general, we would recommend installing 1,2 and 4 packages. +ToMoBAR relies on several dependencies which we list bellow in the order of priority. +In general, we would recommend installing 1,2 and 3 packages. -* 1. `ASTRA-toolbox `_ is the most critical dependency - as ToMoBAR heavily relies on the GPU-accelerated projection/backprojection routines of the toolbox. With - the package installed, one can perform :ref:`tutorials_direct` and :ref:`examples_basic_iter`, - however the regularisation will not be available for :ref:`examples_regul_iter`. +* 1. `ASTRA-toolbox `_ is the major dependency + as ToMoBAR heavily relies on the GPU-accelerated projection/backprojection routines of the toolbox. With + the package installed, one can perform :ref:`tutorials_direct` and :ref:`examples_basic_iter`, + however, the regularisation will not be available for :ref:`examples_regul_iter`. - For Python installation, see this `conda `_ page. + Normally ASTRA included into the list of dependencies, but one can install it with: .. code-block:: console - - $ conda install astra-toolbox::astra-toolbox -* 2. `CCPi-Regularisation-Toolkit `_ [KAZ2019]_ provides - CPU and GPU regularisers (2D/3D) to enable :ref:`examples_regul_iter` in ToMoBAR. - Once installed, one will have an access to more than 10 plug-and-play regularisers to + $ conda install conda-forge::astra-toolbox + +* 2. `CCPi-Regularisation-Toolkit `_ [KAZ2019]_ provides + CPU and GPU regularisers (2D/3D) to enable :ref:`examples_regul_iter` in ToMoBAR. + Once installed, one gets an access to more than 10 plug-and-play regularisers to compliment ToMoBAR's iterative reconstruction algorithms. - For Python installation, see this `conda-ccpi `_ and this - `conda-httomo `_ pages. Either of them should work: + For Python installation, see `conda-httomo `_ + and `conda-ccpi `_ pages. It is recommended + to install using the :code:`httomo` channel first as this combination is normally tested + by the ToMoBAR's author: .. code-block:: console - - $ conda install ccpi::ccpi-regulariser # linux/windows - $ conda install httomo::ccpi-regulariser # linux - $ conda install httomo::ccpi-regularisation-cupy # all OS / CuPy modules only -* 3. Wavelet toolbox `pypwt `_ or **pycudwt** is required if - the soft/hard thresholding of Wavelets coefficients is added to the regularisers above. In some cases - it can be beneficial for the reconstruction quality. - - For Python installation one can try `pip install pycudwt` or: + $ conda install httomo::ccpi-regulariser # linux/windows + $ conda install httomo::ccpi-regularisation-cupy # all OS but CuPy modules only + $ conda install ccpi::ccpi-regulariser # linux/windows (in case if above doesn't work) + + +If one needs to install only CuPy modules (see 6.), the quickest way will be .. code-block:: console - - $ conda install httomo::pypwt # linux only -* 4. `TomoPhantom `_ is optional but can be - helpful for generating synthethic tomographic data and play with :ref:`examples_synth_iter`. - Also most of the Demos in ToMoBAR presented by using TomoPhantom. + $ pip install ccpi-regularisation-cupy # all OS but CuPy modules only + +* 3. `TomoPhantom `_ is optional but can be very + handy to generate synthethic tomographic data and play with :ref:`examples_synth_iter`. + Also most of the `Demos `_ in ToMoBAR using TomoPhantom. For Python installation see the `installation guide `_. .. code-block:: console - + $ conda install httomo::tomophantom # linux/windows -* 5. `CuPy `_ dependency is optional to be able to use algorithms operating on CuPy array kept on the GPU device instead of Numpy arrays. - It is a work in progress to fully support the feature in ToMoBAR, however, many main reconstruction methods such as direct and basic were already ported. - FISTA ordered-subsets with some regularisres has been exposed and offers up to several times acceleration compared to the version in :mod:`tomobar.methodsIR`. - We have plans to continue developing and supporting this new capability as it offers promising efficiency for GPU computations. + +* 4. Wavelet toolbox `pypwt `_ or **pycudwt** is optional and required only + if the CCPi-Regularisation-Toolkit already installed. It adds soft/hard thresholding of Wavelets coefficients to the available regularisers. + In some cases it can be beneficial for the reconstruction quality. + + For Python installation one can try: + +.. code-block:: console + + $ pip install pycudwt + $ conda install httomo::pypwt # if above didn't work (linux only) + + +* 5. `CuPy `_ dependency is optional and used to write high-level code in Python for GPU computations. + Those algorithms operating on CuPy arrays that are kept on the GPU device as opposed to Numpy arrays kept in the CPU memory. + It is a work in progress to fully support the CuPy compute in ToMoBAR, however, some reconstruction methods, such as direct and iterative + were already ported, see :mod:`tomobar.methodsDIR_CuPy` and :mod:`tomobar.methodsIR_CuPy`, respectively. + We have plans to continue developing and supporting this new capability as it offers promising efficiency for GPU computations, no OS-specific builds required, + and simplicity of the implementation. For Python installation see the `conda-cupy `_ page. .. code-block:: console - - $ conda install conda-forge::cupy # linux/windows -* 6. CuPy-enabled CCPi-Regularisation-Toolkit is required when (5) is satisfied. - This extension doesn't depend on (2) and can co-exist with (2) installation or standalone. - Note, however, it is also WIP and not all regularisers :mod:`tomobar.regularisersCuPy` have been ported. + $ conda install conda-forge::cupy # linux/windows + +* 6. CuPy-enabled CCPi-Regularisation-Toolkit can be used when (5) is satisfied. This will give you an access to + :mod:`tomobar.methodsDIR_CuPy` and :mod:`tomobar.methodsIR_CuPy` modules, while regularisation methods of + :mod:`tomobar.methodsIR` won't be accessible. .. code-block:: console - - $ conda install httomo::ccpi-regularisation-cupy # all OS supported -* 7. `mpi4py `_ is a Python extension for parallel computing using MPI. + $ pip install ccpi-regularisation-cupy # all OS but CuPy modules only + + +* 7. `mpi4py `_ is a Python extension for parallel computing using MPI. Install only if you are planning to use multi-GPU computing. ToMoBAR in itself doesn't offer any parallelisation and you might want to check the `HTTomo `_ package. - HTTomo supports MPI-based reconstruction and uses ToMoBAR as a backend. + HTTomo supports MPI-based reconstruction and uses ToMoBAR as a backend. diff --git a/docs/source/introduction/references.rst b/docs/source/introduction/references.rst index 1abceeccd..37cfdcaa2 100644 --- a/docs/source/introduction/references.rst +++ b/docs/source/introduction/references.rst @@ -3,10 +3,15 @@ References *********** +.. note:: To cite ToMoBAR please use [CT2020]_ paper. + .. [CT2020] D. Kazantsev and N. Wadeson. 2020, Tomographic MOdel-BAsed Reconstruction (ToMoBAR) software for high resolution synchrotron X-ray tomography, CT Meeting 2020. Download `here `_. +.. [VanAarle2015] W. Van Aarle, et.al., 2015. The ASTRA Toolbox: A platform for advanced algorithm + development in electron tomography. Ultramicroscopy, 157, pp.35-47. + .. [SX2022] D. Kazantsev, N. Wadeson, M. Basham, 2022. High performance Savu software for fast 3D model-based iterative reconstruction of large data at Diamond Light Source. @@ -16,7 +21,7 @@ References algorithm for linear inverse problems, SIAM Journal on Imaging Sciences, vol. 2, no. 1, pp. 183–202. -.. [Boyd2011] Boyd, N. Parikh, E. Chu, B. Peleato, J. Eckstein, 2011, Distributed optimization and +.. [Boyd2011] N. Boyd et. al., 2011, Distributed optimization and statistical learning via the alternating direction method of multipliers, Found. Trends Mach. Learn., vol. 3, no. 1, pp. 1-122 @@ -46,4 +51,8 @@ References .. [KAZ2017] D. Kazantsev et al. 2017. Model-based iterative reconstruction using higher-order regularization of dynamic - synchrotron data. Measurement Science and Technology, 28(9), p.094004. \ No newline at end of file + synchrotron data. Measurement Science and Technology, 28(9), p.094004. + +.. [NIKITIN2017] V.V. Nikitin, et. al., 2017. Fast hyperbolic Radon transform + represented as convolutions in log-polar coordinates. Computers & Geosciences, + 105, pp.21-33. \ No newline at end of file diff --git a/docs/source/reference/api.rst b/docs/source/reference/api.rst index 36f433ffe..bb3192519 100644 --- a/docs/source/reference/api.rst +++ b/docs/source/reference/api.rst @@ -18,8 +18,5 @@ ToMoBAR Modules ../api/tomobar.methodsIR_CuPy ../api/tomobar.regularisers ../api/tomobar.regularisersCuPy - ../api/tomobar.astra_wrappers.astra_base - ../api/tomobar.astra_wrappers.astra_tools2d - ../api/tomobar.astra_wrappers.astra_tools3d ../api/tomobar.supp.dicts ../api/tomobar.supp.suppTools diff --git a/tests/test_RecToolsIR.py b/tests/test_RecToolsIR.py index 3971723c8..c785bb2e2 100644 --- a/tests/test_RecToolsIR.py +++ b/tests/test_RecToolsIR.py @@ -362,8 +362,8 @@ def test_FISTA_PWLS_2D(angles, raw_data, flats, darks): Iter_rec = RecTools.FISTA(_data_, _algorithm_) assert 17000 <= lc <= 17100 - assert_allclose(np.min(Iter_rec), -0.0003682454, rtol=eps) - assert_allclose(np.max(Iter_rec), 0.010147439, rtol=eps) + assert_allclose(np.min(Iter_rec), -0.0003682454, rtol=0, atol=eps) + assert_allclose(np.max(Iter_rec), 0.010147439, rtol=0, atol=eps) assert Iter_rec.dtype == np.float32 assert Iter_rec.shape == (160, 160) diff --git a/tomobar/methodsDIR.py b/tomobar/methodsDIR.py index 4236037e6..05ee27c3e 100644 --- a/tomobar/methodsDIR.py +++ b/tomobar/methodsDIR.py @@ -1,8 +1,8 @@ -"""Reconstruction class for direct reconstruction methods. +"""Reconstruction class for direct reconstruction methods (2D/3D). -* Fourier Slice Theorem reconstruction (adopted from the Tim Day's code) -* Forward/Backward projection (ASTRA) -* Filtered Back Projection (ASTRA) +* :func:`RecToolsDIR.FORWPROJ` and :func:`RecToolsDIR.BACKPROJ` Forward/Backward 2D/3D projection (ASTRA-Toolbox) +* :func:`RecToolsDIR.FOURIER` Fourier Slice Theorem-based reconstruction in 2D only (adopted from the Tim Day's code) +* :func:`RecToolsDIR.FBP` Filtered Back Projection 2D/3D (ASTRA with the custom built filter). """ import numpy as np diff --git a/tomobar/methodsDIR_CuPy.py b/tomobar/methodsDIR_CuPy.py index 0f25b114a..0702c96cc 100644 --- a/tomobar/methodsDIR_CuPy.py +++ b/tomobar/methodsDIR_CuPy.py @@ -1,8 +1,8 @@ """Reconstruction class for 3D direct methods using CuPy-library. -* Forward/Backward projection (ASTRA with DirectLink and CuPy). -* Filtered Back Projection (ASTRA, Filter implemented with CuPy). -* Fourier direct reconstruction on unequally spaced grids (interpolation in image space), aka log-polar method. +* :func:`RecToolsDIRCuPy.FORWPROJ` and :func:`RecToolsDIRCuPy.BACKPROJ` - Forward/Backward projection modules (ASTRA with DirectLink and CuPy). +* :func:`RecToolsDIRCuPy.FBP` - Filtered Back Projection (ASTRA, the filter is implemented with CuPy). +* :func:`RecToolsDIRCuPy.FOURIER_INV` - Fourier direct reconstruction on unequally spaced grids (interpolation in image space), aka log-polar method [NIKITIN2017]_. """ import numpy as np diff --git a/tomobar/methodsIR.py b/tomobar/methodsIR.py index 75c494479..e13d6f9f7 100644 --- a/tomobar/methodsIR.py +++ b/tomobar/methodsIR.py @@ -1,8 +1,8 @@ -"""Reconstruction class for regularised iterative methods. +"""Reconstruction class for regularised iterative methods (2D/3D). -* Regularised FISTA algorithm [BT2009]_ -* Regularised ADMM algorithm [Boyd2011]_ -* SIRT and CGLS algorithms wrapped directly from the ASTRA package +* :func:`RecToolsIR.FISTA` FISTA - iterative regularised algorithm [BT2009]_, [Xu2016]_. +* :func:`RecToolsIR.ADMM` ADMM iterative regularised algorithm [Boyd2011]_. +* :func:`RecToolsIR.SIRT` and :func:`RecToolsIR.CGLS` algorithms are wrapped directly from the ASTRA package. """ import numpy as xp @@ -35,9 +35,9 @@ class RecToolsIR: """Iterative reconstruction algorithms (FISTA and ADMM) using ASTRA toolbox and CCPi-RGL toolkit. - Parameters for reconstruction algorithms are extracted from three dictionaries: - _data_, _algorithm_ and _regularisation_. See API for `tomobar.supp.dicts` function for all parameters - that are accepted. + Parameters for reconstruction algorithms should be provided in three dictionaries: + :data:`_data_`, :data:`_algorithm_`, and :data:`_regularisation_`. See :mod:`tomobar.supp.dicts` + function of ToMoBAR's :ref:`ref_api` for all parameters explained. Args: DetectorsDimH (int): Horizontal detector dimension. @@ -108,7 +108,6 @@ def cupyrun(self, cupyrun_val): def SIRT(self, _data_: dict, _algorithm_: Union[dict, None] = None) -> xp.ndarray: """Simultaneous Iterations Reconstruction Technique from ASTRA toolbox. - See `tomobar.supp.dicts` for all parameters to the dictionaries bellow. Args: _data_ (dict): Data dictionary, where input data is provided. @@ -130,7 +129,6 @@ def SIRT(self, _data_: dict, _algorithm_: Union[dict, None] = None) -> xp.ndarra def CGLS(self, _data_: dict, _algorithm_: Union[dict, None] = None) -> xp.ndarray: """Conjugate Gradient Least Squares from ASTRA toolbox. - See `tomobar.supp.dicts` for all parameters to the dictionaries bellow. Args: _data_ (dict): Data dictionary, where input data is provided @@ -152,7 +150,7 @@ def CGLS(self, _data_: dict, _algorithm_: Union[dict, None] = None) -> xp.ndarra def powermethod(self, _data_: dict) -> float: """Power iteration algorithm to calculate the eigenvalue of the operator (projection matrix). - projection_raw_data is required for PWLS fidelity (self.datafidelity = PWLS), otherwise will be ignored. + projection_raw_data is required for PWLS fidelity, otherwise will be ignored. Args: _data_ (dict): Data dictionary, where input data is provided. @@ -253,7 +251,7 @@ def powermethod(self, _data_: dict) -> float: y = xp.multiply(sqweight[self.Atools.newInd_Vec[0, :], :], y) else: y = xp.multiply(sqweight[:, self.Atools.newInd_Vec[0, :], :], y) - for iterations in range(power_iterations): + for _ in range(power_iterations): if cupy_imported and self.cupyrun: x1 = self.Atools._backprojOSCuPy(y, 0) else: @@ -282,7 +280,7 @@ def FISTA( ) -> xp.ndarray: """A Fast Iterative Shrinkage-Thresholding Algorithm with various types of regularisation and data fidelity terms provided in three dictionaries. - See `tomobar.supp.dicts` for all parameters to the dictionaries bellow. + See :mod:`tomobar.supp.dicts` for all parameters to the dictionaries bellow. Args: _data_ (dict): Data dictionary, where input data is provided. @@ -669,8 +667,7 @@ def ADMM( _regularisation_: Union[dict, None] = None, ) -> xp.ndarray: """Alternating Directions Method of Multipliers with various types of regularisation and - data fidelity terms provided in three dictionaries. - See `tomobar.supp.dicts` for all parameters to the dictionaries bellow. + data fidelity terms provided in three dictionaries, see :mod:`tomobar.supp.dicts` Args: _data_ (dict): Data dictionary, where input data is provided. @@ -733,7 +730,7 @@ def ADMM_Atb(b): z - u ) outputSolver = scipy.sparse.linalg.gmres( - A_to_solver, b_to_solver, tol=1e-05, maxiter=15 + A_to_solver, b_to_solver, atol=1e-05, maxiter=15 ) X = xp.float32(outputSolver[0]) # get gmres solution if _algorithm_upd_["nonnegativity"] == "ENABLE": diff --git a/tomobar/methodsIR_CuPy.py b/tomobar/methodsIR_CuPy.py index 504b78144..a64517e37 100644 --- a/tomobar/methodsIR_CuPy.py +++ b/tomobar/methodsIR_CuPy.py @@ -1,9 +1,9 @@ """Reconstruction class for regularised iterative methods using CuPy library. -* FISTA regularised algorithm [BT2009]_ . Implemented using ASTRA with DirectLink and CuPy, Regularisation Toolkit-CuPy. -* Landweber algorithm. -* SIRT algorithm. -* CGLS algorithm. +* :func:`RecToolsIRCuPy.FISTA` iterative regularised algorithm [BT2009]_, [Xu2016]_. Implemented using ASTRA's DirectLink and CuPy, Regularisation Toolkit-CuPy. +* :func:`RecToolsIRCuPy.Landweber` algorithm. +* :func:`RecToolsIRCuPy.SIRT` algorithm. +* :func:`RecToolsIRCuPy.CGLS` algorithm. """ import numpy as np @@ -29,8 +29,8 @@ class RecToolsIRCuPy: """CuPy-enabled iterative reconstruction algorithms using ASTRA toolbox, CCPi-RGL toolkit. - Parameters for reconstruction algorithms are extracted from three dictionaries: - _data_, _algorithm_ and _regularisation_. See `tomobar.supp.dicts `_ + Parameters for reconstruction algorithms should be provided in three dictionaries: + :data:`_data_`, :data:`_algorithm_`, and :data:`_regularisation_`. See :mod:`tomobar.supp.dicts` function of ToMoBAR's :ref:`ref_api` for all parameters explained. If FISTA is used it will require CuPy-enabled routines of the CCPi-regularisation toolkit. @@ -258,7 +258,7 @@ def CGLS(self, _data_: dict, _algorithm_: Union[dict, None] = None) -> cp.ndarra def powermethod(self, _data_: dict) -> float: """Power iteration algorithm to calculate the eigenvalue of the operator (projection matrix). - projection_raw_data is required for the PWLS fidelity (self.datafidelity = PWLS), otherwise will be ignored. + projection_raw_data is required for the PWLS fidelity, otherwise will be ignored. Args: _data_ (dict): Data dictionary, where input data is provided. @@ -359,10 +359,10 @@ def FISTA( the regularisation toolkit [KAZ2019]_. All parameters for the algorithm should be provided in three dictionaries: - _data_, _algorithm_, and _regularisation_. See `tomobar.supp.dicts `_ + :data:`_data_`, :data:`_algorithm_`, and :data:`_regularisation_`. See :mod:`tomobar.supp.dicts` function of ToMoBAR's :ref:`ref_api` for all parameters explained. - Please note that not all of the functionality supported in this CuPy implementation compared to FISTA from - `methodsIR `_. + Please note that not all of the functionality supported in this CuPy implementation compared to :func:`RecToolsIR.FISTA` from + :mod:`tomobar.methodsIR`. Args: _data_ (dict): Data dictionary, where input data is provided. @@ -370,7 +370,7 @@ def FISTA( _regularisation_ (dict, optional): Regularisation dictionary. Returns: - cp.ndarray: FISTA-reconstructed 3D cupy array + cp.ndarray: FISTA-reconstructed 3D CuPy array """ cp._default_memory_pool.free_all_blocks() if self.geom == "2D": diff --git a/tomobar/regularisers.py b/tomobar/regularisers.py index dc4ec842f..40ebc627c 100644 --- a/tomobar/regularisers.py +++ b/tomobar/regularisers.py @@ -1,6 +1,5 @@ """Adding regularisers from the CCPi-regularisation toolkit and instantiate a proximal operator for iterative methods. - """ import numpy as np @@ -35,7 +34,7 @@ def prox_regul(self, X: np.ndarray, _regularisation_: dict) -> Union[np.ndarray, Args: X (np.ndarray): 2D or 3D numpy array. - _regularisation_ (dict): Regularisation dictionary with parameters, see `tomobar.supp.dicts `_. + _regularisation_ (dict): Regularisation dictionary with parameters, see :mod:`tomobar.supp.dicts`. Returns: np.ndarray or a tuple: Filtered 2D or 3D numpy array or a tuple. diff --git a/tomobar/regularisersCuPy.py b/tomobar/regularisersCuPy.py index 0cbaae0eb..c6ffbea2a 100644 --- a/tomobar/regularisersCuPy.py +++ b/tomobar/regularisersCuPy.py @@ -1,6 +1,5 @@ """Adding CuPy-enabled regularisers from the CCPi-regularisation toolkit and instantiate a proximal operator for iterative methods. - """ import cupy as cp @@ -19,7 +18,7 @@ def prox_regul(self, X: cp.ndarray, _regularisation_: dict) -> cp.ndarray: Args: X (cp.ndarray): 2D or 3D CuPy array. - _regularisation_ (dict): Regularisation dictionary with parameters, see `tomobar.supp.dicts `_. + _regularisation_ (dict): Regularisation dictionary with parameters, see :mod:`tomobar.supp.dicts`. Returns: cp.ndarray: Filtered 2D or 3D CuPy array. diff --git a/tomobar/supp/dicts.py b/tomobar/supp/dicts.py index 66728a5ea..7d465d54e 100644 --- a/tomobar/supp/dicts.py +++ b/tomobar/supp/dicts.py @@ -24,50 +24,49 @@ def dicts_check( _regularisation_: Union[dict, None] = None, method_run: str = "FISTA", ) -> tuple: - """This function checks `_data_`, `_algorithm_`, and `_regularisation_` + """This function accepts the `_data_`, `_algorithm_`, and `_regularisation_` dictionaries and populates parameters in them, if required. Please note that the dictionaries are - needed for iterative methods only. The most versatile methods that accept a variety of different parameters + needed for iterative methods only. The most versatile methods that can accept a variety of different parameters are FISTA and ADMM. Args: _data_ (dict): *Data dictionary where data-related items must be specified.* _algorithm_ (dict, optional): *Algorithm dictionary. Defaults to None.* - _regularisation_ (dict, optional): Regularisation dictionary. Needed only for FISTA and ADMM algorithms. Defaults to None. - method_run (str): The name of the method to be run. Defaults to "FISTA". + _regularisation_ (dict, optional): *Regularisation dictionary. Needed only for FISTA and ADMM algorithms. Defaults to None.* + method_run (str): *The name of the method to be run. Defaults to "FISTA".* Keyword Args: - _data_['projection_norm_data'] (ndarray): The -log(normalised) projection data as a 2D sinogram or as a 3D data array. + _data_['projection_norm_data'] (ndarray): Negative log(normalised) projection data as a 2D sinogram or as a 3D data array. _data_['projection_raw_data'] (ndarray): Raw data for PWLS and SWLS models. A FISTA-related parameter. - _data_['data_axes_labels_order'] (list, None). The order of the axes labels for the input data, use the following labels: ["detY", "angles", "detX"]. - _data_['OS_number'] (int): The number of ordered subsets, if None or 1 then the classical (full data) algorithm. Defaults to 1. - _data_['huber_threshold'] (float): Parameter for the Huber data fidelity (to supress outliers). - _data_['studentst_threshold] (float): Parameter for Students't data fidelity (to supress outliers). - _data_['ringGH_lambda'] (float): Parameter for Group-Huber data model to supress full rings of the uniform intensity. - _data_['ringGH_accelerate'] (float): Group-Huber data model acceleration factor (can lead to divergence). Defaults to 50. - _data_['beta_SWLS'] (float): Regularisation parameter for stripe-weighted data model (ring artefacts removal) Defaults to 0.1. + _data_['data_axes_labels_order'] (list, None). The order of the axes labels for the input data. The default data labels are: ["detY", "angles", "detX"]. + _data_['OS_number'] (int): The number of the ordered subsets. If None or 1 is used then the classical (full data) algorithm executed. Defaults to 1. + _data_['huber_threshold'] (float): Parameter for the Huber data fidelity (to suppress outliers) [KAZ1_2017]_. + _data_['studentst_threshold] (float): Parameter for Students't data fidelity (to suppress outliers) [KAZ1_2017]_. + _data_['ringGH_lambda'] (float): Parameter for Group-Huber data model [PM2015]_ to suppress the full rings of the uniform intensity. + _data_['ringGH_accelerate'] (float): Group-Huber data model acceleration factor (can lead to divergence for higher values). Defaults to 50. + _data_['beta_SWLS'] (float): Regularisation parameter for stripe-weighted data model [HOA2017]_ for ring artefacts removal. Defaults to 0.1. _algorithm_['iterations'] (int): The number of iterations for the reconstruction algorithm. _algorithm_['nonnegativity'] (bool): Enable nonnegativity for the solution. Defaults to False. - _algorithm_['recon_mask_radius'] (float): Enables a circular mask cutoff in the reconstructed image. Defaults to 1.0. - _algorithm_['initialise'] (ndarray): Initialise an algorithm with an array. - _algorithm_['lipschitz_const'] (float): Lipschitz constant for the FISTA algorithm. If not provided it will be calculated for each method call. + _algorithm_['recon_mask_radius'] (float): Enables the circular mask cutoff in the reconstructed image. Defaults to 1.0. + _algorithm_['initialise'] (ndarray): Initialisation for the solution. An array of the expected output size must be provided. + _algorithm_['lipschitz_const'] (float): Lipschitz constant for the FISTA algorithm. If not provided, it will be calculated for each method call. _algorithm_['ADMM_rho_const'] (float): Augmented Lagrangian parameter for the ADMM algorithm. _algorithm_['ADMM_relax_par'] (float): Over relaxation parameter for the convergence acceleration of the ADMM algorithm. _algorithm_['tolerance'] (float): Tolerance to terminate reconstruction algorithm iterations earlier. Defaults to 0.0. _algorithm_['verbose'] (bool): Switch on printing of iterations number and other messages. Defaults to False. - _regularisation_['method'] (str): Select the regularisation method from the CCPi-regularisation toolkit. The supported + _regularisation_['method'] (str): Select the regularisation method from the CCPi-regularisation toolkit [KAZ2019]_. The supported methods listed: ROF_TV, FGP_TV, PD_TV, SB_TV, LLT_ROF, TGV, NDF, Diff4th, NLTV. - If one also installed `pypwt` package for Wavelets then one can WAVELET regularisation by adding WAVELETS to any method above - by appending "_WAVELETS" string to an existing regulariser. For instance, ROF_TV_WAVELETS would enable dual regularisation with ROF_TV - and wavelets. + If the `pypwt` package is installed for Wavelets, then one can do WAVELET regularisation by adding WAVELETS string to any method's name above. + For instance, ROF_TV_WAVELETS would enable dual regularisation with ROF_TV and wavelets. See `regul_param2` to control wavelets smoothing. _regularisation_['regul_param'] (float): The main regularisation parameter for regularisers to control the amount of smoothing. Defaults to 0.001. - _regularisation_['iterations'] (int): The number of INNER iterations for regularisers. Defaults to 150. - _regularisation_['device_regulariser'] (str, int): Select the device as 'cpu' or 'gpu'. Or provide GPU index (integer) of a specific device. + _regularisation_['iterations'] (int): The number of iterations for regularisers (INNER iterations). Defaults to 150. + _regularisation_['device_regulariser'] (str, int): Select between 'cpu' or 'gpu' devices. One can also provide a GPU index (integer) of a specific GPU device. _regularisation_['edge_threhsold'] (float): Noise-related threshold parameter for NDF and DIFF4th (diffusion) regularisers. _regularisation_['tolerance'] (float): Tolerance to stop inner regularisation iterations prematurely. - _regularisation_['time_marching_step'] (float): Time step parameter for convergence of gradient-based methods: ROF_TV,LLT_ROF,NDF,Diff4th. - _regularisation_['regul_param2'] (float): The second regularisation parameter (LLT_ROF or when using WAVELETS in addition). + _regularisation_['time_marching_step'] (float): Time step parameter for convergence of gradient-based methods: ROF_TV, LLT_ROF, NDF,Diff4th. + _regularisation_['regul_param2'] (float): The second regularisation parameter for LLT_ROF or when WAVELETS used. _regularisation_['TGV_alpha1'] (float): The TGV penalty specific parameter for the 1st order term. _regularisation_['TGV_alpha2'] (float): The TGV penalty specific parameter for the 2nd order term. _regularisation_['PD_LipschitzConstant'] (float): The Primal-Dual (PD) penalty related parameter for convergence (PD_TV and TGV specific). diff --git a/tomobar/supp/suppTools.py b/tomobar/supp/suppTools.py index 4ac265add..181fe1bc1 100644 --- a/tomobar/supp/suppTools.py +++ b/tomobar/supp/suppTools.py @@ -2,8 +2,8 @@ List of functions: -* normaliser - Projection data normalise the raw data and take the negative log (if needed). Options are: 'mean', 'median' and 'dynamic'. -* autocropper - automatically crops the 3D projection data to reduce its size. +* normaliser - Projection data normalisation module. +* autocropper - automatically crops 3D projection data to reduce its size. """ @@ -41,7 +41,7 @@ pass -def DFFC(data, flats, darks, downsample, nrPArepetions): +def _DFFC(data, flats, darks, downsample, nrPArepetions): # Load frames meanDarkfield = np.mean(darks, axis=1, dtype=np.float64) whiteVect = np.zeros( @@ -198,7 +198,7 @@ def normaliser( Args: data (np.array): 3d numpy array of raw data. flats (np.array): 2d numpy array for flat field. - darks (np.array): 2d numpy array for darks field. + darks (np.array): 2d numpy array for dark field. log (bool, optional): Take negative log. Defaults to True. method (str, optional): Normalisation method, choose "mean", "median" or "dynamic". Defaults to "mean". axis (int, optional): Define the ANGLES axis. @@ -233,7 +233,7 @@ def normaliser( dyn_iterations_v = value else: dyn_iterations_v = 10 - [data_norm, EFF, EFF_filt] = DFFC( + [data_norm, EFF, EFF_filt] = _DFFC( data, flats, darks, From 60958fc175f574b598cc292f9960a636eaf13e04 Mon Sep 17 00:00:00 2001 From: dkazanc Date: Fri, 20 Dec 2024 15:40:30 +0000 Subject: [PATCH 7/7] few final fixes --- docs/source/howto/installation.rst | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/source/howto/installation.rst b/docs/source/howto/installation.rst index bcc7b03a8..b01484a60 100644 --- a/docs/source/howto/installation.rst +++ b/docs/source/howto/installation.rst @@ -6,7 +6,7 @@ ToMoBAR is a Python package with several :ref:`ref_dependencies`. To ensure its It mostly relies on the GPU-enabled computations and therefore we suggest using a decent NVIDIA graphics card to support it. ToMoBAR can run with `CuPy `_ or using normal routines using pre-built CUDA modules of the Regularisation Toolkit. -.. note:: CuPy-enabled ToMoBAR is the development in progress. Methods like FISTA can normally run several times faster, however, not every variation is supported. +.. note:: CuPy-enabled ToMoBAR is the development in progress. Methods like FISTA can normally run several times faster, however, not every method variation is supported. .. _ref_python: @@ -16,25 +16,28 @@ Python Install ToMoBAR as a pre-built conda Python package: ++++++++++++++++++++++++++++++++++++++++++++++++++++ +Minimal installation that skips most of :ref:`ref_dependencies`: + .. code-block:: console $ conda install -c httomo tomobar -or install with the dependencies into a new environment: +or install with the dependencies into a new environment (tested on Linux and Windows): .. code-block:: console $ conda install -c httomo -c conda-forge tomophantom tomobar astra-toolbox ccpi-regulariser - $ conda install conda-forge::cupy # install only if you need CuPy-enabled modules - $ pip install pypwt # if wavelet regularisation is to be used -the installation above is tested on Linux and Windows, but one can also try: +In addition you can install CuPy :code:`conda install conda-forge::cupy` if you need CuPy-enabled modules and :code:`pip install pypwt` if you are planning to use +wavelet regularisation. + +If the installation above does not work, one can also try: .. code-block:: console $ conda install -c httomo -c ccpi -c conda-forge tomophantom tomobar astra-toolbox ccpi-regulariser -.. warning:: Packages installed from the CCPi channel might be of different versions and incompatible with the demos. +.. warning:: Note that packages installed from the CCPi channel might be of different versions and incompatible with the demos. Please create an `issue `_ on GitHub if there is a problem with an installation from the httomo channel. Install ToMoBAR from PyPi: ++++++++++++++++++++++++++ @@ -48,8 +51,8 @@ One can install ToMoBAR from PyPi, however, not all dependencies might be at PyP Using conda environment: +++++++++++++++++++++++++ -One can also create a new conda environment by using environment yaml file, -and then **pip** install ToMoBAR into it. +One can also create a new conda environment by using the provided environment yaml file, +and then **pip** install ToMoBAR into the environment. .. code-block:: console