Skip to content

Commit 54d058e

Browse files
committed
Conflicts with master resolved
2 parents 373bddd + 0cd54bc commit 54d058e

File tree

17 files changed

+469
-244
lines changed

17 files changed

+469
-244
lines changed

.zenodo.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,11 @@
563563
"affiliation": "MIT, HMS",
564564
"name": "Ghosh, Satrajit",
565565
"orcid": "0000-0002-5312-6729"
566+
},
567+
{
568+
"affiliation": "University College London",
569+
"name": "Mancini, Matteo",
570+
"orcid": "0000-0001-7194-4568"
566571
}
567572
],
568573
"keywords": [

doc/users/config_file.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,11 @@ Execution
7474

7575
*display_variable*
7676
Override the ``$DISPLAY`` environment variable for interfaces that require
77-
an X server. This option is useful if there is a running X server, but
78-
``$DISPLAY`` was not defined in nipype's environment. For example, if an X
77+
an X server. This option is useful if there is a running X server, but
78+
``$DISPLAY`` was not defined in nipype's environment. For example, if an X
7979
server is listening on the default port of 6000, set ``display_variable = :0``
80-
to enable nipype interfaces to use it. It may also point to displays provided
81-
by VNC, `xnest <http://www.x.org/archive/X11R7.5/doc/man/man1/Xnest.1.html>`_
80+
to enable nipype interfaces to use it. It may also point to displays provided
81+
by VNC, `xnest <http://www.x.org/archive/X11R7.5/doc/man/man1/Xnest.1.html>`_
8282
or `Xvfb <http://www.x.org/archive/X11R6.8.1/doc/Xvfb.1.html>`_.
8383
If neither ``display_variable`` nor the ``$DISPLAY`` environment variable are
8484
set, nipype will try to configure a new virtual server using Xvfb.

nipype/algorithms/tests/test_mesh_ops.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
@pytest.mark.skipif(VTKInfo.no_tvtk(), reason="tvtk is not installed")
1717
def test_ident_distances(tmpdir):
18-
tmpdir.chdir()
18+
tmpdir.chdir()
1919

2020
in_surf = example_data('surf01.vtk')
2121
dist_ident = m.ComputeMeshWarp()

nipype/interfaces/ants/tests/test_resampling.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
2-
# vi: set ft=python sts=4 ts=4 sw=4 et:
2+
# vi: set ft=python sts=4 ts=4 sw=4 et:
33

44
from nipype.interfaces.ants import WarpImageMultiTransform, WarpTimeSeriesImageMultiTransform
55
import os
@@ -66,7 +66,7 @@ def create_wtsimt():
6666
def test_WarpTimeSeriesImageMultiTransform(change_dir, create_wtsimt):
6767
wtsimt = create_wtsimt
6868
assert wtsimt.cmdline == 'WarpTimeSeriesImageMultiTransform 4 resting.nii resting_wtsimt.nii \
69-
-R ants_deformed.nii.gz ants_Warp.nii.gz ants_Affine.txt'
69+
-R ants_deformed.nii.gz ants_Warp.nii.gz ants_Affine.txt'
7070

7171

7272
def test_WarpTimeSeriesImageMultiTransform_invaffine(change_dir, create_wtsimt):

nipype/interfaces/cmtk/tests/test_nbs.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ def test_importerror(creating_graphs, tmpdir):
3131
graphlist = creating_graphs
3232
group1 = graphlist[:3]
3333
group2 = graphlist[3:]
34-
34+
3535
nbs = NetworkBasedStatistic()
3636
nbs.inputs.in_group1 = group1
3737
nbs.inputs.in_group2 = group2
3838
nbs.inputs.edge_key = "weight"
39-
39+
4040
with pytest.raises(ImportError) as e:
4141
nbs.run()
4242
assert "cviewer library is not available" == str(e.value)

nipype/interfaces/mrtrix3/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# -*- coding: utf-8 -*-
55

66
from .utils import (Mesh2PVE, Generate5tt, BrainMask, TensorMetrics,
7-
ComputeTDI, TCK2VTK)
7+
ComputeTDI, TCK2VTK, MRMath, MRConvert, DWIExtract)
88
from .preprocess import ResponseSD, ACTPrepareFSL, ReplaceFSwithFIRST
99
from .tracking import Tractography
1010
from .reconst import FitTensor, EstimateFOD

nipype/interfaces/mrtrix3/preprocess.py

Lines changed: 24 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -16,87 +16,47 @@
1616
import os.path as op
1717

1818
from ..base import (CommandLineInputSpec, CommandLine, traits, TraitedSpec,
19-
File, isdefined)
19+
File, isdefined, Undefined)
2020
from .base import MRTrix3BaseInputSpec, MRTrix3Base
2121

