Skip to content

Commit 20eccd3

Browse files
committed
Merge branch 'master' of git://github.com/nipy/nipype into fix/nipypetest
2 parents c87399e + 1a74013 commit 20eccd3

File tree

12 files changed

+132
-75
lines changed

12 files changed

+132
-75
lines changed

doc/users/saving_workflows.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ This will create a file "outputtestsave.py" with the following content:
5555
from nipype.pipeline.engine import Workflow, Node, MapNode
5656
from nipype.interfaces.utility import IdentityInterface
5757
from nipype.interfaces.utility import Function
58-
from nipype.utils.misc import getsource
58+
from nipype.utils.functions import getsource
5959
from nipype.interfaces.fsl.preprocess import BET
6060
from nipype.interfaces.fsl.utils import ImageMaths
6161
# Functions

nipype/interfaces/afni/preprocess.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2929,6 +2929,17 @@ class QwarpInputSpec(AFNICommandInputSpec):
29292929
'* You CAN use -resample with these 3dQwarp options:'
29302930
'-plusminus -inilev -iniwarp -duplo',
29312931
argstr='-resample')
2932+
allineate = traits.Bool(
2933+
desc='This option will make 3dQwarp run 3dAllineate first, to align '
2934+
'the source dataset to the base with an affine transformation. '
2935+
'It will then use that alignment as a starting point for the '
2936+
'nonlinear warping.',
2937+
argstr='-allineate')
2938+
allineate_opts = traits.Str(
2939+
desc='add extra options to the 3dAllineate command to be run by '
2940+
'3dQwarp.',
2941+
argstr='-allineate_opts %s',
2942+
xand=['allineate'])
29322943
nowarp = traits.Bool(
29332944
desc='Do not save the _WARP file.',
29342945
argstr='-nowarp')
@@ -3465,11 +3476,24 @@ class Qwarp(AFNICommand):
34653476
>>> qwarp2.cmdline # doctest: +ALLOW_UNICODE
34663477
'3dQwarp -base mni.nii -blur 0.0 2.0 -source structural.nii -inilev 7 -iniwarp Q25_warp+tlrc.HEAD -prefix Q11'
34673478
>>> res2 = qwarp2.run() # doctest: +SKIP
3468-
"""
3479+
>>> res2 = qwarp2.run() # doctest: +SKIP
3480+
>>> qwarp3 = afni.Qwarp()
3481+
>>> qwarp3.inputs.in_file = 'structural.nii'
3482+
>>> qwarp3.inputs.base_file = 'mni.nii'
3483+
>>> qwarp3.inputs.allineate = True
3484+
>>> qwarp3.inputs.allineate_opts = '-cose lpa -verb'
3485+
>>> qwarp3.cmdline # doctest: +ALLOW_UNICODE
3486+
"3dQwarp -allineate -allineate_opts '-cose lpa -verb' -base mni.nii -source structural.nii -prefix structural_QW"
3487+
>>> res3 = qwarp3.run() # doctest: +SKIP """
34693488
_cmd = '3dQwarp'
34703489
input_spec = QwarpInputSpec
34713490
output_spec = QwarpOutputSpec
34723491

3492+
def _format_arg(self, name, spec, value):
3493+
if name == 'allineate_opts':
3494+
return spec.argstr % ("'" + value + "'")
3495+
return super(Qwarp, self)._format_arg(name, spec, value)
3496+
34733497
def _list_outputs(self):
34743498
outputs = self.output_spec().get()
34753499

nipype/interfaces/afni/tests/test_auto_Qwarp.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ def test_Qwarp_inputs():
88
),
99
Qonly=dict(argstr='-Qonly',
1010
),
11+
allineate=dict(argstr='-allineate',
12+
),
13+
allineate_opts=dict(argstr='-allineate_opts %s',
14+
xand=['allineate'],
15+
),
1116
allsave=dict(argstr='-allsave',
1217
xor=['nopadWARP', 'duplo', 'plusminus'],
1318
),

nipype/interfaces/fsl/epi.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ def _run_interface(self, runtime):
592592
cmd = self._cmd
593593
if all((FSLDIR != '',
594594
cmd == 'eddy_openmp',
595-
not os.path.exists(os.path.join(FSLDIR, cmd)))):
595+
not os.path.exists(os.path.join(FSLDIR, 'bin', cmd)))):
596596
self._cmd = 'eddy'
597597
runtime = super(Eddy, self)._run_interface(runtime)
598598

nipype/interfaces/utility/wrappers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
BaseInterfaceInputSpec)
2525
from ..io import IOBase, add_traits
2626
from ...utils.filemanip import filename_to_list
27-
from ...utils.misc import getsource, create_function_from_source
27+
from ...utils.functions import getsource, create_function_from_source
2828

2929
logger = logging.getLogger('interface')
3030

nipype/pipeline/engine/nodes.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ def _run_command(self, execute, copyfiles=True):
633633
if copyfiles:
634634
self._copyfiles_to_wd(cwd, execute)
635635

