# Summary of changes in STIR release 2.1 (dated June 2011)

Most of the work in this update was by Kris Thielemans (Hammersmith Imanet Ltd) and Charalampos Tsoumpas (Imperial College and Hammersmith Imanet Ltd, now King's College London). Some older code by Sanida Mustafovic (Imperial College and Hammersmith Imanet Ltd) has now finally been incorporated into STIR as well. Careful testing and investigation by Charalampos Tsoumpas and Irene Polycarpou (both King's College London) uncovered some old bugs, which were corrected after discussions with Matthew Jacobson (Xoran Technologies). Other contributions are mentioned explicitly below.
See also the new `contrib` sub-directory available in the documentation zip file.

- Single scatter estimation routines
  Contributors: Charalampos Tsoumpas, Pablo Aguiar (Univ of Barcelona, when working on this topic), Nikolaos Dikaios (National Technical University of Athens, when working on this topic) and Kris Thielemans.
- Parametric image estimation routines.
  Contributors: Charalampos Tsoumpas and Kris Thielemans
- B-spline interpolation functions and a few numerical algorithms.
  Contributors: Charalampos Tsoumpas, Nikolaos Dikaios (National Technical University of Athens, when working on this topic) and Kris Thielemans.

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

### Important bug fixes

- fixed a problem in the computation for the gradient of the Poisson log-likelihood that occured if a viewgram of the measured data was zero (which should occur only a dramatically noisy situations).
- fixed a problem in the computation of the Poisson log-likelihood that the multiplicative term of the model was ignored. Objective function values prior to this fix were therefore incorrect (except for the case where there was no multiplicative term). However, this bug did not affect actual reconstructed images.
  (In addition, the computation of the objective function now has increased numerical accuracy.)
- the MPI support for OSMAPOSL introduced in STIR 2.0 was broken (it did not compile, and needed some fixes before obtaining the correct result).

### Known problems

- ECAT6 routines seem to have problems since STIR 2.0. ECAT6 is therefore no longer supported
- The interpolating back-projector can still give problems in the centre of the images on some architectures/compiler/optimisation settings. We recommend to use the ray-tracing matrix (with additional rays) instead.
- When using Visual Studio (Express) with the provided solution files, there is a linking problem for some utilities. It is recommended to use the new `CMake` files for building instead.
- Some of the new list mode files might not compile with Visual Studio (Express).

### New utilities

- `abs_image`, `convert_to_binary_image`, `find_fwhm_in_image`, `list_detector_and_bin_info`.
- Utilities in `modelling_utilities`.
- Parametric image reconstruction algorithms `POSMAPOSL` and `POSSPS`. Currently we have only an objective function for Patlak, but extension to other linear models is easy.
- New utilities in `listmode_utilities`: `lm_to_projdata_bootstrap` (useful to generate multiple realisations from a single list mode file to study variance), `list_lm_events` and `lm_fansums` (useful for developing normalization code).
- A few scripts are now also copied with `make install`, including the new `stir_print_voxel_sizes.sh`.

### New functionality of existing utilities

- Added data for the GE Discovery 600.
- Added data for the Biograph 16 (by Robert Barnett, Westmead Hospital, Sydney).
- `stir_math` has 2 new options `--parametric` or `--dynamic`.
- `OSMAPOSL` and `OSSPS` have a new "subset sensitivity filenames" which can be set to e.g. `subsens_%d.hv`. This is useful when `use_subset_sensitivities` is set (which is now recommended).
- `OSMAPOSL` now accepts a prior even if `use_subset_sensitivities` is set.
- In addition to `OSMAPOSL`, `OSSPS` is now also parallelised when using MPI.

### Functionality changes

- The ray tracing projection matrix can be enabled (at compile time) to use a circular FOV that goes to the edge of the image (i.e. approx one pixel larger than what it used to be). However, enabling this gave a change in the `recon_test_pack` results (probably mostly because that data contains scatter, while the `recon_test_pack` code does not model scatter). Therefore, this change is disabled by default. You can add `-DSTIR_PMRT_LARGER_FOV` to `EXTRA_CFLAGS` if you want this anyway.
- Most utilities will now display a somewhat involved message when an error occured. Exact format will be system/compiler dependent, but could be something like

      ERROR: Error opening file test.hv

      terminate called after throwing an instance of 'std::string'
      Aborted (core dumped)

  The useful bit is after the `ERROR` string. Ignore the rest (see here why this happens).

### Documentation changes

- updated doxygen and User's Guide

### recon_test_pack changes