2222

2323
class ResponseSDInputSpec(MRTrix3BaseInputSpec):
24-
in_file = File(exists=True, argstr='%s', mandatory=True, position=-2,
25-
desc='input diffusion weighted images')
26-
27-
out_file = File(
28-
'response.txt', argstr='%s', mandatory=True, position=-1,
29-
usedefault=True, desc='output file containing SH coefficients')
30-
31-
# DW Shell selection options
32-
shell = traits.List(traits.Float, sep=',', argstr='-shell %s',
33-
desc='specify one or more dw gradient shells')
24+
algorithm = traits.Enum('msmt_5tt','dhollander','tournier','tax', argstr='%s', position=-6,
25+
mandatory=True, desc='response estimation algorithm (multi-tissue)')
26+
dwi_file = File(exists=True, argstr='%s', position=-5,
27+
mandatory=True, desc='input DWI image')
28+
mtt_file = File(argstr='%s', position=-4, desc='input 5tt image')
29+
wm_file = File('wm.txt', argstr='%s', position=-3, usedefault=True,
30+
desc='output WM response text file')
31+
gm_file = File(argstr='%s', position=-2, desc='output GM response text file')
32+
csf_file = File(argstr='%s', position=-1, desc='output CSF response text file')
3433
in_mask = File(exists=True, argstr='-mask %s',
35-
desc='provide initial mask image')
34+
desc='provide initial mask image')
3635
max_sh = traits.Int(8, argstr='-lmax %d',
37-
desc='maximum harmonic degree of response function')
38-
out_sf = File('sf_mask.nii.gz', argstr='-sf %s',
39-
desc='write a mask containing single-fibre voxels')
40-
test_all = traits.Bool(False, argstr='-test_all',
41-
desc='re-test all voxels at every iteration')
42-
43-
# Optimization
44-
iterations = traits.Int(0, argstr='-max_iters %d',
45-
desc='maximum number of iterations per pass')
46-
max_change = traits.Float(
47-
argstr='-max_change %f',
48-
desc=('maximum percentile change in any response function coefficient;'
49-
' if no individual coefficient changes by more than this '
50-
'fraction, the algorithm is terminated.'))
51-
52-
# Thresholds
53-
vol_ratio = traits.Float(
54-
.15, argstr='-volume_ratio %f',
55-
desc=('maximal volume ratio between the sum of all other positive'
56-
' lobes in the voxel and the largest FOD lobe'))
57-
disp_mult = traits.Float(
58-
1., argstr='-dispersion_multiplier %f',
59-
desc=('dispersion of FOD lobe must not exceed some threshold as '
60-
'determined by this multiplier and the FOD dispersion in other '
61-
'single-fibre voxels. The threshold is: (mean + (multiplier * '
62-
'(mean - min))); default = 1.0. Criterion is only applied in '
63-
'second pass of RF estimation.'))
64-
int_mult = traits.Float(
65-
2., argstr='-integral_multiplier %f',
66-
desc=('integral of FOD lobe must not be outside some range as '
67-
'determined by this multiplier and FOD lobe integral in other'
68-
' single-fibre voxels. The range is: (mean +- (multiplier * '
69-
'stdev)); default = 2.0. Criterion is only applied in second '
70-
'pass of RF estimation.'))
36+
desc='maximum harmonic degree of response function')
7137

7238

7339
class ResponseSDOutputSpec(TraitedSpec):
74-
out_file = File(exists=True, desc='the output response file')
75-
out_sf = File(desc=('mask containing single-fibre voxels'))
40+
wm_file = File(argstr='%s', desc='output WM response text file')
41+
gm_file = File(argstr='%s', desc='output GM response text file')
42+
csf_file = File(argstr='%s', desc='output CSF response text file')
7643

7744

7845
class ResponseSD(MRTrix3Base):
7946

8047
"""
81-
Generate an appropriate response function from the image data for
82-
spherical deconvolution.
83-
84-
.. [1] Tax, C. M.; Jeurissen, B.; Vos, S. B.; Viergever, M. A. and
85-
Leemans, A., Recursive calibration of the fiber response function
86-
for spherical deconvolution of diffusion MRI data. NeuroImage,
87-
2014, 86, 67-80
88-
48+
Estimate response function(s) for spherical deconvolution using the specified algorithm.
8949
9050
Example
9151
-------
9252
9353
>>> import nipype.interfaces.mrtrix3 as mrt
9454
>>> resp = mrt.ResponseSD()
95-
>>> resp.inputs.in_file = 'dwi.mif'
96-
>>> resp.inputs.in_mask = 'mask.nii.gz'
55+
>>> resp.inputs.dwi_file = 'dwi.mif'
56+
>>> resp.inputs.algorithm = 'tournier'
9757
>>> resp.inputs.grad_fsl = ('bvecs', 'bvals')
9858
>>> resp.cmdline # doctest: +ELLIPSIS
99-
'dwi2response -fslgrad bvecs bvals -mask mask.nii.gz dwi.mif response.txt'
59+
'dwi2response -fslgrad bvecs bvals tournier dwi.mif wm.txt'
10060
>>> resp.run() # doctest: +SKIP
10161
"""
10262

