Skip to content

Commit 9e07a6e

Browse files
authored
Merge pull request #9 from djarecka/oesteban-enh/activations-count-map
Oesteban enh/activations count map
2 parents f81c1cf + 6348862 commit 9e07a6e

File tree

10 files changed

+121
-17
lines changed

10 files changed

+121
-17
lines changed

.circleci/config.yml

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,8 @@ _get_base_image: &get_base_image
3636
echo "Pulling base image ..."
3737
docker pull nipype/nipype:base
3838
elif [ "$GET_BASE" == "BUILD" ]; then
39-
e=1 && for i in {1..5}; do
40-
docker build -t nipype/nipype:base - < docker/Dockerfile.base && e=0 && break || sleep 15
41-
done && [ "$e" -eq "0" ]
39+
tools/retry_cmd.sh -n 5 -s 15 \
40+
docker build -t nipype/nipype:base - < docker/Dockerfile.base
4241
else
4342
echo "Error: method to get base image not understood"
4443
exit 1
@@ -48,22 +47,20 @@ _build_main_image_py36: &build_main_image_py36
4847
name: Build main image (py36)
4948
no_output_timeout: 60m
5049
command: |
51-
e=1 && for i in {1..5}; do
50+
tools/retry_cmd.sh -n 5 -s 15 \
5251
docker build \
5352
--rm=false \
5453
--tag nipype/nipype:latest \
5554
--tag nipype/nipype:py36 \
5655
--build-arg BUILD_DATE="$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \
5756
--build-arg VCS_REF="$(git rev-parse --short HEAD)" \
5857
--build-arg VERSION="${CIRCLE_TAG}" /home/circleci/nipype \
59-
&& e=0 && break || sleep 15
60-
done && [ "$e" -eq "0" ]
6158
6259
_build_main_image_py27: &build_main_image_py27
6360
name: Build main image (py27)
6461
no_output_timeout: 60m
6562
command: |
66-
e=1 && for i in {1..5}; do
63+
tools/retry_cmd.sh -n 5 -s 15 \
6764
docker build \
6865
--rm=false \
6966
--tag nipype/nipype:py27 \
@@ -72,8 +69,6 @@ _build_main_image_py27: &build_main_image_py27
7269
--build-arg BUILD_DATE="$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \
7370
--build-arg VCS_REF="$(git rev-parse --short HEAD)" \
7471
--build-arg VERSION="${CIRCLE_TAG}-py27" /home/circleci/nipype \
75-
&& e=0 && break || sleep 15
76-
done && [ "$e" -eq "0" ]
7772
7873
_download_test_data: &_download_test_data
7974
name: Download test data

nipype/algorithms/tests/test_stats.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import numpy as np
66
import nibabel as nb
77
from nipype.algorithms.stats import ActivationCount
8+
import pytest
89

910

1011
def test_ActivationCount(tmpdir):
@@ -20,3 +21,23 @@ def test_ActivationCount(tmpdir):
2021
pos = nb.load(res.outputs.acm_pos)
2122
neg = nb.load(res.outputs.acm_neg)
2223
assert np.allclose(diff.get_data(), pos.get_data() - neg.get_data())
24+
25+
26+
@pytest.mark.parametrize("threshold, above_thresh", [
27+
(1, 15.865), # above one standard deviation (one side)
28+
(2, 2.275), # above two standard deviations (one side)
29+
(3, 0.135) # above three standard deviations (one side)
30+
])
31+
def test_ActivationCount_normaldistr(tmpdir, threshold, above_thresh):
32+
tmpdir.chdir()
33+
in_files = ['{:d}.nii'.format(i) for i in range(3)]
34+
for fname in in_files:
35+
nb.Nifti1Image(np.random.normal(size=(100, 100, 100)),
36+
np.eye(4)).to_filename(fname)
37+
38+
acm = ActivationCount(in_files=in_files, threshold=threshold)
39+
res = acm.run()
40+
pos = nb.load(res.outputs.acm_pos)
41+
neg = nb.load(res.outputs.acm_neg)
42+
assert np.isclose(pos.get_data().mean(), above_thresh*1.e-2, rtol=0.1, atol=1.e-4)
43+
assert np.isclose(neg.get_data().mean(), above_thresh*1.e-2, rtol=0.1, atol=1.e-4)

nipype/interfaces/afni/tests/test_auto_CatMatvec.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@ def test_CatMatvec_inputs():
3838
),
3939
out_file=dict(
4040
argstr=' > %s',
41+
keep_extension=False,
4142
mandatory=True,
43+
name_source='in_file',
44+
name_template='%s_cat.aff12.1D',
4245
position=-1,
4346
),
4447
outputtype=dict(),

nipype/interfaces/afni/utils.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,8 +564,11 @@ class CatMatvecInputSpec(AFNICommandInputSpec):
564564
argstr="%s",
565565
position=-2)
566566
out_file = File(
567-
desc="File to write concattenated matvecs to",
568567
argstr=" > %s",
568+
name_template='%s_cat.aff12.1D',
569+
name_source='in_file',
570+
keep_extension=False,
571+
desc="File to write concattenated matvecs to",
569572
position=-1,
570573
mandatory=True)
571574
matrix = traits.Bool(

nipype/interfaces/fsl/tests/test_auto_ImageMaths.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,20 @@ def test_ImageMaths_inputs():
2424
argstr='%s',
2525
position=3,
2626
),
27+
mask_file=dict(argstr='-mas %s', ),
2728
op_string=dict(
2829
argstr='%s',
2930
position=2,
3031
),
3132
out_data_type=dict(
3233
argstr='-odt %s',
33-
position=5,
34+
position=-1,
3435
),
3536
out_file=dict(
3637
argstr='%s',
3738
genfile=True,
3839
hash_files=False,
39-
position=4,
40+
position=-2,
4041
),
4142
output_type=dict(),
4243
suffix=dict(),

