Skip to content
This repository was archived by the owner on Dec 27, 2022. It is now read-only.

Commit e117bb8

Browse files
committed
enh: added freesurfer dependency in preproc; updated dockerfile; renamed files for pyafq
1 parent 52c0e32 commit e117bb8

File tree

3 files changed

+147
-14
lines changed

3 files changed

+147
-14
lines changed

Dockerfile renamed to docker/Dockerfile

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,41 @@ RUN conda install -y -q --name preafq \
9898

9999
RUN sed -i '$isource activate preafq' $ND_ENTRYPOINT
100100

101+
102+
ENV FREESURFER_HOME="/opt/freesurfer-6.0.0" \
103+
PATH="/opt/freesurfer-6.0.0/bin:$PATH"
104+
105+
RUN apt-get update -qq \
106+
&& apt-get install -y -q --no-install-recommends \
107+
bc \
108+
libgomp1 \
109+
libxmu6 \
110+
libxt6 \
111+
perl \
112+
tcsh \
113+
&& apt-get clean \
114+
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
115+
&& echo "Downloading FreeSurfer ..." \
116+
&& mkdir -p /opt/freesurfer-6.0.0 \
117+
&& curl -fsSL --retry 5 ftp://surfer.nmr.mgh.harvard.edu/pub/dist/freesurfer/6.0.0/freesurfer-Linux-centos6_x86_64-stable-pub-v6.0.0.tar.gz \
118+
| tar -xz -C /opt/freesurfer-6.0.0 --strip-components 1 \
119+
--exclude='freesurfer/average/mult-comp-cor' \
120+
--exclude='freesurfer/lib/cuda' \
121+
--exclude='freesurfer/lib/qt' \
122+
--exclude='freesurfer/subjects/V1_average' \
123+
--exclude='freesurfer/subjects/bert' \
124+
--exclude='freesurfer/subjects/cvs_avg35' \
125+
--exclude='freesurfer/subjects/cvs_avg35_inMNI152' \
126+
--exclude='freesurfer/subjects/fsaverage3' \
127+
--exclude='freesurfer/subjects/fsaverage4' \
128+
--exclude='freesurfer/subjects/fsaverage5' \
129+
--exclude='freesurfer/subjects/fsaverage6' \
130+
--exclude='freesurfer/subjects/fsaverage_sym' \
131+
--exclude='freesurfer/trctrain' \
132+
&& sed -i '$isource "/opt/freesurfer-6.0.0/SetUpFreeSurfer.sh"' "$ND_ENTRYPOINT"
133+
134+
COPY ./license.txt /opt/freesurfer-6.0.0/license.txt
135+
101136
RUN echo '{ \
102137
\n "pkg_manager": "apt", \
103138
\n "instructions": [ \

docker/license.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
37716
3+
*C9LImOstH7yw
4+
FSrY9yK/yWp8E

run.py

Lines changed: 108 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
def run_preAFQ(dwi_file, bvec_file, bval_file, working_dir, sink_dir):
1+
def run_preAFQ(dwi_file, bvec_file, bval_file, subjects_dir, working_dir, sink_dir):
2+
import nipype.interfaces.freesurfer as fs
23
import nipype.interfaces.fsl as fsl
34
from nipype.interfaces.fsl.utils import AvScale
45
import nipype.pipeline.engine as pe
@@ -8,6 +9,8 @@ def run_preAFQ(dwi_file, bvec_file, bval_file, working_dir, sink_dir):
89
from nipype.interfaces.dipy import DTI
910
from nipype.utils.filemanip import fname_presuffix
1011
import os
12+
from nipype.interfaces.dipy import DTI
13+
from nipype.interfaces.c3 import C3dAffineTool
1114

1215
wf = create_dmri_preprocessing(name='preAFQ',
1316
use_fieldmap=False,
@@ -27,6 +30,73 @@ def run_preAFQ(dwi_file, bvec_file, bval_file, working_dir, sink_dir):
2730
flirt = wf.get_node("motion_correct.coregistration")
2831
#flirt.inputs.save_mats = True
2932

33+
get_tensor = pe.Node(DTI(), name="dipy_tensor")
34+
wf.connect(outputspec, "dmri_corrected",get_tensor,"in_file")
35+
#wf.connect(inputspec2,"bvals", get_tensor, "in_bval")
36+
get_tensor.inputs.in_bval = bval_file
37+
wf.connect(outputspec, "bvec_rotated", get_tensor, "in_bvec")
38+
39+
scale_tensor = pe.Node(name='scale_tensor', interface=fsl.BinaryMaths())
40+
scale_tensor.inputs.operation = 'mul'
41+
scale_tensor.inputs.operand_value = 1000
42+
wf.connect(get_tensor, 'out_file', scale_tensor, 'in_file')
43+
44+
fslroi = pe.Node(fsl.ExtractROI(t_min=0, t_size=1), name="fslroi")
45+
wf.connect(outputspec, "dmri_corrected", fslroi, "in_file")
46+
47+
bbreg = pe.Node(fs.BBRegister(contrast_type="t2", init="fsl", out_fsl_file=True,
48+
subjects_dir=subjects_dir,
49+
epi_mask=True),
50+
name="bbreg")
51+
#wf.connect(inputspec2,"fsid", bbreg,"subject_id")
52+
bbreg.inputs.subject_id = 'freesurfer' #bids_subject_name
53+
wf.connect(fslroi,"roi_file", bbreg, "source_file")
54+
55+
voltransform = pe.Node(fs.ApplyVolTransform(inverse=True),
56+
iterfield=['source_file', 'reg_file'],
57+
name='transform')
58+
voltransform.inputs.subjects_dir = subjects_dir
59+
60+
vt2 = voltransform.clone("transform_aparcaseg")
61+
vt2.inputs.interp = "nearest"
62+
63+
def binarize_aparc(aparc_aseg):
64+
import nibabel as nib
65+
from nipype.utils.filemanip import fname_presuffix
66+
import os
67+
img = nib.load(aparc_aseg)
68+
data, aff = img.get_data(), img.affine
69+
outfile = fname_presuffix(aparc_aseg, suffix="bin.nii.gz", newpath=os.path.abspath("."), use_ext=False)
70+
nib.Nifti1Image((data > 0).astype(float), aff).to_filename(outfile)
71+
return outfile
72+
73+
#wf.connect(inputspec2, "mask_nii", voltransform, "target_file")
74+
create_mask = pe.Node(niu.Function(input_names=["aparc_aseg"],
75+
output_names=["outfile"],
76+
function=binarize_aparc),
77+
name="bin_aparc")
78+
79+
def get_aparc_aseg(subjects_dir, sub):
80+
return os.path.join(subjects_dir, sub, "mri", "aparc+aseg.mgz")
81+
82+
create_mask.inputs.aparc_aseg = get_aparc_aseg(subjects_dir, 'freesurfer')
83+
wf.connect(create_mask, "outfile", voltransform, "target_file")
84+
85+
wf.connect(fslroi, "roi_file", voltransform, "source_file")
86+
wf.connect(bbreg, "out_reg_file", voltransform, "reg_file")
87+
88+
vt2.inputs.target_file = get_aparc_aseg(subjects_dir, 'freesurfer')
89+
#wf.connect(inputspec2, "aparc_aseg", vt2, "target_file")
90+
wf.connect(fslroi, "roi_file", vt2, "source_file")
91+
wf.connect(bbreg, "out_reg_file", vt2, "reg_file")
92+
93+
# AK (2017): THIS NODE MIGHT NOT BE NECESSARY
94+
# AK (2018) doesn't know why she said that above..
95+
threshold2 = pe.Node(fs.Binarize(min=0.5, out_type='nii.gz', dilate=1),
96+
iterfield=['in_file'],
97+
name='threshold2')
98+
wf.connect(voltransform, "transformed_file", threshold2, "in_file")
99+
30100

31101
#wf.connect(getmotion, "motion_params", datasink, "dti.@motparams")
32102

@@ -107,12 +177,35 @@ def rang(b):
107177
("stats.vol0000_flirt_merged.txt", dwi_filename+".art.json"),
108178
("motion_parameters.par", dwi_filename+".motion.txt"),
109179
("_rotated.bvec", ".bvec"),
110-
("derivatives/dwi", "derivatives/{}/dwi".format(bids_subject_name))]
111-
112-
wf.connect(art, "statistic_files", datasink, "dwi.@artstat")
113-
wf.connect(outputspec, "dmri_corrected", datasink, "dwi.@corrected")
114-
wf.connect(outputspec,"bvec_rotated", datasink, "dwi.@rotated")
115-
wf.connect(getmotion, "motion_params", datasink, "dwi.@motion")
180+
("aparc+aseg_warped_out", dwi_filename.replace("_dwi", "_aparc+aseg")),
181+
("art.vol0000_flirt_merged_outliers.txt", dwi_filename+ ".outliers.txt"),
182+
("vol0000_flirt_merged", dwi_filename),
183+
("_roi_bbreg_freesurfer", "_register"),
184+
("aparc+asegbin_warped_thresh", dwi_filename.replace("_dwi", "_mask")),
185+
("derivatives/preafq", "derivatives/{}/preafq".format(bids_subject_name))]
186+
187+
wf.connect(art, "statistic_files", datasink, "preafq.art.@artstat")
188+
wf.connect(art, "outlier_files", datasink, "preafq.art.@artoutlier")
189+
wf.connect(outputspec, "dmri_corrected", datasink, "preafq.dwi.@corrected")
190+
wf.connect(outputspec,"bvec_rotated", datasink, "preafq.dwi.@rotated")
191+
wf.connect(getmotion, "motion_params", datasink, "preafq.art.@motion")
192+
193+
wf.connect(get_tensor, "out_file", datasink, "preafq.dti.@tensor")
194+
wf.connect(get_tensor, "fa_file", datasink, "preafq.dti.@fa")
195+
wf.connect(get_tensor, "md_file", datasink, "preafq.dti.@md")
196+
wf.connect(get_tensor, "ad_file", datasink, "preafq.dti.@ad")
197+
wf.connect(get_tensor, "rd_file", datasink, "preafq.dti.@rd")
198+
wf.connect(get_tensor, "out_file", datasink, "preafq.dti.@scaled_tensor")
199+
200+
wf.connect(bbreg, "min_cost_file", datasink, "preafq.reg.@mincost")
201+
wf.connect(bbreg,"out_fsl_file", datasink, "preafq.reg.@fslfile")
202+
wf.connect(bbreg, "out_reg_file", datasink, "preafq.reg.@reg")
203+
wf.connect(threshold2, "binary_file", datasink, "preafq.anat.@mask")
204+
#wf.connect(vt2, "transformed_file", datasink, "dwi.@aparc_aseg")
205+
206+
convert = pe.Node(fs.MRIConvert(out_type="niigz"), name="convert2nii")
207+
wf.connect(vt2, "transformed_file", convert, "in_file")
208+
wf.connect(convert, "out_file", datasink, "preafq.anat.@aparc_aseg")
116209

