-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This version of MBIRJAX adds the following features: FBP parallel beam reconstruction using the adjoint forward projector FDK cone beam reconstruction using the adjoint forward projector Demos and tests for FBP and FDK * fbp_fdk (#50) * Incorporate fbp and fdk recon from separate branches. * Incorporate fdk_recon from "fdk" branch * Clean up commented lines * Add comments * switch the order of u and v * fix the scale factor: recon_filter *= scaling_factor * Restore fbp and fdk code from separate branches. * Reorganize the setting of parameters and update the tolerances for fbp and fdk. * Update the documentation for fbp and fdk (and remove the shepp-logan filter). --------- Co-authored-by: Yufang Sun <yufang.sun2@gmail.com> * Minor docstring correction * Update version number and pin a version of jaxlib to avoid an error in loading cuda libraries on Gilbreth. * Update test instructions for the GPU. * Update pip install for jax cuda. * use jax.scipy.signal.fftconvolve * Fbp fdk demo (#52) * Constructed the demo file for FBP and FDK reconstruction * Changed the scanning angle to full 360 degrees and added projection angles * write with python notebook format * Update the faqs to discuss fbp/fdk. * Update the install scripts to work on Gilbreth. * Improve and fix a bug in the install scripts. * Update install instructions. * Update fbp/fdk description. * Removed unused parameters: detector_cone_angle, weigth, sharpness and related code; remove VCD reconstruction. * rename file demo_5_FBP_FDK.py to demo_5_fbp_fdk.py * add the fbp/fdk demo link * Update module name for gautschi. * Correct typo. --------- Co-authored-by: ZiyunLiiii <a124601@MacBook-Pro-215.local> Co-authored-by: Yufang Sun <yufang.sun2@gmail.com> --------- Co-authored-by: gbuzzard <54102356+gbuzzard@users.noreply.github.com> Co-authored-by: Yufang Sun <yufang.sun2@gmail.com> Co-authored-by: Greg Buzzard <buzzard@purdue.edu> Co-authored-by: ZiyunLiiii <a124601@MacBook-Pro-215.local>
- Loading branch information
1 parent
1159eef
commit 3d6eda7
Showing
18 changed files
with
512 additions
and
101 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
# -*- coding: utf-8 -*- | ||
"""demo_5_fbp_fdk.ipynb | ||
Automatically generated by Colab. | ||
Original file is located at | ||
https://colab.research.google.com/drive/10ZiCSk1C9D4Fb7Uv6jTtQYxF2lKjmbyh | ||
**MBIRJAX: FBP and FDK Reconstruction Demo** | ||
See the [MBIRJAX documentation](https://mbirjax.readthedocs.io/en/latest/) for an overview and details. | ||
This script demonstrates the MBIRJAX code by creating a 3D phantom inspired by Shepp-Logan, forward projecting it to create a sinogram, and then using MBIRJAX to perform Filtered Back Projection (FBP) for parallel beam reconstruction and Feldkamp-Davis-Kress reconstruction (FDK) for cone beam reconstruntion. | ||
For the demo, we create some synthetic data by first making a phantom, then forward projecting it to obtain a sinogram. | ||
In a real application, you would load your sinogram as a numpy array and use numpy.transpose if needed so that it | ||
has axes in the order (views, rows, channels). For reference, assuming the rotation axis is vertical, then increasing the row index nominally moves down the rotation axis and increasing the channel index moves to the right as seen from the source. | ||
Select a GPU as runtime type for best performance. | ||
""" | ||
|
||
# Commented out IPython magic to ensure Python compatibility. | ||
# %pip install -i https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple mbirjax | ||
|
||
import numpy as np | ||
import time | ||
import jax.numpy as jnp | ||
import mbirjax | ||
|
||
"""**Set the geometry parameters**""" | ||
|
||
# Choose the geometry type | ||
geometry_type = 'cone' # 'cone' or 'parallel' | ||
|
||
# Set parameters for the problem size - you can vary these, but if you make num_det_rows very small relative to | ||
# channels, then the generated phantom may not have an interior. | ||
num_views = 128 | ||
num_det_rows = 128 | ||
num_det_channels = 128 | ||
|
||
# For cone beam geometry, we need to describe the distances source to detector and source to rotation axis. | ||
# np.Inf is an allowable value, in which case this is essentially parallel beam. | ||
source_detector_dist = 4 * num_det_channels | ||
source_iso_dist = source_detector_dist | ||
|
||
# Set parameters for viewing angle. | ||
start_angle = -np.pi | ||
end_angle = np.pi | ||
|
||
"""**Data generation:** For demo purposes, we create a phantom and then project it to create a sinogram. | ||
Note: the sliders on the viewer won't work in notebook form. For that you'll need to run the python code with an interactive matplotlib backend, typcially using the command line or a development environment like Spyder or Pycharm to invoke python. | ||
""" | ||
|
||
# Initialize sinogram | ||
sinogram_shape = (num_views, num_det_rows, num_det_channels) | ||
angles = jnp.linspace(start_angle, end_angle, num_views, endpoint=False) | ||
|
||
if geometry_type == 'cone': | ||
ct_model_for_generation = mbirjax.ConeBeamModel(sinogram_shape, angles, source_detector_dist=source_detector_dist, source_iso_dist=source_iso_dist) | ||
elif geometry_type == 'parallel': | ||
ct_model_for_generation = mbirjax.ParallelBeamModel(sinogram_shape, angles) | ||
else: | ||
raise ValueError('Invalid geometry type. Expected cone or parallel, got {}'.format(geometry_type)) | ||
|
||
# Generate 3D Shepp Logan phantom | ||
print('Creating phantom') | ||
phantom = ct_model_for_generation.gen_modified_3d_sl_phantom() | ||
|
||
# Generate synthetic sinogram data | ||
print('Creating sinogram') | ||
sinogram = ct_model_for_generation.forward_project(phantom) | ||
sinogram = np.array(sinogram) | ||
|
||
# View sinogram | ||
title = 'Original sinogram \nUse the sliders to change the view or adjust the intensity range.' | ||
mbirjax.slice_viewer(sinogram, slice_axis=0, title=title, slice_label='View') | ||
|
||
"""**Initialize for the reconstruction**""" | ||
|
||
# #################### | ||
# Initialize the model for reconstruction. | ||
if geometry_type == 'cone': | ||
ct_model_for_recon = mbirjax.ConeBeamModel(sinogram_shape, angles, source_detector_dist=source_detector_dist, source_iso_dist=source_iso_dist) | ||
elif geometry_type == 'parallel': | ||
ct_model_for_recon = mbirjax.ParallelBeamModel(sinogram_shape, angles) | ||
else: | ||
raise ValueError('Invalid geometry type. Expected cone or parallel, got {}'.format(geometry_type)) | ||
|
||
# Print out model parameters | ||
ct_model_for_recon.print_params() | ||
|
||
"""**Do the reconstruction and display the results.**""" | ||
|
||
# ########################## | ||
# Perform FBP/FDK reconstruction | ||
if geometry_type == 'cone': | ||
print("Starting FDK recon") | ||
time0 = time.time() | ||
recon = ct_model_for_recon.fdk_recon(sinogram, filter_name="ramp") | ||
else: | ||
print("Starting FBP recon") | ||
time0 = time.time() | ||
recon = ct_model_for_recon.fbp_recon(sinogram, filter_name="ramp") | ||
|
||
recon.block_until_ready() | ||
elapsed = time.time() - time0 | ||
# ########################## | ||
|
||
max_diff = np.amax(np.abs(phantom - recon)) | ||
print('Geometry = {}'.format(geometry_type)) | ||
nrmse = np.linalg.norm(recon - phantom) / np.linalg.norm(phantom) | ||
pct_95 = np.percentile(np.abs(recon - phantom), 95) | ||
print('NRMSE between recon and phantom = {}'.format(nrmse)) | ||
print('Maximum pixel difference between phantom and recon = {}'.format(max_diff)) | ||
print('95% of recon pixels are within {} of phantom'.format(pct_95)) | ||
|
||
mbirjax.get_memory_stats() | ||
print('Elapsed time for recon is {:.3f} seconds'.format(elapsed)) | ||
|
||
# Display results | ||
title = (f"Phantom (left) vs {'FDK' if geometry_type == 'cone' else 'FBP'} Recon (right). " | ||
f"Filter used: ramp. \nUse the sliders to change the slice or adjust the intensity range.") | ||
|
||
mbirjax.slice_viewer(phantom, recon, title=title) | ||
|
||
"""**Next:** Try changing some of the parameters and re-running or try [some of the other demos](https://mbirjax.readthedocs.io/en/latest/demos_and_faqs.html). """ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#!/bin/bash | ||
|
||
while [ ${#CONDA_DEFAULT_ENV} -gt 0 ]; do | ||
conda deactivate | ||
done | ||
|
||
rm -rf ~/.conda/* ~/.cache/conda/* ~/.cache/pip/* ~/.local/lib/python* |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.