Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various improvements related to the new X-ray transform implemementation. #461

Merged
merged 49 commits into from
Nov 2, 2023
Merged
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
13216ea
Rename TomographicProjector to XRayTransform
bwohlberg Aug 7, 2023
05d74b2
Remove markup from exception messages and other minor edits
bwohlberg Aug 7, 2023
2d20d65
Rename modules
bwohlberg Aug 7, 2023
77417c6
Rename files and rename TomographicProjector to XRayTransform
bwohlberg Aug 7, 2023
66c3754
Rename AbelProjector to AbelTransform
bwohlberg Aug 7, 2023
f33c905
Docs edits
bwohlberg Aug 7, 2023
b1529e7
Update change summary
bwohlberg Aug 7, 2023
1215f85
Overlooked rename changes
bwohlberg Aug 7, 2023
40d0d52
Replace Radon transform label
bwohlberg Aug 8, 2023
28591ee
Update submodule
bwohlberg Aug 8, 2023
90fffce
Merge branch 'main' into brendt/rename
bwohlberg Sep 28, 2023
fdd4b51
Merge branch 'main' into brendt/rename
bwohlberg Sep 28, 2023
0baed6a
Renaming of some CT projectors (#453)
bwohlberg Sep 29, 2023
18afd6c
Restructure X-ray transform modules
bwohlberg Sep 29, 2023
af96d0d
Update submodule
bwohlberg Sep 29, 2023
c56a6b1
Adjust angles to be equivalent between scico and astra projections
bwohlberg Oct 2, 2023
b826ec2
Clean up output
bwohlberg Oct 2, 2023
d447674
New example script
bwohlberg Oct 2, 2023
9ae8e7e
Minor edits
bwohlberg Oct 2, 2023
c1d67ca
Shorten class name
bwohlberg Oct 3, 2023
c2ad682
Clarify Parallel2dProjector angles
Michael-T-McCann Oct 3, 2023
b16f49c
Merge branch 'main' into brendt/rename
bwohlberg Oct 4, 2023
dc60d86
Docs edits
bwohlberg Oct 6, 2023
d076032
Remove problematic jit
bwohlberg Oct 9, 2023
6d6a4e9
New example script
bwohlberg Oct 9, 2023
82ee32c
Docs improvement
bwohlberg Oct 10, 2023
d4a51fe
Rename parameter
bwohlberg Oct 10, 2023
acd24fa
Docs improvement
bwohlberg Oct 10, 2023
4b8203a
Typo fix
bwohlberg Oct 10, 2023
6af9496
Add noise
bwohlberg Oct 12, 2023
0ae63f8
Add example script
bwohlberg Oct 15, 2023
464ebb9
Change noise level
bwohlberg Oct 15, 2023
e5312ec
Merge branch 'main' into brendt/rename
bwohlberg Oct 24, 2023
1636b9d
Merge branch 'main' into brendt/rename
bwohlberg Oct 26, 2023
2964845
Update notebooks
Michael-T-McCann Oct 26, 2023
b40ccf0
Docs fix
bwohlberg Oct 26, 2023
9c1f796
Update submodule
bwohlberg Oct 26, 2023
0f65ec4
Merge branch 'main' into brendt/rename
bwohlberg Oct 26, 2023
a281e2f
Add warning to api docs
bwohlberg Oct 26, 2023
79941e7
Add overlooked change summary entry
bwohlberg Oct 26, 2023
7d2bd73
Remove unintentionally added file
bwohlberg Oct 27, 2023
80d1f5b
Remove unintentionally added files
bwohlberg Oct 27, 2023
207a156
Remove unintentionally added files
bwohlberg Oct 27, 2023
c29dbfd
Address review comment
bwohlberg Nov 2, 2023
a75d2ea
Remove unintentionally added file
bwohlberg Nov 2, 2023
5952629
Fix docs typo
bwohlberg Nov 2, 2023
52efdcb
Update submodule
bwohlberg Nov 2, 2023
48d7ba8
Merge branch 'main' into brendt/rename
bwohlberg Nov 2, 2023
60e453c
Update submodule
bwohlberg Nov 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ SCICO Release Notes
Version 0.0.5 (unreleased)
----------------------------

• New integrated Radon/X-ray transform ``linop.XRayTransform``.
• Rename modules ``radon_astra`` and ``radon_svmbir`` to ``xray.astra`` and
``xray.svmbir`` respectively, and rename ``TomographicProjector`` classes
to ``XRayTransform``.
• Rename ``AbelProjector`` to ``AbelTransform``.
• Rename ``solver.ATADSolver`` to ``solver.MatrixATADSolver``.
• Support ``jaxlib`` and ``jax`` versions 0.4.3 to 0.4.19.

Expand Down
3 changes: 2 additions & 1 deletion docs/source/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ Computed Tomography
examples/ct_astra_odp_train_foam2
examples/ct_astra_unet_train_foam2
examples/ct_projector_comparison

examples/ct_multi_cs_tv_admm
examples/ct_multi_tv_admm

Deconvolution
^^^^^^^^^^^^^
Expand Down
6 changes: 3 additions & 3 deletions docs/source/inverse.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@ SCICO provides the :class:`.Operator` and :class:`.LinearOperator`
classes, which may be subclassed by users, in order to implement the
forward operator, :math:`A`. It also has several built-in operators,
most of which are linear, e.g., finite convolutions, discrete Fourier
transforms, optical propagators, Abel transforms, and Radon
transforms. For example,
transforms, optical propagators, Abel transforms, and X-ray transforms
(the same as Radon transforms in 2D). For example,

.. code:: python

input_shape = (512, 512)
angles = np.linspace(0, 2 * np.pi, 180, endpoint=False)
channels = 512
A = scico.linop.radon_svmbir.ParallelBeamProjector(input_shape, angles, channels)
A = scico.linop.xray.svmbir.XRayTransform(input_shape, angles, channels)

defines a tomographic projection operator.

Expand Down
22 changes: 17 additions & 5 deletions docs/source/notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,25 @@ via interfaces to the `bm3d <https://pypi.org/project/bm3d/>`__ and
when the full benefits of JAX-based code are required.


Tomographic Projectors
----------------------

The :class:`.radon_svmbir.TomographicProjector` class is implemented
Tomographic Projectors/Radon Transforms
---------------------------------------

Note that the tomographic projections that are frequently referred
to as Radon transforms are referred to as X-ray transforms in SCICO.
While the Radon transform is far more well-known than the X-ray
transform, which is the same as the Radon transform for projections
in two dimensions, these two transform differ in higher numbers of
dimensions, and it is the X-ray transform that is the appropriate
mathematical model for beam attenuation based imaging in three or
more dimensions.

SCICO includes three different implementations of X-ray transforms.
Of these, :class:`.linop.XRayTransform` is an integral component of
SCICO, while the other two depend on external packages.
The :class:`.xray.svmbir.XRayTransform` class is implemented
via an interface to the `svmbir
<https://svmbir.readthedocs.io/en/latest/>`__ package. The
:class:`.radon_astra.TomographicProjector` class is implemented via an
:class:`.xray.astra.XRayTransform` class is implemented via an
interface to the `ASTRA toolbox
<https://www.astra-toolbox.com/>`__. This toolbox does provide some
GPU acceleration support, but efficiency is expected to be lower than
Expand Down
7 changes: 5 additions & 2 deletions examples/scripts/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,11 @@ Computed Tomography
`ct_astra_unet_train_foam2.py <ct_astra_unet_train_foam2.py>`_
CT Training and Reconstructions with UNet
`ct_projector_comparison.py <ct_projector_comparison.py>`_
X-ray Projector Comparison

X-ray Transform Comparison
`ct_multi_cs_tv_admm.py <ct_multi_cs_tv_admm.py>`_
TV-Regularized Sparse-View CT Reconstruction (Multiple Projectors, Common Sinogram)
`ct_multi_tv_admm.py <ct_multi_tv_admm.py>`_
TV-Regularized Sparse-View CT Reconstruction (Multiple Projectors)

Deconvolution
^^^^^^^^^^^^^
Expand Down
4 changes: 2 additions & 2 deletions examples/scripts/ct_abel_tv_admm.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import scico.numpy as snp
from scico import functional, linop, loss, metric, plot
from scico.examples import create_circular_phantom
from scico.linop.abel import AbelProjector
from scico.linop.abel import AbelTransform
from scico.optimize.admm import ADMM, LinearSubproblemSolver
from scico.util import device_info

Expand All @@ -40,7 +40,7 @@
"""
Set up the forward operator and create a test measurement.
"""
A = AbelProjector(x_gt.shape)
A = AbelTransform(x_gt.shape)
y = A @ x_gt
np.random.seed(12345)
y = y + np.random.normal(size=y.shape).astype(np.float32)
Expand Down
6 changes: 3 additions & 3 deletions examples/scripts/ct_abel_tv_admm_tune.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
import scico.numpy as snp
from scico import functional, linop, loss, metric, plot
from scico.examples import create_circular_phantom
from scico.linop.abel import AbelProjector
from scico.linop.abel import AbelTransform
from scico.optimize.admm import ADMM, LinearSubproblemSolver
from scico.ray import tune

Expand All @@ -53,7 +53,7 @@
"""
Set up the forward operator and create a test measurement.
"""
A = AbelProjector(x_gt.shape)
A = AbelTransform(x_gt.shape)
y = A @ x_gt
np.random.seed(12345)
y = y + np.random.normal(size=y.shape).astype(np.float32)
Expand Down Expand Up @@ -85,7 +85,7 @@ def setup(self, config, x_gt, x0, y):
# Put main arrays on jax device.
self.x_gt, self.x0, self.y = jax.device_put([x_gt, x0, y])
# Set up problem to be solved.
self.A = AbelProjector(self.x_gt.shape)
self.A = AbelTransform(self.x_gt.shape)
self.f = loss.SquaredL2Loss(y=self.y, A=self.A)
self.C = linop.FiniteDifference(input_shape=self.x_gt.shape)
self.reset_config(config)
Expand Down
12 changes: 5 additions & 7 deletions examples/scripts/ct_astra_3d_tv_admm.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
$$\mathrm{argmin}_{\mathbf{x}} \; (1/2) \| \mathbf{y} - A \mathbf{x}
\|_2^2 + \lambda \| C \mathbf{x} \|_{2,1} \;,$$

where $A$ is the Radon transform, $\mathbf{y}$ is the sinogram, $C$ is
a 3D finite difference operator, and $\mathbf{x}$ is the desired
image.
where $A$ is the X-ray transform (the CT forward projection operator),
$\mathbf{y}$ is the sinogram, $C$ is a 3D finite difference operator,
and $\mathbf{x}$ is the desired image.
"""


Expand All @@ -29,7 +29,7 @@

from scico import functional, linop, loss, metric, plot
from scico.examples import create_tangle_phantom
from scico.linop.radon_astra import TomographicProjector
from scico.linop.xray.astra import XRayTransform
from scico.optimize.admm import ADMM, LinearSubproblemSolver
from scico.util import device_info

Expand All @@ -46,9 +46,7 @@

n_projection = 10 # number of projections
angles = np.linspace(0, np.pi, n_projection) # evenly spaced projection angles
A = TomographicProjector(
tangle.shape, [1.0, 1.0], [Nz, max(Nx, Ny)], angles
) # Radon transform operator
A = XRayTransform(tangle.shape, [1.0, 1.0], [Nz, max(Nx, Ny)], angles) # CT projection operator
y = A @ tangle # sinogram


Expand Down
6 changes: 3 additions & 3 deletions examples/scripts/ct_astra_modl_train_foam2.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
from scico import metric, plot
from scico.flax.examples import load_ct_data
from scico.flax.train.traversals import clip_positive, construct_traversal
from scico.linop.radon_astra import TomographicProjector
from scico.linop.xray.astra import XRayTransform

"""
Prepare parallel processing. Set an arbitrary processor count (only
Expand All @@ -81,12 +81,12 @@
Build CT projection operator.
"""
angles = np.linspace(0, np.pi, n_projection) # evenly spaced projection angles
A = TomographicProjector(
A = XRayTransform(
input_shape=(N, N),
detector_spacing=1,
det_count=N,
angles=angles,
) # Radon transform operator
) # CT projection operator
A = (1.0 / N) * A # normalized


Expand Down
8 changes: 4 additions & 4 deletions examples/scripts/ct_astra_noreg_pcg.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
$$\mathrm{argmin}_{\mathbf{x}} \; (1/2) \| \mathbf{y} - A \mathbf{x}
\|_2^2 \;,$$

where $A$ is the Radon transform, $\mathbf{y}$ is the sinogram, and
$\mathbf{x}$ is the reconstructed image.
where $A$ is the X-ray transform (the CT forward projection operator),
$\mathbf{y}$ is the sinogram, and $\mathbf{x}$ is the reconstructed image.
"""

from time import time
Expand All @@ -30,7 +30,7 @@

from scico import loss, plot
from scico.linop import CircularConvolve
from scico.linop.radon_astra import TomographicProjector
from scico.linop.xray.astra import XRayTransform
from scico.solver import cg

"""
Expand All @@ -46,7 +46,7 @@
"""
n_projection = N # matches the phantom size so this is not few-view CT
angles = np.linspace(0, np.pi, n_projection) # evenly spaced projection angles
A = 1 / N * TomographicProjector(x_gt.shape, 1, N, angles) # Radon transform operator
A = 1 / N * XRayTransform(x_gt.shape, 1, N, angles) # CT projection operator
y = A @ x_gt # sinogram


Expand Down
6 changes: 3 additions & 3 deletions examples/scripts/ct_astra_odp_train_foam2.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
from scico import metric, plot
from scico.flax.examples import load_ct_data
from scico.flax.train.traversals import clip_positive, construct_traversal
from scico.linop.radon_astra import TomographicProjector
from scico.linop.xray.astra import XRayTransform

"""
Prepare parallel processing. Set an arbitrary processor count (only
Expand All @@ -85,12 +85,12 @@
Build CT projection operator.
"""
angles = np.linspace(0, np.pi, n_projection) # evenly spaced projection angles
A = TomographicProjector(
A = XRayTransform(
input_shape=(N, N),
detector_spacing=1,
det_count=N,
angles=angles,
) # Radon transform operator
) # CT projection operator
A = (1.0 / N) * A # normalized


Expand Down
10 changes: 5 additions & 5 deletions examples/scripts/ct_astra_tv_admm.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
$$\mathrm{argmin}_{\mathbf{x}} \; (1/2) \| \mathbf{y} - A \mathbf{x}
\|_2^2 + \lambda \| C \mathbf{x} \|_{2,1} \;,$$

where $A$ is the Radon transform, $\mathbf{y}$ is the sinogram, $C$ is
a 2D finite difference operator, and $\mathbf{x}$ is the desired
image.
where $A$ is the X-ray transform (the CT forward projection operator),
$\mathbf{y}$ is the sinogram, $C$ is a 2D finite difference operator, and
$\mathbf{x}$ is the desired image.
"""

import numpy as np
Expand All @@ -28,7 +28,7 @@

import scico.numpy as snp
from scico import functional, linop, loss, metric, plot
from scico.linop.radon_astra import TomographicProjector
from scico.linop.xray.astra import XRayTransform
from scico.optimize.admm import ADMM, LinearSubproblemSolver
from scico.util import device_info

Expand All @@ -46,7 +46,7 @@
"""
n_projection = 45 # number of projections
angles = np.linspace(0, np.pi, n_projection) # evenly spaced projection angles
A = TomographicProjector(x_gt.shape, 1, N, angles) # Radon transform operator
A = XRayTransform(x_gt.shape, 1, N, angles) # CT projection operator
y = A @ x_gt # sinogram


Expand Down
14 changes: 7 additions & 7 deletions examples/scripts/ct_astra_weighted_tv_admm.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
$$\mathrm{argmin}_{\mathbf{x}} \; (1/2) \| \mathbf{y} - A \mathbf{x}
\|_W^2 + \lambda \| C \mathbf{x} \|_{2,1} \;,$$

where $A$ is the Radon transform, $\mathbf{y}$ is the sinogram, the norm
weighting $W$ is chosen so that the weighted norm is an approximation to
the Poisson negative log likelihood :cite:`sauer-1993-local`, $C$ is
a 2D finite difference operator, and $\mathbf{x}$ is the desired
image.
where $A$ is the X-ray transform (the CT forward projection),
$\mathbf{y}$ is the sinogram, the norm weighting $W$ is chosen so that
the weighted norm is an approximation to the Poisson negative log
likelihood :cite:`sauer-1993-local`, $C$ is a 2D finite difference
operator, and $\mathbf{x}$ is the desired image.
"""

import numpy as np
Expand All @@ -29,7 +29,7 @@

import scico.numpy as snp
from scico import functional, linop, loss, metric, plot
from scico.linop.radon_astra import TomographicProjector
from scico.linop.xray.astra import XRayTransform
from scico.optimize.admm import ADMM, LinearSubproblemSolver
from scico.util import device_info

Expand All @@ -53,7 +53,7 @@
𝛼 = 1e-2 # attenuation coefficient

angles = np.linspace(0, 2 * np.pi, n_projection) # evenly spaced projection angles
A = TomographicProjector(x_gt.shape, 1.0, N, angles) # Radon transform operator
A = XRayTransform(x_gt.shape, 1.0, N, angles) # CT projection operator
y_c = A @ x_gt # sinogram


Expand Down
6 changes: 3 additions & 3 deletions examples/scripts/ct_fan_svmbir_ppp_bm3d_admm_prox.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
from scico import metric, plot
from scico.functional import BM3D
from scico.linop import Diagonal, Identity
from scico.linop.radon_svmbir import SVMBIRExtendedLoss, TomographicProjector
from scico.linop.xray.svmbir import SVMBIRExtendedLoss, XRayTransform
from scico.optimize.admm import ADMM, LinearSubproblemSolver
from scico.util import device_info

Expand Down Expand Up @@ -67,15 +67,15 @@

dist_source_detector = 1500.0
magnification = 1.2
A_fan = TomographicProjector(
A_fan = XRayTransform(
x_gt.shape,
angles,
num_channels,
geometry="fan-curved",
dist_source_detector=dist_source_detector,
magnification=magnification,
)
A_parallel = TomographicProjector(
A_parallel = XRayTransform(
x_gt.shape,
angles,
num_channels,
Expand Down
Loading
Loading