@@ -106,10 +66,11 @@ class ResponseSD(MRTrix3Base):
10666

10767
def _list_outputs(self):
10868
outputs = self.output_spec().get()
109-
outputs['out_file'] = op.abspath(self.inputs.out_file)
110-
111-
if isdefined(self.inputs.out_sf):
112-
outputs['out_sf'] = op.abspath(self.inputs.out_sf)
69+
outputs['wm_file'] = op.abspath(self.inputs.wm_file)
70+
if self.inputs.gm_file!=Undefined:
71+
outputs['gm_file'] = op.abspath(self.inputs.gm_file)
72+
if self.inputs.csf_file!=Undefined:
73+
outputs['csf_file'] = op.abspath(self.inputs.csf_file)
11374
return outputs
11475

11576

nipype/interfaces/mrtrix3/reconst.py

Lines changed: 30 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
import os.path as op
1717

18-
from ..base import traits, TraitedSpec, File
18+
from ..base import traits, TraitedSpec, File, Undefined
1919
from .base import MRTrix3BaseInputSpec, MRTrix3Base
2020

2121

@@ -74,108 +74,55 @@ def _list_outputs(self):
7474

7575

7676
class EstimateFODInputSpec(MRTrix3BaseInputSpec):
77-
in_file = File(exists=True, argstr='%s', mandatory=True, position=-3,
78-
desc='input diffusion weighted images')
79-
response = File(
80-
exists=True, argstr='%s', mandatory=True, position=-2,
81-
desc=('a text file containing the diffusion-weighted signal response '
82-
'function coefficients for a single fibre population'))
83-
out_file = File(
84-
'fods.mif', argstr='%s', mandatory=True, position=-1,
85-
usedefault=True, desc=('the output spherical harmonics coefficients'
86-
' image'))
77+
algorithm = traits.Enum('csd','msmt_csd', argstr='%s', position=-8,
78+
mandatory=True, desc='FOD algorithm')
79+
dwi_file = File(exists=True, argstr='%s', position=-7,
80+
mandatory=True, desc='input DWI image')
81+
wm_txt = File(argstr='%s', position=-6,
82+
mandatory=True, desc='WM response text file')
83+
wm_odf = File('wm.mif', argstr='%s', position=-5, usedefault=True,
84+
mandatory=True, desc='output WM ODF')
85+
gm_txt = File(argstr='%s', position=-4, desc='GM response text file')
86+
gm_odf = File('gm.mif', argstr='%s', position=-3, desc='output GM ODF')
87+
csf_txt = File(argstr='%s', position=-2, desc='CSF response text file')
88+
csf_odf = File('csf.mif', argstr='%s', position=-1, desc='output CSF ODF')
89+
mask_file = File(exists=True, argstr='-mask %s', desc='mask image')
8790

8891
# DW Shell selection options
8992
shell = traits.List(traits.Float, sep=',', argstr='-shell %s',
9093
desc='specify one or more dw gradient shells')
91-
92-
# Spherical deconvolution options
9394
max_sh = traits.Int(8, argstr='-lmax %d',
9495
desc='maximum harmonic degree of response function')
95-
in_mask = File(exists=True, argstr='-mask %s',
96-
desc='provide initial mask image')
9796
in_dirs = File(
9897
exists=True, argstr='-directions %s',
9998
desc=('specify the directions over which to apply the non-negativity '
10099
'constraint (by default, the built-in 300 direction set is '
101100
'used). These should be supplied as a text file containing the '
102101
'[ az el ] pairs for the directions.'))
103-
sh_filter = File(
104-
exists=True, argstr='-filter %s',
105-
desc=('the linear frequency filtering parameters used for the initial '
106-
'linear spherical deconvolution step (default = [ 1 1 1 0 0 ]). '
107-
'These should be supplied as a text file containing the '
108-
'filtering coefficients for each even harmonic order.'))
109-
110-
neg_lambda = traits.Float(
111-
1.0, argstr='-neg_lambda %f',
112-
desc=('the regularisation parameter lambda that controls the strength'
113-
' of the non-negativity constraint'))
114-
thres = traits.Float(
115-
0.0, argstr='-threshold %f',
116-
desc=('the threshold below which the amplitude of the FOD is assumed '
117-
'to be zero, expressed as an absolute amplitude'))
118-
119-
n_iter = traits.Int(
120-
50, argstr='-niter %d', desc=('the maximum number of iterations '
121-
'to perform for each voxel'))
122102

