Developer¶
Below are a few introductory notes for anyone who wants to compile QUIT from source or might be interested in contributing to QUIT. Although I hope that most QUIT code is fairly clear, the following is provided to give a high-level overview of how most QUIT commands are structured.
Basic Requirements¶
- A C++17 compliant compiler (GCC 7.0.0+, Clang 3.9+)
- CMake version 3.10.2 or higher (http://www.cmake.org)
WARNING - You will require a recent compiler for QUIT as it uses C++17 features. On Mac simply having the most recent software updates is enough, on Linux you will need GCC 7.0.0. No one has been brave enough to compile QUIT on Windows to date.
Installing GCC 7¶
Most Linux systems currently ship with GCC 4.8 or lower as their system compiler. As of QUIT 2.1 you will require GCC 7 as QUIT uses C++17 features. Joost Kuijer has kindly provided the following recipe for installing newer GCC versions in a user directory and using it to compile QUIT.
Follow the GCC guide here: https://gcc.gnu.org/wiki/InstallingGCC
- Before running the
build.sh
script let cmake know about the new compiler export PATH=$HOME/GCC-7.0.0/bin:$PATH export LD_LIBRARY_PATH=$HOME/GCC-7.0.0/lib:$HOME/GCC-7.0.0/lib64:$LD_LIBRARY_PATH export CC=$HOME/GCC-7.0.0/bin/gcc export CXX=$HOME/GCC-7.0.0/bin/g++
- Before running the
- Before executing the compiled code also do (you can add this line to your .bashrc file:
export LD_LIBRARY_PATH=$HOME/GCC-7.0.0/lib:$HOME/GCC-7.0.0/lib64:$LD_LIBRARY_PATH
External Libraries¶
QUIT is built using several C++ libraries. These are currently included in the project as git submodules. The easiest way to initialise these is with the build.sh
script. However, if you are already have some of them available you may wish to not run the script and instead configure them yourself. This is discussed further below. The libraries are:
-
A high performace linear algebra library. Used for all signal equations in QUIT.
-
A high performace, high quality collection of non-linear least squares solvers.
-
The Insight Tool-Kit. This is intended as a registration library for medical images. Although the registration features are not used in QUIT, the overall framework is extremely useful. In particular, ITK reads a large variety of common file-formats, and all ITK filters automatically check that their inputs share a common space / co-ordinate definition. This single feature alone prevents the vast majority of easy user mistakes - e.g. trying to use a B1 map that has a different voxel spacing to the input data.
Compilation¶
If you are unfamiliar with C++/CMake/git etc. a script is provided that should be able to build the tools provided the right software is available on your system. To use it, in a terminal window, change directory to where you unpacked QUIT. Then type ./build.sh
. This should correctly checkout the git repositories for each external library, build Ceres and ITK, and then configure and build QUIT.
CMake projects separate the build
and install
phases. The binaries are only moved to a single folder during install
. By default, the install directory is /usr/local/bin
. If you run ./build.sh -i``it will run the install step to this directory. You can also ``cd
into the build/
directory and then type make install
(or ninja install
) to avoid re-running the entire build.sh
script.
If you want to change where the binaries are installed, you can either:
- Run ./build.sh -i -p /path/to/install
- cd /build; ccmake ./
, change the INSTALL_PREFIX_DIR
, configure (press c), generate (press g), exit, then make install
Note that the binaries will end up in /bin
inside the install prefix.
If you are familiar with C++/CMake/git etc. then compiling QUIT should be straightforward. The rough steps are:
- Ensure you have all the libraries above available. If you do not have system versions, then run
git submodule init; git submodule update
in the QUIT directory. - Compile the Ceres library. Make sure it uses the same version of Eigen that you will use for QUIT.
- Compile ITK following their instructions.
- Create a build directory for QUIT and use cmake/ccmake to configure the project. Specify the paths to the library when prompted. It is likely that CMake will report an error on the first ‘Configure’ attempt if it cannot locate Eigen, specify the correct directory and run the configure step again.
- Compile QUIT.
File Formats¶
The available file formats are controlled by the main CMakeLists.txt
in the root QUIT directory, by listing them as COMPONENTS
in the ITK find_package()
step. Add any additional file formats you wish to use here.
Tests¶
QUIT commands are tested using the nipype
wrappers and unittest
. To run the tests, first build and install QUIT
(so that the executables are available in your $PATH
variable), then cd
into Python/Tests
and then run python -m unittest discover
, which will run all of the tests. It is possible to run the test files individually as well.
Most QUIT commands are tested by generating ground-truth parameter files with qi newimage
, feeding these into each QUIT
command with the --simulate
argument to generate simulated MR images with added noise, and then running them back through the QUIT
command to calculate the parameter maps, and comparing these to the ground-truth with qi diff
. qi diff
calculates a figure-of-merit based on noise factors, i.e. they are a measure of how much the signal noise is amplified in the final maps. In this way the tests also serve to illustrate the quality of the methods as well as whether the commands run correctly. For commands where a ground-truth image cannot be generated easily, the tests at least ensure that the command runs and does not crash.
The ModelFitFilter¶
The core part of QUIT is the ModelFitFilter
and its dependent type FitFunction
, found in Source/Core/
. This is a sub-class of the ITK ImageToImageFilter
. The vast majority of QUIT commands declare an Model and FitFunction sub-class and use these to process the data. ModelFitFilter
abstracts out most of the heavy lifting of extracting voxel-wise data from multiple inputs and writing it out to multiple outputs, leaving the FitFunction
to process a single-voxel. A Model
defines the number of expected inputs and their size, the number of fixed & varying parameters, and the number of outputs.
Example: qi despot1
¶
The structure of qi despot1
is similar to most QUIT commands, and is a good example of most features. At the start are the includes (obviously). After that several FitFunction
subclasses are defined, as well as a Ceres cost-function. The Ceres documentation is excellent, so refer to that for more information. After all the FitFunction
classes are defined, the main command body begins. At the start of the command, all the command-line options are defined and then parsed. Then the various inputs are read and passed to the ModelFitFilter
, which is then updated. Finally, the outputs are written back to disk.