- Moved the tests for the ecat routines to a separate file `run_ecat_tests.sh`
- Created a new script `run_test_simulate_and_recon.sh` that performs a simple analytic simulation of a uniform cylinder, reconstructs it with all STIR reconstruction algorithms and checks ROI values.
- Updated Windows batch files. They were broken in STIR 2.0

### Other changes to tests

- A new test in `recon_test` checks the gradient computation vs a numerical gradient by computing the objective function. This is currently only enabled for `PoissonLogLikelihoodWithLinearModelForMeanAndProjData`.

## What's new for developers (aside from what should be obvious from the above):

### Major bugs fixed

- `ProjData::set_segment` was always writing the same data (namely the one where view_num=segment_num). This bug existed since the very first version of STIR. Nobody seems to have been using this function, as the result was obviously wrong.
- The objective function values were computed ignoring multiplicative corrections and background terms.
- The ECAT962 and 966 list mode event functions `get_detection_coordinates()` and `get_LOR()` returned coordinates in a different coordinate system as expected (z=0 was in the first ring of the scanner as opposed to the centre of the scanner). These functions were not used by the rest of STIR however.

### Major revision of the listmode classes

These are now ready for data from non-CTI scanners.

- `CListEvent::get_detection_coordinates()` no longer exists (use `get_LOR` instead).
- `CListTime::get/set_gating` have been moved to new `CListGatingInput` class as not all scanners have gating related info in the timing event.
- `CListRecordUsingUnion` and `CListModeDataFromStream` no longer exist. The IO functionality of the latter is now in the new (more generic) class `InputStreamWithRecords`.

### New functionality

- `ArrayFilter2DUsingConvolution` and `ArrayFilter3DUsingConvolution`.
- Preliminary classes for dynamic and gated data
- New member `fill_nonidentifiable_target_parameters` of the `GeneralisedObjectiveFunction` hierarchy. This used by OSSPS to avoid problems when initialising with images that have for instance been reconstructed on a square grid.
- B-spline interpolation functions and a few numerical algorithms (IIR and FIR filters, 1d numerical integration).

### Other code changes

- `error()` now throws an exception as opposed to calling exit, such that we can catch the exception in a calling routine. This would be essential for building GUIs etc. Unfortunately, for the user this has the potential to generate some confusion as the error message when a STIR program calls `error()` now talks about unhandled exception. The best way to solve this would be to catch all exceptions in each `main()`, but that is a lot of work...
- `ProjDataInfoCylindrical::set_num_views()` now makes sure that we cover the same range of angles as before (usually, but not necessarily, 180 degrees).
- `PoissonLogLikelihoodWithLinearModelForMean` has been changed to be more consistent in the subset sensitivity interface:
  - The parser has a new keyword `subset sensitivity filenames` which can be set to e.g. `subsens_%d.hv`
  - Derived classes have to define a virtual function `set_up_before_sensitivity()` (essentially replacing what they used to have in `setup()` before, except for the call to `base_type::setup()`).
  - `setup()` now class `set_up_before_sensitivity()`, computes (subset)sensitivities, and if required, writes them to disk.
  - `get_sensitivity(subset_num)` is replaced by `get_sensitivity()` and `get_subset_sensitivity(subset_num)`
  - `set_sensitivity_sptr` is now called `set_subset_sensitivity_sptr`
  - `fill_nonidentifiable_target_parameters` uses `get_sensitivity()` and hence no longer only checks the first subset.
- Most of the .cxx files in the `recon_buildblock` had to be updated to add instantiations for parametric images. This is unfortunate and another mechanism would be nicer.
- moved code that finds subset-num in terms of subiteration-num to `IterativeReconstruction::get_subset_num()`. If you have your own reconstruction classes, you should use this member. `IterativeReconstruction::randomly_permute_subset_order()` is now private.
- `read_stream_in_memory` (in `utilities.h`) now takes a `file_size` argument of type `std::streamsize` as opposed to `unsigned long`. As this parameter is passed as a reference, this change is not backwards compatible (at least on systems where these 2 types are not equal).
- `FullArrayIterator` and `NestedIterator` now have extra constructors to be able to convert compatible iterators (e.g. `full_iterator` to `const_full_iterator`).
- `NestedIterator` has more help classes for cases where the top-level iterator refers to a pointer to the 2nd level iterator.
- Various small fixes for more recent compilers such as gcc 4.3 and Visual Studio Express 2010.
- Initial release of files for an alternative cross-platform build system CMake, based on example files provided by Robert Barnett (Westmead Hospital, Sydney). This is much better for configuration and finding system dependencies. However, tests are not yet included in the CMakeFiles.