diff --git a/nipype/pipeline/engine/tests/test_join.py b/nipype/pipeline/engine/tests/test_join.py index 54ff15048f..77fc0f2fdf 100644 --- a/nipype/pipeline/engine/tests/test_join.py +++ b/nipype/pipeline/engine/tests/test_join.py @@ -627,3 +627,35 @@ def sq(x): joinfield=['in1']) wf.connect(square, 'out', square_join, "in1") wf.run() + + +def test_join_nestediters(tmpdir): + tmpdir.chdir() + + def exponent(x, p): + return x ** p + + wf = pe.Workflow('wf', base_dir=tmpdir.strpath) + + xs = pe.Node(IdentityInterface(['x']), + iterables=[('x', [1, 2])], + name='xs') + ps = pe.Node(IdentityInterface(['p']), + iterables=[('p', [3, 4])], + name='ps') + exp = pe.Node(Function(function=exponent), name='exp') + exp_joinx = pe.JoinNode(Merge(1, ravel_inputs=True), + name='exp_joinx', + joinsource='xs', + joinfield=['in1']) + exp_joinp = pe.JoinNode(Merge(1, ravel_inputs=True), + name='exp_joinp', + joinsource='ps', + joinfield=['in1']) + wf.connect([ + (xs, exp, [('x', 'x')]), + (ps, exp, [('p', 'p')]), + (exp, exp_joinx, [('out', 'in1')]), + (exp_joinx, exp_joinp, [('out', 'in1')])]) + + wf.run() diff --git a/nipype/pipeline/engine/utils.py b/nipype/pipeline/engine/utils.py index 08d357ff64..0a59aac26a 100644 --- a/nipype/pipeline/engine/utils.py +++ b/nipype/pipeline/engine/utils.py @@ -1054,12 +1054,14 @@ def make_field_func(*pair): for src_id in list(old_edge_dict.keys()): # Drop the original JoinNodes; only concerned with # generated Nodes - if hasattr(node, 'joinfield'): + if hasattr(node, 'joinfield') and node.itername == src_id: continue # Patterns: # - src_id : Non-iterable node - # - src_id.[a-z]\d+ : IdentityInterface w/ iterables - # - src_id.[a-z]I.[a-z]\d+ : Non-IdentityInterface w/ iterables + # - src_id.[a-z]\d+ : + # IdentityInterface w/ iterables or nested JoinNode + # - src_id.[a-z]I.[a-z]\d+ : + # Non-IdentityInterface w/ iterables # - src_idJ\d+ : JoinNode(IdentityInterface) if re.match(src_id + r'((\.[a-z](I\.[a-z])?|J)\d+)?$', node.itername):