ConeBeamGeometry.src_position

ConeBeamGeometry.src_position(angle)[source]

Return the source position at angle.

For an angle phi, the source position is given by

src(phi) = translation +
           rot_matrix(phi) * (-src_rad * src_to_det_init) +
           (offset_along_axis + pitch * phi) * axis +
           source_shift(phi)

where src_to_det_init is the initial unit vector pointing from source to detector and

source_shift(phi) = rot_matrix(phi) *
                    (shift1 * (-src_to_det_init) +
                    shift2 * cross(src_to_det_init, axis))
                    shift3 * axis
Parameters:
anglefloat or array-like

Angle(s) in radians describing the counter-clockwise rotation of the detector.

Returns:
posnumpy.ndarray, shape (3,) or (num_angles, 3)

Vector(s) pointing from the origin to the source position. If angle is a single parameter, the returned array has shape (3,), otherwise angle.shape + (3,).

See also

det_refpoint

Examples

With default arguments, the source starts at src_rad * (-e_y) and rotates to src_rad * e_x + pitch/4 * e_z at 90 degrees:

>>> apart = odl.uniform_partition(0, 4 * np.pi, 10)
>>> dpart = odl.uniform_partition([-1, -1], [1, 1], (20, 20))
>>> geom = ConeBeamGeometry(
...     apart, dpart, src_radius=5, det_radius=10, pitch=2)
>>> geom.src_position(0)
array([ 0., -5.,  0.])
>>> np.allclose(geom.src_position(np.pi / 2), [5, 0, 0.5])
True

The method is vectorized, i.e., it can be called with multiple angles at once:

>>> points = geom.src_position([0, np.pi / 2])
>>> np.allclose(points[0], [0, -5, 0])
True
>>> np.allclose(points[1], [5, 0, 0.5])
True
>>> geom.src_position(np.zeros((4, 5))).shape
(4, 5, 3)

Specifying flying focal spot:

>>> apart = odl.uniform_partition(0, 2 * np.pi, 4)
>>> geom = ConeBeamGeometry(
...     apart, dpart,
...     src_radius=1, det_radius=5,
...     src_shift_func=lambda angle: odl.tomo.flying_focal_spot(
...         angle, apart=apart, shifts=[(0, 0.1, 0), (0, 0, 0.1)]),
...     src_to_det_init=(-0.71, 0.71, 0))
>>> geom.angles
array([ 0.78539816,  2.35619449,  3.92699082,  5.49778714])
>>> np.round(geom.src_position(geom.angles), 2)
array([[ 1. ,  0.1,  0. ],
       [ 0. ,  1. ,  0.1],
       [-1. , -0.1,  0. ],
       [-0. , -1. ,  0.1]])