Skip to content

Commit 88333ff

Browse files
authored
Merge pull request #144 from slimnsour/enh-eddy
ENH: Temporary integration of FSL eddy
2 parents 5dc97ae + 059e314 commit 88333ff

File tree

9 files changed

+353
-5
lines changed

9 files changed

+353
-5
lines changed

.circleci/config.yml

100644100755
Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -298,8 +298,12 @@ jobs:
298298
- /tmp/ds000206/work
299299
- run:
300300
name: Run full diffusion workflow on ds000206
301-
no_output_timeout: 2h
301+
no_output_timeout: 4h
302302
command: |
303+
eddy="--ignore eddy"
304+
if [[ "$( git log --format=oneline -n 1 $CIRCLE_SHA1 | grep -i -E '\[run[ _]?eddy\]' )" != "" ]]; then
305+
eddy=""
306+
fi
303307
mkdir -p /tmp/ds000206/work /tmp/ds000206/derivatives
304308
docker run -e FS_LICENSE=$FS_LICENSE --rm \
305309
-v /tmp/data/ds000206:/data \
@@ -309,7 +313,7 @@ jobs:
309313
-v /tmp/templateflow:/home/dmriprep/.cache/templateflow \
310314
-v /tmp/ds000206/work:/work \
311315
--user $(id -u):$(id -g) \
312-
nipreps/dmriprep:latest /data /out participant -vv \
316+
nipreps/dmriprep:latest /data /out participant -vv $eddy \
313317
--fs-subjects-dir /data/derivatives/freesurfer-6.0.1 --sloppy \
314318
--notrack --skip-bids-validation -w /work --omp-nthreads 2 --nprocs 2
315319
- store_artifacts:
@@ -379,8 +383,12 @@ jobs:
379383
docker tag localhost:5000/dmriprep nipreps/dmriprep:latest
380384
- run:
381385
name: Run full diffusion workflow on ds001771
382-
no_output_timeout: 2h
386+
no_output_timeout: 4h
383387
command: |
388+
eddy="--ignore eddy"
389+
if [[ "$( git log --format=oneline -n 1 $CIRCLE_SHA1 | grep -i -E '\[run[ _]?eddy\]' )" != "" ]]; then
390+
eddy=""
391+
fi
384392
mkdir -p /tmp/ds001771/work /tmp/ds001771/derivatives
385393
docker run -e FS_LICENSE=$FS_LICENSE --rm \
386394
-v /tmp/data/ds001771:/data \
@@ -390,7 +398,7 @@ jobs:
390398
-v /tmp/config/nipype.cfg:/home/dmriprep/.nipype/nipype.cfg \
391399
-v /tmp/ds001771/work:/work \
392400
--user $(id -u):$(id -g) \
393-
nipreps/dmriprep:latest /data /out participant -vv \
401+
nipreps/dmriprep:latest /data /out participant -vv $eddy \
394402
-w /work --omp-nthreads 2 --nprocs 2 \
395403
--notrack --skip-bids-validation --sloppy \
396404
--fs-subjects-dir /data/derivatives/freesurfer-6.0.1 \

.docker/fsl-6.0/bin/eddy_openmp

30.8 MB
Binary file not shown.

