Skip to content

Commit 577b516

Browse files
committed
ENH: add VecGeometry.__getitem__
1 parent 9704744 commit 577b516

File tree

1 file changed

+71
-2
lines changed

1 file changed

+71
-2
lines changed

odl/tomo/geometry/geometry.py

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@
1616
from odl.tomo.geometry.detector import Detector, Flat1dDetector, Flat2dDetector
1717
from odl.tomo.util import axis_rotation_matrix, is_inside_bounds
1818
from odl.util import (
19-
normalized_scalar_param_list, safe_int_conv, signature_string_parts,
20-
repr_string, REPR_PRECISION, npy_printoptions)
19+
normalized_scalar_param_list, normalized_index_expression,
20+
safe_int_conv, signature_string_parts, repr_string, REPR_PRECISION,
21+
npy_printoptions, array_str)
2122

2223

2324
__all__ = ('Geometry', 'DivergentBeamGeometry', 'AxisOrientedGeometry',
@@ -1046,6 +1047,74 @@ def det_axes(self, index):
10461047
det_v = det_v_left + frac_part * (det_v_right - det_v_left)
10471048
return (det_u, det_v)
10481049

1050+
def __getitem__(self, indices):
1051+
"""Return ``self[indices]``.
1052+
1053+
The returned geometry is the vec geometry gained by slicing
1054+
`vectors` with the given ``indices`` along the first axis and
1055+
using the original `det_shape`.
1056+
1057+
Parameters
1058+
----------
1059+
indices : index expression
1060+
Object used to slice `vectors` along the first axis.
1061+
1062+
1063+
Raises
1064+
------
1065+
ValueError
1066+
If ``indices`` slices along other axes than the first.
1067+
1068+
Examples
1069+
--------
1070+
>>> vecs_2d = [[0, 1, 0, 1, 1, 0],
1071+
... [0, 1, 0, 1, -1, 0],
1072+
... [-1, 0, -1, 0, 0, 1],
1073+
... [-1, 0, -1, 0, 0, -1]]
1074+
>>> det_shape = (10,)
1075+
>>> geom = odl.tomo.ParallelVecGeometry(det_shape, vecs_2d)
1076+
>>> geom[0] # first angle only
1077+
ParallelVecGeometry((10,), array([[ 0., 1., 0., 1., 1., 0.]]))
1078+
>>> geom[:3] # first 3 angles
1079+
ParallelVecGeometry(
1080+
(10,),
1081+
array([[ 0., 1., 0., 1., 1., 0.],
1082+
[ 0., 1., 0., 1., -1., 0.],
1083+
[-1., 0., -1., 0., 0., 1.]])
1084+
)
1085+
>>> geom[::2] # every second angle, starting at the first
1086+
ParallelVecGeometry(
1087+
(10,),
1088+
array([[ 0., 1., 0., 1., 1., 0.],
1089+
[-1., 0., -1., 0., 0., 1.]])
1090+
)
1091+
>>> geom[[0, -1]] # first and last
1092+
ParallelVecGeometry(
1093+
(10,),
1094+
array([[ 0., 1., 0., 1., 1., 0.],
1095+
[-1., 0., -1., 0., 0., -1.]])
1096+
)
1097+
"""
1098+
# Index vectors and make sure that we still have a valid shape
1099+
# for ASTRA vecs of the same type
1100+
sub_vecs = self.vectors[indices]
1101+
if np.isscalar(sub_vecs) or not hasattr(sub_vecs, 'shape'):
1102+
raise ValueError(
1103+
'indexing of `vectors` results in scalar or non-array '
1104+
'(type {})'.format(type(sub_vecs)))
1105+
1106+
if sub_vecs.ndim == 1 and sub_vecs.shape[0] == self.vectors.shape[1]:
1107+
# Reduced to single vector, add missing dimension
1108+
sub_vecs = sub_vecs[None, :]
1109+
1110+
if sub_vecs.ndim != 2 or sub_vecs.shape[1] != self.vectors.shape[1]:
1111+
raise ValueError(
1112+
'indexing of `vectors` results in array of shape {0}, '
1113+
'expected (N, {1}) or ({1},)'
1114+
''.format(sub_vecs.shape, self.vectors.shape[1]))
1115+
1116+
return type(self)(self.detector.shape, sub_vecs)
1117+
10491118
def __repr__(self):
10501119
"""Return ``repr(self)``."""
10511120
posargs = [self.det_partition.shape, self.vectors]

0 commit comments

Comments
 (0)