Skip to content

Commit b97e55c

Browse files
committed
enh: use 'deltas' name and documentation
1 parent db34949 commit b97e55c

File tree

2 files changed

+31
-20
lines changed

2 files changed

+31
-20
lines changed

nitransforms/nonlinear.py

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@
2626
class DenseFieldTransform(TransformBase):
2727
"""Represents dense field (voxel-wise) transforms."""
2828

29-
__slots__ = ("_field", "_displacements")
29+
__slots__ = ("_field", "_deltas")
3030

31-
def __init__(self, field=None, displacements=True, reference=None):
31+
def __init__(self, field=None, is_deltas=True, reference=None):
3232
"""
3333
Create a dense field transform.
3434
@@ -38,6 +38,17 @@ def __init__(self, field=None, displacements=True, reference=None):
3838
than displacements fields.
3939
SPM generally prefers deformations for that reason.
4040
41+
Parameters
42+
----------
43+
field : :obj:`numpy.array_like` or :obj:`nibabel.SpatialImage`
44+
The field of deformations or displacements (*deltas*). If given as a data array,
45+
then the reference **must** be given.
46+
is_deltas : :obj:`bool`
47+
Whether this is a displacements (deltas) field (default), or deformations.
48+
reference : :obj:`ImageGrid`
49+
Defines the domain of the transform. If not provided, the domain is defined from
50+
the ``field`` input.
51+
4152
Example
4253
-------
4354
>>> DenseFieldTransform(test_dir / "someones_displacement_field.nii.gz")
@@ -56,7 +67,7 @@ def __init__(self, field=None, displacements=True, reference=None):
5667
)
5768
else:
5869
self._field = np.zeros((*reference.shape, reference.ndim), dtype="float32")
59-
displacements = True
70+
is_deltas = True
6071

6172
try:
6273
self.reference = ImageGrid(
@@ -72,14 +83,14 @@ def __init__(self, field=None, displacements=True, reference=None):
7283
ndim = self._field.ndim - 1
7384
if self._field.shape[-1] != ndim:
7485
raise TransformError(
75-
"The number of components of the displacements (%d) does not match "
86+
"The number of components of the field (%d) does not match "
7687
"the number of dimensions (%d)" % (self._field.shape[-1], ndim)
7788
)
7889

79-
if displacements:
80-
self._displacements = self._field
81-
# Convert from displacements to deformations fields
82-
# (just add the origin to the displacements vector)
90+
if is_deltas:
91+
self._deltas = self._field
92+
# Convert from displacements (deltas) to deformations fields
93+
# (just add its origin to each delta vector)
8394
self._field += self.reference.ndcoords.T.reshape(self._field.shape)
8495

8596
def __repr__(self):
@@ -91,29 +102,29 @@ def map(self, x, inverse=False):
91102
Apply the transformation to a list of physical coordinate points.
92103
93104
.. math::
94-
\mathbf{y} = \mathbf{x} + D(\mathbf{x}),
105+
\mathbf{y} = \mathbf{x} + \Delta(\mathbf{x}),
95106
\label{eq:2}\tag{2}
96107
97-
where :math:`D(\mathbf{x})` is the value of the discrete field of displacements
98-
:math:`D` interpolated at the location :math:`\mathbf{x}`.
108+
where :math:`\Delta(\mathbf{x})` is the value of the discrete field of displacements
109+
:math:`\Delta` interpolated at the location :math:`\mathbf{x}`.
99110
100111
Parameters
101112
----------
102-
x : N x D numpy.ndarray
113+
x : N x D :obj:`numpy.array_like`
103114
Input RAS+ coordinates (i.e., physical coordinates).
104-
inverse : bool
115+
inverse : :obj:`bool`
105116
If ``True``, apply the inverse transform :math:`x = f^{-1}(y)`.
106117
107118
Returns
108119
-------
109-
y : N x D numpy.ndarray
120+
y : N x D :obj:`numpy.array_like`
110121
Transformed (mapped) RAS+ coordinates (i.e., physical coordinates).
111122
112123
Examples
113124
--------
114125
>>> xfm = DenseFieldTransform(
115126
... test_dir / "someones_displacement_field.nii.gz",
116-
... displacements=False,
127+
... is_deltas=False,
117128
... )
118129
>>> xfm.map([-6.5, -36., -19.5]).tolist()
119130
[[0.0, -0.47516798973083496, 0.0]]
@@ -123,7 +134,7 @@ def map(self, x, inverse=False):
123134
124135
>>> xfm = DenseFieldTransform(
125136
... test_dir / "someones_displacement_field.nii.gz",
126-
... displacements=True,
137+
... is_deltas=True,
127138
... )
128139
>>> xfm.map([[-6.5, -36., -19.5], [-1., -41.5, -11.25]]).tolist()
129140
[[-6.5, -36.47516632080078, -19.5], [-1.0, -42.03835678100586, -11.25]]
@@ -135,7 +146,7 @@ def map(self, x, inverse=False):
135146
ijk = self.reference.index(x)
136147
indexes = np.round(ijk).astype("int")
137148
if np.any(np.abs(ijk - indexes) > 0.05):
138-
warnings.warn("Some coordinates are off-grid of the displacements field.")
149+
warnings.warn("Some coordinates are off-grid of the field.")
139150
indexes = tuple(tuple(i) for i in indexes.T)
140151
return self._field[indexes]
141152

@@ -147,7 +158,7 @@ def __matmul__(self, b):
147158
--------
148159
>>> deff = DenseFieldTransform(
149160
... test_dir / "someones_displacement_field.nii.gz",
150-
... displacements=False,
161+
... is_deltas=False,
151162
... )
152163
>>> deff2 = deff @ TransformBase()
153164
>>> deff == deff2
@@ -162,7 +173,7 @@ def __matmul__(self, b):
162173
retval = b.map(
163174
self._field.reshape((-1, self._field.shape[-1]))
164175
).reshape(self._field.shape)
165-
return DenseFieldTransform(retval, displacements=False, reference=self.reference)
176+
return DenseFieldTransform(retval, is_deltas=False, reference=self.reference)
166177

167178
def __eq__(self, other):
168179
"""

nitransforms/tests/test_nonlinear.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def test_displacements_init():
6868
)
6969

7070
assert np.array_equal(identity1._field, identity2._field)
71-
assert np.array_equal(identity1._displacements, identity2._displacements)
71+
assert np.array_equal(identity1._deltas, identity2._deltas)
7272

7373
with pytest.raises(TransformError):
7474
DenseFieldTransform()

0 commit comments

Comments
 (0)