Skip to content

Commit 515fb0a

Browse files
committed
enh: write lta
1 parent e821b80 commit 515fb0a

File tree

2 files changed

+22
-10
lines changed

2 files changed

+22
-10
lines changed

nitransforms/io.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import numpy as np
22
from nibabel.wrapstruct import LabeledWrapStruct
33
from nibabel.volumeutils import Recoder
4+
from nibabel.affines import voxel_sizes
45

56
transform_codes = Recoder((
67
(0, 'LINEAR_VOX_TO_VOX'),
@@ -69,10 +70,10 @@ def from_image(klass, img):
6970
sa = volgeom.structarr
7071
sa['valid'] = 1
7172
sa['volume'][:, 0] = img.shape[:3] # Assumes xyzt-ordered image
72-
sa['voxelsize'][:, 0] = img.header.get_zooms()[:3]
73+
sa['voxelsize'][:, 0] = voxel_sizes(img.affine)[:3]
7374
A = img.affine[:3, :3]
7475
b = img.affine[:3, [3]]
75-
cols = A * (1 / sa['voxelsize'])
76+
cols = A / sa['voxelsize']
7677
sa['xras'] = cols[:, [0]]
7778
sa['yras'] = cols[:, [1]]
7879
sa['zras'] = cols[:, [2]]
@@ -208,6 +209,10 @@ def from_string(klass, string):
208209

209210
val = np.genfromtxt([valstring.encode()],
210211
dtype=klass.dtype[key])
212+
if val not in (0, 1):
213+
raise NotImplementedError(
214+
"LTA type {0} is not currently supported".format(transform_codes.label[val])
215+
)
211216
sa[key] = val.reshape(sa[key].shape) if val.size else ''
212217
for _ in range(sa['nxforms']):
213218
lta._xforms.append(

nitransforms/linear.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from nibabel.affines import from_matvec, voxel_sizes, obliquity
1818
from .base import TransformBase
1919
from .patched import shape_zoom_affine
20-
from .io import LinearTransformArray, VolumeGeometry
20+
from .io import LinearTransformArray, LinearTransform, VolumeGeometry
2121

2222

2323
LPS = np.diag([-1, -1, 1, 1])
@@ -300,12 +300,20 @@ def to_filename(self, filename, fmt='X5', moving=None):
300300
np.savetxt(filename, mat[0], delimiter=' ', fmt='%g')
301301
return filename
302302
elif fmt.lower() in ('fs', 'lta'):
303-
# linear tranform info
304-
src = VolumeGeometry.from_image(moving)
305-
dst = VolumeGeometry.from_image(self.reference)
306-
307-
303+
# xform info
304+
lt = LinearTransform()
305+
lt['sigma'] = 1.
306+
lt['m_L'] = self.matrix
307+
lt['src'] = VolumeGeometry.from_image(moving)
308+
lt['dst'] = VolumeGeometry.from_image(self.reference)
309+
# to make LTA file format
310+
lta = LinearTransformArray()
311+
lta['type'] = 1 # RAS2RAS
312+
lta['xforms'] = [lt]
308313

314+
with open(filename, 'w') as f:
315+
f.write(lta.to_string())
316+
return filename
309317

310318
return super(Affine, self).to_filename(filename, fmt=fmt)
311319

@@ -338,8 +346,7 @@ def load(filename, fmt='X5', reference=None):
338346
elif fmt.lower() in ('fs', 'lta'):
339347
with open(filename) as ltafile:
340348
lta = LinearTransformArray.from_fileobj(ltafile)
341-
# TODO: multiple transforms?
342-
assert lta['nxforms'] == 1
349+
assert lta['nxforms'] == 1 # ever have multiple transforms?
343350
matrix = lta._xforms[0]['m_L']
344351
elif fmt.lower() in ('x5', 'bids'):
345352
raise NotImplementedError

0 commit comments

Comments
 (0)