Skip to content

Commit 23ff63d

Browse files
committed
Merge remote-tracking branch 'upstream/master' into doc/pr_template_update
2 parents b458366 + 4a3dfef commit 23ff63d

File tree

8 files changed

+190
-1
lines changed

8 files changed

+190
-1
lines changed

.circleci/config.yml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,46 @@ jobs:
156156
- /tmp/data
157157
- /tmp/ds005/derivatives/freesurfer
158158

159+
get_regression_data:
160+
machine:
161+
# Ubuntu 14.04 with Docker 17.10.0-ce
162+
image: circleci/classic:201711-01
163+
working_directory: /home/circleci/data
164+
steps:
165+
- restore_cache:
166+
keys:
167+
- regression-v0-{{ epoch }}
168+
- regression-v0-
169+
- run:
170+
name: Get truncated BOLD series
171+
command: |
172+
mkdir -p /tmp/data
173+
if [[ ! -d /tmp/data/fmriprep_bold_truncated ]]; then
174+
wget --retry-connrefused --waitretry=5 --read-timeout=20 --timeout=15 -t 0 -q \
175+
-O fmriprep_bold_truncated.tar.gz "https://osf.io/286yr/download"
176+
tar xvzf fmriprep_bold_truncated.tar.gz -C /tmp/data/
177+
else
178+
echo "Truncated BOLD series were cached"
179+
fi
180+
- run:
181+
name: Get pre-computed masks
182+
command: |
183+
if [[ ! -d /tmp/data/fmriprep_bold_mask ]]; then
184+
wget --retry-connrefused --waitretry=5 --read-timeout=20 --timeout=15 -t 0 -q \
185+
-O fmriprep_bold_mask.tar.gz "https://osf.io/s4f7b/download"
186+
tar xvzf fmriprep_bold_mask.tar.gz -C /tmp/data/
187+
else
188+
echo "Pre-computed masks were cached"
189+
fi
190+
- persist_to_workspace:
191+
root: /tmp
192+
paths:
193+
- data
194+
- save_cache:
195+
key: regression-v0-{{ epoch }}
196+
paths:
197+
- /tmp/data
198+
159199
update_cache:
160200
machine:
161201
# Ubuntu 14.04 with Docker 17.10.0-ce
@@ -186,6 +226,10 @@ jobs:
186226
fi
187227
- attach_workspace:
188228
at: /tmp
229+
- restore_cache:
230+
keys:
231+
- regression-v0-{{ epoch }}
232+
- regression-v0-
189233
- run:
190234
name: Load Docker image layer cache
191235
no_output_timeout: 30m
@@ -202,6 +246,9 @@ jobs:
202246
no_output_timeout: 2h
203247
command: |
204248
docker run -ti --rm=false \
249+
-v /tmp/data:/tmp/data \
250+
-e FMRIPREP_REGRESSION_SOURCE=/tmp/data/fmriprep_bold_truncated \
251+
-e FMRIPREP_REGRESSION_TARGETS=/tmp/data/fmriprep_bold_mask \
205252
--entrypoint="py.test" poldracklab/fmriprep:latest \
206253
/root/src/fmriprep/ --doctest-modules --ignore=docs --ignore=setup.py
207254
- run:
@@ -665,6 +712,11 @@ workflows:
665712
tags:
666713
only: /.*/
667714

715+
- get_regression_data:
716+
filters:
717+
branches:
718+
ignore: /docs?\/.*/
719+
668720
- build_docs:
669721
requires:
670722
- build
@@ -684,6 +736,7 @@ workflows:
684736
- test_pytest:
685737
requires:
686738
- build
739+
- get_regression_data
687740
filters:
688741
branches:
689742
ignore: /docs?\/.*/

