3
3
Notes on the SPM orientation machinery.
4
4
5
5
There are symbolic versions of the code in ``spm_dicom_convert``,
6
- ``write_volume`` subfunction, around line 509 in the version I have
7
- (SPM8, late 2009 vintage).
6
+ ``write_volume`` subfunction, around line 509 in the version I have (SPM8, late
7
+ 2009 vintage).
8
8
'''
9
9
10
10
import numpy as np
11
11
12
12
import sympy
13
13
from sympy import Matrix , Symbol , symbols , zeros , ones , eye
14
14
15
+
15
16
# The code below is general (independent of SPMs code)
16
17
def numbered_matrix (nrows , ncols , symbol_prefix ):
17
18
return Matrix (nrows , ncols , lambda i , j : Symbol (
18
19
symbol_prefix + '_{%d%d}' % (i + 1 , j + 1 )))
19
20
21
+
20
22
def numbered_vector (nrows , symbol_prefix ):
21
23
return Matrix (nrows , 1 , lambda i , j : Symbol (
22
24
symbol_prefix + '_{%d}' % (i + 1 )))
23
25
26
+
24
27
# premultiplication matrix to go from 0 based to 1 based indexing
25
28
one_based = eye (4 )
26
29
one_based [:3 ,3 ] = (1 ,1 ,1 )
@@ -35,27 +38,27 @@ def numbered_vector(nrows, symbol_prefix):
35
38
missing_r_col = numbered_vector (3 , 'k' )
36
39
pos_pat_0 = numbered_vector (3 , 'T^1' )
37
40
pos_pat_N = numbered_vector (3 , 'T^N' )
38
- pixel_spacing = symbols (('\Delta{r}' , '\Delta{c}' ))
41
+ pixel_spacing = symbols ((r '\Delta{r}' , r '\Delta{c}' ))
39
42
NZ = Symbol ('N' )
40
- slice_thickness = Symbol ('\Delta{s}' )
43
+ slice_spacing = Symbol ('\Delta{s}' )
41
44
42
45
R3 = orient_pat * np .diag (pixel_spacing )
43
- R = zeros (( 4 , 2 ) )
46
+ R = zeros (4 , 2 )
44
47
R [:3 ,:] = R3
45
48
46
49
# The following is specific to the SPM algorithm.
47
- x1 = ones (( 4 , 1 ) )
48
- y1 = ones (( 4 , 1 ) )
50
+ x1 = ones (4 , 1 )
51
+ y1 = ones (4 , 1 )
49
52
y1 [:3 ,:] = pos_pat_0
50
53
51
- to_inv = zeros (( 4 , 4 ) )
54
+ to_inv = zeros (4 , 4 )
52
55
to_inv [:,0 ] = x1
53
- to_inv [:,1 ] = symbols ('abcd ' )
56
+ to_inv [:,1 ] = symbols ('a b c d ' )
54
57
to_inv [0 ,2 ] = 1
55
58
to_inv [1 ,3 ] = 1
56
- inv_lhs = zeros (( 4 , 4 ) )
59
+ inv_lhs = zeros (4 , 4 )
57
60
inv_lhs [:,0 ] = y1
58
- inv_lhs [:,1 ] = symbols ('efgh ' )
61
+ inv_lhs [:,1 ] = symbols ('e f g h ' )
59
62
inv_lhs [:,2 :] = R
60
63
61
64
def spm_full_matrix (x2 , y2 ):
@@ -66,17 +69,17 @@ def spm_full_matrix(x2, y2):
66
69
return lhs * rhs .inv ()
67
70
68
71
# single slice case
69
- orient = zeros (( 3 , 3 ) )
72
+ orient = zeros (3 , 3 )
70
73
orient [:3 ,:2 ] = orient_pat
71
74
orient [:,2 ] = orient_cross
72
75
x2_ss = Matrix ((0 ,0 ,1 ,0 ))
73
- y2_ss = zeros (( 4 , 1 ) )
74
- y2_ss [:3 ,:] = orient * Matrix ((0 ,0 ,slice_thickness ))
76
+ y2_ss = zeros (4 , 1 )
77
+ y2_ss [:3 ,:] = orient * Matrix ((0 ,0 ,slice_spacing ))
75
78
A_ss = spm_full_matrix (x2_ss , y2_ss )
76
79
77
80
# many slice case
78
81
x2_ms = Matrix ((1 ,1 ,NZ ,1 ))
79
- y2_ms = ones (( 4 , 1 ) )
82
+ y2_ms = ones (4 , 1 )
80
83
y2_ms [:3 ,:] = pos_pat_N
81
84
A_ms = spm_full_matrix (x2_ms , y2_ms )
82
85
@@ -88,7 +91,7 @@ def spm_full_matrix(x2, y2):
88
91
# single slice case
89
92
single_aff = eye (4 )
90
93
rot = orient
91
- rot_scale = rot * np .diag (pixel_spacing [:] + [ slice_thickness ] )
94
+ rot_scale = rot * np .diag (pixel_spacing [:] + ( slice_spacing ,) )
92
95
single_aff [:3 ,:3 ] = rot_scale
93
96
single_aff [:3 ,3 ] = pos_pat_0
94
97
@@ -137,23 +140,23 @@ def my_latex(expr):
137
140
S = sympy .latex (expr )
138
141
return S [1 :- 1 ]
139
142
140
- print 'Latex stuff'
141
- print ' R = ' + my_latex (to_inv )
142
- print ' '
143
- print ' L = ' + my_latex (inv_lhs )
144
- print
145
- print ' 0B = ' + my_latex (one_based )
146
- print
147
- print ' ' + my_latex (solved )
148
- print
149
- print ' A_{multi} = ' + my_latex (multi_aff_solved )
150
- print ' '
151
- print ' A_{single} = ' + my_latex (single_aff )
152
- print
153
- print r' \left(\begin{smallmatrix}T^N\\1\end{smallmatrix}\right) = A ' + my_latex (trans_z_N )
154
- print
155
- print ' A_j = A_{single} ' + my_latex (nz_trans )
156
- print
157
- print ' T^j = ' + my_latex (IPP_j )
158
- print
159
- print ' T^j \cdot \mathbf{c} = ' + my_latex (spm_z )
143
+ print ( 'Latex stuff' )
144
+ print ( ' R = ' + my_latex (to_inv ) )
145
+ print ( ' ' )
146
+ print ( ' L = ' + my_latex (inv_lhs ) )
147
+ print ()
148
+ print ( ' 0B = ' + my_latex (one_based ) )
149
+ print ()
150
+ print ( ' ' + my_latex (solved ) )
151
+ print ()
152
+ print ( ' A_{multi} = ' + my_latex (multi_aff_solved ) )
153
+ print ( ' ' )
154
+ print ( ' A_{single} = ' + my_latex (single_aff ) )
155
+ print ()
156
+ print ( r' \left(\begin{smallmatrix}T^N\\1\end{smallmatrix}\right) = A ' + my_latex (trans_z_N ) )
157
+ print ()
158
+ print ( ' A_j = A_{single} ' + my_latex (nz_trans ) )
159
+ print ()
160
+ print ( ' T^j = ' + my_latex (IPP_j ) )
161
+ print ()
162
+ print ( ' T^j \cdot \mathbf{c} = ' + my_latex (spm_z ) )
0 commit comments