Skip to content

Commit 1af4bac

Browse files
committed
Merge remote-tracking branch 'nipy/master'
2 parents b3c71b0 + 94a11f0 commit 1af4bac

File tree

4 files changed

+184
-3
lines changed

4 files changed

+184
-3
lines changed

nipype/interfaces/afni/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
Seg, SkullStrip, TCorr1D, TCorrMap, TCorrelate,
1818
TShift, Volreg, Warp, QwarpPlusMinus)
1919
from .svm import (SVMTest, SVMTrain)
20-
from .utils import (AFNItoNIFTI, Autobox, BrickStat, Calc, Copy,
20+
from .utils import (AFNItoNIFTI, Autobox, BrickStat, Calc, Copy, Edge3,
2121
Eval, FWHMx,
2222
MaskTool, Merge, Notes, Refit, Resample, TCat, TStat, To3D,
2323
Unifize, ZCutUp, GCOR, Zcat, Zeropad)
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT
2+
from __future__ import unicode_literals
3+
from ..utils import Edge3
4+
5+
6+
def test_Edge3_inputs():
7+
input_map = dict(args=dict(argstr='%s',
8+
),
9+
datum=dict(argstr='-datum %s',
10+
),
11+
environ=dict(nohash=True,
12+
usedefault=True,
13+
),
14+
fscale=dict(argstr='-fscale',
15+
xor=['gscale', 'nscale', 'scale_floats'],
16+
),
17+
gscale=dict(argstr='-gscale',
18+
xor=['fscale', 'nscale', 'scale_floats'],
19+
),
20+
ignore_exception=dict(nohash=True,
21+
usedefault=True,
22+
),
23+
in_file=dict(argstr='-input %s',
24+
copyfile=False,
25+
mandatory=True,
26+
position=0,
27+
),
28+
nscale=dict(argstr='-nscale',
29+
xor=['fscale', 'gscale', 'scale_floats'],
30+
),
31+
out_file=dict(argstr='-prefix %s',
32+
position=-1,
33+
),
34+
outputtype=dict(),
35+
scale_floats=dict(argstr='-scale_floats %f',
36+
xor=['fscale', 'gscale', 'nscale'],
37+
),
38+
terminal_output=dict(nohash=True,
39+
),
40+
verbose=dict(argstr='-verbose',
41+
),
42+
)
43+
inputs = Edge3.input_spec()
44+
45+
for key, metadata in list(input_map.items()):
46+
for metakey, value in list(metadata.items()):
47+
assert getattr(inputs.traits()[key], metakey) == value
48+
49+
50+
def test_Edge3_outputs():
51+
output_map = dict(out_file=dict(),
52+
)
53+
outputs = Edge3.output_spec()
54+
55+
for key, metadata in list(output_map.items()):
56+
for metakey, value in list(metadata.items()):
57+
assert getattr(outputs.traits()[key], metakey) == value

nipype/interfaces/afni/utils.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,99 @@ class Copy(AFNICommand):
394394
output_spec = AFNICommandOutputSpec
395395

396396

397+
class Edge3InputSpec(AFNICommandInputSpec):
398+
in_file = File(
399+
desc='input file to 3dedge3',
400+
argstr='-input %s',
401+
position=0,
402+
mandatory=True,
403+
exists=True,
404+
copyfile=False)
405+
out_file = File(
406+
desc='output image file name',
407+
position=-1,
408+
argstr='-prefix %s')
409+
datum = traits.Enum(
410+
'byte','short','float',
411+
argstr='-datum %s',
412+
desc='specify data type for output. Valid types are \'byte\', '
413+
'\'short\' and \'float\'.')
414+
fscale = traits.Bool(
415+
desc='Force scaling of the output to the maximum integer range.',
416+
argstr='-fscale',
417+
xor=['gscale', 'nscale', 'scale_floats'])
418+
gscale = traits.Bool(
419+
desc='Same as \'-fscale\', but also forces each output sub-brick to '
420+
'to get the same scaling factor.',
421+
argstr='-gscale',
422+
xor=['fscale', 'nscale', 'scale_floats'])
423+
nscale = traits.Bool(
424+
desc='Don\'t do any scaling on output to byte or short datasets.',
425+
argstr='-nscale',
426+
xor=['fscale', 'gscale', 'scale_floats'])
427+
scale_floats = traits.Float(
428+
desc='Multiply input by VAL, but only if the input datum is '
429+
'float. This is needed when the input dataset '
430+
'has a small range, like 0 to 2.0 for instance. '
431+
'With such a range, very few edges are detected due to '
432+
'what I suspect to be truncation problems. '
433+
'Multiplying such a dataset by 10000 fixes the problem '
434+
'and the scaling is undone at the output.',
435+
argstr='-scale_floats %f',
436+
xor=['fscale', 'gscale', 'nscale'])
437+
verbose = traits.Bool(
438+
desc='Print out some information along the way.',
439+
argstr='-verbose')
440+
441+
442+
class Edge3(AFNICommand):
443+
"""Does 3D Edge detection using the library 3DEdge
444+
by Gregoire Malandain ([email protected]).
445+
446+
For complete details, see the `3dedge3 Documentation.
447+
<https://afni.nimh.nih.gov/pub/dist/doc/program_help/3dedge3.html>`_
448+
449+
references_ = [{'entry': BibTeX('@article{Deriche1987,'
450+
'author={R. Deriche},'
451+
'title={Optimal edge detection using recursive filtering},'
452+
'journal={International Journal of Computer Vision},'
453+
'volume={2},',
454+
'pages={167-187},'
455+
'year={1987},'
456+
'}'),
457+
'tags': ['method'],
458+
},
459+
{'entry': BibTeX('@article{MongaDericheMalandainCocquerez1991,'
460+
'author={O. Monga, R. Deriche, G. Malandain, J.P. Cocquerez},'
461+
'title={Recursive filtering and edge tracking: two primary tools for 3D edge detection},'
462+
'journal={Image and vision computing},'
463+
'volume={9},',
464+
'pages={203-214},'
465+
'year={1991},'
466+
'}'),
467+
'tags': ['method'],
468+
},
469+
]
470+
471+
Examples
472+
========
473+
474+
>>> from nipype.interfaces import afni
475+
>>> edge3 = afni.Edge3()
476+
>>> edge3.inputs.in_file = 'functional.nii'
477+
>>> edge3.inputs.out_file = 'edges.nii'
478+
>>> edge3.inputs.datum = 'byte'
479+
>>> edge3.cmdline # doctest: +ALLOW_UNICODE
480+
'3dedge3 -input functional.nii -datum byte -prefix edges.nii'
481+
>>> res = edge3.run() # doctest: +SKIP
482+
483+
"""
484+
485+
_cmd = '3dedge3'
486+
input_spec = Edge3InputSpec
487+
output_spec = AFNICommandOutputSpec
488+
489+
397490
class EvalInputSpec(AFNICommandInputSpec):
398491
in_file_a = File(
399492
desc='input file to 1deval',

nipype/interfaces/base.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,6 +1381,35 @@ def _get_ram_mb(pid, pyfunc=False):
13811381
return mem_mb
13821382

13831383

1384+
def _canonicalize_env(env):
1385+
"""Windows requires that environment be dicts with bytes as keys and values
1386+
This function converts any unicode entries for Windows only, returning the
1387+
dictionary untouched in other environments.
1388+
1389+
Parameters
1390+
----------
1391+
env : dict
1392+
environment dictionary with unicode or bytes keys and values
1393+
1394+
Returns
1395+
-------
1396+
env : dict
1397+
Windows: environment dictionary with bytes keys and values
1398+
Other: untouched input ``env``
1399+
"""
1400+
if os.name != 'nt':
1401+
return env
1402+
1403+
out_env = {}
1404+
for key, val in env:
1405+
if not isinstance(key, bytes):
1406+
key = key.encode('utf-8')
1407+
if not isinstance(val, bytes):
1408+
val = key.encode('utf-8')
1409+
out_env[key] = val
1410+
return out_env
1411+
1412+
13841413
# Get max resources used for process
13851414
def get_max_resources_used(pid, mem_mb, num_threads, pyfunc=False):
13861415
"""Function to get the RAM and threads usage of a process
@@ -1435,6 +1464,8 @@ def run_command(runtime, output=None, timeout=0.01, redirect_x=False):
14351464
raise RuntimeError('Xvfb was not found, X redirection aborted')
14361465
cmdline = 'xvfb-run -a ' + cmdline
14371466

1467+
env = _canonicalize_env(runtime.environ)
1468+
14381469
default_encoding = locale.getdefaultlocale()[1]
14391470
if default_encoding is None:
14401471
default_encoding = 'UTF-8'
@@ -1449,14 +1480,14 @@ def run_command(runtime, output=None, timeout=0.01, redirect_x=False):
14491480
stderr=stderr,
14501481
shell=True,
14511482
cwd=runtime.cwd,
1452-
env=runtime.environ)
1483+
env=env)
14531484
else:
14541485
proc = subprocess.Popen(cmdline,
14551486
stdout=PIPE,
14561487
stderr=PIPE,
14571488
shell=True,
14581489
cwd=runtime.cwd,
1459-
env=runtime.environ)
1490+
env=env)
14601491
result = {}
14611492
errfile = os.path.join(runtime.cwd, 'stderr.nipype')
14621493
outfile = os.path.join(runtime.cwd, 'stdout.nipype')

0 commit comments

Comments
 (0)