Skip to content

Commit f6eef41

Browse files
authored
Merge pull request #5 from BIDS-Apps/fs
add recon-all
2 parents 97a3e91 + d09c9dc commit f6eef41

File tree

8 files changed

+316
-129
lines changed

8 files changed

+316
-129
lines changed

Dockerfile

Lines changed: 56 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,68 @@
1-
FROM ubuntu:trusty
1+
FROM bids/base_validator:latest
22

33
RUN apt-get update \
44
&& apt-get install -y wget tcsh
55

6-
RUN wget -qO- ftp://surfer.nmr.mgh.harvard.edu/pub/dist/freesurfer/5.3.0-HCP/freesurfer-Linux-centos4_x86_64-stable-pub-v5.3.0-HCP.tar.gz | tar zxv -C /opt \
7-
--exclude='freesurfer/trctrain' \
8-
--exclude='freesurfer/subjects/fsaverage_sym' \
9-
--exclude='freesurfer/subjects/fsaverage3' \
10-
--exclude='freesurfer/subjects/fsaverage5' \
11-
--exclude='freesurfer/subjects/fsaverage6' \
12-
--exclude='freesurfer/subjects/cvs_avg35' \
13-
--exclude='freesurfer/subjects/cvs_avg35_inMNI152' \
14-
--exclude='freesurfer/subjects/bert' \
15-
--exclude='freesurfer/subjects/V1_average' \
16-
--exclude='freesurfer/average/mult-comp-cor' \
17-
--exclude='freesurfer/lib/cuda' \
18-
--exclude='freesurfer/lib/qt'
6+
RUN wget -qO- https://surfer.nmr.mgh.harvard.edu/pub/dist/freesurfer/5.3.0/freesurfer-Linux-centos6_x86_64-stable-pub-v5.3.0.tar.gz | tar zxv -C /opt \
7+
--exclude='freesurfer/trctrain' \
8+
--exclude='freesurfer/subjects/fsaverage_sym' \
9+
--exclude='freesurfer/subjects/fsaverage3' \
10+
--exclude='freesurfer/subjects/fsaverage5' \
11+
--exclude='freesurfer/subjects/fsaverage6' \
12+
--exclude='freesurfer/subjects/cvs_avg35' \
13+
--exclude='freesurfer/subjects/cvs_avg35_inMNI152' \
14+
--exclude='freesurfer/subjects/bert' \
15+
--exclude='freesurfer/subjects/V1_average' \
16+
--exclude='freesurfer/average/mult-comp-cor' \
17+
--exclude='freesurfer/lib/cuda' \
18+
--exclude='freesurfer/lib/qt'
19+
1920

2021
RUN /bin/bash -c 'touch /opt/freesurfer/.license'
2122

