99 DisplacementsField ,
1010 LinearParameters ,
1111 TransformFileError ,
12+ _ensure_image ,
1213)
1314
1415LPS = np .diag ([- 1 , - 1 , 1 , 1 ])
@@ -34,19 +35,25 @@ def to_string(self, banner=True):
3435
3536 @classmethod
3637 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 ):
4246 print ("Reference affine axes are oblique." )
4347 M = reference .affine
4448 A = shape_zoom_affine (
4549 reference .shape , voxel_sizes (M ), x_flip = False , y_flip = False
4650 )
4751 pre = M .dot (np .linalg .inv (A )).dot (LPS )
4852
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 ):
5057 print ("Moving affine axes are oblique." )
5158 M2 = moving .affine
5259 A2 = shape_zoom_affine (
@@ -55,7 +62,7 @@ def from_ras(cls, ras, moving=None, reference=None):
5562 post = A2 .dot (np .linalg .inv (M2 ))
5663
5764 # 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 )
5966
6067 tf = cls ()
6168 tf .structarr ["parameters" ] = parameters .T
@@ -84,6 +91,26 @@ def from_string(cls, string):
8491 sa ["parameters" ] = parameters
8592 return tf
8693
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+
87114
88115class AFNILinearTransformArray (BaseLinearTransformList ):
89116 """A string-based structure for series of AFNI linear transforms."""
0 commit comments