123103

124104
class EstimateFODOutputSpec(TraitedSpec):
125-
out_file = File(exists=True, desc='the output response file')
105+
wm_odf = File(argstr='%s', desc='output WM ODF')
106+
gm_odf = File(argstr='%s', desc='output GM ODF')
107+
csf_odf = File(argstr='%s', desc='output CSF ODF')
126108

127109

128110
class EstimateFOD(MRTrix3Base):
129111

130112
"""
131-
Convert diffusion-weighted images to tensor images
132-
133-
Note that this program makes use of implied symmetries in the diffusion
134-
profile. First, the fact the signal attenuation profile is real implies
135-
that it has conjugate symmetry, i.e. Y(l,-m) = Y(l,m)* (where * denotes
136-
the complex conjugate). Second, the diffusion profile should be
137-
antipodally symmetric (i.e. S(x) = S(-x)), implying that all odd l
138-
components should be zero. Therefore, this program only computes the even
139-
elements.
140-
141-
Note that the spherical harmonics equations used here differ slightly from
142-
those conventionally used, in that the (-1)^m factor has been omitted.
143-
This should be taken into account in all subsequent calculations.
144-
The spherical harmonic coefficients are stored as follows. First, since
145-
the signal attenuation profile is real, it has conjugate symmetry, i.e.
146-
Y(l,-m) = Y(l,m)* (where * denotes the complex conjugate). Second, the
147-
diffusion profile should be antipodally symmetric (i.e. S(x) = S(-x)),
148-
implying that all odd l components should be zero. Therefore, only the
149-
even elements are computed.
150-
151-
Note that the spherical harmonics equations used here differ slightly from
152-
those conventionally used, in that the (-1)^m factor has been omitted.
153-
This should be taken into account in all subsequent calculations.
154-
Each volume in the output image corresponds to a different spherical
155-
harmonic component. Each volume will correspond to the following:
156-
157-
volume 0: l = 0, m = 0
158-
volume 1: l = 2, m = -2 (imaginary part of m=2 SH)
159-
volume 2: l = 2, m = -1 (imaginary part of m=1 SH)
160-
volume 3: l = 2, m = 0
161-
volume 4: l = 2, m = 1 (real part of m=1 SH)
162-
volume 5: l = 2, m = 2 (real part of m=2 SH)
163-
etc...
164-
165-
113+
Estimate fibre orientation distributions from diffusion data using spherical deconvolution
166114
167115
Example
168116
-------
169117
170118
>>> import nipype.interfaces.mrtrix3 as mrt
171119
>>> fod = mrt.EstimateFOD()
172-
>>> fod.inputs.in_file = 'dwi.mif'
173-
>>> fod.inputs.response = 'response.txt'
174-
>>> fod.inputs.in_mask = 'mask.nii.gz'
120+
>>> fod.inputs.algorithm = 'csd'
121+
>>> fod.inputs.dwi_file = 'dwi.mif'
122+
>>> fod.inputs.wm_txt = 'wm.txt'
175123
>>> fod.inputs.grad_fsl = ('bvecs', 'bvals')
176124
>>> fod.cmdline # doctest: +ELLIPSIS
177-
'dwi2fod -fslgrad bvecs bvals -mask mask.nii.gz dwi.mif response.txt\
178-
fods.mif'
125+
'dwi2fod -fslgrad bvecs bvals csd dwi.mif wm.txt wm.mif'
179126
>>> fod.run() # doctest: +SKIP
180127
"""
181128

@@ -185,5 +132,12 @@ class EstimateFOD(MRTrix3Base):
185132

186133
def _list_outputs(self):
187134
outputs = self.output_spec().get()
188-
outputs['out_file'] = op.abspath(self.inputs.out_file)
135+
outputs['wm_odf'] = op.abspath(self.inputs.wm_odf)
136+
if self.inputs.gm_odf!=Undefined:
137+
outputs['gm_odf'] = op.abspath(self.inputs.gm_odf)
138+
if self.inputs.csf_odf!=Undefined:
139+
outputs['csf_odf'] = op.abspath(self.inputs.csf_odf)
189140
return outputs
141+
142+
143+

0 commit comments

Comments
 (0)