Diff of /code/decimation.py [000000] .. [32d261]

Switch to unified view

a b/code/decimation.py
1
#!/usr/bin/python
2
import os, glob
3
from multiprocessing import Pool
4
from functools import partial
5
6
7
# Perform motion tracking for cine MR
8
def track_cine(data_dir, par_dir, tamplate_dir):
9
    
10
    motion_dir = os.path.join(data_dir, 'motion')
11
    if os.path.exists(motion_dir):
12
       os.system('rm -r {0}'.format(motion_dir))
13
       os.mkdir(motion_dir)
14
    else:
15
       os.mkdir(motion_dir)
16
17
    # Split 4D nifti into time phases
18
    os.system('splitvolume '
19
              '{0}/lvsa_.nii.gz '
20
              '{1}/lvsa_ '
21
              '-sequence'
22
              .format(data_dir, motion_dir))
23
24
    n_frame = len(glob.glob('{0}/lvsa_??.nii.gz'.format(motion_dir)))
25
26
    # Inter-frame motion estimation
27
    for fr in range(1, n_frame):
28
        target = '{0}/lvsa_{1:02d}.nii.gz'.format(motion_dir, fr-1)
29
        source = '{0}/lvsa_{1:02d}.nii.gz'.format(motion_dir, fr)
30
        par = '{0}/ffd_motion.cfg'.format(par_dir)
31
        dof = '{0}/ffd_{1:02d}_to_{2:02d}.dof.gz'.format(motion_dir, fr-1, fr)
32
33
        if not os.path.exists(dof):
34
            os.system('mirtk register '
35
                      '{0} '
36
                      '{1} '
37
                      '-parin {2} '
38
                      '-dofout {3}'
39
                      .format(target, source, par, dof))
40
41
    # Compose inter-frame transformation fields
42
    for fr in range(2, n_frame):
43
        dofs = ''
44
        for k in range(1, fr+1):
45
            dof = '{0}/ffd_{1:02d}_to_{2:02d}.dof.gz'.format(motion_dir, k-1, k)
46
            dofs += dof + ' '
47
            dof_out = '{0}/ffd_comp_00_to_{1:02d}.dof.gz'.format(motion_dir, fr)
48
            if not os.path.exists(dof_out):
49
                os.system('mirtk compose-dofs '
50
                          '{0} '
51
                          '{1}'
52
                          .format(dofs, dof_out))
53
54
    # Refine motion fields
55
    # Composition of inter-frame motion fields can lead to accumulative errors. At this step, we refine the motion fields
56
    # by re-registering the n-th frame with the ED frame.
57
    for fr in range(2, n_frame):
58
        target = '{0}/lvsa_00.nii.gz'.format(motion_dir)
59
        source = '{0}/lvsa_{1:02d}.nii.gz'.format(motion_dir, fr)
60
        par = '{0}/ffd_refine.cfg'.format(par_dir)
61
        dofin = '{0}/ffd_comp_00_to_{1:02d}.dof.gz'.format(motion_dir, fr)
62
        dof = '{0}/ffd_00_to_{1:02d}.dof.gz'.format(motion_dir, fr)
63
        if not os.path.exists(dof):
64
            os.system('mirtk register '
65
                      '{0} '
66
                      '{1} '
67
                      '-parin {2} '
68
                      '-dofin {3} '
69
                      '-dofout {4}'
70
                      .format(target, source, par, dofin, dof))
71
72
    # Obtain the RV mesh with the same number of points as the template mesh
73
    os.system('srreg '
74
              '{2}/vtks/RV_ED.vtk '
75
              '{0}/RVendo_ED.vtk '
76
              '-dofout {1}/RV_srreg.dof.gz '
77
              '-symmetric'
78
              .format(tamplate_dir, motion_dir, data_dir))
79
    
80
    os.system('mirtk transform-points '
81
              '{0}/RVendo_ED.vtk '
82
              '{1}/RV_ED_srreg.vtk '
83
              '-dofin {1}/RV_srreg.dof.gz '
84
              '-invert'
85
              .format(tamplate_dir, motion_dir))
86
    
87
    os.system('sareg '
88
              '{0}/RV_ED_srreg.vtk '
89
              '{1}/vtks/RV_ED.vtk '
90
              '-dofout {0}/RV_sareg.dof.gz '
91
              '-symmetric'
92
              .format(motion_dir, data_dir))
93
    
94
    os.system('snreg '
95
              '{0}/RV_ED_srreg.vtk '
96
              '{1}/vtks/RV_ED.vtk '
97
              '-dofin {0}/RV_sareg.dof.gz '
98
              '-dofout {0}/RV_snreg.dof.gz '
99
              '-ds 20 -symmetric'
100
              .format(motion_dir, data_dir))
