From e530d445040259d9e6b031e11c617eec7b9fb8dd Mon Sep 17 00:00:00 2001 From: mathiasg Date: Fri, 21 Feb 2020 15:55:57 -0500 Subject: [PATCH 1/3] ENH: Detect values for EulerNumber interface --- nipype/interfaces/freesurfer/utils.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/nipype/interfaces/freesurfer/utils.py b/nipype/interfaces/freesurfer/utils.py index a2b3b7a47b..5a4d6ca425 100644 --- a/nipype/interfaces/freesurfer/utils.py +++ b/nipype/interfaces/freesurfer/utils.py @@ -2592,7 +2592,9 @@ class EulerNumberInputSpec(FSTraitedSpec): class EulerNumberOutputSpec(TraitedSpec): - out_file = File(exists=False, desc="Output file for EulerNumber") + euler = traits.Int(desc="Euler number of cortical surface. A value of 2 signals a " + "topologically correct surface model with no holes") + defects = traits.Int(desc="Number of defects") class EulerNumber(FSCommand): @@ -2612,9 +2614,22 @@ class EulerNumber(FSCommand): input_spec = EulerNumberInputSpec output_spec = EulerNumberOutputSpec + def _run_interface(self, runtime): + runtime = super()._run_interface(runtime) + self._parse_output(runtime.stdout, runtime.stderr) + return runtime + + def _parse_output(self, stdout, stderr): + """Parse stdout / stderr and extract defects""" + m = re.search(r'(?<=total defect index = )\d+', stdout or stderr) + if m is None: + raise RuntimeError("Could not fetch defect index") + self._defects = int(m.group()) + def _list_outputs(self): outputs = self._outputs().get() - outputs["out_file"] = os.path.abspath(self.inputs.in_file) + outputs["defects"] = self._defects + outputs["euler"] = 2 - (2 * self._defects) return outputs From b03db6abedd468e67a5d3b5bde5ab542cdc1a4ad Mon Sep 17 00:00:00 2001 From: mathiasg Date: Fri, 21 Feb 2020 16:30:16 -0500 Subject: [PATCH 2/3] fix: forgotten autotest --- nipype/interfaces/freesurfer/tests/test_auto_EulerNumber.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/freesurfer/tests/test_auto_EulerNumber.py b/nipype/interfaces/freesurfer/tests/test_auto_EulerNumber.py index d31c9278bc..a90be6bca4 100644 --- a/nipype/interfaces/freesurfer/tests/test_auto_EulerNumber.py +++ b/nipype/interfaces/freesurfer/tests/test_auto_EulerNumber.py @@ -17,7 +17,7 @@ def test_EulerNumber_inputs(): def test_EulerNumber_outputs(): - output_map = dict(out_file=dict(extensions=None,),) + output_map = dict(defects=dict(), euler=dict(),) outputs = EulerNumber.output_spec() for key, metadata in list(output_map.items()): From 312ae3d5395ee9f550a70076a9979bb65e4e154a Mon Sep 17 00:00:00 2001 From: mathiasg Date: Sun, 23 Feb 2020 22:49:49 -0500 Subject: [PATCH 3/3] ENH: add testcase --- nipype/interfaces/freesurfer/tests/test_utils.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/nipype/interfaces/freesurfer/tests/test_utils.py b/nipype/interfaces/freesurfer/tests/test_utils.py index 52348bb5e0..996453d654 100644 --- a/nipype/interfaces/freesurfer/tests/test_utils.py +++ b/nipype/interfaces/freesurfer/tests/test_utils.py @@ -230,3 +230,19 @@ def test_mrisexpand(tmpdir): assert op.dirname(if_out_file) == op.dirname(fsavginfo["smoothwm"]) # Node places output in working directory assert op.dirname(nd_out_file) == nd_res.runtime.cwd + + +@pytest.mark.skipif(fs.no_freesurfer(), reason="freesurfer is not installed") +def test_eulernumber(tmpdir): + # grab a surface from fsaverage + fssrc = FreeSurferSource( + subjects_dir=fs.Info.subjectsdir(), subject_id="fsaverage", hemi="lh" + ) + pial = fssrc.run().outputs.pial + assert isinstance(pial, str), "Problem when fetching surface file" + + eu = fs.EulerNumber() + eu.inputs.in_file = pial + res = eu.run() + assert res.outputs.defects == 0 + assert res.outputs.euler == 2