Skip to content

Commit 001bb6d

Browse files
committed
WIP
1 parent a348684 commit 001bb6d

File tree

1 file changed

+56
-22
lines changed

1 file changed

+56
-22
lines changed

nipype/pipeline/engine.py

Lines changed: 56 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,8 +1102,8 @@ def _get_dot(self, prefix=None, hierarchy=None, colored=True,
11021102
class InterfacedWorkflow(Workflow):
11031103
"""
11041104
A workflow that automatically generates the input and output nodes to avoid
1105-
repetitive inputnode.* and outputnode.* connections and allow for fast pipeline
1106-
chaining.
1105+
repetitive inputnode.* and outputnode.* connections and allow for agile
1106+
pipeline chaining.
11071107
"""
11081108

11091109
@property
@@ -1129,22 +1129,26 @@ def __init__(self, name, base_dir=None, input_names=[], output_names=[]):
11291129
super(InterfacedWorkflow, self).__init__(name, base_dir)
11301130

11311131
if isinstance(input_names, str):
1132-
input_names = [ input_names ]
1132+
input_names = [input_names]
11331133

11341134
if input_names is None or not input_names:
1135-
raise ValueError('InterfacedWorkflow input_names must be a non-empty list')
1135+
raise ValueError(('InterfacedWorkflow input_names must be a '
1136+
'non-empty list'))
11361137

11371138
if isinstance(output_names, str):
1138-
output_names = [ output_names ]
1139+
output_names = [output_names]
11391140

11401141
if output_names is None or not output_names:
1141-
raise ValueError('InterfacedWorkflow output_names must be a non-empty list')
1142+
raise ValueError(('InterfacedWorkflow output_names must be a '
1143+
'non-empty list'))
11421144

11431145
self._input_names = input_names
11441146
self._output_names = output_names
11451147

1146-
self._inputnode = Node(IdentityInterface(fields=input_names), name='inputnode')
1147-
self._outputnode = Node(IdentityInterface(fields=output_names), name='outputnode')
1148+
self._inputnode = Node(IdentityInterface(fields=input_names),
1149+
name='inputnode')
1150+
self._outputnode = Node(IdentityInterface(fields=output_names),
1151+
name='outputnode')
11481152

11491153
def connect(self, *args, **kwargs):
11501154
"""
@@ -1189,7 +1193,8 @@ def connect(self, *args, **kwargs):
11891193
dstnames = dstnode.inputs.copyable_trait_names()
11901194
for n in srcnames:
11911195
if n not in dstnames:
1192-
raise RuntimeError(('Interface missmatch between workflows, %s port is not '
1196+
raise RuntimeError(('Interface missmatch between '
1197+
'workflows, %s port is not '
11931198
'present in destination node') % n)
11941199
ports = [(srcpref+k, dstpref+k) for k in srcnames]
11951200
else:
@@ -1255,6 +1260,26 @@ class GraftWorkflow(InterfacedWorkflow):
12551260
i/o interfaces, and are run on the same input data.
12561261
This workflow produces as many outputs as inserted subworkflows, and
12571262
an outputnode with all the outputs merged.
1263+
1264+
Example
1265+
-------
1266+
>>> import nipype.pipeline.engine as npe
1267+
>>> import nipype.interfaces.utility as niu
1268+
>>> from nipype.algorithms.metrics import ErrorMap
1269+
>>> from nipype.interfaces.utility import IdentityInterface
1270+
>>> wf1 = npe.InterfacedWorkflow(name='testname1', input_names=['in_ref',
1271+
>>> 'in_tst', 'mask'],
1272+
>>> output_names=['out_map'])
1273+
>>> errormap = npe.Node(ErrorMap(), name='internalnode')
1274+
>>> wf1.connect([ ('in', errormap), (errormap, 'out') ])
1275+
>>> wf2 = wf1.clone(name='testname2')
1276+
>>> wf = npe.GraftWorkflow(name='graft', fields_from=wf1)
1277+
>>> wf.insert(wf1)
1278+
>>> wf.insert(wf2)
1279+
>>> wf.inputs.in_ref = 'reference.nii'
1280+
>>> wf.inputs.in_tst = 'test.nii'
1281+
>>> wf.write_graph(format='pdf') # doctest: +SKIP
1282+
>>> wf.run() # doctest: +SKIP
12581283
"""
12591284
_children = dict()
12601285
_outnodes = dict()
@@ -1286,10 +1311,6 @@ def __init__(self, name, base_dir=None, fields_from=None,
12861311
input_names=input_names,
12871312
output_names=output_names)
12881313

1289-
self._outputnode = InputMultiNode(IdentityInterface(
1290-
fields=output_names),
1291-
name='outputnode')
1292-
12931314
def insert(self, workflow):
12941315
"""
12951316
Inserts an InterfacedWorkflow into the workflow
@@ -1320,11 +1341,14 @@ def insert(self, workflow):
13201341
self.connect([('in', workflow), (workflow, self._outnodes[ckey]),
13211342
(self._outnodes[ckey], 'out')])
13221343

1323-
def write_graph(self, *args, **kwargs):
1324-
return super(GraftWorkflow, self).write_graph(*args, **kwargs)
1344+
#def write_graph(self, *args, **kwargs):
1345+
# return super(GraftWorkflow, self).write_graph(*args, **kwargs)
13251346

13261347
def run(self, *args, **kwargs):
1327-
return super(GraftWorkflow, self).run(*args, **kwargs)
1348+
logger.debug('Starting GraftWorkflow %s' % self)
1349+
runtime = super(GraftWorkflow, self).run(*args, **kwargs)
1350+
logger.debug('Ending GraftWorkflow %s' % self)
1351+
return runtime
13281352

13291353

13301354
class Node(WorkflowBase):
@@ -1694,6 +1718,7 @@ def _save_hashfile(self, hashfile, hashed_inputs):
16941718
else:
16951719
logger.critical('Unable to open the file in write mode: %s' %
16961720
hashfile)
1721+
16971722
def _get_inputs(self):
16981723
return self._get_all_inputs()
16991724

@@ -1999,6 +2024,16 @@ def write_report(self, report_type=None, cwd=None):
19992024
class InputMultiNode(Node):
20002025
"""
20012026
Wraps interface objects that join nodes into lists of inputs
2027+
2028+
Examples
2029+
--------
2030+
2031+
>>> from nipype import InputMultiNode
2032+
>>> from nipype.interfaces.fsl import Threshold
2033+
>>> realign = InputMultiNode(spm.Realign(), 'realign')
2034+
>>> realign.inputs.in_files = 'functional.nii'
2035+
>>> realign.inputs.register_to_mean = True
2036+
>>> realign.run() # doctest: +SKIP
20022037
"""
20032038
def __init__(self, interface, name, **kwargs):
20042039
"""
@@ -2046,15 +2081,13 @@ def set_input(self, parameter, val):
20462081
20472082
Priority goes to interface.
20482083
"""
2049-
logger.debug('InputMultiNode: setting nodelevel(%s) input %s = %s' % (str(self),
2050-
parameter,
2051-
str(val)))
2084+
logger.debug(('InputMultiNode: setting nodelevel(%s) input '
2085+
'%s = %s') % (str(self), parameter, str(val)))
20522086
self._set_multinode_input(self.inputs, parameter, deepcopy(val))
20532087

20542088
def _set_multinode_input(self, object, name, newvalue):
2055-
logger.debug('setting multinode(%s) input: %s -> %s' % (str(self),
2056-
name,
2057-
str(newvalue)))
2089+
logger.debug(('setting multinode(%s) input: %s ->'
2090+
' %s') % (str(self), name, str(newvalue)))
20582091
if name in self.fields:
20592092
setattr(self._inputs, name, newvalue)
20602093
else:
@@ -2504,6 +2537,7 @@ def _slot_value(self, field, index):
25042537
" to hold the %s value at index %d: %s"
25052538
% (self, slot_field, field, index, e))
25062539

2540+
25072541
class MapNode(Node):
25082542
"""Wraps interface objects that need to be iterated on a list of inputs.
25092543

0 commit comments

Comments
 (0)