101
    
102
    os.system('mirtk transform-points '
103
              '{0}/RV_ED_srreg.vtk '
104
              '{0}/RV_fr00.vtk '
105
              '-dofin {0}/RV_snreg.dof.gz'
106
              .format(motion_dir))
107
108
    # Transform the mesh
109
    for fr in range(1, n_frame):
110
        os.system('mirtk transform-points '
111
                  '{0}/RV_fr00.vtk '
112
                  '{0}/RV_fr{1:02d}.vtk '
113
                  '-dofin {0}/ffd_00_to_{1:02d}.dof.gz'
114
                  .format(motion_dir, fr))
115
     
116
    # Convert vtks to text files
117
    for fr in range(0, n_frame):
118
        os.system('vtk2txt '
119
                  '{0}/RV_fr{1:02d}.vtk '
120
                  '{0}/RV_fr{1:02d}.txt'
121
                  .format(motion_dir, fr))
122
123
124
def apply_PC(subject, data_dir):
125
    
126
    print('  decimateing {0}'.format(subject))    
127
    
128
    subject_dir = os.path.join(data_dir, subject)
129
        
130
    motion_dir = os.path.join(subject_dir, 'motion')
131
            
132
    os.system('mirtk decimate-surface '
133
              '{0}/RV_fr00.vtk '
134
              '{0}/RV_fr00_new.vtk '
135
              '-reduceby 98.9 '
136
              '-preservetopology on'
137
              .format(motion_dir))
138
    
139
    os.system('snreg '
140
              '{0}/RV_fr00_new.vtk '
141
              '{0}/RV_fr00.vtk '
142
              '-dofout {0}/transformation.vtk '
143
              '-epsilon 0.0001'
144
              .format(motion_dir))
145
   
146
    os.system('mirtk transform-points '
147
              '{0}/RV_fr00_new.vtk '
148
              '{0}/RV_fr00_new_new.vtk '
149
              '-dofin {0}/transformation.vtk'
150
              .format(motion_dir))
151
    
152
    os.system('mirtk match-points '
153
              '{0}/RV_fr00_new_new.vtk '
154
              '{0}/RV_fr00.vtk '
155
              '-corout {0}/matchedpointsnew.txt'
156
              .format(motion_dir))
157
158
159
def decimate(dir_0, coreNo, parallel):
160
               
161
    if parallel:
162
    
163
        print('decimationg running on {0} cores'.format(coreNo))
164
        
165
        pool = Pool(processes = coreNo) 
166
        
167
        # partial only in Python 2.7+
168
#        pool.map(partial(apply_PC, sorted(os.listdir(dir_0))))
169
        
170
        pool.map(partial(apply_PC, data_dir=dir_0), sorted(os.listdir(dir_0)))    
171
                
172
    else:
173
        
174
        print('decimation running subsequently')
175
                
176
        data_dir = dir_0
177
         
178
        i = 0
179
                                     
180
        for subject in sorted(os.listdir(data_dir)):
181
            
182
            if i == 0:
183
            
184
                subject_dir = os.path.join(data_dir, subject)
185
    
186
                if not os.path.isdir(subject_dir):
187
                    
188
                    print('  {0} is not a valid folder, Skip'.format(subject_dir))
189
                    
190
                    continue 
191
                       
192
                print('  decimating {0}'.format(subject))  
193
                
194
                motion_dir = os.path.join(subject_dir, 'motion')
195
                
196
                os.system('mirtk decimate-surface '
197
                          '{0}/RV_fr00.vtk '
198
                          '{0}/RV_fr00_new.vtk '
199
                          '-reduceby 98.9 '
200
                          '-preservetopology on'
201
                          .format(motion_dir))
202
                
203
                os.system('snreg '
204
                          '{0}/RV_fr00_new.vtk '
205
                          '{0}/RV_fr00.vtk '
206
                          '-dofout {0}/transformation.vtk '
207
                          '-epsilon 0.0001'
208
                          .format(motion_dir))
209
           
210
                os.system('mirtk transform-points '
211
                          '{0}/RV_fr00_new.vtk '
212
                          '{0}/RV_fr00_new_new.vtk '
213
                          '-dofin {0}/transformation.vtk'
214
                          .format(motion_dir))
215
                
216
                os.system('mirtk match-points '
217
                          '{0}/RV_fr00_new_new.vtk '
218
                          '{0}/RV_fr00.vtk '
219
                          '-corout {1}/matchedpointsnew.txt'
220
                          .format(motion_dir, data_dir))
221
             
222
                i = 1 
223
                
224
            print('  finish decimation in {0}'.format(subject))