Skip to content

Commit f02dd3a

Browse files
authored
Merge pull request #2969 from oesteban/enh/refactor-aggregate_outputs
MAINT: Refactor ``aggregate_outputs`` for readability
2 parents 3454c9a + bb736ae commit f02dd3a

File tree

1 file changed

+31
-29
lines changed

1 file changed

+31
-29
lines changed

nipype/interfaces/base/core.py

+31-29
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,10 @@ def _check_requires(self, spec, name, value):
204204
]
205205
if any(values) and isdefined(value):
206206
if len(values) > 1:
207-
fmt = ("%s requires values for inputs %s because '%s' is set. "
207+
fmt = ("%s requires values for inputs %s because '%s' is set. "
208208
"For a list of required inputs, see %s.help()")
209209
else:
210-
fmt = ("%s requires a value for input %s because '%s' is set. "
210+
fmt = ("%s requires a value for input %s because '%s' is set. "
211211
"For a list of required inputs, see %s.help()")
212212
msg = fmt % (self.__class__.__name__,
213213
', '.join("'%s'" % req for req in spec.requires),
@@ -450,34 +450,36 @@ def _list_outputs(self):
450450
return None
451451

452452
def aggregate_outputs(self, runtime=None, needed_outputs=None):
453-
""" Collate expected outputs and check for existence
454-
"""
455-
456-
predicted_outputs = self._list_outputs()
457-
outputs = self._outputs()
458-
if predicted_outputs:
459-
_unavailable_outputs = []
460-
if outputs:
461-
_unavailable_outputs = \
462-
self._check_version_requirements(self._outputs())
463-
for key, val in list(predicted_outputs.items()):
464-
if needed_outputs and key not in needed_outputs:
465-
continue
466-
if key in _unavailable_outputs:
467-
raise KeyError(('Output trait %s not available in version '
468-
'%s of interface %s. Please inform '
469-
'developers.') % (key, self.version,
470-
self.__class__.__name__))
471-
try:
472-
setattr(outputs, key, val)
473-
except TraitError as error:
474-
if getattr(error, 'info',
475-
'default').startswith('an existing'):
476-
msg = ("File/Directory '%s' not found for %s output "
477-
"'%s'." % (val, self.__class__.__name__, key))
478-
raise FileNotFoundError(msg)
479-
raise error
453+
"""Collate expected outputs and apply output traits validation."""
454+
outputs = self._outputs() # Generate an empty output spec object
455+
predicted_outputs = self._list_outputs() # Predictions from _list_outputs
456+
if not predicted_outputs:
457+
return outputs
480458

459+
# Precalculate the list of output trait names that should be aggregated
460+
aggregate_names = set(predicted_outputs)
461+
if needed_outputs is not None:
462+
aggregate_names = set(needed_outputs).intersection(aggregate_names)
463+
464+
if aggregate_names: # Make sure outputs are compatible
465+
_na_outputs = self._check_version_requirements(outputs)
466+
na_names = aggregate_names.intersection(_na_outputs)
467+
if na_names:
468+
# XXX Change to TypeError in Nipype 2.0
469+
raise KeyError("""\
470+
Output trait(s) %s not available in version %s of interface %s.\
471+
""" % (', '.join(na_names), self.version, self.__class__.__name__))
472+
473+
for key in aggregate_names: # Final aggregation
474+
val = predicted_outputs[key]
475+
try:
476+
setattr(outputs, key, val)
477+
except TraitError as error:
478+
if 'an existing' in getattr(error, 'info', 'default'):
479+
msg = "No such file or directory for output '%s' of a %s interface" % \
480+
(key, self.__class__.__name__)
481+
raise FileNotFoundError(val, message=msg)
482+
raise error
481483
return outputs
482484

483485
@property

0 commit comments

Comments
 (0)