22-
ENV OS Linux
23-
ENV FS_OVERRIDE 0
23+
ENV OS=Linux
24+
ENV FS_OVERRIDE=0
2425
ENV FIX_VERTEX_AREA=
25-
ENV SUBJECTS_DIR /opt/freesurfer/subjects
26-
ENV FSF_OUTPUT_FORMAT nii.gz
27-
ENV MNI_DIR /opt/freesurfer/mni
28-
ENV LOCAL_DIR /opt/freesurfer/local
29-
ENV FREESURFER_HOME /opt/freesurfer
30-
ENV FSFAST_HOME /opt/freesurfer/fsfast
31-
ENV MINC_BIN_DIR /opt/freesurfer/mni/bin
32-
ENV MINC_LIB_DIR /opt/freesurfer/mni/lib
33-
ENV MNI_DATAPATH /opt/freesurfer/mni/data
34-
ENV FMRI_ANALYSIS_DIR /opt/freesurfer/fsfast
35-
ENV PERL5LIB /opt/freesurfer/mni/lib/perl5/5.8.5
36-
ENV MNI_PERL5LIB /opt/freesurfer/mni/lib/perl5/5.8.5
37-
ENV PATH /opt/freesurfer/bin:/opt/freesurfer/fsfast/bin:/opt/freesurfer/tktools:/opt/freesurfer/mni/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
26+
ENV SUBJECTS_DIR=/opt/freesurfer/subjects
27+
ENV FSF_OUTPUT_FORMAT=nii.gz
28+
ENV MNI_DIR=/opt/freesurfer/mni
29+
ENV LOCAL_DIR=/opt/freesurfer/local
30+
ENV FREESURFER_HOME=/opt/freesurfer
31+
ENV FSFAST_HOME=/opt/freesurfer/fsfast
32+
ENV MINC_BIN_DIR=/opt/freesurfer/mni/bin
33+
ENV MINC_LIB_DIR=/opt/freesurfer/mni/lib
34+
ENV MNI_DATAPATH=/opt/freesurfer/mni/data
35+
ENV FMRI_ANALYSIS_DIR=/opt/freesurfer/fsfast
36+
ENV PERL5LIB=/opt/freesurfer/mni/lib/perl5/5.8.5
37+
ENV MNI_PERL5LIB=/opt/freesurfer/mni/lib/perl5/5.8.5
38+
ENV PATH=/opt/freesurfer/bin:/opt/freesurfer/fsfast/bin:/opt/freesurfer/tktools:/opt/freesurfer/mni/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH
39+
40+
RUN sudo apt-get update && apt-get install -y tree htop unzip
41+
RUN sudo apt-get update && apt-get install -y tcsh
42+
RUN sudo apt-get update && apt-get install -y bc
43+
RUN sudo apt-get update && apt-get install -y tar libgomp1 perl-modules
3844

