2D Geometries

Volume geometry

Create a 2D volume geometry:

vol_geom = astra.create_vol_geom(n_rows_and_cols)
vol_geom = astra.create_vol_geom((n_rows, n_cols))
vol_geom = astra.create_vol_geom(n_rows, n_cols)

In the first form, the volume contains an equal number of rows and columns. In the first, second and third forms, voxels are squares with sides of unit length, and the volume is centered around the origin.

Specify the extent of the 2D volume (note that rows are oriented along the Y axis and columns along the X axis):

vol_geom = astra.create_vol_geom(
    n_rows, n_cols,
    min_x, max_x,
    min_y, max_y
)

This can be used to control the voxel size, including specifying anisotropic voxels.

Warning

The 2D CUDA algorithms expect the volume to be centered around the origin and pixels to be square. This is not always explicitly checked in all functions, so not following these requirements may have unpredictable results.

Projection geometries

parallel

Create a 2D parallel beam geometry:

proj_geom = astra.create_proj_geom('parallel', det_spacing, det_count, angles)
  • det_spacing : distance between the centers of two adjacent detector elements

  • det_count : number of detector elements in a single projection

  • angles : projection angles in radians

fanflat

Create a 2D flat fan beam geometry:

proj_geom = astra.create_proj_geom('fanflat', det_spacing, det_count, angles, source_origin_distance, origin_detector_distance)
  • det_spacing : distance between the centers of two adjacent detector elements

  • det_count : number of detector elements in a single projection

  • angles : projection angles in radians

  • source_origin_distance : distance between the source and the center of rotation

  • origin_detector_distance : distance between the center of rotation and the detector array

parallel_vec

Create a 2D parallel beam geometry specified by 2D vectors:

proj_geom = astra.create_proj_geom('parallel_vec', det_count, vectors)
  • det_count : number of detector elements in a single projection

  • vectors : a matrix defining the geometry

Each row of vectors corresponds to a single projection, and consists of:

( dirX, dirY, dX, dY, uX, uY )
  • dir : the illumination direction

  • d : the detector center coordinate

  • u : the vector between the centers of detector elements 0 and 1

To illustrate this, here is a script to convert a single projection in a geometry of type “parallel” into such a 6-element row:

# ray direction
vectors[i,0] = numpy.sin(proj_geom['ProjectionAngles'][i])
vectors[i,1] = -numpy.cos(proj_geom['ProjectionAngles'][i])

# center of detector
vectors[i,2] = 0
vectors[i,3] = 0

# vector from detector element 0 to 1
vectors[i,4] = numpy.cos(proj_geom['ProjectionAngles'][i]) * proj_geom['DetectorWidth']
vectors[i,5] = numpy.sin(proj_geom['ProjectionAngles'][i]) * proj_geom['DetectorWidth']

This conversion is also available as a function in the toolbox:

proj_geom_vec = astra.geom_2vec(proj_geom)

fanflat_vec

Create a 2D flat fan beam geometry specified by 2D vectors:

proj_geom = astra.create_proj_geom('fanflat_vec', det_count, vectors)
  • det_count : number of detector elements in a single projection

  • vectors : a matrix defining the geometry

Each row of vectors corresponds to a single projection, and consists of:

( srcX, srcY, dX, dY, uX, uY )
  • src : the illumination source position

  • d : the detector center coordinate

  • u : the vector between the centers of detector elements 0 and 1

To illustrate, this is a script to convert a single projection in a geometry of type “fanflat” into such a 6-element row:

# source
vectors[i,0] = numpy.sin(proj_geom['ProjectionAngles'][i]) * proj_geom['DistanceOriginSource']
vectors[i,1] = -numpy.cos(proj_geom['ProjectionAngles'][i]) * proj_geom['DistanceOriginSource']

# center of detector
vectors[i,2] = -numpy.sin(proj_geom['ProjectionAngles'][i]) * proj_geom['DistanceOriginDetector']
vectors[i,3] = numpy.cos(proj_geom['ProjectionAngles'][i]) * proj_geom['DistanceOriginDetector']

# vector from detector element 0 to 1
vectors[i,4] = numpy.cos(proj_geom['ProjectionAngles'][i]) * proj_geom['DetectorWidth']
vectors[i,5] = numpy.sin(proj_geom['ProjectionAngles'][i]) * proj_geom['DetectorWidth']

This conversion is also available as a function in the toolbox:

proj_geom_vec = astra.geom_2vec(proj_geom)

sparse_matrix

Create a 2D projection geometry defined by its system matrix:

proj_geom = astra.create_proj_geom('sparse_matrix', det_width, det_count, angles, matrix_id)
  • det_width : unused, but has to be present (for compatibility reasons)

  • det_count : number of detectors in a single projection

  • angles : a vector, the length of which is the number of projections. The contents are unused.

  • matrix_id : a astra.matrix/astra_mex_matrix object ID of a sparse matrix of the right dimensions.

The matrix is an ID returned by

matrix_id = astra.matrix.create(scipy_sparse_csr_matrix)

The sparse matrix must be of size (det_count * numel(angles), x*y), where (x,y) is the size of the volume geometry to be used.

The rows of the sparse matrix are ordered by projection: The first row of the matrix corresponds to the first detector pixel of the first projection, and the second row of the matrix corresponds to the second detector pixel of the first projection.

The columns of the sparse matrix are ordered by row: The first column of the matrix corresponds to pixel (0,0) in Python (which is (1,1) in MATLAB) and the second column to pixel (0,1) in Python (which is (1,2) in MATLAB) in the volume.