3
3
from nibabel .volumeutils import Recoder
4
4
from nibabel .affines import voxel_sizes
5
5
6
- from .base import StringBasedStruct
6
+ from .base import StringBasedStruct , TransformFileError
7
7
8
8
9
9
transform_codes = Recoder ((
@@ -20,10 +20,10 @@ class VolumeGeometry(StringBasedStruct):
20
20
('valid' , 'i4' ), # Valid values: 0, 1
21
21
('volume' , 'i4' , (3 , 1 )), # width, height, depth
22
22
('voxelsize' , 'f4' , (3 , 1 )), # xsize, ysize, zsize
23
- ('xras' , 'f4 ' , (3 , 1 )), # x_r, x_a, x_s
24
- ('yras' , 'f4 ' , (3 , 1 )), # y_r, y_a, y_s
25
- ('zras' , 'f4 ' , (3 , 1 )), # z_r, z_a, z_s
26
- ('cras' , 'f4 ' , (3 , 1 )), # c_r, c_a, c_s
23
+ ('xras' , 'f8 ' , (3 , 1 )), # x_r, x_a, x_s
24
+ ('yras' , 'f8 ' , (3 , 1 )), # y_r, y_a, y_s
25
+ ('zras' , 'f8 ' , (3 , 1 )), # z_r, z_a, z_s
26
+ ('cras' , 'f8 ' , (3 , 1 )), # c_r, c_a, c_s
27
27
('filename' , 'U1024' )]) # Not conformant (may be >1024 bytes)
28
28
dtype = template_dtype
29
29
@@ -80,7 +80,7 @@ def from_string(klass, string):
80
80
lines = string .splitlines ()
81
81
for key in ('valid' , 'filename' , 'volume' , 'voxelsize' ,
82
82
'xras' , 'yras' , 'zras' , 'cras' ):
83
- label , valstring = lines .pop (0 ).split (' = ' )
83
+ label , valstring = lines .pop (0 ).split (' =' )
84
84
assert label .strip () == key
85
85
86
86
val = np .genfromtxt ([valstring .encode ()],
@@ -92,11 +92,11 @@ def from_string(klass, string):
92
92
93
93
class LinearTransform (StringBasedStruct ):
94
94
template_dtype = np .dtype ([
95
- ('mean' , 'f4' , (3 , 1 )), # x0, y0, z0
95
+ ('mean' , 'f4' , (3 , 1 )), # x0, y0, z0
96
96
('sigma' , 'f4' ),
97
- ('m_L' , 'f4 ' , (4 , 4 )),
98
- ('m_dL' , 'f4 ' , (4 , 4 )),
99
- ('m_last_dL' , 'f4 ' , (4 , 4 )),
97
+ ('m_L' , 'f8 ' , (4 , 4 )),
98
+ ('m_dL' , 'f8 ' , (4 , 4 )),
99
+ ('m_last_dL' , 'f8 ' , (4 , 4 )),
100
100
('src' , VolumeGeometry ),
101
101
('dst' , VolumeGeometry ),
102
102
('label' , 'i4' )])
@@ -190,7 +190,10 @@ def to_string(self):
190
190
def from_string (klass , string ):
191
191
lta = klass ()
192
192
sa = lta .structarr
193
- lines = string .splitlines ()
193
+ lines = [l .strip () for l in string .splitlines ()
194
+ if l .strip () and not l .strip ().startswith ('#' )]
195
+ if not lines or not lines [0 ].startswith ('type' ):
196
+ raise TransformFileError ("Invalid LTA format" )
194
197
for key in ('type' , 'nxforms' ):
195
198
label , valstring = lines .pop (0 ).split (' = ' )
196
199
assert label .strip () == key
@@ -207,12 +210,16 @@ def from_string(klass, string):
207
210
# Optional keys
208
211
if not lines [0 ].startswith (key ):
209
212
continue
210
- label , valstring = lines .pop (0 ).split (' ' )
211
- assert label .strip () == key
213
+ try :
214
+ label , valstring = lines .pop (0 ).split (' ' )
215
+ except ValueError :
216
+ sa [key ] = ''
217
+ else :
218
+ assert label .strip () == key
212
219
213
- val = np .genfromtxt ([valstring .encode ()],
214
- dtype = klass .dtype [key ])
215
- sa [key ] = val .reshape (sa [key ].shape ) if val .size else ''
220
+ val = np .genfromtxt ([valstring .encode ()],
221
+ dtype = klass .dtype [key ])
222
+ sa [key ] = val .reshape (sa [key ].shape ) if val .size else ''
216
223
217
224
assert len (lta ._xforms ) == sa ['nxforms' ]
218
225
return lta
@@ -240,7 +247,7 @@ def set_type(self, target):
240
247
241
248
# VOX2VOX -> RAS2RAS
242
249
if current == 0 and target == 1 :
243
- M = np . linalg . inv ( src . as_affine ()) .dot (xform ['m_L' ]) .dot (dst . as_affine ())
250
+ M = dst . as_affine ().dot (xform ['m_L' ].dot (np . linalg . inv ( src . as_affine ()) ))
244
251
else :
245
252
raise NotImplementedError (
246
253
"Converting {0} to {1} is not yet available" .format (
0 commit comments