33Notes on the SPM orientation machinery.
44
55There 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).
88'''
99
1010import numpy as np
1111
1212import sympy
1313from sympy import Matrix , Symbol , symbols , zeros , ones , eye
1414
15+
1516# The code below is general (independent of SPMs code)
1617def numbered_matrix (nrows , ncols , symbol_prefix ):
1718 return Matrix (nrows , ncols , lambda i , j : Symbol (
1819 symbol_prefix + '_{%d%d}' % (i + 1 , j + 1 )))
1920
21+
2022def numbered_vector (nrows , symbol_prefix ):
2123 return Matrix (nrows , 1 , lambda i , j : Symbol (
2224 symbol_prefix + '_{%d}' % (i + 1 )))
2325
26+
2427# premultiplication matrix to go from 0 based to 1 based indexing
2528one_based = eye (4 )
2629one_based [:3 ,3 ] = (1 ,1 ,1 )
@@ -35,27 +38,27 @@ def numbered_vector(nrows, symbol_prefix):
3538missing_r_col = numbered_vector (3 , 'k' )
3639pos_pat_0 = numbered_vector (3 , 'T^1' )
3740pos_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}' ))
3942NZ = Symbol ('N' )
40- slice_thickness = Symbol ('\Delta{s}' )
43+ slice_spacing = Symbol ('\Delta{s}' )
4144
4245R3 = orient_pat * np .diag (pixel_spacing )
43- R = zeros (( 4 , 2 ) )
46+ R = zeros (4 , 2 )
4447R [:3 ,:] = R3
4548
4649# 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 )
4952y1 [:3 ,:] = pos_pat_0
5053
51- to_inv = zeros (( 4 , 4 ) )
54+ to_inv = zeros (4 , 4 )
5255to_inv [:,0 ] = x1
53- to_inv [:,1 ] = symbols ('abcd ' )
56+ to_inv [:,1 ] = symbols ('a b c d ' )
5457to_inv [0 ,2 ] = 1
5558to_inv [1 ,3 ] = 1
56- inv_lhs = zeros (( 4 , 4 ) )
59+ inv_lhs = zeros (4 , 4 )
5760inv_lhs [:,0 ] = y1
58- inv_lhs [:,1 ] = symbols ('efgh ' )
61+ inv_lhs [:,1 ] = symbols ('e f g h ' )
5962inv_lhs [:,2 :] = R
6063
6164def spm_full_matrix (x2 , y2 ):
@@ -66,17 +69,17 @@ def spm_full_matrix(x2, y2):
6669 return lhs * rhs .inv ()
6770
6871# single slice case
69- orient = zeros (( 3 , 3 ) )
72+ orient = zeros (3 , 3 )
7073orient [:3 ,:2 ] = orient_pat
7174orient [:,2 ] = orient_cross
7275x2_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 ))
7578A_ss = spm_full_matrix (x2_ss , y2_ss )
7679
7780# many slice case
7881x2_ms = Matrix ((1 ,1 ,NZ ,1 ))
79- y2_ms = ones (( 4 , 1 ) )
82+ y2_ms = ones (4 , 1 )
8083y2_ms [:3 ,:] = pos_pat_N
8184A_ms = spm_full_matrix (x2_ms , y2_ms )
8285
@@ -88,7 +91,7 @@ def spm_full_matrix(x2, y2):
8891# single slice case
8992single_aff = eye (4 )
9093rot = orient
91- rot_scale = rot * np .diag (pixel_spacing [:] + [ slice_thickness ] )
94+ rot_scale = rot * np .diag (pixel_spacing [:] + ( slice_spacing ,) )
9295single_aff [:3 ,:3 ] = rot_scale
9396single_aff [:3 ,3 ] = pos_pat_0
9497
@@ -137,23 +140,23 @@ def my_latex(expr):
137140 S = sympy .latex (expr )
138141 return S [1 :- 1 ]
139142
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