@@ -32,7 +32,7 @@ class MCRIBReconAllInputSpec(CommandLineInputSpec):
32
32
t1w_file = File (
33
33
exists = True ,
34
34
copyfile = True ,
35
- desc = 'T1w to be used for deformable (must be registered to T2w image)' ,
35
+ desc = 'T1w to be used for deformable (must be in register with T2w image)' ,
36
36
)
37
37
t2w_file = File (
38
38
exists = True ,
@@ -47,14 +47,20 @@ class MCRIBReconAllInputSpec(CommandLineInputSpec):
47
47
48
48
# MCRIBS options
49
49
conform = traits .Bool (
50
+ False ,
51
+ usedefault = True ,
50
52
argstr = '--conform' ,
51
53
desc = 'Reorients to radiological, axial slice orientation. Resamples to isotropic voxels' ,
52
54
)
53
55
tissueseg = traits .Bool (
56
+ False ,
57
+ usedefault = True ,
54
58
argstr = '--tissueseg' ,
55
59
desc = 'Perform tissue type segmentation' ,
56
60
)
57
61
surfrecon = traits .Bool (
62
+ False ,
63
+ usedefault = True ,
58
64
argstr = '--surfrecon' ,
59
65
desc = 'Reconstruct surfaces' ,
60
66
)
@@ -75,6 +81,8 @@ class MCRIBReconAllInputSpec(CommandLineInputSpec):
75
81
desc = 'Use Deformable fast collision test' ,
76
82
)
77
83
autorecon_after_surf = traits .Bool (
84
+ False ,
85
+ usedefault = True ,
78
86
argstr = '--autoreconaftersurf' ,
79
87
desc = 'Do all steps after surface reconstruction' ,
80
88
)
@@ -99,25 +107,51 @@ class MCRIBReconAll(CommandLine):
99
107
output_spec = MCRIBReconAllOutputSpec
100
108
_no_run = False
101
109
110
+ _expected_files = {
111
+ 'surfrecon' : {
112
+ 'meshes' : (
113
+ 'pial-lh-reordered.vtp' ,
114
+ 'pial-rh-reordered.vtp' ,
115
+ 'white-rh.vtp' ,
116
+ 'white-lh.vtp' ,
117
+ )
118
+ },
119
+ 'autorecon' : {
120
+ 'mri' : ('T2.mgz' , 'aseg.presurf.mgz' , 'ribbon.mgz' , 'brain.mgz' ),
121
+ 'label' : ('lh.cortex.label' , 'rh.cortex.label' ),
122
+ 'stats' : ('aseg.stats' , 'brainvol.stats' , 'lh.aparc.stats' , 'rh.curv.stats' ),
123
+ 'surf' : (
124
+ 'lh.pial' , 'rh.pial' ,
125
+ 'lh.white' , 'rh.white' ,
126
+ 'lh.curv' , 'rh.curv' ,
127
+ 'lh.thickness' , 'rh.thickness' ),
128
+ }
129
+ } # fmt:skip
130
+
102
131
@property
103
132
def cmdline (self ):
104
133
cmd = super ().cmdline
105
- # Avoid processing if valid
134
+ if self .inputs .surfrecon and not self .inputs .t2w_file :
135
+ raise AttributeError ('Missing `t2w_file` input.' )
136
+
137
+ # If an output directory is provided, check if we can skip the run
106
138
if self .inputs .outdir :
107
139
sid = self .inputs .subject_id
108
140
# Check MIRTK surface recon deformable
109
141
if self .inputs .surfrecon :
110
142
surfrecon_dir = Path (self .inputs .outdir ) / sid / 'SurfReconDeformable' / sid
111
- if self ._verify_surfrecon_outputs ( surfrecon_dir , error = False ):
143
+ if self ._verify_outputs ( 'surfrecon' , surfrecon_dir ):
112
144
self ._no_run = True
113
145
# Check FS directory population
114
- elif self .inputs .autorecon_after_surf :
146
+ if self .inputs .autorecon_after_surf :
115
147
fs_dir = Path (self .inputs .outdir ) / sid / 'freesurfer' / sid
116
- if self ._verify_autorecon_outputs ( fs_dir , error = False ):
148
+ if self ._verify_outputs ( 'autorecon' , fs_dir ):
117
149
self ._no_run = True
150
+ else :
151
+ self ._no_run = False
118
152
119
153
if self ._no_run :
120
- return 'echo MCRIBSReconAll : nothing to do'
154
+ return 'echo MCRIBReconAll : nothing to do'
121
155
return cmd
122
156
123
157
def _setup_directory_structure (self , mcribs_dir : Path ) -> None :
@@ -204,8 +238,6 @@ def _run_interface(self, runtime):
204
238
mcribs_dir = self .inputs .outdir or Path (runtime .cwd ) / 'mcribs'
205
239
self ._mcribs_dir = Path (mcribs_dir )
206
240
if self .inputs .surfrecon :
207
- if not self .inputs .t2w_file :
208
- raise AttributeError ('Missing T2w input' )
209
241
self ._setup_directory_structure (self ._mcribs_dir )
210
242
# overwrite CWD to be in MCRIB subject's directory
211
243
runtime .cwd = str (self ._mcribs_dir / self .inputs .subject_id )
@@ -217,11 +249,11 @@ def _list_outputs(self):
217
249
if self .inputs .surfrecon :
218
250
# verify surface reconstruction was successful
219
251
surfrecon_dir = self ._mcribs_dir / sid / 'SurfReconDeformable' / sid
220
- self ._verify_surfrecon_outputs ( surfrecon_dir , error = True )
252
+ self ._verify_outputs ( 'surfrecon' , surfrecon_dir , error = True )
221
253
222
254
mcribs_fs = self ._mcribs_dir / sid / 'freesurfer' / sid
223
255
if self .inputs .autorecon_after_surf :
224
- self ._verify_autorecon_outputs ( mcribs_fs , error = True )
256
+ self ._verify_outputs ( 'autorecon' , mcribs_fs , error = True )
225
257
226
258
outputs ['mcribs_dir' ] = str (self ._mcribs_dir )
227
259
if self .inputs .autorecon_after_surf and self .inputs .subjects_dir :
@@ -241,56 +273,19 @@ def _list_outputs(self):
241
273
242
274
return outputs
243
275
244
- @staticmethod
245
- def _verify_surfrecon_outputs (surfrecon_dir : Path , error : bool ) -> bool :
276
+ def _verify_outputs (self , step : str , root : Path , error : bool = False ) -> bool :
246
277
"""
247
- Sanity check to ensure the surface reconstruction was successful.
278
+ Method to check to ensure the expected files are present successful.
248
279
249
280
MCRIBReconAll does not return a failing exit code if a step failed, which leads
250
281
this interface to be marked as completed without error in such cases.
251
282
"""
252
- # fmt:off
253
- surfrecon_files = {
254
- 'meshes' : (
255
- 'pial-lh-reordered.vtp' ,
256
- 'pial-rh-reordered.vtp' ,
257
- 'white-rh.vtp' ,
258
- 'white-lh.vtp' ,
259
- )
260
- }
261
- # fmt:on
262
- for d , fls in surfrecon_files .items ():
263
- for fl in fls :
264
- if not (surfrecon_dir / d / fl ).exists ():
265
- if error :
266
- raise FileNotFoundError (f'SurfReconDeformable missing: { fl } ' )
267
- return False
268
- return True
269
-
270
- @staticmethod
271
- def _verify_autorecon_outputs (fs_dir : Path , error : bool ) -> bool :
272
- """
273
- Sanity check to ensure the necessary FreeSurfer files have been created.
274
283
275
- MCRIBReconAll does not return a failing exit code if a step failed, which leads
276
- this interface to be marked as completed without error in such cases.
277
- """
278
- # fmt:off
279
- fs_files = {
280
- 'mri' : ('T2.mgz' , 'aseg.presurf.mgz' , 'ribbon.mgz' , 'brain.mgz' ),
281
- 'label' : ('lh.cortex.label' , 'rh.cortex.label' ),
282
- 'stats' : ('aseg.stats' , 'brainvol.stats' , 'lh.aparc.stats' , 'rh.curv.stats' ),
283
- 'surf' : (
284
- 'lh.pial' , 'rh.pial' ,
285
- 'lh.white' , 'rh.white' ,
286
- 'lh.curv' , 'rh.curv' ,
287
- 'lh.thickness' , 'rh.thickness' ),
288
- }
289
- # fmt:on
290
- for d , fls in fs_files .items ():
291
- for fl in fls :
292
- if not (fs_dir / d / fl ).exists ():
284
+ expected = self ._expected_files [step ]
285
+ for d , files in expected .items ():
286
+ for fl in files :
287
+ if not (root / d / fl ).exists ():
293
288
if error :
294
- raise FileNotFoundError (f'FreeSurfer directory missing: { fl } ' )
289
+ raise FileNotFoundError (f'{ step . capitalize () } missing: { fl } ' )
295
290
return False
296
291
return True
0 commit comments