3945
# make freesurfer python scripts python3 ready
4046
RUN 2to3-3.4 -w $FREESURFER_HOME/bin/aparcstats2table
4147
RUN 2to3-3.4 -w $FREESURFER_HOME/bin/asegstats2table
4248
RUN 2to3-3.4 -w $FREESURFER_HOME/bin/*.py
4349

50+
# download models
51+
RUN mkdir /code
52+
RUN wget -qO models.zip https://www.dropbox.com/s/5xbqw8i2e7x0g02/models.zip?dl=0 && \
53+
unzip models.zip && mv models /code/ && rm models.zip
54+
55+
# freesurfer repo
56+
RUN wget https://github.com/bids-apps/freesurfer/archive/v6.0.0-5.tar.gz && \
57+
tar xfz v6.0.0-5.tar.gz && rm -r v6.0.0-5.tar.gz && \
58+
cd freesurfer-6.0.0-5 && mv run.py /code/run_freesurfer.py
59+
# since we are using freesurfer-bids-app-run-code from FS6 and we run it with FS5.3,
60+
# we need to remove the parallel flag of recon-all
61+
RUN sed -e "s/-parallel //g" -i /code/run_freesurfer.py
62+
RUN echo "FS5.3_BIDSAPPv6.0.0-5" > /code/version
63+
ENV PATH=/code:$PATH
64+
65+
4466
# Install anaconda
4567
RUN echo 'export PATH=/usr/local/anaconda:$PATH' > /etc/profile.d/conda.sh && \
4668
wget --quiet https://repo.continuum.io/archive/Anaconda3-4.2.0-Linux-x86_64.sh -O anaconda.sh && \
@@ -56,11 +78,13 @@ ENV LC_ALL=C.UTF-8
5678

5779

5880
RUN pip install nibabel
81+
RUN pip install pybids
82+
RUN pip install duecredit
83+
84+
5985
COPY . /code/
6086
RUN cd /code && ls && pip install -e .
6187

62-
RUN apt-get install -y unzip
63-
RUN wget -qO models.zip https://www.dropbox.com/s/5xbqw8i2e7x0g02/models.zip?dl=0 && \
64-
unzip models.zip && mv models /code/ && rm models.zip
88+
6589

6690
ENTRYPOINT ["run_brain_age_bids.py"]

README.md

Lines changed: 55 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,30 @@ based on data from Freesurfer 5.3.
77
It combines data from cortical thickness, cortical surface area, and
88
subcortical information (see Liem et al., 2017).
99

10-
**How to cite BARACUS:** If you use BARACUS in your work please cite:
11-
1. Liem et al. (2017) and
10+
## Requirements
11+
Your data has to be organized according to the
12+
[BIDS standard](http://bids.neuroimaging.io) and each subject needs at
13+
least one T1w image.
14+
In a first step, BARACUS runs [FreeSurfer's](http://freesurfer.net)
15+
`recon-all` command and saves the output in `--freesurfer_dir`.
16+
If the data has previously been analyzed with FreeSurfer version 5.3.0,
17+
and BARACUS finds them in `--freesurfer_dir` this step ist skippen.
18+
19+
**Important:** if you use previously processed FreeSurfer data
20+
21+
1. the data has to be preprocessed with
22+
Freesurfer's 5.3.0 installation, not the 5.3.0-HCP installation;
23+
2. FreeSurfer data needs to be BIDS-formatted, i.e. subject folders
24+
should be named *sub-<subject_label>*, (e.g., sub-01, sub-02...)
25+
26+
27+
## Acknowledgements
28+
If you use BARACUS in your work please cite:
29+
30+
1. Liem et al. (2017),
1231
1. the [zenodo DOI](https://zenodo.org/badge/latestdoi/93560323)
13-
of the version you used.
32+
of the BARACUS version you used, and
33+
1. The [FreeSurfer tool](https://surfer.nmr.mgh.harvard.edu/fswiki/FreeSurferMethodsCitation)
1434

1535
Liem et al. (2017). Predicting brain-age
1636
from multimodal imaging data captures cognitive impairment.
@@ -19,26 +39,6 @@ Neuroimage, 148:179–188,
1939
[\[preprint\]](http://www.biorxiv.org/content/early/2016/11/07/085506)
2040

2141

22-
## Requirements
23-
Before age prediction can be performed, [FreeSurfer's](http://freesurfer.net)
24-
`recon-all` command has to be run with Freesurfer version 5.3.
25-
Freesurfer data has to be in [BIDS format](http://bids.neuroimaging.io),
26-
i.e. subject folders should be named
27-
*sub-<subject_label>*, (e.g., sub-01, sub-02...).
28-
29-
**Important:** The data has to be preprocessed with
30-
Freesurfer's 5.3.0 installation, not the 5.3.0-HCP installation.
31-
The [fliem/freesurfer:v6.0.0-3-FSv5.3.0-1](https://hub.docker.com/r/fliem/freesurfer/tags/)
32-
docker image can be used for that and can be run like this:
33-
34-
docker run -ti --rm \
35-
-v /Users/filo/data/ds005:/bids_dataset:ro \
36-
-v /Users/filo/outputs:/outputs \
37-
fliem/freesurfer:v6.0.0-3-FSv5.3.0-1 \
38-
/bids_dataset /outputs participant --participant_label 01 \
39-
--license_key "XXXXXXXX"
40-
41-
4242
## Models
4343
**Liem2016__OCI_norm**: Model trained on subjects that have no
4444
objective cognitive impairment (OCI) (*OCI norm* in Liem et al., 2017).
@@ -50,10 +50,8 @@ Sample: N = 2377, 1133f/1244m, age: M=58.4, SD=15.4, 18-83y;
5050
containing data from the LIFE and NKI studies.
5151

5252

53-
54-
5553
## Modes
56-
It can be run in **BIDS mode** and in in **FILE mode**.
54+
It can be run in **BIDS mode** (recommended) and in in **FILE mode**.
5755

5856
In BIDS mode the input is a BIDS formatted Freesurfer folder.
5957

@@ -66,42 +64,50 @@ aseg files extracted via asegstats2table.
6664

6765
## BIDS mode
6866
### Example
69-
#### Introduction
7067
These examples demonstrate how to run the `bids/baracus` docker container.
7168
For a brief introduction how to run BIDS Apps see
7269
[this site](http://bids-apps.neuroimaging.io/tutorial/).
73-
In the examples `project/freesurfer` and `/project/out` are directories
70+
In the examples `/project/bids_sourcedata`, `/project/freesurfer` and
71+
`/project/baracus` are directories
7472
on your hard drive, which are mapped into the docker container directories
75-
`/data/in` and `/data/out`, respectively, via the `-v` flag.
73+
`/data/in`, `/data/freesurfer` and `/data/out`, respectively, via
74+
the `-v` flag.
7675

7776
#### Participants
7877

7978
docker run -ti --rm \
80-
-v /project/freesurfer/:/data/in \
81-
-v /project/out:/data/out \
82-
bids/baracus /data/in /data/out participant
79+
-v /project/bids_sourcedata/:/data/in \
80+
-v /project/freesurfer/:/data/freesurfer \
81+
-v /project/baracus:/data/out \
82+
bids/baracus /data/in /data/out participant \
83+
--license_key "XX" --freesurfer_dir /data/freesurfer
8384

8485
#### Group
8586

8687
docker run -ti --rm \
87-
-v /project/freesurfer/:/data/in \
88-
-v /project/out:/data/out \
89-
bids/baracus /data/in /data/out group
88+
-v /project/bids_sourcedata/:/data/in \
89+
-v /project/freesurfer/:/data/freesurfer \
90+
-v /project/baracus:/data/out \
91+
bids/baracus /data/in /data/out group \
92+
--license_key "XX" --freesurfer_dir /data/freesurfer
9093

9194
### Usage
9295

96+
docker run -ti --rm bids/${CIRCLE_PROJECT_REPONAME,,} -h
9397
usage: run_brain_age_bids.py [-h]
9498
[--participant_label PARTICIPANT_LABEL [PARTICIPANT_LABEL ...]]
99+
--freesurfer_dir FREESURFER_DIR
95100
[--models {Liem2016__OCI_norm,Liem2016__full_2samp_training} [{Liem2016__OCI_norm,Liem2016__full_2samp_training} ...]]
96-
freesurfer_dir out_dir {participant,group}
101+
--license_key LICENSE_KEY [--n_cpus N_CPUS] [-v]
102+
bids_dir out_dir {participant,group}
97103

98104
BARACUS: Brain-Age Regression Analysis and Computation Utility Software. BIDS
99105
mode. You specify a BIDS-formatted freesurfer folder as input. All data is
100106
extracted automatiacally from that folder.
101107

102108
positional arguments:
103-
freesurfer_dir Folder with freesurfer subjects formatted according to
104-
BIDS standard.
109+
bids_dir The directory with the input dataset formatted
110+
according to the BIDS standard.
105111
out_dir Results are put here.
106112
{participant,group} Level of the analysis that will be performed.
107113
"participant": predicts single subject brain age,
@@ -116,8 +122,18 @@ on your hard drive, which are mapped into the docker container directories
116122
parameter is not provided all subjects should be
117123
analyzed. Multiple participants can be specified with
118124
a space separated list.
125+
--freesurfer_dir FREESURFER_DIR
126+
Folder with FreeSurfer subjects formatted according to
127+
BIDS standard. If subject's recon-all folder cannot be
128+
found, recon-all will be run.
119129
--models {Liem2016__OCI_norm,Liem2016__full_2samp_training} [{Liem2016__OCI_norm,Liem2016__full_2samp_training} ...]
120-
130+
--license_key LICENSE_KEY
131+
FreeSurfer license key - letters and numbers after "*"
132+
in the email you received after registration. To
133+
register (for free) visit
134+
https://surfer.nmr.mgh.harvard.edu/registration.html
135+
--n_cpus N_CPUS Number of CPUs/cores available to use.
136+
-v, --version show program's version number and exit
121137

122138

123139
## FILE mode

baracus/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
with open(os.path.join(dir_path, "../version")) as fi:
44
__version__ = fi.read().strip()
55

6-
models_list = ["Liem2016__OCI_norm", "Liem2016__full_2samp_training"]
6+
models_list = ["Liem2016__OCI_norm", "Liem2016__full_2samp_training"]
77

88
__changes__ = """
9+
* 1.0.0: compute recon-all
910
* 0.9.4: fixed models in brain_age_files
1011
* 0.9.3: fix tagging issue
1112
* 0.9.2: fixed typo, -v flag

baracus/prepare.py

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,6 @@
11
import os
2-
from subprocess import Popen, PIPE
3-
import subprocess
42

5-
6-
# https://github.com/BIDS-Apps/freesurfer/blob/master/run.py#L12
7-
def run(command, env={}, ignore_errors=False):
8-
merged_env = os.environ
9-
merged_env.update(env)
10-
# DEBUG env triggers freesurfer to produce gigabytes of files
11-
merged_env.pop('DEBUG', None)
12-
process = Popen(command, stdout=PIPE, stderr=subprocess.STDOUT, shell=True, env=merged_env)
13-
while True:
14-
line = process.stdout.readline()
15-
line = str(line, 'utf-8')[:-1]
16-
print(line)
17-
if line == '' and process.poll() != None:
18-
break
19-
if process.returncode != 0 and not ignore_errors:
20-
raise Exception("Non zero return code: %d" % process.returncode)
3+
from baracus.utils import run, run_fs_if_not_available
214

225

236
def prepare_fs_data(fs_dir, out_dir, subject):
@@ -54,17 +37,34 @@ def prepare_aseg(fs_dir, out_dir, subject):
5437
return out_file
5538

5639

57-
def run_prepare_all(freesurfer_dir, out_dir, subjects_to_analyze):
58-
# downsample surfaces to fsaverage4 and extract subcortical data from aseg
40+
def run_prepare_all(bids_dir, freesurfer_dir, out_dir, subjects_to_analyze, sessions_to_analyze, n_cpus, license_key):
41+
"""
42+
43+
:param bids_dir:
44+
:param freesurfer_dir:
45+
:param out_dir:
46+
:param subjects_to_analyze:
47+
:param sessions_to_analyze: {"subject_label": ["test", "retest"],...}; {} if not truly_long_study
48+
:return:
49+
"""
50+
5951
fsav_dir = os.path.join(os.environ["FREESURFER_HOME"], "subjects")
6052
for fsav in ["fsaverage", "fsaverage4"]:
6153
if not os.path.exists(os.path.join(freesurfer_dir, fsav)):
6254
os.symlink(os.path.join(fsav_dir, fsav), os.path.join(freesurfer_dir, fsav))
6355

64-
out_files = {}
56+
# check if freesurfer is available and run if missing
57+
freesurfer_subjects = []
6558
for subject in subjects_to_analyze:
66-
print("preparing %s" % subject)
67-
out_files[subject] = prepare_fs_data(freesurfer_dir, out_dir, subject)
59+
sessions = sessions_to_analyze.get(subject)
60+
freesurfer_subjects.extend(run_fs_if_not_available(bids_dir, freesurfer_dir, subject, license_key, n_cpus,
61+
sessions))
62+
63+
# downsample surfaces to fsaverage4 and extract subcortical data from aseg
64+
out_files = {}
65+
for fs_subject in freesurfer_subjects:
66+
print("preparing %s" % fs_subject)
67+
out_files[fs_subject] = prepare_fs_data(freesurfer_dir, out_dir, fs_subject)
6868

69-
print("FINISHED. Prepared %s" % " ".join(subjects_to_analyze))
69+
print("FINISHED. Prepared %s" % " ".join(freesurfer_subjects))
7070
return out_files

0 commit comments

Comments
 (0)