.docker/fsl-6.0/bin/imglob

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#!/usr/bin/env python
2+
# imglob - expand list of image filenames
3+
# Stephen Smith, Mark Jenkinson and Matthew Webster FMRIB Image Analysis Group
4+
# Copyright (C) 2009 University of Oxford
5+
# Part of FSL - FMRIB's Software Library
6+
# http://www.fmrib.ox.ac.uk/fsl
7+
8+
#
9+
# Developed at FMRIB (Oxford Centre for Functional Magnetic Resonance
10+
# Imaging of the Brain), Department of Clinical Neurology, Oxford
11+
# University, Oxford, UK
12+
#
13+
#
14+
# LICENCE
15+
#
16+
# FMRIB Software Library, Release 5.0 (c) 2012, The University of
17+
# Oxford (the "Software")
18+
#
19+
# The Software remains the property of the University of Oxford ("the
20+
# University").
21+
#
22+
# The Software is distributed "AS IS" under this Licence solely for
23+
# non-commercial use in the hope that it will be useful, but in order
24+
# that the University as a charitable foundation protects its assets for
25+
# the benefit of its educational and research purposes, the University
26+
# makes clear that no condition is made or to be implied, nor is any
27+
# warranty given or to be implied, as to the accuracy of the Software,
28+
# or that it will be suitable for any particular purpose or for use
29+
# under any specific conditions. Furthermore, the University disclaims
30+
# all responsibility for the use which is made of the Software. It
31+
# further disclaims any liability for the outcomes arising from using
32+
# the Software.
33+
#
34+
# The Licensee agrees to indemnify the University and hold the
35+
# University harmless from and against any and all claims, damages and
36+
# liabilities asserted by third parties (including claims for
37+
# negligence) which arise directly or indirectly from the use of the
38+
# Software or the sale of any products based on the Software.
39+
#
40+
# No part of the Software may be reproduced, modified, transmitted or
41+
# transferred in any form or by any means, electronic or mechanical,
42+
# without the express permission of the University. The permission of
43+
# the University is not required if the said reproduction, modification,
44+
# transmission or transference is done without financial return, the
45+
# conditions of this Licence are imposed upon the receiver of the
46+
# product, and all original and amended source code is included in any
47+
# transmitted product. You may be held legally responsible for any
48+
# copyright infringement that is caused or encouraged by your failure to
49+
# abide by these terms and conditions.
50+
#
51+
# You are not permitted under this Licence to use this Software
52+
# commercially. Use for which any financial return is received shall be
53+
# defined as commercial use, and includes (1) integration of all or part
54+
# of the source code or the Software into a product for sale or license
55+
# by or on behalf of Licensee to third parties or (2) use of the
56+
# Software or any derivative of it for research with the final aim of
57+
# developing software products for sale or license to a third party or
58+
# (3) use of the Software or any derivative of it for research with the
59+
# final aim of developing non-software products for sale or license to a
60+
# third party, or (4) use of the Software to provide any service to an
61+
# external organisation for which payment is received. If you are
62+
# interested in using the Software commercially, please contact Isis
63+
# Innovation Limited ("Isis"), the technology transfer company of the
64+
# University, to negotiate a licence. Contact details are:
65+
# [email protected] quoting reference DE/9564.
66+
67+
import sys
68+
import os
69+
import glob
70+
71+
setAvailable=True
72+
if sys.version_info < (2, 4):
73+
import sets
74+
from sets import Set
75+
setAvailable=False
76+
77+
def usage():
78+
print("Usage: $0 [-extension/extensions] <list of names>")
79+
print(" -extension for one image with full extension")
80+
print(" -extensions for image list with full extensions")
81+
sys.exit(1)
82+
83+
def isImage(input,allExtensions): #Returns whether an input filename has an image extension ( and the basename and extension pair )
84+
for extension in allExtensions:
85+
if input[-len(extension):] == extension:
86+
return True, input[:-len(extension)], extension
87+
return False, input, ''
88+
89+
def removeImageExtension(input,allExtensions):
90+
return isImage(input,allExtensions)[1]
91+
92+
if len(sys.argv) <= 1:
93+
usage()
94+
95+
deleteExtensions=True
96+
primaryExtensions=['.nii.gz', '.nii', '.hdr.gz', '.hdr']
97+
secondaryExtensions=['.img.gz', '.img']
98+
allExtensions=primaryExtensions+secondaryExtensions
99+
validExtensions=primaryExtensions
100+
startingArg=1
101+
102+
if sys.argv[1] == "-extensions":
103+
validExtensions=allExtensions
104+
deleteExtensions=False
105+
startingArg=2
106+
if sys.argv[1] == "-extension":
107+
deleteExtensions=False
108+
startingArg=2
109+
110+
filelist=[]
111+
for arg in range(startingArg, len(sys.argv)):
112+
# if isImage(sys.argv[arg],allExtensions)[0]: #These enable a "pedantic" style mode currently not used
113+
# filelist.extend(glob.glob(sys.argv[arg]))
114+
# else:
115+
# for currentExtension in validExtensions:
116+
# filelist.extend(glob.glob(sys.argv[arg]+currentExtension))
117+
for currentExtension in validExtensions:
118+
filelist.extend(glob.glob(removeImageExtension(sys.argv[arg],allExtensions)+currentExtension))
119+
120+
if deleteExtensions:
121+
for file in range(0, len(filelist)):
122+
filelist[file]=removeImageExtension(filelist[file],allExtensions)
123+
if setAvailable:
124+
filelist=list(set(filelist))
125+
else:
126+
filelist=list(Set(filelist))
127+
filelist.sort()
128+
129+
for file in range(0, len(filelist)):
130+
print(filelist[file], end=' ')
131+
if file < len(filelist)-1:
132+
print(" ", end=' ')

Dockerfile

