Skip to content

Commit 66aa596

Browse files
committed
RF: Tie expected files to class attribute
1 parent 1b1010b commit 66aa596

File tree

1 file changed

+40
-54
lines changed

1 file changed

+40
-54
lines changed

nibabies/interfaces/mcribs.py

Lines changed: 40 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class MCRIBReconAllInputSpec(CommandLineInputSpec):
3232
t1w_file = File(
3333
exists=True,
3434
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)',
3636
)
3737
t2w_file = File(
3838
exists=True,
@@ -107,26 +107,51 @@ class MCRIBReconAll(CommandLine):
107107
output_spec = MCRIBReconAllOutputSpec
108108
_no_run = False
109109

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+
110131
@property
111132
def cmdline(self):
112133
cmd = super().cmdline
113-
# 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
114138
if self.inputs.outdir:
115139
sid = self.inputs.subject_id
116140
# Check MIRTK surface recon deformable
117141
if self.inputs.surfrecon:
118142
surfrecon_dir = Path(self.inputs.outdir) / sid / 'SurfReconDeformable' / sid
119-
if self._verify_surfrecon_outputs(surfrecon_dir):
120-
self.inputs.surfrecon = False
143+
if self._verify_outputs('surfrecon', surfrecon_dir):
121144
self._no_run = True
122145
# Check FS directory population
123146
if self.inputs.autorecon_after_surf:
124147
fs_dir = Path(self.inputs.outdir) / sid / 'freesurfer' / sid
125-
if self._verify_autorecon_outputs(fs_dir):
148+
if self._verify_outputs('autorecon', fs_dir):
126149
self._no_run = True
150+
else:
151+
self._no_run = False
127152

128153
if self._no_run:
129-
return 'echo MCRIBSReconAll: nothing to do'
154+
return 'echo MCRIBReconAll: nothing to do'
130155
return cmd
131156

132157
def _setup_directory_structure(self, mcribs_dir: Path) -> None:
@@ -213,8 +238,6 @@ def _run_interface(self, runtime):
213238
mcribs_dir = self.inputs.outdir or Path(runtime.cwd) / 'mcribs'
214239
self._mcribs_dir = Path(mcribs_dir)
215240
if self.inputs.surfrecon:
216-
if not self.inputs.t2w_file:
217-
raise AttributeError('Missing T2w input')
218241
self._setup_directory_structure(self._mcribs_dir)
219242
# overwrite CWD to be in MCRIB subject's directory
220243
runtime.cwd = str(self._mcribs_dir / self.inputs.subject_id)
@@ -226,11 +249,11 @@ def _list_outputs(self):
226249
if self.inputs.surfrecon:
227250
# verify surface reconstruction was successful
228251
surfrecon_dir = self._mcribs_dir / sid / 'SurfReconDeformable' / sid
229-
self._verify_surfrecon_outputs(surfrecon_dir, error=True)
252+
self._verify_outputs('surfrecon', surfrecon_dir, error=True)
230253

231254
mcribs_fs = self._mcribs_dir / sid / 'freesurfer' / sid
232255
if self.inputs.autorecon_after_surf:
233-
self._verify_autorecon_outputs(mcribs_fs, error=True)
256+
self._verify_outputs('autorecon', mcribs_fs, error=True)
234257

235258
outputs['mcribs_dir'] = str(self._mcribs_dir)
236259
if self.inputs.autorecon_after_surf and self.inputs.subjects_dir:
@@ -250,56 +273,19 @@ def _list_outputs(self):
250273

251274
return outputs
252275

253-
@staticmethod
254-
def _verify_surfrecon_outputs(surfrecon_dir: Path, error: bool = False) -> bool:
255-
"""
256-
Sanity check to ensure the surface reconstruction was successful.
257-
258-
MCRIBReconAll does not return a failing exit code if a step failed, which leads
259-
this interface to be marked as completed without error in such cases.
260-
"""
261-
262-
surfrecon_files = {
263-
'meshes': (
264-
'pial-lh-reordered.vtp',
265-
'pial-rh-reordered.vtp',
266-
'white-rh.vtp',
267-
'white-lh.vtp',
268-
)
269-
} # fmt:skip
270-
271-
for d, fls in surfrecon_files.items():
272-
for fl in fls:
273-
if not (surfrecon_dir / d / fl).exists():
274-
if error:
275-
raise FileNotFoundError(f'SurfReconDeformable missing: {fl}')
276-
return False
277-
return True
278-
279-
@staticmethod
280-
def _verify_autorecon_outputs(fs_dir: Path, error: bool = False) -> bool:
276+
def _verify_outputs(self, step: str, root: Path, error: bool = False) -> bool:
281277
"""
282-
Sanity check to ensure the necessary FreeSurfer files have been created.
278+
Method to check to ensure the expected files are present successful.
283279
284280
MCRIBReconAll does not return a failing exit code if a step failed, which leads
285281
this interface to be marked as completed without error in such cases.
286282
"""
287283

288-
fs_files = {
289-
'mri': ('T2.mgz', 'aseg.presurf.mgz', 'ribbon.mgz', 'brain.mgz'),
290-
'label': ('lh.cortex.label', 'rh.cortex.label'),
291-
'stats': ('aseg.stats', 'brainvol.stats', 'lh.aparc.stats', 'rh.curv.stats'),
292-
'surf': (
293-
'lh.pial', 'rh.pial',
294-
'lh.white', 'rh.white',
295-
'lh.curv', 'rh.curv',
296-
'lh.thickness', 'rh.thickness'),
297-
} # fmt:skip
298-
299-
for d, fls in fs_files.items():
300-
for fl in fls:
301-
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():
302288
if error:
303-
raise FileNotFoundError(f'FreeSurfer directory missing: {fl}')
289+
raise FileNotFoundError(f'{step.capitalize()} missing: {fl}')
304290
return False
305291
return True

0 commit comments

Comments
 (0)