9
9
DisplacementsField ,
10
10
LinearParameters ,
11
11
TransformFileError ,
12
+ _ensure_image ,
12
13
)
13
14
14
15
LPS = np .diag ([- 1 , - 1 , 1 , 1 ])
@@ -34,19 +35,25 @@ def to_string(self, banner=True):
34
35
35
36
@classmethod
36
37
def from_ras (cls , ras , moving = None , reference = None ):
37
- """Create an ITK affine from a nitransform's RAS+ matrix."""
38
- ras = ras .copy ()
39
- pre = LPS .copy ()
40
- post = LPS .copy ()
41
- if _is_oblique (reference .affine ):
38
+ """Create an AFNI affine from a nitransform's RAS+ matrix."""
39
+ pre = LPS
40
+ post = LPS
41
+
42
+ if reference is not None :
43
+ reference = _ensure_image (reference )
44
+
45
+ if reference is not None and _is_oblique (reference .affine ):
42
46
print ("Reference affine axes are oblique." )
43
47
M = reference .affine
44
48
A = shape_zoom_affine (
45
49
reference .shape , voxel_sizes (M ), x_flip = False , y_flip = False
46
50
)
47
51
pre = M .dot (np .linalg .inv (A )).dot (LPS )
48
52
49
- if _is_oblique (moving .affine ):
53
+ if moving is not None :
54
+ moving = _ensure_image (moving )
55
+
56
+ if moving is not None and _is_oblique (moving .affine ):
50
57
print ("Moving affine axes are oblique." )
51
58
M2 = moving .affine
52
59
A2 = shape_zoom_affine (
@@ -55,7 +62,7 @@ def from_ras(cls, ras, moving=None, reference=None):
55
62
post = A2 .dot (np .linalg .inv (M2 ))
56
63
57
64
# swapaxes is necessary, as axis 0 encodes series of transforms
58
- parameters = np .swapaxes (post . dot ( ras . dot ( pre )) , 0 , 1 )
65
+ parameters = np .swapaxes (post @ ras @ pre , 0 , 1 )
59
66
60
67
tf = cls ()
61
68
tf .structarr ["parameters" ] = parameters .T
@@ -84,6 +91,26 @@ def from_string(cls, string):
84
91
sa ["parameters" ] = parameters
85
92
return tf
86
93
94
+ def to_ras (self , moving = None , reference = None ):
95
+ """Return a nitransforms internal RAS+ matrix."""
96
+ pre = LPS
97
+ post = LPS
98
+
99
+ if reference is not None :
100
+ reference = _ensure_image (reference )
101
+
102
+ if reference is not None and _is_oblique (reference .affine ):
103
+ raise NotImplementedError
104
+
105
+ if moving is not None :
106
+ moving = _ensure_image (moving )
107
+
108
+ if moving is not None and _is_oblique (moving .affine ):
109
+ raise NotImplementedError
110
+
111
+ # swapaxes is necessary, as axis 0 encodes series of transforms
112
+ return post @ np .swapaxes (self .structarr ["parameters" ].T , 0 , 1 ) @ pre
113
+
87
114
88
115
class AFNILinearTransformArray (BaseLinearTransformList ):
89
116
"""A string-based structure for series of AFNI linear transforms."""
0 commit comments