Skip to content

Commit 761befa

Browse files
authored
Merge pull request #16 from ntraut/skip
allow to skip not segmented subjects
2 parents 84e3c72 + 3c3512d commit 761befa

File tree

5 files changed

+80
-26
lines changed

5 files changed

+80
-26
lines changed

.circleci/config.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,15 @@ jobs:
5757
else
5858
echo "ds114_test2_freesurfer was cached"
5959
fi
60+
- run:
61+
name: Create a FreeSurfer folder with subject 02 missing
62+
command: |
63+
if [[ ! -d /tmp/data/ds114_test1_freesurfer_missing ]]; then
64+
mkdir /tmp/data/ds114_test1_freesurfer_missing
65+
cp -R /tmp/data/ds114_test1_freesurfer/sub-01 /tmp/data/ds114_test1_freesurfer_missing
66+
else
67+
echo "ds114_test1_freesurfer_missing was cached"
68+
fi
6069
- save_cache:
6170
key: data-v3-{{ .Revision }}-{{ epoch }}
6271
paths:
@@ -269,6 +278,31 @@ jobs:
269278
command: |
270279
cat ${OUTDIR}/ds114_test2/baracus/00_group/group_predicted_age.tsv
271280
281+
# Test 5: skip_missing
282+
- run:
283+
name: Test 5 skip_missing - 1
284+
command: |
285+
docker run --rm -ti -v ${DATADIR}/ds114_test1:/data/in \
286+
-v ${DATADIR}/ds114_test1_freesurfer_missing:/data/fs \
287+
-v ${OUTDIR}/ds114_test1_missing:/data/out \
288+
bids/${CIRCLE_PROJECT_REPONAME}:latest \
289+
/data/in /data/out participant --freesurfer_dir /data/fs \
290+
--license_key="~/test.key" --skip_missing
291+
- run:
292+
name: Test 5 skip_missing - 2
293+
command: |
294+
docker run --rm -ti -v ${DATADIR}/ds114_test1:/data/in \
295+
-v ${DATADIR}/ds114_test1_freesurfer_missing:/data/fs \
296+
-v ${OUTDIR}/ds114_test1_missing:/data/out \
297+
bids/${CIRCLE_PROJECT_REPONAME}:latest \
298+
/data/in /data/out group --freesurfer_dir /data/fs \
299+
--license_key="~/test.key" --skip_missing
300+
- run:
301+
name: Test 5 skip_missing - 3
302+
command: |
303+
cat ${OUTDIR}/ds114_test1_missing/baracus/00_group/group_predicted_age.tsv
304+
305+
272306
- store_artifacts:
273307
path: /tmp/outputs/
274308

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ previously processed data:
139139
found, recon-all will be run. If not specified
140140
freesurfer data will be saved to {out_dir}/freesurfer
141141
--models {Liem2016__OCI_norm,Liem2016__full_2samp_training} [{Liem2016__OCI_norm,Liem2016__full_2samp_training} ...]
142+
--skip_missing
143+
Flag to skip not segmented subjects
142144
--license_key LICENSE_KEY
143145
FreeSurfer license key - letters and numbers after "*"
144146
in the email you received after registration. To