636-
message = 'Running node "%s" (a "%s" interface)'
636+
message = 'Running node "%s" ("%s.%s")'
637637
if issubclass(self._interface.__class__, CommandLine):
638638
try:
639639
cmd = self._interface.cmdline
@@ -644,7 +644,7 @@ def _run_command(self, execute, copyfiles=True):
644644
with open(cmdfile, 'wt') as fd:
645645
print(cmd + "\n", file=fd)
646646
message += ', a CommandLine Interface with command:\n%s' % cmd
647-
logger.info(message + '.', self.name,
647+
logger.info(message + '.', self.name, self._interface.__module__,
648648
self._interface.__class__.__name__)
649649
try:
650650
result = self._interface.run()

nipype/pipeline/engine/utils.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929

3030
from ...utils.filemanip import (fname_presuffix, FileNotFoundError, to_str,
3131
filename_to_list, get_related_files)
32-
from ...utils.misc import create_function_from_source, str2bool
32+
from ...utils.misc import str2bool
33+
from ...utils.functions import create_function_from_source
3334
from ...interfaces.base import (CommandLine, isdefined, Undefined,
3435
InterfaceResult)
3536
from ...interfaces.utility import IdentityInterface
@@ -99,7 +100,7 @@ def _write_inputs(node):
99100
lines[-1] = lines[-1].replace(' %s(' % funcname,
100101
' %s_1(' % funcname)
101102
funcname = '%s_1' % funcname
102-
lines.append('from nipype.utils.misc import getsource')
103+
lines.append('from nipype.utils.functions import getsource')
103104
lines.append("%s.inputs.%s = getsource(%s)" % (nodename,
104105
key,
105106
funcname))

nipype/pipeline/engine/workflows.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,9 @@
3636

3737

3838
from ... import config, logging
39-
from ...utils.misc import (unflatten, str2bool,
40-
getsource, create_function_from_source)
39+
40+
from ...utils.misc import (unflatten, str2bool)
41+
from ...utils.functions import (getsource, create_function_from_source)
4142
from ...interfaces.base import (traits, InputMultiPath, CommandLine,
4243
Undefined, TraitedSpec, DynamicTraitedSpec,
4344
Bunch, InterfaceResult, md5, Interface,

nipype/utils/functions.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
Handles custom functions used in Function interface. Future imports
4+
are avoided to keep namespace as clear as possible.
5+
"""
6+
from builtins import next, str
7+
from future.utils import raise_from
8+
import inspect
9+
from textwrap import dedent
10+
11+
def getsource(function):
12+
"""Returns the source code of a function"""
13+
return dedent(inspect.getsource(function))
14+
15+
16+
def create_function_from_source(function_source, imports=None):
17+
"""Return a function object from a function source
18+
19+
Parameters
20+
----------
21+
function_source : unicode string
22+
unicode string defining a function
23+
imports : list of strings
24+
list of import statements in string form that allow the function
25+
to be executed in an otherwise empty namespace
26+
"""
27+
ns = {}
28+
import_keys = []
29+
30+
try:
31+
if imports is not None:
32+
for statement in imports:
33+
exec(statement, ns)
34+
import_keys = list(ns.keys())
35+
exec(function_source, ns)
36+
37+
except Exception as e:
38+
msg = 'Error executing function\n{}\n'.format(function_source)
39+
msg += ("Functions in connection strings have to be standalone. "
40+
"They cannot be declared either interactively or inside "
41+
"another function or inline in the connect string. Any "
42+
"imports should be done inside the function.")
43+
raise_from(RuntimeError(msg), e)
44+
ns_funcs = list(set(ns) - set(import_keys + ['__builtins__']))
45+
assert len(ns_funcs) == 1, "Function or inputs are ill-defined"
46+
func = ns[ns_funcs[0]]
47+
return func

nipype/utils/misc.py

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# vi: set ft=python sts=4 ts=4 sw=4 et:
44
"""Miscellaneous utility functions
55
"""
6-
from __future__ import print_function, division, unicode_literals, absolute_import
6+
from __future__ import print_function, unicode_literals, division, absolute_import
77
from future import standard_library
88
standard_library.install_aliases()
99
from builtins import next, str
@@ -66,47 +66,6 @@ def trim(docstring, marker=None):
6666
return '\n'.join(trimmed)
6767

6868

69-
def getsource(function):
70-
"""Returns the source code of a function"""
71-
src = dedent(inspect.getsource(function))
72-
return src
73-
74-
75-
def create_function_from_source(function_source, imports=None):
76-
"""Return a function object from a function source
77-
78-
Parameters
79-
----------
80-
function_source : pickled string
81-
string in pickled form defining a function
82-
imports : list of strings
83-
list of import statements in string form that allow the function
84-
to be executed in an otherwise empty namespace
85-
"""
86-
ns = {}
87-
import_keys = []
88-
try:
89-
if imports is not None:
90-
for statement in imports:
91-
exec(statement, ns)
92-
import_keys = list(ns.keys())
93-
exec(function_source, ns)
94-
95-
except Exception as e:
96-
msg = '\nError executing function:\n %s\n' % function_source
97-
msg += '\n'.join(["Functions in connection strings have to be standalone.",
98-
"They cannot be declared either interactively or inside",
99-
"another function or inline in the connect string. Any",
100-
"imports should be done inside the function"
101-
])
102-
raise_from(RuntimeError(msg), e)
103-
ns_funcs = list(set(ns) - set(import_keys + ['__builtins__']))
104-
assert len(ns_funcs) == 1, "Function or inputs are ill-defined"
105-
funcname = ns_funcs[0]
106-
func = ns[funcname]
107-
return func
108-
109-
11069
def find_indices(condition):
11170
"Return the indices where ravel(condition) is true"
11271
res, = np.nonzero(np.ravel(condition))

0 commit comments

Comments
 (0)