C++ Cuda CMake Python
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.



Tomos is a library with many tools for tomographic reconstruction, with the following features:

  • Modular system, where projectors, geometries, volumes and algorithmic skeletons are all independent and can be mixed and matched.
  • Tomos supports a general model for distributed computing, enabling the resulting algorithms to run on clusters
  • It is not bound to CUDA, MATLAB, or Python, although Python bindings and GPU computing are supported
  • Written in modern C++, with OO / generic programming style like STL, enabling abstractions without performance penalties.
  • It has efficient CPU implementations for the algorithms.
  • Support for 2D, 3D or higher dimensional reconstructions.

Code example

Reconstructing a Shepp-Logan phantom using SIRT:

#include "tomos/tomos.hpp"

int main() {
    using T = float;
    constexpr tomo::dimension D = 2_D;

    int size = 128;
    auto v = tomo::volume<D, T>(size);
    auto g = tomo::geometry::parallel<D, T>(v, size, size);
    auto f = tomo::modified_shepp_logan_phantom<T>(v);
    auto k = tomo::dim::joseph<D, T>(v);
    auto p = tomo::forward_projection<D, T>(f, g, k);

    auto x = tomo::reconstruction::sirt(v, g, k, p);


The following libraries are required:


  • glm header only mathematics library mimicking GLSL
  • boost::program_options for portable program options
  • (optional) zeromq for communicating with visualization servers
  • (optional) boost::hana is used to generate the Python bindings.
  • (optional) CUDA (>= 7.0)

Provided as submodules

  • Catch, for unit tests
  • fmt as an iostream replacement
  • bulk for distributed computing
  • cpptoml for reading specification and configuration files
  • (optional) RECAST3D as an visualization server
  • (optional) pybind11 to generate Python bindings

The following build tools should be available:

  • CMake (>= 3.0)
  • Modern C++ compiler (with support for at least C++17), e.g. GCC >= 7.0 or clang >= 4.0

The library is being tested on Fedora 24 and Arch Linux, but the code should be portable to other platforms.



The core of the library is header only, so it does not have to be built itself. We start with initializing the submodules:

git submodule init
git submodule update --remote

To build the examples:

cd build
cmake ..

The resulting binaries will be in the bin folder.

Building the Python bindings

To generate the Python bindings:

cd python/build
cmake .

The Python bindings can be used through tomo.py in the Python folder, which also adds some rudimentary plotting functionality on top of the bindings.

Building with optional features

To build with ZMQ (and MPI), run instead of cmake .:

cmake -DWITH_MPI=on -DWITH_ZMQ=on .

CUDA support is experimental and has no public build interface.

Writing your own algorithms


First of all, have a look at the examples provided in the examples folder.

There are four core components that are used for reconstruction:

  • tomo::volume represents the volume geometry, i.e. the part of space in which the image object resides.
  • tomo::dim is the namespace for the 'discrete integration methods' (also called interpolators, projectors or kernels).
    • closest projects any point on the ray to the closest voxel
    • linear does D-dimensional linear interpolation around the ray point to the surrounding voxels
    • joseph does (D-1) dimensional linear interpolation by considering points on the ray that have integer coordinates in one fixed dimension.
  • tomo::geometry is the namespace for the various acquisition geometries
    • cone_beam
    • dual_axis_parallel
    • dynamic_cone_beam
    • fan
    • helical_cone_beam
    • laminography
    • list is a list of lines without any implied stucture.
    • parallel<2_D>
    • parallel<3_D>
    • tomosynthesis
    • trajectory is the base class for cone-beam-like geometries where the source and the (position and tilt of the) detector follow a given path.
  • tomo::image represents the image data, there is only one phantom
    • shepp_logan<2_D>
    • shepp_logan<3_D>
    • modified_shepp_logan<2_D>
    • modified_shepp_logan<3_D>

These can be used together completely independently. The reason is that we take the following approach to these concepts:

  • A geometry acts as nothing more than a container of lines, so you can write:
for (auto line : geometry) {
    // use line
  • A discrete integration method takes a line, and produces a number of 'matrix elements', that contain the voxel (as an index), and the attenuation coefficient (value of the matrix element):
for (auto element : projector(line)) {
    // element.index is the voxel
    // element.value is the coefficient

Using this approach, many interesting algorithms can be written in an efficient but flexible manner.

There are also some standard algorithms implemented, including ART, SART, and SIRT.


The Python bindings expose the different concepts (images, volumes, geometries and dims) as well as the standard implemented algorithms.