Skip to content

Commit 3a9a132

Browse files
committed
enh: add ITK-to-LTA tests
Closes #72
1 parent f4beed0 commit 3a9a132

4 files changed

+96
-3
lines changed

nitransforms/linear.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,16 @@ def to_filename(self, filename, fmt="X5", moving=None):
166166
# xform info
167167
lt = io.LinearTransform()
168168
lt["sigma"] = 1.
169-
lt["m_L"] = self.matrix
170169
# Just for reference, nitransforms does not write VOX2VOX
171-
lt["src"] = io.VolumeGeometry.from_image(moving)
172-
lt["dst"] = io.VolumeGeometry.from_image(self.reference)
170+
# PLEASE NOTE THAT LTA USES THE "POINTS" CONVENTION, therefore
171+
# the source is the reference (coordinates for which we need
172+
# to find a projection) and destination is the moving image
173+
# (from which data is pulled-back).
174+
lt["src"] = io.VolumeGeometry.from_image(self.reference)
175+
lt["dst"] = io.VolumeGeometry.from_image(moving)
176+
# However, the affine needs to be inverted
177+
# (i.e., it is not a pure "points" convention).
178+
lt["m_L"] = np.linalg.inv(self.matrix)
173179
# to make LTA file format
174180
lta = io.LinearTransformArray()
175181
lta["type"] = 1 # RAS2RAS
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Created with lta_convert
2+
# lta_convert --inlta from-fsnative_to-bold_mode-image.lta --outlta from-fsnative_to-bold_mode-image_type-ras2ras.lta
3+
type = 1 # LINEAR_RAS_TO_RAS
4+
nxforms = 1
5+
mean = 0.0000 0.0000 0.0000
6+
sigma = 10000.0000
7+
1 4 4
8+
9.997106194496155e-01 9.580537676811218e-03 2.206108532845974e-02 -4.897087097167969e+00
9+
5.824727471917868e-03 7.934973239898682e-01 -6.085451841354370e-01 -6.588146209716797e+01
10+
-2.333561331033707e-02 6.084975600242615e-01 7.932120561599731e-01 1.111579895019531e+01
11+
0.000000000000000e+00 0.000000000000000e+00 0.000000000000000e+00 1.000000000000000e+00
12+
src volume info
13+
valid = 1 # volume info valid
14+
filename = /home/oesteban/tmp/fmriprep-ds005/fprep-work/fmriprep_wf/single_subject_01_wf/func_preproc_task_mixedgamblestask_run_01_wf/bold_reg_wf/bbreg_wf/bbregister/uni_xform_masked.nii.gz
15+
volume = 64 64 34
16+
voxelsize = 3.125000000000000e+00 3.125000000000000e+00 4.000000000000000e+00
17+
xras = -1.000000000000000e+00 0.000000000000000e+00 0.000000000000000e+00
18+
yras = 0.000000000000000e+00 1.000000000000000e+00 0.000000000000000e+00
19+
zras = 0.000000000000000e+00 0.000000000000000e+00 1.000000000000000e+00
20+
cras = 1.000000000000000e+00 2.800000000000000e+01 -3.100000000000000e+01
21+
dst volume info
22+
valid = 1 # volume info valid
23+
filename = /oak/stanford/groups/russpold/data/openfmri/derivatives/ds000005/freesurfer-6.0.1/sub-01/mri/orig.mgz
24+
volume = 256 256 256
25+
voxelsize = 1.000000000000000e+00 1.000000000000000e+00 1.000000000000000e+00
26+
xras = -9.999999403953552e-01 0.000000000000000e+00 0.000000000000000e+00
27+
yras = 0.000000000000000e+00 0.000000000000000e+00 -9.999999403953552e-01
28+
zras = 0.000000000000000e+00 9.999999403953552e-01 0.000000000000000e+00
29+
cras = -9.999847412109375e-01 -5.000015258789062e+00 -1.000038146972656e+00
30+
subject sub-01
31+
fscale 0.100000
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Created with lta_convert
2+
# lta_convert --inlta from-scanner_to-bold_mode-image.lta --outlta from-scanner_to-bold_mode-image_type-ras2ras.lta
3+
type = 1 # LINEAR_RAS_TO_RAS
4+
nxforms = 1
5+
mean = 0.0000 0.0000 0.0000
6+
sigma = 1.0000
7+
1 4 4
8+
9.997058510780334e-01 9.539666585624218e-03 2.228682115674019e-02 -4.884338378906250e+00
9+
5.996740423142910e-03 7.934408783912659e-01 -6.086167693138123e-01 -6.589652252197266e+01
10+
-2.348928898572922e-02 6.085714697837830e-01 7.931506037712097e-01 1.110400390625000e+01
11+
0.000000000000000e+00 0.000000000000000e+00 0.000000000000000e+00 9.999998807907104e-01
12+
src volume info
13+
valid = 1 # volume info valid
14+
filename = /home/oesteban/tmp/fmriprep-ds005/fprep-work/fmriprep_wf/single_subject_01_wf/func_preproc_task_mixedgamblestask_run_01_wf/bold_reg_wf/bbreg_wf/bbregister/uni_xform_masked.nii.gz
15+
volume = 64 64 34
16+
voxelsize = 3.125000000000000e+00 3.125000000000000e+00 4.000000000000000e+00
17+
xras = -1.000000000000000e+00 0.000000000000000e+00 0.000000000000000e+00
18+
yras = 0.000000000000000e+00 1.000000000000000e+00 0.000000000000000e+00
19+
zras = 0.000000000000000e+00 0.000000000000000e+00 1.000000000000000e+00
20+
cras = 1.000000000000000e+00 2.800000000000000e+01 -3.100000000000000e+01
21+
dst volume info
22+
valid = 1 # volume info valid
23+
filename = /oak/stanford/groups/russpold/data/openfmri/ds000005/sub-01/anat/sub-01_T1w.nii.gz
24+
volume = 160 192 192
25+
voxelsize = 1.000000000000000e+00 1.333333015441895e+00 1.333333015441895e+00
26+
xras = 1.000000000000000e+00 0.000000000000000e+00 0.000000000000000e+00
27+
yras = 0.000000000000000e+00 1.000000000000000e+00 0.000000000000000e+00
28+
zras = 0.000000000000000e+00 0.000000000000000e+00 1.000000000000000e+00
29+
cras = -1.000000000000000e+00 -5.000030517578125e+00 -1.000030517578125e+00
30+
subject sub-01
31+
fscale 0.100000

