@@ -39,7 +39,7 @@ def factory(dataset):
39
39
class SampledSpatialData :
40
40
"""Represent sampled spatial data: regularly gridded (images) and surfaces."""
41
41
42
- __slots__ = [' _ndim' , ' _coords' , ' _npoints' , ' _shape' ]
42
+ __slots__ = [" _ndim" , " _coords" , " _npoints" , " _shape" ]
43
43
44
44
def __init__ (self , dataset ):
45
45
"""Create a sampling reference."""
@@ -53,19 +53,20 @@ def __init__(self, dataset):
53
53
if isinstance (dataset , (str , Path )):
54
54
dataset = _nbload (str (dataset ))
55
55
56
- if hasattr (dataset , ' numDA' ): # Looks like a Gifti file
57
- _das = dataset .get_arrays_from_intent (INTENT_CODES [' pointset' ])
56
+ if hasattr (dataset , " numDA" ): # Looks like a Gifti file
57
+ _das = dataset .get_arrays_from_intent (INTENT_CODES [" pointset" ])
58
58
if not _das :
59
59
raise TypeError (
60
- 'Input Gifti file does not contain reference coordinates.' )
60
+ "Input Gifti file does not contain reference coordinates."
61
+ )
61
62
self ._coords = np .vstack ([da .data for da in _das ])
62
63
self ._npoints , self ._ndim = self ._coords .shape
63
64
return
64
65
65
66
if isinstance (dataset , Cifti2Image ):
66
67
raise NotImplementedError
67
68
68
- raise ValueError (' Dataset could not be interpreted as an irregular sample.' )
69
+ raise ValueError (" Dataset could not be interpreted as an irregular sample." )
69
70
70
71
@property
71
72
def npoints (self ):
@@ -91,7 +92,7 @@ def shape(self):
91
92
class ImageGrid (SampledSpatialData ):
92
93
"""Class to represent spaces of gridded data (images)."""
93
94
94
- __slots__ = [' _affine' , ' _inverse' , ' _ndindex' ]
95
+ __slots__ = [" _affine" , " _inverse" , " _ndindex" ]
95
96
96
97
def __init__ (self , image ):
97
98
"""Create a gridded sampling reference."""
@@ -101,17 +102,15 @@ def __init__(self, image):
101
102
self ._affine = image .affine
102
103
self ._shape = image .shape
103
104
104
- self ._ndim = getattr (image , ' ndim' , len (image .shape ))
105
+ self ._ndim = getattr (image , " ndim" , len (image .shape ))
105
106
if self ._ndim == 4 :
106
107
self ._shape = image .shape [:3 ]
107
108
self ._ndim = 3
108
109
109
- self ._npoints = getattr (image , 'npoints' ,
110
- np .prod (self ._shape ))
110
+ self ._npoints = getattr (image , "npoints" , np .prod (self ._shape ))
111
111
self ._ndindex = None
112
112
self ._coords = None
113
- self ._inverse = getattr (image , 'inverse' ,
114
- np .linalg .inv (image .affine ))
113
+ self ._inverse = getattr (image , "inverse" , np .linalg .inv (image .affine ))
115
114
116
115
@property
117
116
def affine (self ):
@@ -128,8 +127,9 @@ def ndindex(self):
128
127
"""List the indexes corresponding to the space grid."""
129
128
if self ._ndindex is None :
130
129
indexes = tuple ([np .arange (s ) for s in self ._shape ])
131
- self ._ndindex = np .array (np .meshgrid (
132
- * indexes , indexing = 'ij' )).reshape (self ._ndim , self ._npoints )
130
+ self ._ndindex = np .array (np .meshgrid (* indexes , indexing = "ij" )).reshape (
131
+ self ._ndim , self ._npoints
132
+ )
133
133
return self ._ndindex
134
134
135
135
@property
@@ -139,7 +139,7 @@ def ndcoords(self):
139
139
self ._coords = np .tensordot (
140
140
self ._affine ,
141
141
np .vstack ((self .ndindex , np .ones ((1 , self ._npoints )))),
142
- axes = 1
142
+ axes = 1 ,
143
143
)[:3 , ...]
144
144
return self ._coords
145
145
@@ -152,15 +152,17 @@ def index(self, x):
152
152
return _apply_affine (x , self ._inverse , self ._ndim )
153
153
154
154
def _to_hdf5 (self , group ):
155
- group .attrs [' Type' ] = ' image'
156
- group .attrs [' ndim' ] = self .ndim
157
- group .create_dataset (' affine' , data = self .affine )
158
- group .create_dataset (' shape' , data = self .shape )
155
+ group .attrs [" Type" ] = " image"
156
+ group .attrs [" ndim" ] = self .ndim
157
+ group .create_dataset (" affine" , data = self .affine )
158
+ group .create_dataset (" shape" , data = self .shape )
159
159
160
160
def __eq__ (self , other ):
161
161
"""Overload equals operator."""
162
- return (np .allclose (self .affine , other .affine , rtol = EQUALITY_TOL )
163
- and self .shape == other .shape )
162
+ return (
163
+ np .allclose (self .affine , other .affine , rtol = EQUALITY_TOL )
164
+ and self .shape == other .shape
165
+ )
164
166
165
167
def __ne__ (self , other ):
166
168
"""Overload not equal operator."""
@@ -170,7 +172,7 @@ def __ne__(self, other):
170
172
class TransformBase :
171
173
"""Abstract image class to represent transforms."""
172
174
173
- __slots__ = (' _reference' , )
175
+ __slots__ = (" _reference" , )
174
176
175
177
def __init__ (self , reference = None ):
176
178
"""Instantiate a transform."""
@@ -195,13 +197,14 @@ def __add__(self, b):
195
197
196
198
"""
197
199
from .manip import TransformChain
200
+
198
201
return TransformChain (transforms = [self , b ])
199
202
200
203
@property
201
204
def reference (self ):
202
205
"""Access a reference space where data will be resampled onto."""
203
206
if self ._reference is None :
204
- warnings .warn (' Reference space not set' )
207
+ warnings .warn (" Reference space not set" )
205
208
return self ._reference
206
209
207
210
@reference .setter
@@ -213,8 +216,16 @@ def ndim(self):
213
216
"""Access the dimensions of the reference space."""
214
217
return self .reference .ndim
215
218
216
- def apply (self , spatialimage , reference = None ,
217
- order = 3 , mode = 'constant' , cval = 0.0 , prefilter = True , output_dtype = None ):
219
+ def apply (
220
+ self ,
221
+ spatialimage ,
222
+ reference = None ,
223
+ order = 3 ,
224
+ mode = "constant" ,
225
+ cval = 0.0 ,
226
+ prefilter = True ,
227
+ output_dtype = None ,
228
+ ):
218
229
"""
219
230
Apply a transformation to an image, resampling on the reference spatial object.
220
231
@@ -252,17 +263,18 @@ def apply(self, spatialimage, reference=None,
252
263
if reference is not None and isinstance (reference , (str , Path )):
253
264
reference = _nbload (str (reference ))
254
265
255
- _ref = self .reference if reference is None \
256
- else SpatialReference .factory (reference )
266
+ _ref = (
267
+ self .reference if reference is None else SpatialReference .factory (reference )
268
+ )
257
269
258
270
if isinstance (spatialimage , (str , Path )):
259
271
spatialimage = _nbload (str (spatialimage ))
260
272
261
273
data = np .asanyarray (spatialimage .dataobj )
262
274
output_dtype = output_dtype or data .dtype
263
275
targets = ImageGrid (spatialimage ).index ( # data should be an image
264
- _as_homogeneous (self .map (_ref .ndcoords .T ),
265
- dim = _ref . ndim ) )
276
+ _as_homogeneous (self .map (_ref .ndcoords .T ), dim = _ref . ndim )
277
+ )
266
278
267
279
resampled = ndi .map_coordinates (
268
280
data ,
@@ -276,8 +288,8 @@ def apply(self, spatialimage, reference=None,
276
288
277
289
if isinstance (_ref , ImageGrid ): # If reference is grid, reshape
278
290
moved = spatialimage .__class__ (
279
- resampled .reshape (_ref .shape ),
280
- _ref . affine , spatialimage . header )
291
+ resampled .reshape (_ref .shape ), _ref . affine , spatialimage . header
292
+ )
281
293
moved .header .set_data_dtype (output_dtype )
282
294
return moved
283
295
@@ -304,12 +316,12 @@ def map(self, x, inverse=False):
304
316
"""
305
317
return x
306
318
307
- def to_filename (self , filename , fmt = 'X5' ):
319
+ def to_filename (self , filename , fmt = "X5" ):
308
320
"""Store the transform in BIDS-Transforms HDF5 file format (.x5)."""
309
- with h5py .File (filename , 'w' ) as out_file :
310
- out_file .attrs [' Format' ] = 'X5'
311
- out_file .attrs [' Version' ] = np .uint16 (1 )
312
- root = out_file .create_group ('/0' )
321
+ with h5py .File (filename , "w" ) as out_file :
322
+ out_file .attrs [" Format" ] = "X5"
323
+ out_file .attrs [" Version" ] = np .uint16 (1 )
324
+ root = out_file .create_group ("/0" )
313
325
self ._to_hdf5 (root )
314
326
315
327
return filename
@@ -319,7 +331,7 @@ def _to_hdf5(self, x5_root):
319
331
raise NotImplementedError
320
332
321
333
322
- def _as_homogeneous (xyz , dtype = ' float32' , dim = 3 ):
334
+ def _as_homogeneous (xyz , dtype = " float32" , dim = 3 ):
323
335
"""
324
336
Convert 2D and 3D coordinates into homogeneous coordinates.
325
337
0 commit comments