Source code for odl.tomo.util.source_detector_shifts

# Copyright 2014-2020 The ODL contributors
#
# This file is part of ODL.
#
# This Source Code Form is subject to the terms of the Mozilla Public License,
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
# obtain one at https://mozilla.org/MPL/2.0/.

"""Source and detector shifts for divergent beam geometries."""

from __future__ import print_function, division, absolute_import
import numpy as np
from odl.discr.discr_utils import nearest_interpolator

__all__ = ('flying_focal_spot',)


[docs]def flying_focal_spot(angle, apart, shifts): """Flying focal spot shifts for divergent beam geometries. Shifts are defined only for grid points of angular partition. For all other angles nearest neighbor interpolation is used. Parameters ---------- angle : float or `array-like` Angle(s) in radians describing the counter-clockwise rotation of source and detector. apart : 1-dim. `RectPartition` Partition of the angle interval. shifts : sequence of `array-like` Each vectors in a sequence represent a subsequent shift relative to the default source position. Vector elements represent shifts along the following directions: det_to_src, tangent to the rotation (projected on a plane perpendicular to rotation axis), rotation axis. """ assert apart.ndim == 1 angle = np.array(angle, dtype=float, copy=False, ndmin=1) assert angle.ndim == 1 shifts = np.array(shifts, dtype=float, ndmin=2) if shifts.shape[1] not in [2, 3]: raise ValueError('Flying focal spot shifts must have ' 'shape (2,) or (3,), got {}'.format(shifts)) interpolator = nearest_interpolator(np.arange(apart.size), apart.coord_vectors) ind = interpolator(angle) k = len(shifts) result = [shifts[int(i) % k] for i in ind] return np.array(result, dtype=float, ndmin=2)