Skip to content

Commit

Permalink
Update docs and demos (#45)
Browse files Browse the repository at this point in the history
* Update granularity sequence and vcd figure generation.

* Update FAQs documentation

* Update docs and demos.

* Update version number.

---------

Co-authored-by: Charles Bouman <Charles.Bouman@gmail.com>
  • Loading branch information
gbuzzard and cabouman authored Jul 31, 2024
1 parent 0235f7d commit 47189b6
Show file tree
Hide file tree
Showing 16 changed files with 285 additions and 142 deletions.
2 changes: 1 addition & 1 deletion demo/demo_1_shepp_logan.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,4 @@
title = 'Phantom (left) vs VCD Recon (right) \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/examples.html). """
"""**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). """
9 changes: 2 additions & 7 deletions demo/demo_2_large_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,7 @@
# approximate the phantom shape. Note that it doesn't have to be an exact match.
recon_row_scale = 1.0
recon_col_scale = 1.5
# Version 0.4.X:
(num_rows, num_cols, num_slices) = ct_model_for_recon.get_params('recon_shape')
new_shape = (int(num_rows * recon_row_scale), int(num_cols * recon_col_scale), num_slices)
ct_model_for_recon.set_params(recon_shape=new_shape)
# Version 0.5.0:
# ct_model_for_recon.scale_recon_shape(row_scale=recon_row_scale, col_scale=recon_col_scale)
ct_model_for_recon.scale_recon_shape(row_scale=recon_row_scale, col_scale=recon_col_scale)

# Reset the default sharpness
sharpness = 0
Expand All @@ -166,4 +161,4 @@
title += '\nEdges are sharp, outer ring is mostly gone, and the partially projected pixels are partially recovered.'
mbirjax.slice_viewer(phantom, recon_enlarged, title=title, vmin=0.0, vmax=2.0)

"""**Next:** Try changing some of the parameters and re-running or try [some of the other demos](https://mbirjax.readthedocs.io/en/latest/examples.html). """
"""**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). """
9 changes: 2 additions & 7 deletions demo/demo_3_cropped_center_recon.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,7 @@
sharpness = -0.5
recon_row_scale = 0.5
recon_col_scale = 0.5

# Version 0.4.X:
recon_shape = (phantom.shape[0] // 2, phantom.shape[1] // 2, phantom.shape[2])
ct_model_for_recon.set_params(recon_shape=recon_shape)
# Version 0.5.0:
# ct_model_for_recon.scale_recon_shape(row_scale=recon_row_scale, col_scale=recon_col_scale)
ct_model_for_recon.scale_recon_shape(row_scale=recon_row_scale, col_scale=recon_col_scale)

ct_model_for_recon.set_params(sharpness=sharpness)

Expand All @@ -118,4 +113,4 @@
cropped_phantom = phantom[start_inds[0]:end_inds[0], start_inds[1]:end_inds[1]]
mbirjax.slice_viewer(cropped_phantom, recon, title=title, vmin=0.0, vmax=2.0)

"""**Next:** Try changing some of the parameters and re-running or try [some of the other demos](https://mbirjax.readthedocs.io/en/latest/examples.html). """
"""**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). """
2 changes: 1 addition & 1 deletion demo/demo_4_wrong_rotation_direction.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,4 @@
title += '\nThe incorrect angle specification leads to shape distortion and top/bottom reflection.'
mbirjax.slice_viewer(recon_correct, recon_incorrect, title=title, vmin=0.0, vmax=1.0)

"""**Next:** Try changing some of the parameters and re-running or try [some of the other demos](https://mbirjax.readthedocs.io/en/latest/examples.html). """
"""**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). """
129 changes: 129 additions & 0 deletions docs/source/demos_and_faqs.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
.. _DemosFAQs:

==============
Demos and FAQs
==============

Demos
-----

Here are some demos to illustrate the basics of MBIRJAX along with some more advanced features.

1. **Basic Demo:** `Jupyter notebook <https://colab.research.google.com/drive/1zG_H6CDjuQxeMRQHan3XEyX2YVKcSSNC?usp=drive_link>`__ or `Python script <https://github.com/cabouman/mbirjax/blob/main/demo/demo_1_shepp_logan.py>`__
2. **Large Object:** `Jupyter notebook <https://colab.research.google.com/drive/1-kk_HeR8Y8f6pZ2zjTza8NTEpAgwgVRB?usp=sharing>`__ or `Python script <https://github.com/cabouman/mbirjax/blob/main/demo/demo_2_large_object.py>`__
3. **Cropped Center:** `Jupyter notebook <https://colab.research.google.com/drive/1WQwIJ_mDcuMMcWseM66aRPvtv6FmMWF-?usp=sharing>`__ or `Python script <https://github.com/cabouman/mbirjax/blob/main/demo/demo_3_cropped_center.py>`__
4. **Wrong Rotation:** `Jupyter notebook <https://colab.research.google.com/drive/1Gd-fMm3XK1WBsuJUklHdZ-4jjsvdpeIT?usp=sharing>`__ or `Python script <https://github.com/cabouman/mbirjax/blob/main/demo/demo_4_wrong_rotation_direction.py>`__

First browse the notebooks, then copy and run in your own notebook environment,
or follow the installation instructions at :ref:`InstallationDocs` and run the scripts directly.

Then adjust some of the parameters to better understand how the code works.
If you have a GPU, you can increase the problem size by changing ``num_views``, ``num_det_rows``, and ``num_det_channels``.

The separate repo `mbirjax_applications <https://github.com/cabouman/mbirjax_applications>`__ provides a wider variety of examples using real data.


FAQs
----

Q: Why is there a bright ring around my reconstruction?
+++++++++++++++++++++++++++++++++++++++++++++++++++++++

A: If the object does not project completely inside the detector, then MBIR will produce a bright ring
around the edge of the reconstruction to account for the portion of the object that projects to the detector in only some views.
See Demo 2: Large Object for an example of this.
You can improve the reconstruction by increasing recon_shape:

.. code-block:: python
ct_model.scale_recon_shape(row_scale=1.2, col_scale=1.2)
Note that the scale factor need only be large enough to give some padding around the region of valid projection --
it does not need to match the size of the true object. Larger scale factors will lead to increased time and memory.

Q: Why is my reconstruction blurry?
+++++++++++++++++++++++++++++++++++

A: If your reconstruction is blurry, the first thing to try is to increase the sharpness parameter. Values of
``sharpness=1.0`` or ``sharpness=2.0`` are typical, but larger values can further improve sharpness.
You can also increase the assumed SNR by setting the parameter ``snr_db=35`` or ``snr_db=40``. This is similar to increasing sharpness but will also create higher contrast edges in the reconstruction.

If the reconstruction remains blurry, it is often the case that some geometry parameter is incorrectly set for your data.
Typical problems include an incorrect center of rotation (change ``det_channel_offset``), incorrect rotation direction
(reverse the angles using ``angles[::-1]``), or an incorrect ``source_detector_dist`` or ``source_iso_dist`` for
cone beam reconstructions.

Q: How can I do larger reconstructions?
+++++++++++++++++++++++++++++++++++++++

A: MBIRJAX runs on both CPU and GPU computers, but we strongly recommend the use of GPUs for large reconstructions since they are much faster.
On a GPU, the size of the reconstruction is typically limited by the amount of GPU memory.
So you should find a fast GPU with the largest possible memory. These days that is typically 40GB to 80GB of GPU memory.
The GPU will be hosted on a CPU, and it is best if that CPU also has even a larger amount of memory, ideally greater than 200GB.

Note that a 2K x 2K x 2K reconstruction occupies 32GB of memory, not counting the sinogram or memory needed for processing.
If your reconstruction is too large for your GPU memory, MBIRJAX will use CPU memory for some processing and then transfer
to the GPU as needed; this reduces memory use but increases reconstruction time. If you have no GPU or your GPU memory is small relative
to the problem size, then all processing is done on the CPU.

If you have a parallel beam system, you can select a subset of rows of your sinogram, reconstruct them separately, and then
concatenate them at the end. If you have a cone beam system, you can reconstruct a subset of the central slices. In either
case, you can do a center cropped reconstruction as in Demo 3: Cropped Center, although as seen in that demo, this can
introduce an intensity shift and other artifacts.

We continue to improve the time and memory efficiency of MBIRJAX and will investigate multi-GPU/multi-CPU solutions.
So stay tuned for further improvements.


Q: Why does my reconstruction have artifacts?
+++++++++++++++++++++++++++++++++++++++++++++

There are many reasons that a reconstruction may have artifacts including noise, blurring, streaks, cupping, etc.

First, make sure you are using the geometry (parallel or cone) that matches your data.
Parallel beam geometry is faster and could be used for cone beam data, but it may not be accurate if the source is too
close to the object.

For transmission tomography, it is critically important to preprocess the raw photon measurements by normalizing by an air-scan and taking the negative log of the ratio.
We provide simple preprocessing utilities in ``mbirjax.preprocess`` for doing this, and we plan to provide more utilities for specific instruments in the future.

In conebeam scans, it is sometimes the case that the rotation direction is reversed.
This can cause the reconstruction to look blurry or distorted.
You can correct this by simply taking the negative of your view angles.
See Demo 3: Wrong Rotation Direction above for an example of what can happen if the rotation direction is incorrect.

A common artifact is rings near the center of the reconstruction that are generated when the center-of-rotation is
not in the center of the detector. This can be corrected by setting the parameter ``det_channel_offset`` to reposition
the center-of-rotation.

If your reconstruction is blurry, see the FAQ above.

If the reconstruction is too noisy, you might try reducing the value of the ``sharpness`` or ``snr_db`` parameters (discussed
more in the FAQ above on blurry reconstructions).
You can also improve reconstruction quality by using the ``weights`` array that can be generated using the ``gen_weights()`` method.
The weights provide information on the reliability of the sinogram values, with larger weights indicating higher reliability.

Streaks are often caused by metal in the object being scanned.
One advantage of MBIR is that it generally has fewer metal artifacts, but some artifacts typically remain.
Using weights will reduce metal artifacts, and the function ``gen_weights_mar()`` can be used to generate weights that further reduce metal artifacts.

Cupping is typically caused by beam hardening with polychromatic X-ray sources.
This can be partially corrected with a low order polynomial correction.
We are working on utilities to do beam hardening correction in the future.

Ring artifacts away from the center of reconstruction are typically caused by detector nonuniformity.
Detector nonuniformity results from the variation in detector sensitivity from pixel to pixel.
This variation is taken out to some degree by air scan normalization, but some variation may remain.
These variations will lead to concentric rings in the reconstruction.
We are working on preprocessing utilities for reducing these ring artifacts.


Q: How can I shift region-of-reconstruction up or down for a conebeam reconstruction?
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

A: You can shift the region of reconstruction up or down using ``ct_model.set_params(recon_slice_offset=offset)``
before calling recon.
Positive values of ``offset`` will shift the region down relative to the detector.
This is useful if you would like to reconstruct the top or bottom half of a conebeam reconstruction in order to save memory.


110 changes: 0 additions & 110 deletions docs/source/examples.rst

This file was deleted.

2 changes: 1 addition & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ MBIRJAX: High-performance tomographic reconstruction

install
usr_api
examples
demos_and_faqs

.. toctree::
:hidden:
Expand Down
2 changes: 1 addition & 1 deletion docs/source/overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Here are the reasons to use MBIRJAX:
Supports proximal map interfaces, so it can be used with PnP deep neural net priors.


In :ref:`ExamplesFAQs`, we provide several demos as Jupyter notebooks and python scripts that make it easy to get started.
In :ref:`DemosFAQs`, we provide several demos as Jupyter notebooks and python scripts that make it easy to get started.
You can use pip install to install mbirjax or install from source as described in :ref:`InstallationDocs`.

**Geometries**
Expand Down
4 changes: 3 additions & 1 deletion docs/source/quick_start.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Demos
The best way to start is to:

- **Install MBIRJAX** using the instructions provided on the :ref:`Installation Page <InstallationDocs>`. We recommend installing in a conda environment or pip virtual environment.
- **View and run demos** in :ref:`ExamplesFAQs`
- **View and run demos** in :ref:`DemosFAQs`

You can then adapt these demos to suit your needs.

Expand All @@ -37,6 +37,8 @@ Below are simple instructions on how to do your first reconstruction:
Note that each row of sinogram data is assumed to be perpendicular to the rotation axis and each view is assumed to be in conventional raster order (i.e., left-to-right, top-to-bottom) looking through the object from the source to the detector.


For transmission tomography, it is critically important to preprocess the raw photon measurements by normalizing by an air-scan and taking the negative log of the ratio. We provide simple preprocessing utilities in ``mbirjax.preprocess`` for doing this, and we plan to provide more utilities for specific instruments in the future.

- **Initialize a model:**

- Run ``model = mbirjax.ParallelBeamModel(sinogram.shape, angles)`` to initialize a parallel beam model.
Expand Down
2 changes: 1 addition & 1 deletion docs/source/usr_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ User API
========

Most functions can be accessed by importing mbirjax and creating a model or through mbirjax directly. Most
commonly used functions are described below. See :ref:`ExamplesFAQs` for examples.
commonly used functions are described below. See :ref:`DemosFAQs` for examples.

Geometry Models
---------------
Expand Down
Loading

0 comments on commit 47189b6

Please sign in to comment.