Skip to content

[BUG] possible bug label2label interface in Linux #2310

@PeerHerholz

Description

@PeerHerholz

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions