Repository: nipy/nipype

Issue:
FSL dtifit add sse to outputspec
### Summary
nipype's interface for FSL dtifit currently has a parameter "sse" which produces the sum of squared errors. This output does not appear in the OutputSpec.

### Actual behavior
You can use the parameter and the image is produced correctly, but there is no way to further connect the output to other nodes, since it is not part of dtifit's official outputs.

### Expected behavior
Similar to the tensor file the sse-image should be made available for further processing.

### How to replicate the behavior
    >>> from nipype.interfaces import fsl
    >>> dti = fsl.DTIFit()
    >>> dti.inputs.dwi = 'diffusion.nii'
    >>> dti.inputs.bvecs = 'bvecs'
    >>> dti.inputs.bvals = 'bvals'
    >>> dti.inputs.base_name = 'TP'
    >>> dti.inputs.mask = 'mask.nii'
    >>> dti.inputs.sse = True
    >>> dti.save_tensor = True
    >>> dti.cmdline
    'dtifit -k diffusion.nii -o TP -m mask.nii -r bvecs -b bvals --save_tensor --sse'
    >>> out = dti.run()
    >>> out.outputs
    'FA = private/dtifit__FA.nii.gz
     L1 = private/dtifit__L1.nii.gz
     L2 = private/dtifit__L2.nii.gz
     L3 = private/dtifit__L3.nii.gz
     MD = private/dtifit__MD.nii.gz
     MO = private/dtifit__MO.nii.gz
     S0 = private/dtifit__S0.nii.gz
     V1 = private/dtifit__V1.nii.gz
     V2 = private/dtifit__V2.nii.gz
     V3 = private/dtifit__V3.nii.gz
     tensor = private/dtifit__tensor.nii.gz'

-> sse is missing

### Platform details:
This is not platform dependant!
{'commit_hash': '3ec8065',
 'commit_source': 'repository',
 'networkx_version': '2.1',
 'nibabel_version': '2.1.0',
 'nipype_version': '1.1.4-dev+g3ec8065',
 'numpy_version': '1.15.0',
 'pkg_path': 'private/nipype/nipype',
 'scipy_version': '1.1.0',
 'sys_executable': '/usr/bin/python',
 'sys_platform': 'linux2',
 'sys_version': '2.7.9 (default, Jun 29 2016, 13:08:31) \n[GCC 4.9.2]',
 'traits_version': '4.6.0'}

I have written a fix based on the example of 'save_tensor', but the guidelines say i should open an issue before making a pull request, so here you go ;)
Thanks for the great work so far!




Discussion:
A PR would be great - thanks!

Resolving patch:
diff --git a/nipype/interfaces/fsl/dti.py b/nipype/interfaces/fsl/dti.py
--- a/nipype/interfaces/fsl/dti.py
+++ b/nipype/interfaces/fsl/dti.py
@@ -85,6 +85,8 @@ class DTIFitOutputSpec(TraitedSpec):
               'diffusion weighting'))
     tensor = File(
         exists=True, desc='path/name of file with the 4D tensor volume')
+    sse = File(
+        exists=True, desc='path/name of file with the summed squared error')
 
 
 class DTIFit(FSLCommand):
@@ -111,13 +113,21 @@ class DTIFit(FSLCommand):
     output_spec = DTIFitOutputSpec
 
     def _list_outputs(self):
+        keys_to_ignore = {'outputtype', 'environ', 'args'}
+        # Optional output: Map output name to input flag
+        opt_output = {'tensor': self.inputs.save_tensor,
+                      'sse': self.inputs.sse}
+        # Ignore optional output, whose corresponding input-flag is not defined
+        # or set to False
+        for output, input_flag in opt_output.items():
+            if isdefined(input_flag) and input_flag:
+                # this is wanted output, do not ignore
+                continue
+            keys_to_ignore.add(output)
+
         outputs = self.output_spec().get()
-        for k in list(outputs.keys()):
-            if k not in ('outputtype', 'environ', 'args'):
-                if k != 'tensor' or (isdefined(self.inputs.save_tensor)
-                                     and self.inputs.save_tensor):
-                    outputs[k] = self._gen_fname(
-                        self.inputs.base_name, suffix='_' + k)
+        for k in set(outputs.keys()) - keys_to_ignore:
+            outputs[k] = self._gen_fname(self.inputs.base_name, suffix='_' + k)
         return outputs
 
 


Test patch:
diff --git a/nipype/interfaces/fsl/tests/test_auto_DTIFit.py b/nipype/interfaces/fsl/tests/test_auto_DTIFit.py
--- a/nipype/interfaces/fsl/tests/test_auto_DTIFit.py
+++ b/nipype/interfaces/fsl/tests/test_auto_DTIFit.py
@@ -66,6 +66,7 @@ def test_DTIFit_outputs():
         V2=dict(),
         V3=dict(),
         tensor=dict(),
+        sse=dict(),
     )
     outputs = DTIFit.output_spec()