Skip to content

Commit 5d0c823

Browse files
authored
Merge pull request #1901 from effigies/enh/floating_freesurfer
ENH: Add ``--fs-subjects-dir`` flag
2 parents 493af6d + 4c2c278 commit 5d0c823

File tree

6 files changed

+41
-19
lines changed

6 files changed

+41
-19
lines changed

.circleci/config.yml

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,9 @@ jobs:
113113
steps:
114114
- restore_cache:
115115
keys:
116-
- data-v6-{{ .Revision }}
117-
- data-v6-
116+
- data-v7-{{ .Branch }}-{{ .Revision }}
117+
- data-v7-{{ .Branch }}
118+
- data-v7-
118119
- run:
119120
name: Get test data from ds000005
120121
command: |
@@ -149,11 +150,11 @@ jobs:
149150
- run:
150151
name: Get FreeSurfer derivatives for ds000005
151152
command: |
152-
if [[ ! -d /tmp/ds005/derivatives/freesurfer ]]; then
153-
mkdir -p /tmp/ds005/derivatives
153+
if [[ ! -d /tmp/ds005/freesurfer ]]; then
154+
mkdir -p /tmp/ds005
154155
wget --retry-connrefused --waitretry=5 --read-timeout=20 --timeout=15 -t 0 -q \
155156
-O ds005_derivatives_freesurfer.tar.gz "https://files.osf.io/v1/resources/fvuh8/providers/osfstorage/58fe59eb594d900250960180"
156-
tar xvzf ds005_derivatives_freesurfer.tar.gz -C /tmp/ds005/derivatives
157+
tar xvzf ds005_derivatives_freesurfer.tar.gz -C /tmp/ds005
157158
else
158159
echo "FreeSurfer derivatives of ds000005 were cached"
159160
fi
@@ -180,10 +181,10 @@ jobs:
180181
- ds054/nipype.cfg
181182
- ds210/nipype.cfg
182183
- save_cache:
183-
key: data-v6-{{ .Revision }}-{{ epoch }}
184+
key: data-v7-{{ .Branch }}-{{ .Revision }}-{{ epoch }}
184185
paths:
185186
- /tmp/data
186-
- /tmp/ds005/derivatives/freesurfer
187+
- /tmp/ds005/freesurfer
187188

188189
test_pytest:
189190
machine:
@@ -325,13 +326,13 @@ jobs:
325326
- docker-v3-{{ .Branch }}-{{ .Revision }}
326327
- restore_cache:
327328
keys:
328-
- data-v6-{{ .Revision }}
329+
- data-v7-{{ .Branch }}-{{ .Revision }}
329330
- restore_cache:
330331
keys:
331-
- ds005-anat-v16-{{ .Branch }}-{{ .Revision }}
332-
- ds005-anat-v16-{{ .Branch }}
333-
- ds005-anat-v16-master
334-
- ds005-anat-v16-
332+
- ds005-anat-v17-{{ .Branch }}-{{ .Revision }}
333+
- ds005-anat-v17-{{ .Branch }}
334+
- ds005-anat-v17-master
335+
- ds005-anat-v17-
335336
- run:
336337
name: Setting up test
337338
command: |
@@ -362,6 +363,7 @@ jobs:
362363
-e FMRIPREP_DEV 1 -u $(id -u) \
363364
--config $PWD/nipype.cfg -w /tmp/ds005/work \
364365
/tmp/data/ds005 /tmp/ds005/derivatives participant \
366+
--fs-subjects-dir /tmp/ds005/freesurfer \
365367
--skull-strip-template OASIS30ANTs:res-1 \
366368
--output-spaces MNI152NLin2009cAsym MNI152NLin6Asym \
367369
--sloppy --write-graph --mem_mb 4096 \
@@ -373,7 +375,7 @@ jobs:
373375
rm -rf /tmp/ds005/work/reportlets
374376
rm -rf /tmp/ds005/derivatives/fmriprep
375377
- save_cache:
376-
key: ds005-anat-v16-{{ .Branch }}-{{ .Revision }}-{{ epoch }}
378+
key: ds005-anat-v17-{{ .Branch }}-{{ .Revision }}-{{ epoch }}
377379
paths:
378380
- /tmp/ds005/work
379381

