ConeBeamGeometry¶
- class odl.tomo.geometry.conebeam.ConeBeamGeometry(apart, dpart, src_radius, det_radius, det_curvature_radius=None, pitch=0, axis=(0, 0, 1), src_shift_func=None, det_shift_func=None, **kwargs)[source]¶
Bases:
DivergentBeamGeometry,AxisOrientedGeometryCone beam geometry with circular/helical source curve.
The source moves along a spiral oriented along a fixed
axis, with radiussrc_radiusin the azimuthal plane and a givenpitch. The detector reference point is opposite to the source, i.e. in the point at distancesrc_rad + det_radon the line in the azimuthal plane through the source point andaxis.The motion parameter is the 1d rotation angle parameterizing source and detector positions simultaneously.
In the standard configuration, the rotation axis is
(0, 0, 1), the initial source-to-detector vector is(0, 1, 0), and the initial detector axes are[(1, 0, 0), (0, 0, 1)].For details, check the online docs.
- Attributes:
anglesDiscrete angles given in this geometry.
axisNormalized axis of rotation, a 3d vector.
check_boundsIf
True, methods computing vectors check input arguments.det_axes_initInitial axes defining the detector orientation.
det_curvature_radiusDetector curve radius of this geometry.
det_gridSampling grid of
det_params.det_paramsContinuous detector parameter range, an
IntervalProd.det_partitionPartition of the detector parameter set into subsets.
det_radiusDetector circle radius of this geometry.
det_shift_funcDetector shifts in the geometry.
detectorDetector representation of this geometry.
gridJoined sampling grid for motion and detector.
implementation_cacheDictionary acting as a cache for this geometry.
motion_gridSampling grid of
motion_params.motion_paramsContinuous motion parameter range, an
IntervalProd.motion_partitionPartition of the motion parameter set into subsets.
ndimNumber of dimensions of the geometry.
offset_along_axisScalar offset along
axisatangle=0.paramsJoined parameter set for motion and detector.
partitionJoined parameter set partition for motion and detector.
pitchConstant vertical distance traversed in a full rotation.
src_radiusSource circle radius of this geometry.
src_shift_funcSource shifts in the geometry.
src_to_det_initInitial state of the vector pointing from source to detector reference point.
translationShift of the origin of this geometry.
Methods
det_axes(angle)Return the detector axes tuple at
angle.det_point_position(mparam, dparam)Return the detector point at
(mparam, dparam).det_refpoint(angle)Return the detector reference point position at
angle.det_to_src(angle, dparam[, normalized])Vector or direction from a detector location to the source.
frommatrix(apart, dpart, src_radius, ...[, ...])Create an instance of
ConeBeamGeometryusing a matrix.rotation_matrix(angle)Return the rotation matrix to the system state at
angle.src_position(angle)Return the source position at
angle.- __init__(apart, dpart, src_radius, det_radius, det_curvature_radius=None, pitch=0, axis=(0, 0, 1), src_shift_func=None, det_shift_func=None, **kwargs)[source]¶
Initialize a new instance.
- Parameters:
- apart1-dim.
RectPartition Partition of the angle interval.
- dpart2-dim.
RectPartition Partition of the detector parameter rectangle.
- src_radiusnonnegative float
Radius of the source circle.
- det_radiusnonnegative float
Radius of the detector circle. Must be nonzero if
src_radiusis zero.- det_curvature_radius2-tuple of nonnegative floats, optional
Radius or radii of the detector curvature. If
None, a flat detector is used. If(r, None)or(r, float('inf')), a cylindrical detector is used. If(r1, r2), a spherical detector is used.- pitchfloat, optional
Constant distance along
axisthat a point on the helix traverses when increasing the angle parameter by2 * pi. The default casepitch=0results in a circular cone beam geometry.- axis
array-like, shape(3,), optional Vector defining the fixed rotation axis of this geometry.
- src_shift_funccallable, optional
Function with signature
src_shift_func(angle) -> shiftreturning a source shift for a given angle. Each shift is interpreted as a vector[shift_d, shift_t, shift_r], where "d", "t" and "r" denote shifts along the following directions: detector-to-source, tangent to the rotation (projected on plane perpendicular to rotation axis), rotation axis.- det_shift_funccallable, optional
Function with signature
det_shift_func(angle) -> shiftreturning a detector shift for a given angle. Each shift is interpreted as a vector[shift_d, shift_t, shift_r], where "d", "t" and "r" denote shifts along the following directions: source-to-detector, tangent to the rotation (projected on plane perpendicular to rotation axis), rotation axis.
- apart1-dim.
- Other Parameters:
- offset_along_axisfloat, optional
Scalar offset along the
axisatangle=0, i.e., the translation along the axis at angle 0 isoffset_along_axis * axis. Default: 0.- src_to_det_init
array-like, shape(3,), optional Initial state of the vector pointing from source to detector reference point. The zero vector is not allowed. The default depends on
axis, see Notes.- det_axes_initlength-2-sequence of
array-like's, optional Initial axes defining the detector orientation, provided as arrays with shape
(3,). Default: depends onaxis, see Notes.- translation
array-like, shape(3,), optional Global translation of the geometry. This is added last in any method that computes an absolute vector, e.g.,
det_refpoint, and also shifts the axis of rotation. Default:(0, 0, 0)- check_boundsbool, optional
If
True, methods computing vectors check input arguments. Checks are vectorized and add only a small overhead. Default:True
Notes
In the default configuration, the rotation axis is
(0, 0, 1), the initial source-to-detector direction is(0, 1, 0), and the default detector axes are[(1, 0, 0), (0, 0, 1)]. If a differentaxisis provided, the new default initial position and the new default axes are the computed by rotating the original ones by a matrix that transforms(0, 0, 1)to the new (normalized)axis. This matrix is calculated with therotation_matrix_from_tofunction. Expressed in code, we haveinit_rot = rotation_matrix_from_to((0, 0, 1), axis) src_to_det_init = init_rot.dot((0, 1, 0)) det_axes_init[0] = init_rot.dot((1, 0, 0)) det_axes_init[1] = init_rot.dot((0, 0, 1))
Examples
Initialization with default parameters and some (arbitrary) choices for pitch and radii:
>>> 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.]) >>> geom.det_refpoint(0) array([ 0., 10., 0.]) >>> np.allclose(geom.src_position(2 * np.pi), ... geom.src_position(0) + (0, 0, 2)) # z shift by pitch True
Checking the default orientation:
>>> geom.axis array([ 0., 0., 1.]) >>> geom.src_to_det_init array([ 0., 1., 0.]) >>> geom.det_axes_init array([[ 1., 0., 0.], [ 0., 0., 1.]])
Specifying curvature of the cylindrical detector:
>>> apart = odl.uniform_partition(0, 4 * np.pi, 10) >>> dpart = odl.uniform_partition( ... [-np.pi / 2, -1], [np.pi / 2, 1], (20, 20)) >>> geom = ConeBeamGeometry(apart, dpart, ... src_radius=5, det_radius=10, det_curvature_radius=(10, None)) >>> # (10*sin(pi/2), 10*cos(pi/2), 1) >>> np.round(geom.det_point_position(0, [ np.pi / 2, 1] ), 2) array([ 10., 0., 1.])
Specifying curvature of the spherical detector:
>>> apart = odl.uniform_partition(0, 4 * np.pi, 10) >>> dpart = odl.uniform_partition([-np.pi / 2, -np.pi / 4], ... [ np.pi / 2, np.pi / 4], (20, 20)) >>> geom = ConeBeamGeometry(apart, dpart, ... src_radius=5, det_radius=10, det_curvature_radius=(10, 10)) >>> # 10*( cos(pi/4), 0, sin(pi/4)) >>> np.round(geom.det_point_position(0, [ np.pi / 2, np.pi / 4] ), 2) array([ 7.07, 0. , 7.07])
Specifying an axis by default rotates the standard configuration to this position:
>>> e_x, e_y, e_z = np.eye(3) # standard unit vectors >>> geom = ConeBeamGeometry( ... apart, dpart, src_radius=5, det_radius=10, pitch=2, ... axis=(0, 1, 0)) >>> np.allclose(geom.axis, e_y) True >>> np.allclose(geom.src_to_det_init, -e_z) True >>> np.allclose(geom.det_axes_init, (e_x, e_y)) True >>> geom = ConeBeamGeometry( ... apart, dpart, src_radius=5, det_radius=10, pitch=2, ... axis=(1, 0, 0)) >>> np.allclose(geom.axis, e_x) True >>> np.allclose(geom.src_to_det_init, e_y) True >>> np.allclose(geom.det_axes_init, (-e_z, e_x)) True
The initial source-to-detector vector and the detector axes can also be set explicitly:
>>> geom = ConeBeamGeometry( ... apart, dpart, src_radius=5, det_radius=10, pitch=2, ... src_to_det_init=(-1, 0, 0), ... det_axes_init=((0, 1, 0), (0, 0, 1))) >>> np.allclose(geom.axis, e_z) True >>> np.allclose(geom.src_to_det_init, -e_x) True >>> np.allclose(geom.det_axes_init, (e_y, e_z)) True
Specifying a flying focal spot and detector offset:
>>> 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)]), ... det_shift_func=lambda angle: [0.0, 0.05, 0.03]) >>> geom.src_shift_func(geom.angles) array([[ 0. , 0.1, 0. ], [ 0. , 0. , 0.1], [ 0. , 0.1, 0. ], [ 0. , 0. , 0.1]]) >>> geom.det_shift_func(geom.angles) [0.0, 0.05, 0.03]