117210
wf.base_dir = working_dir
118211
wf.run()
@@ -121,11 +214,12 @@ def rang(b):
121214
import os
122215
from shutil import copyfile
123216

124-
copyfile(bval_file, os.path.join(sink_dir, bids_subject_name, "dwi", os.path.split(bval_file)[1]))
217+
copyfile(bval_file, os.path.join(sink_dir, bids_subject_name, "preafq", "dwi", os.path.split(bval_file)[1]))
125218

126-
dmri_corrected = glob(os.path.join(sink_dir, '*/dwi', '*.nii.gz'))[0]
127-
bvec_rotated = glob(os.path.join(sink_dir, '*/dwi', '*.bvec'))[0]
128-
bval_file = glob(os.path.join(sink_dir, '*/dwi', '*.bval'))[0]
129-
art_file = glob(os.path.join(sink_dir, '*/dwi', '*.art.json'))[0]
130-
motion_file = glob(os.path.join(sink_dir, '*/dwi', '*.motion.txt'))[0]
131-
return dmri_corrected, bvec_rotated, art_file, motion_file
219+
dmri_corrected = glob(os.path.join(sink_dir, '*/preafq/dwi', '*.nii.gz'))[0]
220+
bvec_rotated = glob(os.path.join(sink_dir, '*/preafq/dwi', '*.bvec'))[0]
221+
bval_file = glob(os.path.join(sink_dir, '*/preafq/dwi', '*.bval'))[0]
222+
art_file = glob(os.path.join(sink_dir, '*/preafq/art', '*.art.json'))[0]
223+
motion_file = glob(os.path.join(sink_dir, '*/preafq/art', '*.motion.txt'))[0]
224+
outlier_file = glob(os.path.join(sink_dir, '*/preafq/art', '*.outliers.txt'))[0]
225+
return dmri_corrected, bvec_rotated, art_file, motion_file, outlier_file

0 commit comments

Comments
 (0)