baracus/prepare.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ def downsample_surfs(fs_dir, out_dir, subject, hemis=["lh", "rh"], meas=["thickn
1818
os.makedirs(subject_dir)
1919
out_file = os.path.join(subject_dir, "{h}.{m}.mgh".format(h=h, m=m))
2020
out_files[h + "_" + m + "_file"] = out_file
21-
22-
cmd = "mris_preproc --s {subject} --target fsaverage4 --hemi {h} " \
23-
"--meas {m} --out {out_file}".format(subject=subject, h=h, m=m, out_file=out_file)
24-
run(cmd, env={"SUBJECTS_DIR": fs_dir})
21+
if not os.path.isfile(out_file):
22+
cmd = "mris_preproc --s {subject} --target fsaverage4 --hemi {h} " \
23+
"--meas {m} --out {out_file}".format(
24+
subject=subject, h=h, m=m, out_file=out_file)
25+
run(cmd, env={"SUBJECTS_DIR": fs_dir})
2526
return out_files
2627

2728

@@ -30,14 +31,16 @@ def prepare_aseg(fs_dir, out_dir, subject):
3031
if not os.path.isdir(subject_dir):
3132
os.makedirs(subject_dir)
3233
out_file = os.path.join(subject_dir, "aseg")
33-
cmd = "asegstats2table --subjects {subject} --meas volume --tablefile {out_file}".format(subject=subject,
34-
out_file=out_file)
35-
print(cmd)
36-
run(cmd, env={"SUBJECTS_DIR": fs_dir})
34+
if not os.path.isfile(out_file):
35+
cmd = "asegstats2table --subjects {subject} --meas volume --tablefile {out_file}".format(subject=subject,
36+
out_file=out_file)
37+
print(cmd)
38+
run(cmd, env={"SUBJECTS_DIR": fs_dir})
3739
return out_file
3840

3941

40-
def run_prepare_all(bids_dir, freesurfer_dir, out_dir, subjects_to_analyze, sessions_to_analyze, n_cpus, license_key):
42+
def run_prepare_all(bids_dir, freesurfer_dir, out_dir, subjects_to_analyze, sessions_to_analyze, n_cpus, license_key,
43+
skip_missing=False):
4144
"""
4245
4346
:param bids_dir:
@@ -58,7 +61,7 @@ def run_prepare_all(bids_dir, freesurfer_dir, out_dir, subjects_to_analyze, sess
5861
for subject in subjects_to_analyze:
5962
sessions = sessions_to_analyze.get(subject)
6063
freesurfer_subjects.extend(run_fs_if_not_available(bids_dir, freesurfer_dir, subject, license_key, n_cpus,
61-
sessions))
64+
sessions, skip_missing))
6265

6366
# downsample surfaces to fsaverage4 and extract subcortical data from aseg
6467
out_files = {}

baracus/utils.py

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def run(command, env={}, ignore_errors=False):
1919
raise Exception("Non zero return code: %d" % process.returncode)
2020

2121

22-
def run_fs_if_not_available(bids_dir, freesurfer_dir, subject_label, license_key, n_cpus, sessions=[]):
22+
def run_fs_if_not_available(bids_dir, freesurfer_dir, subject_label, license_key, n_cpus, sessions=[], skip_missing=False):
2323
freesurfer_subjects = []
2424
if sessions:
2525
# long
@@ -32,21 +32,32 @@ def run_fs_if_not_available(bids_dir, freesurfer_dir, subject_label, license_key
3232
fs_missing = False
3333
for fss in freesurfer_subjects:
3434
if not os.path.exists(os.path.join(freesurfer_dir, fss, "scripts/recon-all.done")):
35-
fs_missing = True
35+
if skip_missing:
36+
freesurfer_subjects.remove(fss)
37+
else:
38+
fs_missing = True
3639

37-
if fs_missing:
38-
cmd = "run_freesurfer.py {in_dir} {out_dir} participant " \
39-
"--hires_mode disable " \
40-
"--participant_label {subject_label} " \
41-
"--license_key {license_key} " \
42-
"--n_cpus {n_cpus} --steps cross-sectional".format(in_dir=bids_dir,
43-
out_dir=freesurfer_dir,
44-
subject_label=subject_label,
45-
license_key=license_key,
46-
n_cpus=n_cpus)
40+
if fs_missing:
41+
cmd = "run_freesurfer.py {in_dir} {out_dir} participant " \
42+
"--hires_mode disable " \
43+
"--participant_label {subject_label} " \
44+
"--license_key {license_key} " \
45+
"--n_cpus {n_cpus} --steps cross-sectional".format(in_dir=bids_dir,
46+
out_dir=freesurfer_dir,
47+
subject_label=subject_label,
48+
license_key=license_key,
49+
n_cpus=n_cpus)
4750

48-
print("Freesurfer for {} not found. Running recon-all: {}".format(subject_label, cmd))
49-
run(cmd)
51+
print("Freesurfer for {} not found. Running recon-all: {}".format(subject_label, cmd))
52+
run(cmd)
53+
54+
for fss in freesurfer_subjects:
55+
aseg_file = os.path.join(freesurfer_dir, fss, "stats/aseg.stats")
56+
if not os.path.isfile(aseg_file):
57+
if skip_missing:
58+
freesurfer_subjects.remove(fss)
59+
else:
60+
raise FileNotFoundError(aseg_file)
5061
return freesurfer_subjects
5162

5263

scripts/run_brain_age_bids.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"out_dir}/freesurfer")
3939
parser.add_argument('--models', choices=models_list, default=["Liem2016__OCI_norm"], help='',
4040
nargs="+")
41+
parser.add_argument('--skip_missing', help='Flag to skip not segmented subjects', action='store_true')
4142
parser.add_argument('--license_key',
4243
help='FreeSurfer license key - letters and numbers after "*" in the email you '
4344
'received after registration. To register (for free) visit '
@@ -72,7 +73,7 @@
7273
if args.analysis_level == "participant":
7374

7475
data_files = run_prepare_all(args.bids_dir, freesurfer_dir, out_dir, subjects_to_analyze,
75-
sessions_to_analyze, args.n_cpus, args.license_key)
76+
sessions_to_analyze, args.n_cpus, args.license_key, args.skip_missing)
7677

7778
for subject, d in data_files.items():
7879
d["out_dir"] = out_dir
@@ -86,7 +87,10 @@
8687
df = pd.DataFrame([])
8788
for subject in freesurfer_subjects_to_analyze:
8889
in_file = os.path.join(out_dir, subject, subject + "_predicted_age.tsv")
89-
df = df.append(pd.read_csv(in_file, sep="\t"))
90+
if os.path.isfile(in_file):
91+
df = df.append(pd.read_csv(in_file, sep="\t"))
92+
elif not args.skip_missing:
93+
raise FileNotFoundError(in_file)
9094

9195
group_out_dir = os.path.join(out_dir, "00_group")
9296
if not os.path.isdir(group_out_dir):

0 commit comments

Comments
 (0)