.github/config.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome
2+
3+
# Comment to be posted to on PRs from first time contributors in your repository
4+
newPRWelcomeComment: >
5+
Thanks for opening this pull request!
6+
We have detected this is the first time for you to contribute
7+
to *fMRIPrep*.
8+
Please check out our [contributing guidelines](https://github.com/poldracklab/fmriprep/blob/master/CONTRIBUTING.md).
9+
10+
We invite you to list yourself as a *fMRIPrep* contributor, so if your name
11+
is not already mentioned, please modify the
12+
[``.zenodo.json``](https://github.com/poldracklab/fmriprep/blob/master/.zenodo.json)
13+
file with your data right above Russ' entry. Example:
14+
15+
```
16+
17+
{
18+
"name": "Contributor, New FMRIPrep",
19+
"affiliation": "Department of fMRI prep'ing, Open Science Made-Up University",
20+
"orcid": "<your id>"
21+
},
22+
23+
{
24+
"name": "Poldrack, Russell A.",
25+
"affiliation": "Department of Psychology, Stanford University",
26+
"orcid": "0000-0001-6755-0259"
27+
},
28+
29+
```
30+
31+
32+
Of course, if you want to opt-out this time there is no
33+
problem at all with adding your name later.
34+
You will be always welcome to add it in the future whenever
35+
you feel it should be listed.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
__pycache__/
33
*.py[cod]
44
*$py.class
5+
.pytest_cache/
56

67
# C extensions
78
*.so

Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ RUN echo "${VERSION}" > /root/src/fmriprep/fmriprep/VERSION && \
164164
pip install .[all] && \
165165
rm -rf ~/.cache/pip
166166

167+
RUN install -m 0755 \
168+
/root/src/fmriprep/scripts/generate_reference_mask.py \
169+
/usr/local/bin/generate_reference_mask
170+
167171
RUN ldconfig
168172
WORKDIR /tmp/
169173
ENTRYPOINT ["/usr/local/miniconda/bin/fmriprep"]

docs/installation.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ If the data to be preprocessed is also on the HPC, you are ready to run fmriprep
136136
--omp-nthreads 16
137137

138138

139-
or, unset the ``PYTHONPATH`` variable before running: ::
139+
or, unset the ``PYTHONPATH`` variable before running: ::
140140

141141
$ unset PYTHONPATH; singularity run ~/poldracklab_fmriprep_latest-2016-12-04-5b74ad9a4c4d.img \
142142
/work/04168/asdf/lonestar/ $WORK/lonestar/output \

fmriprep/workflows/bold/tests/__init__.py

Whitespace-only changes.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
''' Testing module for fmriprep.workflows.bold.util '''
2+
import pytest
3+
import os
4+
5+
import numpy as np
6+
from nipype.utils.filemanip import fname_presuffix
7+
from nilearn.image import load_img
8+
from ..util import init_bold_reference_wf
9+
10+
11+
def symmetric_overlap(img1, img2):
12+
mask1 = load_img(img1).get_data() > 0
13+
mask2 = load_img(img2).get_data() > 0
14+
15+
total1 = np.sum(mask1)
16+
total2 = np.sum(mask2)
17+
overlap = np.sum(mask1 & mask2)
18+
return overlap / np.sqrt(total1 * total2)
19+
20+
21+
@pytest.mark.skipif(not os.getenv('FMRIPREP_REGRESSION_SOURCE') or
22+
not os.getenv('FMRIPREP_REGRESSION_TARGETS'),
23+
reason='FMRIPREP_REGRESSION_{SOURCE,TARGETS} env vars not set')
24+
@pytest.mark.parametrize('input_fname,expected_fname', [
25+
(os.path.join(os.getenv('FMRIPREP_REGRESSION_SOURCE', ''),
26+
base_fname),
27+
fname_presuffix(base_fname, suffix='_mask', use_ext=True,
28+
newpath=os.path.join(
29+
os.getenv('FMRIPREP_REGRESSION_TARGETS', ''),
30+
os.path.dirname(base_fname))))
31+
for base_fname in (
32+
'ds000116/sub-12_task-visualoddballwithbuttonresponsetotargetstimuli_run-02_bold.nii.gz',
33+
'ds000133/sub-06_ses-post_task-rest_run-01_bold.nii.gz',
34+
'ds000140/sub-32_task-heatpainwithregulationandratings_run-02_bold.nii.gz',
35+
'ds000157/sub-23_task-passiveimageviewing_bold.nii.gz',
36+
'ds000210/sub-06_task-rest_run-01_echo-1_bold.nii.gz',
37+
'ds000210/sub-06_task-rest_run-01_echo-2_bold.nii.gz',
38+
'ds000210/sub-06_task-rest_run-01_echo-3_bold.nii.gz',
39+
'ds000216/sub-03_task-rest_echo-1_bold.nii.gz',
40+
'ds000216/sub-03_task-rest_echo-2_bold.nii.gz',
41+
'ds000216/sub-03_task-rest_echo-3_bold.nii.gz',
42+
'ds000216/sub-03_task-rest_echo-4_bold.nii.gz',
43+
'ds000237/sub-03_task-MemorySpan_acq-multiband_run-01_bold.nii.gz',
44+
'ds000237/sub-06_task-MemorySpan_acq-multiband_run-01_bold.nii.gz',
45+
)
46+
])
47+
def test_masking(input_fname, expected_fname):
48+
bold_reference_wf = init_bold_reference_wf(omp_nthreads=1, enhance_t2=True)
49+
bold_reference_wf.inputs.inputnode.bold_file = input_fname
50+
res = bold_reference_wf.run(plugin='MultiProc')
51+
52+
combine_masks = [node for node in res.nodes if node.name.endswith('combine_masks')][0]
53+
overlap = symmetric_overlap(expected_fname,
54+
combine_masks.result.outputs.out_file)
55+
56+
assert overlap > 0.95, input_fname

scripts/generate_reference_mask.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/usr/bin/env python
2+
import sys
3+
from nipype.pipeline import engine as pe
4+
from nipype.interfaces import utility as niu
5+
from fmriprep.workflows.bold.util import init_bold_reference_wf
6+
7+
8+
def sink_mask_file(in_file, orig_file, out_dir):
9+
import os
10+
from nipype.utils.filemanip import fname_presuffix, copyfile
11+
os.makedirs(out_dir, exist_ok=True)
12+
out_file = fname_presuffix(orig_file, suffix='_mask', newpath=out_dir)
13+
copyfile(in_file, out_file, copy=True, use_hardlink=True)
14+
return out_file
15+
16+
17+
def init_main_wf(bold_file, out_dir, base_dir=None, name='main_wf'):
18+
wf = init_bold_reference_wf(enhance_t2=True,
19+
omp_nthreads=4,
20+
name=name)
21+
wf.base_dir = base_dir
22+
wf.inputs.inputnode.bold_file = bold_file
23+
24+
sink = pe.Node(niu.Function(function=sink_mask_file),
25+
name='sink')
26+
sink.inputs.out_dir = out_dir
27+
sink.inputs.orig_file = bold_file
28+
wf.connect([
29+
(wf.get_node('outputnode'), sink, [('bold_mask', 'in_file')]),
30+
])
31+
return wf
32+
33+
34+
def main():
35+
main_wf = init_main_wf(sys.argv[1], sys.argv[2])
36+
main_wf.run(plugin='MultiProc')
37+
38+
39+
if __name__ == '__main__':
40+
main()

0 commit comments

Comments
 (0)