Skip to content

Commit 07c840b

Browse files
authored
Merge pull request #3173 from mgxd/enh/euler-number
ENH: Detect values for EulerNumber interface
2 parents 523dad9 + 312ae3d commit 07c840b

File tree

3 files changed

+34
-3
lines changed

3 files changed

+34
-3
lines changed

nipype/interfaces/freesurfer/tests/test_auto_EulerNumber.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def test_EulerNumber_inputs():
1717

1818

1919
def test_EulerNumber_outputs():
20-
output_map = dict(out_file=dict(extensions=None,),)
20+
output_map = dict(defects=dict(), euler=dict(),)
2121
outputs = EulerNumber.output_spec()
2222

2323
for key, metadata in list(output_map.items()):

nipype/interfaces/freesurfer/tests/test_utils.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,3 +230,19 @@ def test_mrisexpand(tmpdir):
230230
assert op.dirname(if_out_file) == op.dirname(fsavginfo["smoothwm"])
231231
# Node places output in working directory
232232
assert op.dirname(nd_out_file) == nd_res.runtime.cwd
233+
234+
235+
@pytest.mark.skipif(fs.no_freesurfer(), reason="freesurfer is not installed")
236+
def test_eulernumber(tmpdir):
237+
# grab a surface from fsaverage
238+
fssrc = FreeSurferSource(
239+
subjects_dir=fs.Info.subjectsdir(), subject_id="fsaverage", hemi="lh"
240+
)
241+
pial = fssrc.run().outputs.pial
242+
assert isinstance(pial, str), "Problem when fetching surface file"
243+
244+
eu = fs.EulerNumber()
245+
eu.inputs.in_file = pial
246+
res = eu.run()
247+
assert res.outputs.defects == 0
248+
assert res.outputs.euler == 2

nipype/interfaces/freesurfer/utils.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2592,7 +2592,9 @@ class EulerNumberInputSpec(FSTraitedSpec):
25922592

25932593

25942594
class EulerNumberOutputSpec(TraitedSpec):
2595-
out_file = File(exists=False, desc="Output file for EulerNumber")
2595+
euler = traits.Int(desc="Euler number of cortical surface. A value of 2 signals a "
2596+
"topologically correct surface model with no holes")
2597+
defects = traits.Int(desc="Number of defects")
25962598

25972599

25982600
class EulerNumber(FSCommand):
@@ -2612,9 +2614,22 @@ class EulerNumber(FSCommand):
26122614
input_spec = EulerNumberInputSpec
26132615
output_spec = EulerNumberOutputSpec
26142616

2617+
def _run_interface(self, runtime):
2618+
runtime = super()._run_interface(runtime)
2619+
self._parse_output(runtime.stdout, runtime.stderr)
2620+
return runtime
2621+
2622+
def _parse_output(self, stdout, stderr):
2623+
"""Parse stdout / stderr and extract defects"""
2624+
m = re.search(r'(?<=total defect index = )\d+', stdout or stderr)
2625+
if m is None:
2626+
raise RuntimeError("Could not fetch defect index")
2627+
self._defects = int(m.group())
2628+
26152629
def _list_outputs(self):
26162630
outputs = self._outputs().get()
2617-
outputs["out_file"] = os.path.abspath(self.inputs.in_file)
2631+
outputs["defects"] = self._defects
2632+
outputs["euler"] = 2 - (2 * self._defects)
26182633
return outputs
26192634

26202635

0 commit comments

Comments
 (0)