You probably want to split your anatomical and functional preprocessing into separate workflows. Something like:
inputnode = Node(IdentityInterface(fields=['anatomical_file', 'functional_file']), name='inputnode')
inputnode.iterables = ('functional_file', functional_files)
# Assume we have functions to generate subworkflows
anat_wf = init_anat_wf(...)
func_wf = init_func_wf(...)
workflow.connect([
(inputnode, anat_wf, [('anatomical_file', 'inputnode.in_file')]),
(inputnode, func_wf, [('functional_file', 'inputnode.in_file')]),
(anat_wf, func_wf, [('outputnode.out_file', 'inputnode.anatomical_ref')]),
])
The only issue is that in nipype 1.x, there’s no way to dynamically create an iterable based on the output of a node. You might consider using pydra which can split over workflow-runtime outputs.
Note that I’m not 100% positive about the behavior of iterables. But if iterating over functional_file
causes anat_wf
to be iterated over, you can always split the sources into multiple IdentityInterface
s and only provide an iterable to one. e.g.,
anat_src = Node(IdentityInterface(fields=['anatomical_file']), name='anat_src')
func_src = Node(IdentityInterface(fields=['functional_file']), name='func_src')
func_src.iterables = ('functional_file', functional_files)
# Assume we have functions to generate subworkflows
anat_wf = init_anat_wf(...)
func_wf = init_func_wf(...)
workflow.connect([
(anat_src, anat_wf, [('anatomical_file', 'inputnode.in_file')]),
(func_src, func_wf, [('functional_file', 'inputnode.in_file')]),
(anat_wf, func_wf, [('outputnode.out_file', 'inputnode.anatomical_ref')]),
])
Yet another option, which is what fMRIPrep does, is to actually specifically create a workflow for each BOLD file. (We do this because the metadata about each BOLD file can differ and cause us to construct the workflow differently.)
# Assume we have functions to generate subworkflows
anat_wf = init_anat_wf(...)
for functional_file in functional_files:
func_wf = init_func_wf(...)
workflow.connect([
(anat_wf, func_wf, [('outputnode.out_file', 'inputnode.anatomical_ref')]),
])