100644100755
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ ENV FSLDIR="/usr/share/fsl/5.0" \
9393
ENV PATH="/usr/lib/fsl/5.0:/usr/lib/afni/bin:$PATH"
9494

9595
COPY .docker/fsl-6.0/bin/topup /usr/share/fsl/5.0/bin/topup
96+
COPY .docker/fsl-6.0/bin/imglob /usr/share/fsl/5.0/bin/imglob
97+
COPY .docker/fsl-6.0/bin/eddy_openmp /usr/lib/fsl/5.0/eddy_openmp
9698
COPY .docker/fsl-6.0/lib/* /usr/lib/fsl/5.0/
9799

98100
# Installing ANTs 2.3.3 (NeuroDocker build)

dmriprep/cli/parser.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ def _bids_filter(value):
191191
action="store",
192192
nargs="+",
193193
default=[],
194-
choices=["fieldmaps", "sbref"],
194+
choices=["fieldmaps", "sbref", "eddy"],
195195
help="ignore selected aspects of the input dataset to disable corresponding "
196196
"parts of the workflow (a space delimited list)",
197197
)

dmriprep/config/reports-spec.yml

100644100755
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,13 @@ sections:
7474
description: The reportlet shows a <em>b=0</em> reference <em>before</em> and <em>after</em> distortion correction.
7575
static: false
7676
subtitle: Unwarping of susceptibility distortions
77+
- bids: {datatype: figures, desc: eddy, suffix: dwi}
78+
caption: Head-motion and eddy current corrected diffusion data
79+
description: Eddy current-induced geometric distortions and head-motion
80+
realignment parameters were estimated with the joint modeling of
81+
<code>eddy_openmp</code>, included in FSL.
82+
static: false
83+
subtitle: Eddy corrected diffusion data
7784
- bids: {datatype: figures, desc: coreg, suffix: dwi}
7885
caption: Diffusion-weighted data and anatomical data (EPI-space and T1w-space)
7986
were aligned with <code>mri_coreg</code> (FreeSurfer).

dmriprep/workflows/dwi/base.py

100644100755
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,10 @@ def init_dwi_preproc_wf(dwi_file, has_fieldmap=False):
6969
7070
"""
7171
from ...interfaces.vectors import CheckGradientTable
72+
from niworkflows.interfaces import SimpleBeforeAfter
7273
from .util import init_dwi_reference_wf
7374
from .outputs import init_reportlets_wf
75+
from .eddy import init_eddy_wf
7476

7577
layout = config.execution.layout
7678

@@ -201,6 +203,44 @@ def _bold_reg_suffix(fallback):
201203
])
202204
# fmt: on
203205

206+
if "eddy" not in config.workflow.ignore:
207+
# Eddy distortion correction
208+
eddy_wf = init_eddy_wf(debug=config.execution.debug)
209+
eddy_wf.inputs.inputnode.metadata = layout.get_metadata(str(dwi_file))
210+
211+
ds_report_eddy = pe.Node(
212+
DerivativesDataSink(
213+
base_directory=str(config.execution.output_dir),
214+
desc="eddy",
215+
datatype="figures",
216+
),
217+
name="ds_report_eddy",
218+
run_without_submitting=True,
219+
)
220+
221+
eddy_report = pe.Node(
222+
SimpleBeforeAfter(before_label="Distorted", after_label="Eddy Corrected",),
223+
name="eddy_report",
224+
mem_gb=0.1,
225+
)
226+
227+
# fmt:off
228+
workflow.connect([
229+
(dwi_reference_wf, eddy_wf, [
230+
("outputnode.dwi_file", "inputnode.dwi_file"),
231+
("outputnode.dwi_mask", "inputnode.dwi_mask"),
232+
]),
233+
(inputnode, eddy_wf, [
234+
("in_bvec", "inputnode.in_bvec"),
235+
("in_bval", "inputnode.in_bval")
236+
]),
237+
(dwi_reference_wf, eddy_report, [("outputnode.ref_image", "before")]),
238+
(eddy_wf, eddy_report, [('outputnode.eddy_ref_image', 'after')]),
239+
(dwi_reference_wf, ds_report_eddy, [("outputnode.dwi_file", "source_file")]),
240+
(eddy_report, ds_report_eddy, [("out_report", "in_file")]),
241+
])
242+
# fmt:on
243+
204244
# REPORTING ############################################################
205245
reportlets_wf = init_reportlets_wf(
206246
str(config.execution.output_dir),

0 commit comments

Comments
 (0)