@@ -389,6 +391,7 @@ jobs:
389391
-e FMRIPREP_DEV 1 -u $(id -u) \
390392
--config $PWD/nipype.cfg -w /tmp/ds005/work \
391393
/tmp/data/ds005 /tmp/ds005/derivatives participant \
394+
--fs-subjects-dir /tmp/ds005/freesurfer \
392395
--sloppy --write-graph --use-syn-sdc --mem_mb 4096 \
393396
--use-aroma \
394397
--skull-strip-template OASIS30ANTs:res-1 \
@@ -399,7 +402,6 @@ jobs:
399402
name: Move intermediate results for second run
400403
command: |
401404
mkdir -p /tmp/ds005/derivatives_partial
402-
sudo mv /tmp/ds005/derivatives/freesurfer /tmp/ds005/derivatives_partial
403405
sudo cp -a /tmp/ds005/work /tmp/ds005/work_partial
404406
sudo rm -rf /tmp/ds005/work_partial/fmriprep_wf/single_subject_01_wf/func_preproc_task_mixedgamblestask_run_02_wf/ica_aroma_wf
405407
- run:
@@ -418,6 +420,7 @@ jobs:
418420
-e FMRIPREP_DEV 1 -u $(id -u) \
419421
--config $PWD/nipype.cfg -w /tmp/ds005/work_partial \
420422
/tmp/data/ds005 /tmp/ds005/derivatives_partial participant \
423+
--fs-subjects-dir /tmp/ds005/freesurfer \
421424
--sloppy --write-graph --use-syn-sdc --mem_mb 4096 \
422425
--output-spaces MNI152NLin2009cAsym fsaverage5 fsnative MNI152NLin6Asym anat \
423426
--aroma-melodic-dimensionality 2 --use-aroma \
@@ -479,7 +482,7 @@ jobs:
479482
- docker-v3-{{ .Branch }}-{{ .Revision }}
480483
- restore_cache:
481484
keys:
482-
- data-v6-{{ .Revision }}
485+
- data-v7-{{ .Branch }}-{{ .Revision }}
483486
- restore_cache:
484487
keys:
485488
- ds054-anat-v14-{{ .Branch }}-{{ .Revision }}
@@ -616,7 +619,7 @@ jobs:
616619
- docker-v3-{{ .Branch }}-{{ .Revision }}
617620
- restore_cache:
618621
keys:
619-
- data-v6-{{ .Revision }}
622+
- data-v7-{{ .Branch }}-{{ .Revision }}
620623
- restore_cache:
621624
keys:
622625
- ds210-anat-v12-{{ .Branch }}-{{ .Revision }}

docs/outputs.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ conformed space for surface reconstruction (``fsnative``) is stored in::
9090

9191
FreeSurfer derivatives
9292
~~~~~~~~~~~~~~~~~~~~~~
93-
A FreeSurfer subjects directory is created in ``<output_dir>/freesurfer``::
93+
A FreeSurfer subjects directory is created in ``<output dir>/freesurfer``, or the
94+
directory indicated with the ``--fs-subjects-dir`` flag. ::
9495

9596
<output_dir>/
9697
fmriprep/

docs/workflows.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ All surface preprocessing may be disabled with the ``--fs-no-reconall`` flag.
202202
Surface processing will be skipped if the outputs already exist.
203203

204204
In order to bypass reconstruction in *fMRIPrep*, place existing reconstructed
205-
subjects in ``<output dir>/freesurfer`` prior to the run.
205+
subjects in ``<output dir>/freesurfer`` prior to the run, or specify an external
206+
subjects directory with the ``--fs-subjects-dir`` flag.
206207
*fMRIPrep* will perform any missing ``recon-all`` steps, but will not perform
207208
any steps whose outputs already exist.
208209

