6
6
# copyright and license terms.
7
7
#
8
8
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
9
- ''' Linear transforms '''
10
- from __future__ import division , print_function , absolute_import
9
+ """Linear transforms."""
11
10
import sys
12
11
import numpy as np
13
12
from scipy import ndimage as ndi
21
20
22
21
23
22
class Affine (TransformBase ):
24
- '''Represents linear transforms on image data'''
23
+ """Represents linear transforms on image data."""
24
+
25
25
__slots__ = ['_matrix' ]
26
26
27
27
def __init__ (self , matrix = None , reference = None ):
28
- '''Initialize a transform
28
+ """
29
+ Initialize a linear transform.
29
30
30
31
Parameters
31
32
----------
32
-
33
33
matrix : ndarray
34
34
The inverse coordinate transformation matrix **in physical
35
35
coordinates**, mapping coordinates from *reference* space
@@ -38,15 +38,15 @@ def __init__(self, matrix=None, reference=None):
38
38
39
39
Examples
40
40
--------
41
-
42
41
>>> xfm = Affine([[1, 0, 0, 4], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])
43
42
>>> xfm.matrix # doctest: +NORMALIZE_WHITESPACE
44
43
array([[1, 0, 0, 4],
45
44
[0, 1, 0, 0],
46
45
[0, 0, 1, 0],
47
46
[0, 0, 0, 1]])
48
47
49
- '''
48
+ """
49
+ super (Affine , self ).__init__ ()
50
50
if matrix is None :
51
51
matrix = [np .eye (4 )]
52
52
@@ -56,7 +56,6 @@ def __init__(self, matrix=None, reference=None):
56
56
self ._matrix = np .array (matrix )
57
57
assert self ._matrix .ndim == 3 , 'affine matrix should be 3D'
58
58
assert self ._matrix .shape [- 2 ] == self ._matrix .shape [- 1 ], 'affine matrix is not square'
59
- super (Affine , self ).__init__ ()
60
59
61
60
if reference :
62
61
if isinstance (reference , str ):
@@ -69,11 +68,11 @@ def matrix(self):
69
68
70
69
def resample (self , moving , order = 3 , mode = 'constant' , cval = 0.0 , prefilter = True ,
71
70
output_dtype = None ):
72
- '''Resample the moving image in reference space
71
+ """
72
+ Resample the moving image in reference space.
73
73
74
74
Parameters
75
75
----------
76
-
77
76
moving : `spatialimage`
78
77
The image object containing the data to be resampled in reference
79
78
space
@@ -96,21 +95,19 @@ def resample(self, moving, order=3, mode='constant', cval=0.0, prefilter=True,
96
95
97
96
Returns
98
97
-------
99
-
100
98
moved_image : `spatialimage`
101
99
The moving imaged after resampling to reference space.
102
100
103
101
104
102
Examples
105
103
--------
106
-
107
104
>>> import nibabel as nib
108
105
>>> xfm = Affine([[1, 0, 0, 4], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])
109
106
>>> ref = nib.load('image.nii.gz')
110
107
>>> xfm.reference = ref
111
108
>>> xfm.resample(ref, order=0)
112
109
113
- '''
110
+ """
114
111
if output_dtype is None :
115
112
output_dtype = moving .header .get_data_dtype ()
116
113
@@ -163,13 +160,15 @@ def resample(self, moving, order=3, mode='constant', cval=0.0, prefilter=True,
163
160
return moved_image
164
161
165
162
def map_point (self , coords , index = 0 , forward = True ):
163
+ """Apply y = f(x), where x is the argument `coords`."""
166
164
coords = np .array (coords )
167
165
if coords .shape [0 ] == self ._matrix [index ].shape [0 ] - 1 :
168
166
coords = np .append (coords , [1 ])
169
167
affine = self ._matrix [index ] if forward else np .linalg .inv (self ._matrix [index ])
170
168
return affine .dot (coords )[:- 1 ]
171
169
172
170
def map_voxel (self , index , nindex = 0 , moving = None ):
171
+ """Apply ijk' = f_ijk((i, j, k)), equivalent to the above with indexes."""
173
172
try :
174
173
reference = self .reference
175
174
except ValueError :
@@ -191,6 +190,7 @@ def map_voxel(self, index, nindex=0, moving=None):
191
190
return tuple (matrix .dot (index )[:- 1 ])
192
191
193
192
def _to_hdf5 (self , x5_root ):
193
+ """Serialize this object into the x5 file format."""
194
194
xform = x5_root .create_dataset ('Transform' , data = self ._matrix )
195
195
xform .attrs ['Type' ] = 'affine'
196
196
x5_root .create_dataset ('Inverse' , data = np .linalg .inv (self ._matrix ))
@@ -199,9 +199,7 @@ def _to_hdf5(self, x5_root):
199
199
self .reference ._to_hdf5 (x5_root .create_group ('Reference' ))
200
200
201
201
def to_filename (self , filename , fmt = 'X5' , moving = None ):
202
- '''Store the transform in BIDS-Transforms HDF5 file format (.x5).
203
- '''
204
-
202
+ """Store the transform in BIDS-Transforms HDF5 file format (.x5)."""
205
203
if fmt .lower () in ['itk' , 'ants' , 'elastix' , 'nifty' ]:
206
204
with open (filename , 'w' ) as f :
207
205
f .write ('#Insight Transform File V1.0\n ' )
@@ -257,8 +255,7 @@ def to_filename(self, filename, fmt='X5', moving=None):
257
255
258
256
259
257
def load (filename , fmt = 'X5' , reference = None ):
260
- ''' Load a linear transform '''
261
-
258
+ """Load a linear transform."""
262
259
if fmt .lower () in ['itk' , 'ants' , 'elastix' , 'nifty' ]:
263
260
with open (filename ) as itkfile :
264
261
itkxfm = itkfile .read ().splitlines ()
@@ -293,7 +290,10 @@ def load(filename, fmt='X5', reference=None):
293
290
294
291
295
292
def _fsl_aff_adapt (space ):
296
- """Calculates a matrix to convert from the original RAS image
293
+ """
294
+ Adapt FSL affines.
295
+
296
+ Calculates a matrix to convert from the original RAS image
297
297
coordinates to FSL's internal coordinate system of transforms
298
298
"""
299
299
aff = space .affine
0 commit comments