- Notifications
You must be signed in to change notification settings - Fork 536
Description
Summary
Addressing a possible bug in nipype's label2label interface after asking about an error on neurostars.org.
I stumbled upon this while working on a workflow which transforms some ROIs (.label) from mni to native space.
problem "output file"
I defined my label2label node like this:
# Transform the surface ROIs to the target space inverse_transform_mni_surface_lh_post2ant = MapNode(Label2Label(hemisphere = 'lh', subjects_dir=fs_dir), iterfield=['source_label'], name = 'inverse_transform_mni_surface_lh_post2ant')
Actual behavior "output file"
error message:
Traceback (most recent call last): File "/home/lmn/install/miniconda3/lib/python3.6/site-packages/nipype/pipeline/plugins/multiproc.py", line 52, in run_node result['result'] = node.run(updatehash=updatehash) File "/home/lmn/install/miniconda3/lib/python3.6/site-packages/nipype/pipeline/engine/nodes.py", line 372, in run self._run_interface() File "/home/lmn/install/miniconda3/lib/python3.6/site-packages/nipype/pipeline/engine/nodes.py", line 482, in _run_interface self._result = self._run_command(execute) File "/home/lmn/install/miniconda3/lib/python3.6/site-packages/nipype/pipeline/engine/nodes.py", line 613, in _run_command result = self._interface.run() File "/home/lmn/install/miniconda3/lib/python3.6/site-packages/nipype/interfaces/freesurfer/model.py", line 1167, in run return super(Label2Label, self).run(**inputs) File "/home/lmn/install/miniconda3/lib/python3.6/site-packages/nipype/interfaces/freesurfer/base.py", line 162, in run return super(FSCommand, self).run(**inputs) File "/home/lmn/install/miniconda3/lib/python3.6/site-packages/nipype/interfaces/base.py", line 1082, in run outputs = self.aggregate_outputs(runtime) File "/home/lmn/install/miniconda3/lib/python3.6/site-packages/nipype/interfaces/base.py", line 1153, in aggregate_outputs predicted_outputs = self._list_outputs() File "/home/lmn/install/miniconda3/lib/python3.6/site-packages/nipype/interfaces/freesurfer/model.py", line 1140, in _list_outputs self.inputs.out_file) File "/home/lmn/install/miniconda3/lib/python3.6/posixpath.py", line 92, in join genericpath._check_arg_types('join', a, *p) File "/home/lmn/install/miniconda3/lib/python3.6/genericpath.py", line 149, in _check_arg_types (funcname, s.__class__.__name__)) from None TypeError: join() argument must be str or bytes, not '_Undefined' Interface Label2Label failed to run.
Expected behavior "output file"
store transformed .label
files in datasink container / subject's label
folder.
→ setting an output file name within the node, solves the error, but then all transformed files would've the same name.
problem "copy inputs"
After checking the docs again, I recognized that I need to set the optional input argument "copy_inputs" to "True" if the function is running as a node.
Here's the respective line from the .help():
copy_inputs: (a boolean) If running as a node, set this to True.This will copy the input files to the node directory.
Changing my node accordingly to look like this:
inverse_transform_mni_surface_lh_post2ant = MapNode(Label2Label(hemisphere = 'lh', subjects_dir=fs_dir, copy_inputs=True), iterfield=['source_label'], name = 'inverse_transform_mni_surface_lh_post2ant')
results in a different error:
Actual behavior "copy inputs"
171128-18:41:07,658 workflow INFO: Traceback (most recent call last): File "/home/lmn/install/miniconda3/lib/python3.6/site-packages/nipype/pipeline/plugins/multiproc.py", line 52, in run_node result['result'] = node.run(updatehash=updatehash) File "/home/lmn/install/miniconda3/lib/python3.6/site-packages/nipype/pipeline/engine/nodes.py", line 372, in run self._run_interface() File "/home/lmn/install/miniconda3/lib/python3.6/site-packages/nipype/pipeline/engine/nodes.py", line 482, in _run_interface self._result = self._run_command(execute) File "/home/lmn/install/miniconda3/lib/python3.6/site-packages/nipype/pipeline/engine/nodes.py", line 613, in _run_command result = self._interface.run() File "/home/lmn/install/miniconda3/lib/python3.6/site-packages/nipype/interfaces/freesurfer/model.py", line 1150, in run '{0}.sphere.reg'.format(hemi)) File "/home/lmn/install/miniconda3/lib/python3.6/site-packages/nipype/interfaces/freesurfer/utils.py", line 72, in copy2subjdir shutil.copy(in_file, out_file) File "/home/lmn/install/miniconda3/lib/python3.6/shutil.py", line 242, in copy copymode(src, dst, follow_symlinks=follow_symlinks) File "/home/lmn/install/miniconda3/lib/python3.6/shutil.py", line 144, in copymode chmod_func(dst, stat.S_IMODE(st.st_mode)) PermissionError: [Errno 1] Operation not permitted: '/path/to/my/pipeline/workingdir_inverse_transform_ROIs_ants_AMCP/inverse_ROI_ANTS_flow/_source_subject_fsaverage_subject_id_AM_1/inverse_transform_mni_surface_lh_post2ant/mapflow/_inverse_transform_mni_surface_lh_post2ant4/AM_1/surf/lh.sphere.reg'
Expected behavior "copy_inputs"
copy input files to a temporary directory within the node directory.
→ checking the error in more detail, especially the respective line in /home/lmn/install/miniconda3/lib/python3.6/shutil.py
, it might be a Linux related problem:
def copymode(src, dst, *, follow_symlinks=True): """Copy mode bits from src to dst. If follow_symlinks is not set, symlinks aren't followed if and only if both `src` and `dst` are symlinks. If `lchmod` isn't available (e.g. Linux) this method does nothing. """ if not follow_symlinks and os.path.islink(src) and os.path.islink(dst): if hasattr(os, 'lchmod'): stat_func, chmod_func = os.lstat, os.lchmod else: return elif hasattr(os, 'chmod'): stat_func, chmod_func = os.stat, os.chmod else: return st = stat_func(src) chmod_func(dst, stat.S_IMODE(st.st_mode))
→ running the same script on my macOS (El Capitan) works fine and like it should, saving the transformed files named respectively in the datasink container.
Script/Workflow details
More information on the workflow on neurostars.org
Platform details:
Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-97-generic x86_64)
nipype version:
{'commit_hash': '<not found>', 'commit_source': '(none found)', 'networkx_version': '1.11', 'nibabel_version': '2.2.0', 'nipype_version': '0.13.1', 'numpy_version': '1.13.3', 'pkg_path': '/home/lmn/install/miniconda3/lib/python3.6/site-packages/nipype', 'scipy_version': '1.0.0', 'sys_executable': '/home/lmn/install/miniconda3/bin/python', 'sys_platform': 'linux', 'sys_version': '3.6.2 | packaged by conda-forge | (default, Jul 23 2017, 22:59:30) \n[GCC 4.8.2 20140120 (Red Hat 4.8.2-15)]', 'traits_version': '4.6.0'}
freesurfer version:
freesurfer-Linux-centos6_x86_64-stable-pub-v6.0.0-2beb96c
Execution environment
- My python environment (Python 3.6.2 | packaged by conda-forge | (default, Jul 23 2017, 22:59:30) outside container, Ubuntu 16.04.3 LTS
- same distribution on macOS El Capitan
Question
→ I need to set "output_file" and "copy_inputs" to get the pipeline running as it should.
Is this really a bug within the label2label interface or am I missing something obvious here?