Repository: nipy/nipype

Issue:
Removal of AFNICommand._gen_fname breaks Allineate
### Summary
I'm trying to use 3dAllineate within a workflow, and when writing out the transformation (but forgetting to end it with `1D`) I came across an error with the automatic output filename determination. It looks like the method `_gen_fname` was removed from `AFNICommand` in #2964. I'm not sure what the appropriate fix is- should `_gen_fname` be re-added, or was it removed with another long-term solution in mind?

### Actual behavior
After it successfully runs, Allineate raises the following error:
```
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/interfaces/base/core.py", line 378, in run
    outputs = self.aggregate_outputs(runtime)
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/interfaces/base/core.py", line 455, in aggregate_outputs
    predicted_outputs = self._list_outputs()  # Predictions from _list_outputs
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/interfaces/afni/preprocess.py", line 506, in _list_outputs
    outputs['out_matrix'] = self._gen_fname(
AttributeError: 'Allineate' object has no attribute '_gen_fname'
```
### Expected behavior
The node should run and the output files should reflect what files were generated, rather than the filename I specified.

### How to replicate the behavior
Run Allineate with `out_matrix` or `out_param_file` set as a filename that _doesn't_ end in `1D` or `1d`. This should trigger `AFNICommand._gen_fname`, but that method doesn't exist.

### Script/Workflow details

```python
from nipype.interfaces import afni

allin = afni.Allineate(
    reference='/bids_dataset/sub-TEST1/ses-S2/anat/sub-TEST1_ses-S2_T1w.nii.gz',
    in_file='/bids_dataset/sub-TEST1/ses-S2/func/sub-TEST1_ses-S2_task-primaryEstimation_rec-magnitude_run-01_echo-1_sbref.nii.gz',
    out_matrix='sbref2anat.mat')
allin.run()
```

### Platform details:

<!-- Please run the following code from your shell and place the output between the triple ticks, below.
python -c "import nipype; from pprint import pprint; pprint(nipype.get_info())"
-->

```
{'commit_hash': '4b69cfcfa',
 'commit_source': 'installation',
 'networkx_version': '2.3',
 'nibabel_version': '2.5.0',
 'nipype_version': '1.2.2',
 'numpy_version': '1.15.4',
 'pkg_path': '/usr/local/miniconda/lib/python3.7/site-packages/nipype',
 'scipy_version': '1.1.0',
 'sys_executable': '/usr/local/miniconda/bin/python',
 'sys_platform': 'linux',
 'sys_version': '3.7.1 (default, Dec 14 2018, 19:28:38) \n[GCC 7.3.0]',
 'traits_version': '4.6.0'}
```

### Execution environment
Docker container built from the current fMRIPrep development Dockerfile (with pybids master installed).

Choose one
- **Container [Tag: ???]**
- My python environment inside container [Base Tag: ???]
- My python environment outside container



Discussion:

Resolving patch:
diff --git a/nipype/interfaces/afni/base.py b/nipype/interfaces/afni/base.py
--- a/nipype/interfaces/afni/base.py
+++ b/nipype/interfaces/afni/base.py
@@ -11,7 +11,7 @@
 from distutils import spawn
 
 from ... import logging, LooseVersion
-from ...utils.filemanip import split_filename
+from ...utils.filemanip import split_filename, fname_presuffix
 from ..base import (CommandLine, traits, CommandLineInputSpec, isdefined, File,
                     TraitedSpec, PackageInfo)
 from ...external.due import BibTeX
@@ -237,6 +237,55 @@ def _list_outputs(self):
                         outputs[name] = outputs[name] + "+orig.BRIK"
         return outputs
 
+    def _gen_fname(self,
+                   basename,
+                   cwd=None,
+                   suffix=None,
+                   change_ext=True,
+                   ext=None):
+        """
+        Generate a filename based on the given parameters.
+
+        The filename will take the form: cwd/basename<suffix><ext>.
+        If change_ext is True, it will use the extentions specified in
+        <instance>intputs.output_type.
+
+        Parameters
+        ----------
+        basename : str
+            Filename to base the new filename on.
+        cwd : str
+            Path to prefix to the new filename. (default is os.getcwd())
+        suffix : str
+            Suffix to add to the `basename`.  (defaults is '' )
+        change_ext : bool
+            Flag to change the filename extension to the FSL output type.
+            (default True)
+
+        Returns
+        -------
+        fname : str
+            New filename based on given parameters.
+
+        """
+        if not basename:
+            msg = 'Unable to generate filename for command %s. ' % self.cmd
+            msg += 'basename is not set!'
+            raise ValueError(msg)
+
+        if cwd is None:
+            cwd = os.getcwd()
+        if ext is None:
+            ext = Info.output_type_to_ext(self.inputs.outputtype)
+        if change_ext:
+            suffix = ''.join((suffix, ext)) if suffix else ext
+
+        if suffix is None:
+            suffix = ''
+        fname = fname_presuffix(
+            basename, suffix=suffix, use_ext=False, newpath=cwd)
+        return fname
+
 
 def no_afni():
     """Check whether AFNI is not available."""
diff --git a/nipype/interfaces/afni/model.py b/nipype/interfaces/afni/model.py
--- a/nipype/interfaces/afni/model.py
+++ b/nipype/interfaces/afni/model.py
@@ -309,58 +309,6 @@ def _list_outputs(self):
         return outputs
 
 
-    def _gen_fname(self,
-                   basename,
-                   cwd=None,
-                   suffix=None,
-                   change_ext=True,
-                   ext=None):
-        """Generate a filename based on the given parameters.
-
-        The filename will take the form: cwd/basename<suffix><ext>.
-        If change_ext is True, it will use the extentions specified in
-        <instance>intputs.output_type.
-
-        Parameters
-        ----------
-        basename : str
-            Filename to base the new filename on.
-        cwd : str
-            Path to prefix to the new filename. (default is os.getcwd())
-        suffix : str
-            Suffix to add to the `basename`.  (defaults is '' )
-        change_ext : bool
-            Flag to change the filename extension to the FSL output type.
-            (default True)
-
-        Returns
-        -------
-        fname : str
-            New filename based on given parameters.
-
-        """
-        from nipype.utils.filemanip import fname_presuffix
-
-        if basename == '':
-            msg = 'Unable to generate filename for command %s. ' % self.cmd
-            msg += 'basename is not set!'
-            raise ValueError(msg)
-        if cwd is None:
-            cwd = os.getcwd()
-        if ext is None:
-            ext = Info.output_type_to_ext(self.inputs.outputtype)
-        if change_ext:
-            if suffix:
-                suffix = ''.join((suffix, ext))
-            else:
-                suffix = ext
-        if suffix is None:
-            suffix = ''
-        fname = fname_presuffix(
-            basename, suffix=suffix, use_ext=False, newpath=cwd)
-        return fname
-
-
 class RemlfitInputSpec(AFNICommandInputSpec):
     # mandatory files
     in_files = InputMultiPath(


Test patch: