Skip to content

Commit 89ba3b4

Browse files
committed
Merge branch 'master' of https://github.com/rciric/nipype
2 parents 1b1b6fa + 4c1af8a commit 89ba3b4

File tree

10 files changed

+331
-21
lines changed

10 files changed

+331
-21
lines changed

.zenodo.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,11 @@
335335
"name": "Ciric, Rastko",
336336
"orcid": "0000-0001-6347-7939"
337337
},
338+
{
339+
"affiliation": "The Centre for Addiction and Mental Health",
340+
"name": "Joseph, Michael",
341+
"orcid": "0000-0002-0068-230X"
342+
},
338343
{
339344
"affiliation": "UniversityHospital Heidelberg, Germany",
340345
"name": "Kleesiek, Jens"

nipype/interfaces/fsl/epi.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1383,7 +1383,7 @@ def _list_outputs(self):
13831383
# If the output directory isn't defined, the interface seems to use
13841384
# the default but not set its value in `self.inputs.output_dir`
13851385
if not isdefined(self.inputs.output_dir):
1386-
out_dir = os.path.abspath(os.path.basename(self.inputs.base_name) + '.qc.nii.gz')
1386+
out_dir = os.path.abspath(os.path.basename(self.inputs.base_name) + '.qc')
13871387
else:
13881388
out_dir = os.path.abspath(self.inputs.output_dir)
13891389

@@ -1421,4 +1421,3 @@ def _list_outputs(self):
14211421
outputs['clean_volumes'] = clean_volumes
14221422

14231423
return outputs
1424-

nipype/interfaces/fsl/preprocess.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1160,7 +1160,7 @@ def _list_outputs(self):
11601160
if suffix.endswith('.txt'):
11611161
change_ext = False
11621162
if isdefined(inval):
1163-
outputs[key] = inval
1163+
outputs[key] = os.path.abspath(inval)
11641164
else:
11651165
outputs[key] = self._gen_fname(
11661166
self.inputs.in_file,

nipype/interfaces/image.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from ..utils.filemanip import fname_presuffix
66
from .base import (SimpleInterface, TraitedSpec, BaseInterfaceInputSpec,
77
traits, File)
8+
from .. import LooseVersion
89

910

1011
class RescaleInputSpec(BaseInterfaceInputSpec):
@@ -186,8 +187,8 @@ def _run_interface(self, runtime):
186187
transform = ornt_transform(orig_ornt, targ_ornt)
187188
affine_xfm = inv_ornt_aff(transform, orig_img.shape)
188189

189-
# Check can be eliminated when minimum nibabel version >= 2.2
190-
if hasattr(orig_img, 'as_reoriented'):
190+
# Check can be eliminated when minimum nibabel version >= 2.4
191+
if LooseVersion(nb.__version__) >= LooseVersion('2.4.0'):
191192
reoriented = orig_img.as_reoriented(transform)
192193
else:
193194
reoriented = _as_reoriented_backport(orig_img, transform)
@@ -212,7 +213,7 @@ def _run_interface(self, runtime):
212213

213214

214215
def _as_reoriented_backport(img, ornt):
215-
"""Backport of img.as_reoriented as of nibabel 2.2.0"""
216+
"""Backport of img.as_reoriented as of nibabel 2.4.0"""
216217
import numpy as np
217218
import nibabel as nb
218219
from nibabel.orientations import inv_ornt_aff
@@ -225,13 +226,8 @@ def _as_reoriented_backport(img, ornt):
225226

226227
if isinstance(reoriented, nb.Nifti1Pair):
227228
# Also apply the transform to the dim_info fields
228-
new_dim = list(reoriented.header.get_dim_info())
229-
for idx, value in enumerate(new_dim):
230-
# For each value, leave as None if it was that way,
231-
# otherwise check where we have mapped it to
232-
if value is None:
233-
continue
234-
new_dim[idx] = np.where(ornt[:, 0] == idx)[0]
229+
new_dim = [None if orig_dim is None else int(ornt[orig_dim, 0])
230+
for orig_dim in img.header.get_dim_info()]
235231

236232
reoriented.header.set_dim_info(*new_dim)
237233

nipype/interfaces/mrtrix3/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from .utils import (Mesh2PVE, Generate5tt, BrainMask, TensorMetrics,
77
ComputeTDI, TCK2VTK, MRMath, MRConvert, DWIExtract)
88
from .preprocess import (ResponseSD, ACTPrepareFSL, ReplaceFSwithFIRST,
9-
DWIDenoise)
9+
DWIDenoise, MRDeGibbs, DWIBiasCorrect)
1010
from .tracking import Tractography
1111
from .reconst import FitTensor, EstimateFOD
1212
from .connectivity import LabelConfig, LabelConvert, BuildConnectome

nipype/interfaces/mrtrix3/preprocess.py

Lines changed: 174 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,18 @@ class DWIDenoiseInputSpec(MRTrix3BaseInputSpec):
2828
desc='set the window size of the denoising filter. (default = 5,5,5)')
2929
noise = File(
3030
argstr='-noise %s',
31-
desc='noise map')
31+
desc='the output noise map')
3232
out_file = File(name_template='%s_denoised',
3333
name_source='in_file',
3434
keep_extension=True,
35-
argstr="%s",
35+
argstr='%s',
3636
position=-1,
37-
desc="the output denoised DWI image")
37+
desc='the output denoised DWI image',
38+
genfile=True)
3839

