Ahoi hoi folks,
while working on some pipelines I stumbled across a possible bug within nipype’s label2label
interface, but wanted to ask here before I go nuts on github.
In my pipeline I want to transform some .label
files into native space using freesurfer’s label2label
. More precisely, I have 5 .label
files per hemisphere in two versions that I want to transform from fsaverage into certain participant’s native space. The respective node looks like this:
# Transform the surface ROIs to the target space
inverse_transform_mni_surface_lh_post2ant = MapNode(Label2Label(hemisphere = 'lh'),
iterfield=['source_label'],
name = 'inverse_transform_mni_surface_lh_post2ant')
I collect the remaining inputs via fssource
, infosource
and selectfiles
:
fssource_lh = Node(FreeSurferSource(subjects_dir=fs_dir, hemi='lh'),
run_without_submitting=True,
name='fssource_lh')
infosource = Node(IdentityInterface(fields=['subject_id',
'source_subject']),
name="infosource")
infosource.iterables = [('subject_id', subject_list),
('source_subject', source_id)]
source_subject_white_lh = opj(input_dir_source, '{source_subject}', 'surf/lh.white') # source .white
source_subject_sphere_lh = opj(input_dir_source, '{source_subject}', 'surf/lh.sphere.reg') # source .sphere.reg
mni_surface_lh_post2ant = opj(input_dir_ROI, 'surf_posterior2anterior/lh*.label') # label files in source space that should be transformed
target = opj(input_dir_preproc, 'realign', '{subject_id}', 'mean*merged.nii') # participant's target space
Subsequently I connect everything within my workflow:
inverse_ROI_ANTS_flow.connect([(infosource, selectfiles, [('subject_id', 'subject_id'),
('source_subject', 'source_subject')]),
(infosource, fssource_lh, [('subject_id', 'subject_id')]),
(infosource, fssource_rh, [('subject_id', 'subject_id')]),
(infosource, inverse_transform_mni_surface_lh_post2ant, [('subject_id', 'subject_id')]),
(fssource_lh, inverse_transform_mni_surface_lh_post2ant, [('sphere_reg', 'sphere_reg')]),
(fssource_lh, inverse_transform_mni_surface_lh_post2ant, [('white', 'white')]),
(infosource, inverse_transform_mni_surface_lh_post2ant, [('source_subject', 'source_subject')]),
(selectfiles, inverse_transform_mni_surface_lh_post2ant, [('source_subject_white_lh', 'source_white')]),
(selectfiles, inverse_transform_mni_surface_lh_post2ant, [('source_subject_sphere_lh', 'source_sphere_reg')]),
(selectfiles, inverse_transform_mni_surface_lh_post2ant, [('mni_surface_lh_post2ant', 'source_label')]),
])
Running the workflow like this results in the following error:
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.
As far as I get it, there’s problem creating the output path for the out_files
of label2label
.
Both, report.rst and command.txt within the node’s workingdir folder look fine. Except of course, I don’t get any output there. Interestingly, the transformed .label files are still correctly generated and stored in the participant’s freesurfer/{subject_id}/label/
folder. Setting a specific out_file name
within the node like this:
inverse_transform_mni_surface_lh_post2ant = MapNode(Label2Label(hemisphere = 'lh',
out_file='test.label'),
iterfield=['source_label'],
name = 'inverse_transform_mni_surface_lh_post2ant')
solves the error and puts a .label
file with the respective name in the node’s workingdir as well as datasink folder.
Am I being a dumb dumb and missing something obvious here, or is it really a label2label/nipype
problem in that sense, that the output path isn’t generated/passed correctly?
Would be great to get some input from you.
Best, Peer