fmriprep/cli/run.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,10 @@ def get_parser():
249249
'--fs-license-file', metavar='PATH', type=Path,
250250
help='Path to FreeSurfer license key file. Get it (for free) by registering'
251251
' at https://surfer.nmr.mgh.harvard.edu/registration.html')
252+
g_fs.add_argument(
253+
'--fs-subjects-dir', metavar='PATH', type=Path,
254+
help='Path to existing FreeSurfer subjects directory to reuse. '
255+
'(default: OUTPUT_DIR/freesurfer)')
252256

253257
# Surface generation xor
254258
g_surfs = parser.add_argument_group('Surface preprocessing options')
@@ -673,6 +677,7 @@ def build_workflow(opts, retval):
673677
fmap_demean=opts.fmap_no_demean,
674678
force_syn=opts.force_syn,
675679
freesurfer=opts.run_reconall,
680+
fs_subjects_dir=opts.fs_subjects_dir,
676681
hires=opts.hires,
677682
ignore=opts.ignore,
678683
layout=layout,

fmriprep/workflows/base.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ def init_fmriprep_wf(
4747
fmap_demean,
4848
force_syn,
4949
freesurfer,
50+
fs_subjects_dir,
5051
hires,
5152
ignore,
5253
layout,
@@ -101,6 +102,7 @@ def init_fmriprep_wf(
101102
fmap_demean=True,
102103
force_syn=True,
103104
freesurfer=True,
105+
fs_subjects_dir=None,
104106
hires=True,
105107
ignore=[],
106108
layout=BIDSLayout('.'),
@@ -221,6 +223,8 @@ def init_fmriprep_wf(
221223
spaces=[s for s in output_spaces.keys() if s.startswith('fsaverage')] + [
222224
'fsnative'] * ('fsnative' in output_spaces)),
223225
name='fsdir_run_' + run_uuid.replace('-', '_'), run_without_submitting=True)
226+
if fs_subjects_dir is not None:
227+
fsdir.inputs.subjects_dir = str(fs_subjects_dir.absolute())
224228

225229
reportlets_dir = os.path.join(work_dir, 'reportlets')
226230
for subject_id in subject_list:

wrapper/fmriprep_docker.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ def merge_help(wrapper_help, target_help):
142142
# Make sure we're not clobbering options we don't mean to
143143
overlap = set(w_flags).intersection(t_flags)
144144
expected_overlap = set(['h', 'version', 'w', 'template-resampling-grid',
145-
'fs-license-file', 'use-plugin'])
145+
'fs-license-file', 'fs-subjects-dir', 'use-plugin'])
146146

147147
assert overlap == expected_overlap, "Clobbering options: {}".format(
148148
', '.join(overlap - expected_overlap))
@@ -242,6 +242,10 @@ def get_parser():
242242
default=os.getenv('FS_LICENSE', None),
243243
help='Path to FreeSurfer license key file. Get it (for free) by registering'
244244
' at https://surfer.nmr.mgh.harvard.edu/registration.html')
245+
g_wrap.add_argument(
246+
'--fs-subjects-dir', metavar='PATH', type=os.path.abspath,
247+
help='Path to existing FreeSurfer subjects directory to reuse. '
248+
'(default: OUTPUT_DIR/freesurfer)')
245249
g_wrap.add_argument(
246250
'--use-plugin', metavar='PATH', action='store', default=None,
247251
type=os.path.abspath, help='nipype plugin configuration file')
@@ -366,6 +370,10 @@ def main():
366370
main_args.append('/out')
367371
main_args.append(opts.analysis_level)
368372

373+
if opts.fs_subjects_dir:
374+
command.extend(['-v', '{}:/opt/subjects'.format(opts.fs_subjects_dir)])
375+
unknown_args.extend(['--fs-subjects-dir', '/opt/subjects'])
376+
369377
if opts.work_dir:
370378
command.extend(['-v', ':'.join((opts.work_dir, '/scratch'))])
371379
unknown_args.extend(['-w', '/scratch'])

0 commit comments

Comments
 (0)