3940
class DWIDenoiseOutputSpec(TraitedSpec):
40-
out_file = File(desc="the output denoised DWI image", exists=True)
41+
noise = File(desc='the output noise map', exists=True)
42+
out_file = File(desc='the output denoised DWI image', exists=True)
4143

4244
class DWIDenoise(MRTrix3Base):
4345
"""
@@ -74,6 +76,174 @@ class DWIDenoise(MRTrix3Base):
7476
input_spec = DWIDenoiseInputSpec
7577
output_spec = DWIDenoiseOutputSpec
7678

79+
def _list_outputs(self):
80+
outputs = self.output_spec().get()
81+
outputs['out_file'] = op.abspath(self.inputs.out_file)
82+
if self.inputs.noise != Undefined:
83+
outputs['noise'] = op.abspath(self.inputs.noise)
84+
return outputs
85+
86+
87+
class MRDeGibbsInputSpec(MRTrix3BaseInputSpec):
88+
in_file = File(
89+
exists=True,
90+
argstr='%s',
91+
position=-2,
92+
mandatory=True,
93+
desc='input DWI image')
94+
axes = traits.ListInt(
95+
default_value=[0,1],
96+
usedefault=True,
97+
sep=',',
98+
minlen=2,
99+
maxlen=2,
100+
argstr='-axes %s',
101+
desc='indicate the plane in which the data was acquired (axial = 0,1; '
102+
'coronal = 0,2; sagittal = 1,2')
103+
nshifts = traits.Int(
104+
default_value=20,
105+
usedefault=True,
106+
argstr='-nshifts %d',
107+
desc='discretization of subpixel spacing (default = 20)')
108+
minW = traits.Int(
109+
default_value=1,
110+
usedefault=True,
111+
argstr='-minW %d',
112+
desc='left border of window used for total variation (TV) computation '
113+
'(default = 1)')
114+
maxW = traits.Int(
115+
default_value=3,
116+
usedefault=True,
117+
argstr='-maxW %d',
118+
desc='right border of window used for total variation (TV) computation '
119+
'(default = 3)')
120+
out_file = File(name_template='%s_unr',
121+
name_source='in_file',
122+
keep_extension=True,
123+
argstr='%s',
124+
position=-1,
125+
desc='the output unringed DWI image',
126+
genfile=True)
127+
128+
class MRDeGibbsOutputSpec(TraitedSpec):
129+
out_file = File(desc='the output unringed DWI image', exists=True)
130+
131+
class MRDeGibbs(MRTrix3Base):
132+
"""
133+
Remove Gibbs ringing artifacts.
134+
135+
This application attempts to remove Gibbs ringing artefacts from MRI images
136+
using the method of local subvoxel-shifts proposed by Kellner et al.
137+
138+
This command is designed to run on data directly after it has been
139+
reconstructed by the scanner, before any interpolation of any kind has
140+
taken place. You should not run this command after any form of motion
141+
correction (e.g. not after dwipreproc). Similarly, if you intend running
142+
dwidenoise, you should run this command afterwards, since it has the
143+
potential to alter the noise structure, which would impact on dwidenoise's
144+
performance.
145+
146+
Note that this method is designed to work on images acquired with full
147+
k-space coverage. Running this method on partial Fourier ('half-scan') data
148+
may lead to suboptimal and/or biased results, as noted in the original
149+
reference below. There is currently no means of dealing with this; users
150+
should exercise caution when using this method on partial Fourier data, and
151+
inspect its output for any obvious artefacts.
152+
153+
For more information, see
154+
<https://mrtrix.readthedocs.io/en/latest/reference/commands/mrdegibbs.html>
155+
156+
Example
157+
-------
158+
159+
>>> import nipype.interfaces.mrtrix3 as mrt
160+
>>> unring = mrt.MRDeGibbs()
161+
>>> unring.inputs.in_file = 'dwi.mif'
162+
>>> unring.cmdline
163+
'mrdegibbs -axes 0,1 -maxW 3 -minW 1 -nshifts 20 dwi.mif dwi_unr.mif'
164+
>>> unring.run() # doctest: +SKIP
165+
"""
166+
167+
_cmd = 'mrdegibbs'
168+
input_spec = MRDeGibbsInputSpec
169+
output_spec = MRDeGibbsOutputSpec
170+
171+
172+
class DWIBiasCorrectInputSpec(MRTrix3BaseInputSpec):
173+
in_file = File(
174+
exists=True,
175+
argstr='%s',
176+
position=-2,
177+
mandatory=True,
178+
desc='input DWI image')
179+
in_mask = File(
180+
argstr='-mask %s',
181+
desc='input mask image for bias field estimation')
182+
_xor_methods = ('use_ants', 'use_fsl')
183+
use_ants = traits.Bool(
184+
default_value=True,
185+
usedefault=True,
186+
argstr='-ants',
187+
desc='use ANTS N4 to estimate the inhomogeneity field',
188+
xor=_xor_methods)
189+
use_fsl = traits.Bool(
190+
argstr='-fsl',
191+
desc='use FSL FAST to estimate the inhomogeneity field',
192+
xor=_xor_methods,
193+
min_ver='5.0.10')
194+
_xor_grads = ('mrtrix_grad', 'fsl_grad')
195+
mrtrix_grad = File(
196+
argstr='-grad %s',
197+
desc='diffusion gradient table in MRtrix format',
198+
xor=_xor_grads)
199+
fsl_grad = File(
200+
argstr='-fslgrad %s %s',
201+
desc='diffusion gradient table in FSL bvecs/bvals format',
202+
xor=_xor_grads)
203+
bias = File(
204+
argstr='-bias %s',
205+
desc='bias field')
206+
out_file = File(name_template='%s_biascorr',
207+
name_source='in_file',
208+
keep_extension=True,
209+
argstr='%s',
210+
position=-1,
211+
desc='the output bias corrected DWI image',
212+
genfile=True)
213+
214+
class DWIBiasCorrectOutputSpec(TraitedSpec):
215+
bias = File(desc='the output bias field', exists=True)
216+
out_file = File(desc='the output bias corrected DWI image', exists=True)
217+
218+
class DWIBiasCorrect(MRTrix3Base):
219+
"""
220+
Perform B1 field inhomogeneity correction for a DWI volume series.
221+
222+
For more information, see
223+
<https://mrtrix.readthedocs.io/en/latest/reference/scripts/dwibiascorrect.html>
224+
225+
Example
226+
-------
227+
228+
>>> import nipype.interfaces.mrtrix3 as mrt
229+
>>> bias_correct = mrt.DWIBiasCorrect()
230+
>>> bias_correct.inputs.in_file = 'dwi.mif'
231+
>>> bias_correct.cmdline
232+
'dwibiascorrect -ants dwi.mif dwi_biascorr.mif'
233+
>>> bias_correct.run() # doctest: +SKIP
234+
"""
235+
236+
_cmd = 'dwibiascorrect'
237+
input_spec = DWIBiasCorrectInputSpec
238+
output_spec = DWIBiasCorrectOutputSpec
239+
240+
def _list_outputs(self):
241+
outputs = self.output_spec().get()
242+
outputs['out_file'] = op.abspath(self.inputs.out_file)
243+
if self.inputs.bias != Undefined:
244+
outputs['bias'] = op.abspath(self.inputs.bias)
245+
return outputs
246+
77247

78248
class ResponseSDInputSpec(MRTrix3BaseInputSpec):
79249
algorithm = traits.Enum(
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT
2+
from __future__ import unicode_literals
3+
from ..preprocess import DWIBiasCorrect
4+
5+
6+
def test_DWIBiasCorrect_inputs():
7+
input_map = dict(
8+
args=dict(argstr='%s', ),
9+
bias=dict(argstr='-bias %s', ),
10+
bval_scale=dict(argstr='-bvalue_scaling %s', ),
11+
environ=dict(
12+
nohash=True,
13+
usedefault=True,
14+
),
15+
fsl_grad=dict(
16+
argstr='-fslgrad %s %s',
17+
xor=('mrtrix_grad', 'fsl_grad'),
18+
),
19+
grad_file=dict(argstr='-grad %s', ),
20+
grad_fsl=dict(argstr='-fslgrad %s %s', ),
21+
in_bval=dict(),
22+
in_bvec=dict(argstr='-fslgrad %s %s', ),
23+
in_file=dict(
24+
argstr='%s',
25+
mandatory=True,
26+
position=-2,
27+
),
28+
in_mask=dict(argstr='-mask %s', ),
29+
mrtrix_grad=dict(
30+
argstr='-grad %s',
31+
xor=('mrtrix_grad', 'fsl_grad'),
32+
),
33+
nthreads=dict(
34+
argstr='-nthreads %d',
35+
nohash=True,
36+
),
37+
out_file=dict(
38+
argstr='%s',
39+
genfile=True,
40+
keep_extension=True,
41+
name_source='in_file',
42+
name_template='%s_biascorr',
43+
position=-1,
44+
),
45+
use_ants=dict(
46+
argstr='-ants',
47+
usedefault=True,
48+
xor=('use_ants', 'use_fsl'),
49+
),
50+
use_fsl=dict(
51+
argstr='-fsl',
52+
min_ver='5.0.10',
53+
xor=('use_ants', 'use_fsl'),
54+
),
55+
)
56+
inputs = DWIBiasCorrect.input_spec()
57+
58+
for key, metadata in list(input_map.items()):
59+
for metakey, value in list(metadata.items()):
60+
assert getattr(inputs.traits()[key], metakey) == value
61+
def test_DWIBiasCorrect_outputs():
62+
output_map = dict(
63+
bias=dict(),
64+
out_file=dict(),
65+
)
66+
outputs = DWIBiasCorrect.output_spec()
67+
68+
for key, metadata in list(output_map.items()):
69+
for metakey, value in list(metadata.items()):
70+
assert getattr(outputs.traits()[key], metakey) == value

nipype/interfaces/mrtrix3/tests/test_auto_DWIDenoise.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ def test_DWIDenoise_inputs():
3232
),
3333
out_file=dict(
3434
argstr='%s',
35+
genfile=True,
3536
keep_extension=True,
3637
name_source='in_file',
3738
name_template='%s_denoised',
@@ -44,7 +45,10 @@ def test_DWIDenoise_inputs():
4445
for metakey, value in list(metadata.items()):
4546
assert getattr(inputs.traits()[key], metakey) == value
4647
def test_DWIDenoise_outputs():
47-
output_map = dict(out_file=dict(), )
48+
output_map = dict(
49+
noise=dict(),
50+
out_file=dict(),
51+
)
4852
outputs = DWIDenoise.output_spec()
4953

5054
for key, metadata in list(output_map.items()):

0 commit comments

Comments
 (0)