nipype/interfaces/fsl/utils.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,9 @@ def _list_outputs(self):
500500
class ImageMathsInputSpec(FSLCommandInputSpec):
501501
in_file = File(exists=True, argstr="%s", mandatory=True, position=1)
502502
in_file2 = File(exists=True, argstr="%s", position=3)
503-
out_file = File(argstr="%s", position=4, genfile=True, hash_files=False)
503+
mask_file = File(exists=True, argstr='-mas %s',
504+
desc='use (following image>0) to mask current image')
505+
out_file = File(argstr="%s", position=-2, genfile=True, hash_files=False)
504506
op_string = traits.Str(
505507
argstr="%s",
506508
position=2,
@@ -514,7 +516,7 @@ class ImageMathsInputSpec(FSLCommandInputSpec):
514516
'double',
515517
'input',
516518
argstr="-odt %s",
517-
position=5,
519+
position=-1,
518520
desc=("output datatype, one of (char, short, "
519521
"int, float, double, input)"))
520522

nipype/pipeline/engine/nodes.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
from ...utils.filemanip import (md5, FileNotFoundError, filename_to_list,
2828
list_to_filename, copyfiles, fnames_presuffix,
2929
loadpkl, split_filename, load_json, makedirs,
30-
emptydirs, savepkl, to_str)
30+
emptydirs, savepkl, to_str, indirectory)
3131

3232
from ...interfaces.base import (traits, InputMultiPath, CommandLine, Undefined,
3333
DynamicTraitedSpec, Bunch, InterfaceResult,
@@ -627,7 +627,8 @@ def _run_command(self, execute, copyfiles=True):
627627
self._interface.__class__.__name__)
628628
if issubclass(self._interface.__class__, CommandLine):
629629
try:
630-
cmd = self._interface.cmdline
630+
with indirectory(outdir):
631+
cmd = self._interface.cmdline
631632
except Exception as msg:
632633
result.runtime.stderr = '{}\n\n{}'.format(
633634
getattr(result.runtime, 'stderr', ''), msg)

nipype/utils/filemanip.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import os.path as op
1919
import re
2020
import shutil
21+
import contextlib
2122
import posixpath
2223
import simplejson as json
2324
import numpy as np
@@ -916,3 +917,13 @@ def relpath(path, start=None):
916917
if not rel_list:
917918
return os.curdir
918919
return op.join(*rel_list)
920+
921+
922+
@contextlib.contextmanager
923+
def indirectory(path):
924+
cwd = os.getcwd()
925+
os.chdir(path)
926+
try:
927+
yield
928+
finally:
929+
os.chdir(cwd)

nipype/utils/tests/test_filemanip.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
save_json, load_json, fname_presuffix, fnames_presuffix, hash_rename,
1515
check_forhash, _parse_mount_table, _cifs_table, on_cifs, copyfile,
1616
copyfiles, filename_to_list, list_to_filename, check_depends,
17-
split_filename, get_related_files)
17+
split_filename, get_related_files, indirectory)
1818

1919

2020
def _ignore_atime(stat):
@@ -490,3 +490,34 @@ def test_cifs_check():
490490

491491
_cifs_table[:] = []
492492
_cifs_table.extend(orig_table)
493+
494+
495+
def test_indirectory(tmpdir):
496+
tmpdir.chdir()
497+
498+
os.makedirs('subdir1/subdir2')
499+
sd1 = os.path.abspath('subdir1')
500+
sd2 = os.path.abspath('subdir1/subdir2')
501+
502+
assert os.getcwd() == tmpdir.strpath
503+
with indirectory('/'):
504+
assert os.getcwd() == '/'
505+
assert os.getcwd() == tmpdir.strpath
506+
with indirectory('subdir1'):
507+
assert os.getcwd() == sd1
508+
with indirectory('subdir2'):
509+
assert os.getcwd() == sd2
510+
with indirectory('..'):
511+
assert os.getcwd() == sd1
512+
with indirectory('/'):
513+
assert os.getcwd() == '/'
514+
assert os.getcwd() == sd1
515+
assert os.getcwd() == sd2
516+
assert os.getcwd() == sd1
517+
assert os.getcwd() == tmpdir.strpath
518+
try:
519+
with indirectory('subdir1'):
520+
raise ValueError("Erroring out of context")
521+
except ValueError:
522+
pass
523+
assert os.getcwd() == tmpdir.strpath

tools/retry_cmd.sh

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/bin/sh
2+
#
3+
# retry_cmd.sh [-n NLOOPS] [-s SLEEP] CMD
4+
#
5+
# Retry command until success or pre-specified number of failures
6+
#
7+
# 2018 Chris Markiewicz
8+
# Released into public domain
9+
10+
NLOOPS=3
11+
TOSLEEP=5
12+
13+
while true; do
14+
case "$1" in
15+
-n ) NLOOPS="$2"; shift 2 ;;
16+
-s ) TOSLEEP="$2"; shift 2 ;;
17+
-- ) shift; break ;;
18+
* ) break ;;
19+
esac
20+
done
21+
22+
# Normalize whitespace in command, preserving quotes
23+
CMD=""
24+
for ARG; do
25+
CMD="$CMD \"$ARG\"";
26+
done
27+
28+
RET=0
29+
for i in `seq $NLOOPS`; do
30+
sh -c "$CMD"
31+
RET="$?"
32+
if [ "$RET" -eq 0 ]; then break; fi
33+
if [ "$i" -ne "$NLOOPS" ]; then sleep $TOSLEEP; fi
34+
done
35+
36+
exit $RET

0 commit comments

Comments
 (0)