Skip to content

v6.3.0

Latest

Choose a tag to compare

@KrisThielemans KrisThielemans released this 01 Nov 08:00
· 67 commits to master since this release
7e10575

Summary of changes in STIR release 6.3

Overall summary

This version is 100% backwards compatible with STIR 6.2, aside from three important bug fixes, which will change results (see below).

This is a release with many new features, as listed below. Highlights are

  • the new Gibbs penalty hierarchy with CUDA and OpenMP support (and much easier addition of new potential functions) (Matteo Neel Colombo, Univ of Milano-Bicocca),
  • new 2D analytic reconstruction algorithms (including two that allow quantitative reconstruction of SPECT) (Dimitra Kyriakopoulou, UCL),
  • better Python support including algebraic operations and faster conversion to NumPy arrays (Kris Thielemans, UCL),
  • continuous memory storage for arrays (allowing zero-copy access to image/projection data in SIRF Python, but not yet in STIR Python)
    (Kris Thielemans, UCL),
  • faster scatter estimation for blocks on cylindrical scanners (Markus Jehl, Positrigo),
  • reduced memory usage for iterative reconstructions, avoiding hitting the current limitation of 2^31 elements in ProjDataInMemory (Kris Thielemans, UCL),
  • Python code for adapting e7tools output for Siemens Vision 600 to STIR (Nicole Jurjew, UCL)

But there are many other changes from other contibutors as well, see below. Of course, there is also the usual code-cleanup and some
improvements to the documentation. Overall overview and release management was by Kris Thielemans (UCL) with help from Daniel Deidda (NPL).

Patch release info

Summary for end users (also to be read by developers)

New functionality