nitransforms/tests/test_conversions.py

+25
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import numpy as np
55
import pytest
66
from .. import linear as _l
7+
from ..io import LinearTransformArray as LTA
78

89

910
@pytest.mark.parametrize('filename', [
@@ -21,6 +22,30 @@ def test_lta2itk_conversions(data_path, filename):
2122
assert np.allclose(lta.matrix, itk.matrix)
2223

2324

25+
@pytest.mark.parametrize('filename,moving,reference', [
26+
("from-fsnative_to-bold_mode-image", "T1w_fsnative.nii.gz", "bold.nii.gz"),
27+
("from-fsnative_to-scanner_mode-image", "T1w_fsnative.nii.gz", "T1w_scanner.nii.gz"),
28+
("from-scanner_to-bold_mode-image", "T1w_scanner.nii.gz", "bold.nii.gz"),
29+
("from-scanner_to-fsnative_mode-image", "T1w_scanner.nii.gz", "T1w_fsnative.nii.gz"),
30+
])
31+
def test_itk2lta_conversions(data_path, tmp_path, filename, moving, reference):
32+
"""Check conversions between formats."""
33+
itk = _l.load(data_path / "regressions" / "".join((filename, ".tfm")),
34+
fmt="itk")
35+
itk.reference = data_path / "regressions" / reference
36+
itk.to_filename(tmp_path / "test.lta", fmt="fs",
37+
moving=data_path / "regressions" / moving)
38+
39+
converted_lta = LTA.from_filename(tmp_path / "test.lta")
40+
expected_fname = data_path / "regressions" / "".join((filename, "_type-ras2ras.lta"))
41+
if not expected_fname.exists():
42+
expected_fname = data_path / "regressions" / "".join((filename, ".lta"))
43+
44+
exp_lta = LTA.from_filename(expected_fname)
45+
assert np.allclose(converted_lta['xforms'][0]['m_L'],
46+
exp_lta['xforms'][0]['m_L'])
47+
48+
2449
def test_concatenation(data_path):
2550
"""Check replacement to lta_concat."""
2651
lta0 = _l.load(data_path / "regressions" / "from-scanner_to-fsnative_mode-image.lta",

0 commit comments

Comments
 (0)