General

  • Several 2D analytic reconstruction algorithms were added for PET (i.e. inverting the 2D Radon transform) and parallel beam SPECT (inverting the 2D attenuated Radon transform). The latter allow quantitatively correct analytic reconstruction of SPECT data (after scatter correction).

    • The Spline Reconstruction Technique (SRT) algorithm has been added in 2 different versions: SRT2D for PET and SRT2DSPECT for SPECT.
      The reference for the implemented algorithms is:
      Fokas, A. S., A. Iserles, and V. Marinakis. Reconstruction algorithm for single photon emission computed tomography and its numerical implementation. Journal of the Royal Society Interface 3.6 (2006): 45-54.
    • GRD2D for PET is a direct Fourier method using regridding with Kaiser-Bessel functions.
    • DDSR2D for parallel beam SPECT uses Hilbert transforms in projection space.

    The reference for the implementation of these algorithms is:
    Dimitra Kyriakopoulou, Analytical and Numerical Aspects of Tomography,
    PhD thesis, University College London (UCL), 2024,
    Available at:
    discovery.ucl.ac.uk/id/eprint/10202525/.
    PR #1420 and PR #1595.

  • Wiener and Gamma filters were added.
    PR #1420.

  • ScatterSimulation can now downsample the scanner transaxially (crystals per ring) for BlocksOnCylindrical, scanners, which speeds
    up ScatterEstimation considerably. By default, downsampling the detectors per reading is disabled for backwards compatibility.
    PR #1291

  • The priors code has been refactored to provide two common, parallelized base classes for CPU and GPU implementations
    (GibbsPenalty and CudaGibbsPenalty).
    On CPU, we introduce GibbsQuadraticPenalty and GibbsRelativeDifferencePenalty, which inherit from the parallelized
    GibbsPenalty base class (now parallelized using OpenMP).
    GPU implementations are also provided as CudaGibbsQuadraticPenalty and CudaGibbsRelativeDifferencePenalty.
    Currently, the new Gibbs penalties are still missing the paraboloidal surrogates related method implementations. They provide two new
    methods: compute_gradient_times_input and compute_Hessian_diagonal.
    PR #1629

  • Data from GE Discovery MI systems in RDF9 should now be readable. TOF information on these scanners has also been added. However, projection data is currently still always returned as non-TOF (but list-mode data is read as TOF).
    PR #1503

  • Added the ability to set a forward projector for mask projection in the ScatterEstimation class.
    PR #1530

  • Duration in sinogram interfile/exam_info obtained from LmToProjData/lm_to_projdata has the correct value if we unlist all
    the events. This is not true for ROOT files PR #1519

  • LmToProjData class/lm_to_projdata utility now no longer requires a template projection data. If none is specified, it will use the
    proj_data_info from the input list-mode.
    Warning for some scanners with TOF capabilities, this will result in very large projection data (possibly larger than the default from
    the vendor).
    PR #1315

  • Adapt the SPECTUB projector to handle data with only a subset of the views (constructed using ProjData::get_subsets(). This is useful for SIRF/CIL applications using stochastic optimisation.
    PR #1596

Python

  • "Container" classes such as FloatVoxelsOnCartesianGrid, ProjDataInMemory and array-classes now have numerical operations
    properly defined, for instance a = b + c and a -= 3. Note that a = 1 + b is not yet available.
    PR #1630
  • The above "container" classes now have an extra member `as_array()` which returns a numpy ndarray. This is equivalent to
    `stirextra.to_numpy()` which will become deprecated later. In addition, the fill() method now directly accepts an ndarray,
    avoiding the need to go via an iterator. These additions also make it easier to prt SIRF python code to STIR.
    PR #1632
  • Added a Python script to convert e7tools generated Siemens Biograph Vision 600 sinograms to STIR compatible format.
    PR #1593

Utilities

  • stir_timings has now an extra option to parse a par-file for a projector-pair.

Changed functionality

  • In previous versions, when reading data/images where the radionuclide was not set, a default was used (F18 for PET, Tcm99 for SPECT). This led to surprising (and sometimes wrong) behaviour. The radionuclide is now kept as "unknown".
    PR #1574
  • Default ECAT scanner configurations updated to use a negative intrinsic tilt.
  • When computing the sensitivity images in PoissonLogLikelihoodWithLinearModelForMeanAndProjData, we now avoid creating an extra ProjDataInMemory in most cases (there are still some corner cases for TOF data when using non-TOF projector for the sensitivity, but then the memory overhead is small). This enables LAFOV PET reconstructions with the "ray tracing" matrix (we use less memory, and we avoid running into a current ProjDataInMemory
    limitation on the number of bins).
    PR #1716
  • Boost format was replaced by `std::format` for formatting strings. If C++20 or newer is not yet used, a work-around is in place by using the {fmt} library (included as as a git submodule). Import stir/format.h and then use the format() function to create strings containing various variables. If the format string is not known at compile time, use runtime_format() instead.
    Check the updated STIR-developers-overview.
    PR #1591 and PR
    #1605

Changes to examples

  • Python example plot_sinogram_profiles.py has been renamed to plot_projdata_profiles.py and generalised to work with TOF
    dimensions etc. A small pytest has been added as well.
    PR #1370
  • Python example ProjDataVisualisation.py now has a vmax slider.
    PR #1568

Bug fixes

  • Fixed a bug in the scatter estimation code (introduced in release 5.1.0) if input data is 3D and "cylindrical" (there was no bug for
    "blocksoncylindrical" data). The scatter estimation runs on data constructed via SSRB. However, the attenuation correction factors were
    incorrectly obtained with adding of oblique segments (as opposed to averaging). This resulted in intermediate images that had the wrong
    attenuation correction which were approximately num_segments times
    larger. This was compensated by the tail-fitting, but resulted in unexpected scale factors (scale factors were around 1/num_segments
    times what was expected). This means that if you used the "min/max scale factor" feature in the scatter estimate, you will have to adjust your threshold values. Expected scatter tail-fitting scale factors should now be restored to ~1-1.5 (depending on the amount of multiple and out-of-FOV scatter). See Issue #1532 for more detail.
    Fixed by using averaging functionality of SSRB instead of adding segments for attenuation correction factors.
    PR #1531
  • Fixed a bug in the distributed LM computation code (introduced in 6.1) that neglected to accumulate outputs when not built with OpenMP.
    See PR #1566.
  • Fixed bugs in accumulate_sub_Hessian_times_input and accumulate_sub_Hessian_times_input (and hence the non-subset versions) for objective functions when the prior is not zero.
    See PR #1649 and PR #1651.

Build system

  • Enable more diagnostics in CMake when finding CERN's ROOT (we used to silence them)
    PR #1552
  • Use OpenMP by default Introduce advanced variable MINI_STIR defaulting to OFF for developers. This will build a heavily reduced version of STIR which can speed up development time.
    PR #1584

Known problems

See our issue tracker.
An important bug is for the "ray tracing matrix" projector for TOF PET. Oblique segments currently have problems, see #1537.

What is new for developers (aside from what should be obvious from the above):

New functionality

  • ProjDataInMemory read_from_file method now returns a ProjDataInMemory object.
  • Array::resize and Array::grow argument initialise_with_0 usage fixed.

Changed functionality

  • In C++, "Container" classes such as VoxelsOnCartesianGrid, ProjDataInMemory and array-classes now have numerical operations that return objects of the correct type. (Previously, it was a base-class such as NumericVectorWithOffset<Array<2, float>, float>).
    PR #1630
  • Made 2 (deprecated) members of ProjDataInfoBlocksOnCylindricalNoArcCorr private and do some clean-up of which files to include.
    PR #1556
  • LmToProjData::get_template_proj_data_info_sptr() is now a const member returning a shared_ptr<const ProjDataInfo>.
    PR #1315
  • As stir::Array template arguments might change in the future, it is now recommended to include stir/ArrayFwd.h when using forward declaration and use the ArrayType template-alias in places where a rectangular array that might live on a GPU is intended.
    PR #1589
  • Array copy constructor now also uses contiguous memory allocation (as opposed to a sequence of 1D vectors).
    PR #1592.

Bug fixes

  • Fixed minor incompatibility with gcc-14 and clang-18 by adding an extra include file.
    PR #1552
  • Changed the way that some SWIG work-arounds are implemented, avoiding the SWIG-generated wrapper to be compiled with the SWIG preprocessor symbol.
    PR #1647

New Deprecations and renames

  • truncate_end_planes will be removed in v7.0 legacy compatibility with version 3, 4 and 5 will be removed in v7.0. CMake options STIR_PROJECTORS_AS_V3, STIR_LEGACY_IGNORE_VIEW_OFFSET and STIR_ROOT_ROTATION_AS_V4 will therefore be removed.
  • Starting from v7.0, GeneralizedPrior will be renamed to GeneralizedPenalty. QuadraticPrior, RelativeDifferencePrior, and LogcoshPrior will be removed in favor of the new GibbsPenalty framework. Issue #1426

Test changes

All new features and most code changes were accompanied by new tests.