Skip to content

Commit f8712e2

Browse files
committed
Editing docstring to follow nipype template and add some tests.
1 parent b03dad0 commit f8712e2

18 files changed

+393
-307
lines changed

nipype/interfaces/niftyfit/asl.py

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33

44
"""
55
The ASL module of niftyfit, which wraps the fitting methods in NiftyFit.
6+
7+
Change directory to provide relative paths for doctests
8+
>>> import os
9+
>>> filepath = os.path.dirname( os.path.realpath( __file__ ) )
10+
>>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data'))
11+
>>> os.chdir(datadir)
612
"""
713

814
from ..base import TraitedSpec, traits, isdefined, CommandLineInputSpec
@@ -37,19 +43,19 @@ class FitAslInputSpec(CommandLineInputSpec):
3743
m0mape = traits.File(exists=True, argstr='-m0mape %s', desc=desc)
3844
desc = 'Filename of a [1,2,5]s Inversion Recovery volume (T1/M0 fitting \
3945
carried out internally).'
40-
IRvolume = traits.File(exists=True, argstr='-IRvolume %s', desc=desc)
46+
ir_volume = traits.File(exists=True, argstr='-IRvolume %s', desc=desc)
4147
desc = 'Output of [1,2,5]s Inversion Recovery fitting.'
42-
IRoutput = traits.File(exists=True, argstr='-IRoutput %s', desc=desc)
48+
ir_output = traits.File(exists=True, argstr='-IRoutput %s', desc=desc)
4349

4450
# *** Experimental options (Choose those suitable for the model!):
4551
mask = traits.File(position=2,
4652
exists=True,
4753
desc='Filename of image mask.',
4854
argstr='-mask %s')
49-
T1a = traits.Float(desc='T1 of arterial component [1650ms].',
50-
argstr='-T1a %f')
55+
t1_art_cmp = traits.Float(desc='T1 of arterial component [1650ms].',
56+
argstr='-T1a %f')
5157
desc = 'Single plasma/tissue partition coefficient [0.9ml/g].'
52-
L = traits.Float(desc=desc, argstr='-L %f')
58+
plasma_coeff = traits.Float(desc=desc, argstr='-L %f')
5359
desc = 'Labelling efficiency [0.99 (pasl), 0.85 (pcasl)], ensure any \
5460
background suppression pulses are included in -eff'
5561
eff = traits.Float(desc=desc, argstr='-eff %f')
@@ -58,32 +64,32 @@ class FitAslInputSpec(CommandLineInputSpec):
5864
out = traits.Float(desc=desc, argstr='-out %f')
5965

6066
# *** PCASL options (Choose those suitable for the model!):
61-
PLD = traits.Float(desc='Post Labelling Delay [2000ms].', argstr='-PLD %f')
62-
LDD = traits.Float(desc='Labelling Duration [1800ms].', argstr='-LDD %f')
67+
pld = traits.Float(desc='Post Labelling Delay [2000ms].', argstr='-PLD %f')
68+
ldd = traits.Float(desc='Labelling Duration [1800ms].', argstr='-LDD %f')
6369
desc = 'Difference in labelling delay per slice [0.0 ms/slice.'
64-
dPLD = traits.Float(desc=desc, argstr='-dPLD %f')
70+
dpld = traits.Float(desc=desc, argstr='-dPLD %f')
6571

6672
# *** PASL options (Choose those suitable for the model!):
67-
Tinv1 = traits.Float(desc='Saturation pulse time [800ms].',
68-
argstr='-Tinv1 %f')
69-
Tinv2 = traits.Float(desc='Inversion time [2000ms].', argstr='-Tinv2 %f')
73+
t_inv1 = traits.Float(desc='Saturation pulse time [800ms].',
74+
argstr='-Tinv1 %f')
75+
t_inv2 = traits.Float(desc='Inversion time [2000ms].', argstr='-Tinv2 %f')
7076
desc = 'Difference in inversion time per slice [0ms/slice].'
71-
dTinv2 = traits.Float(desc=desc, argstr='-dTinv2 %f')
77+
dt_inv2 = traits.Float(desc=desc, argstr='-dTinv2 %f')
7278

7379
# *** Other experimental assumptions:
7480

7581
# Not programmed yet
7682
# desc = 'Slope and intercept for Arterial Transit Time.'
7783
# ATT = traits.Float(desc=desc, argstr='-ATT %f')
7884

79-
gmT1 = traits.Float(desc='T1 of GM [1150ms].', argstr='-gmT1 %f')
80-
gmL = traits.Float(desc='Plasma/GM water partition [0.95ml/g].',
81-
argstr='-gmL %f')
82-
gmTTT = traits.Float(desc='Time to GM [ATT+0ms].', argstr='-gmTTT %f')
83-
wmT1 = traits.Float(desc='T1 of WM [800ms].', argstr='-wmT1 %f')
84-
wmL = traits.Float(desc='Plasma/WM water partition [0.82ml/g].',
85-
argstr='-wmL %f')
86-
wmTTT = traits.Float(desc='Time to WM [ATT+0ms].', argstr='-wmTTT %f')
85+
gm_t1 = traits.Float(desc='T1 of GM [1150ms].', argstr='-gmT1 %f')
86+
gm_plasma = traits.Float(desc='Plasma/GM water partition [0.95ml/g].',
87+
argstr='-gmL %f')
88+
gm_ttt = traits.Float(desc='Time to GM [ATT+0ms].', argstr='-gmTTT %f')
89+
wm_t1 = traits.Float(desc='T1 of WM [800ms].', argstr='-wmT1 %f')
90+
wm_plasma = traits.Float(desc='Plasma/WM water partition [0.82ml/g].',
91+
argstr='-wmL %f')
92+
wm_ttt = traits.Float(desc='Time to WM [ATT+0ms].', argstr='-wmTTT %f')
8793

8894
# *** Segmentation options:
8995
desc = 'Filename of the 4D segmentation (in ASL space) for L/T1 \
@@ -103,7 +109,7 @@ class FitAslInputSpec(CommandLineInputSpec):
103109
mulgm = traits.Bool(desc='Multiply CBF by segmentation [Off].',
104110
argstr='-sig')
105111
desc = 'Set PV threshold for switching off LSQR [O.05].'
106-
pvthreshold = traits.Bool(desc=desc, argstr='-pvthreshold')
112+
pv_threshold = traits.Bool(desc=desc, argstr='-pvthreshold')
107113
segstyle = traits.Bool(desc='Set CBF as [gm,wm] not [wm,gm].',
108114
argstr='-segstyle')
109115

@@ -130,11 +136,11 @@ class FitAsl(NiftyFitCommand):
130136
131137
Examples
132138
--------
133-
>>> from nipype.interfaces.niftyfit import FitAsl
134-
>>> node = FitAsl()
135-
>>> node.inputs.source_file = "asl.nii.gz" # doctest: +SKIP
139+
>>> from nipype.interfaces import niftyfit
140+
>>> node = niftyfit.FitAsl()
141+
>>> node.inputs.source_file = 'asl.nii.gz'
136142
>>> node.cmdline # doctest: +SKIP
137-
'fit_asl -source asl.nii -cbf asl_cbf.nii.gz -error asl_error.nii.gz \
143+
'fit_asl -source asl.nii.gz -cbf asl_cbf.nii.gz -error asl_error.nii.gz \
138144
-syn asl_syn.nii.gz'
139145
140146
"""

nipype/interfaces/niftyfit/dwi.py

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33

44
"""
55
The dwi module of niftyfit, which wraps the fitting methods in NiftyFit.
6+
7+
Change directory to provide relative paths for doctests
8+
>>> import os
9+
>>> filepath = os.path.dirname( os.path.realpath( __file__ ) )
10+
>>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data'))
11+
>>> os.chdir(datadir)
612
"""
713

814
from ..base import TraitedSpec, traits, isdefined, CommandLineInputSpec
@@ -46,8 +52,8 @@ class FitDwiInputSpec(CommandLineInputSpec):
4652
desc=desc)
4753
desc = 'Rotate the output tensors according to the q/s form of the image \
4854
(resulting tensors will be in mm coordinates, default: 0).'
49-
rotsform_flag = traits.Int(desc=desc,
50-
argstr='-rotsform %d')
55+
rot_sform_flag = traits.Int(desc=desc,
56+
argstr='-rotsform %d')
5157

5258
# generic output options:
5359
error_file = traits.File(desc='Filename of parameter error maps.',
@@ -221,16 +227,15 @@ class FitDwi(NiftyFitCommand):
221227
Examples
222228
--------
223229
224-
>>> from nipype.interfaces.niftyfit import FitDwi
225-
>>> fit_dwi = FitDwi()
226-
>>> fit_dwi.inputs.source_file = 'im1.nii.gz' # doctest: +SKIP
227-
>>> fit_dwi.inputs.bvec_file = 'im1.bval' # doctest: +SKIP
228-
>>> fit_dwi.inputs.bval_file = 'im1.bvec' # doctest: +SKIP
229-
>>> fit_dwi.inputs.dti_flag = True
230-
>>> fit_dwi.inputs.rgbmap_file = 'rgb_map.nii.gz'
230+
>>> from nipype.interfaces import niftyfit
231+
>>> fit_dwi = niftyfit.FitDwi(dti_flag=True)
232+
>>> fit_dwi.inputs.source_file = 'dwi.nii.gz'
233+
>>> fit_dwi.inputs.bvec_file = 'bvals'
234+
>>> fit_dwi.inputs.bval_file = 'bvecs'
235+
>>> fit_dwi.inputs.rgbmap_file = 'rgb.nii.gz'
231236
>>> fit_dwi.cmdline # doctest: +SKIP
232-
'fit_dwi -source im1.nii.gz -bval im1.val -bvec im1.bvec -dti -rgbmap \
233-
rgb_map.nii.gz -syn dwifit_syn.nii.gz -res dwifit_mcmap.nii.gz\
237+
'fit_dwi -source dwi.nii.gz -bval bvals -bvec bvecs -dti -rgbmap \
238+
rgb.nii.gz -syn dwifit_syn.nii.gz -res dwifit_mcmap.nii.gz\
234239
-mdmap dwifit_mdmap.nii.gz -famap dwifit_famap.nii.gz -v1map \
235240
dwifit_v1map.nii.gz -tenmap2 dwifit_tenmap2.nii.gz -rotsform 0 -error \
236241
dwifit_error.nii.gz'
@@ -493,14 +498,13 @@ class DwiTool(NiftyFitCommand):
493498
Examples
494499
--------
495500
496-
>>> from nipype.interfaces.niftyfit import DwiTool
497-
>>> dwi_tool = DwiTool()
498-
>>> dwi_tool.inputs.source_file = 'im1.nii.gz' # doctest: +SKIP
499-
>>> dwi_tool.inputs.bvec_file = 'im1.bval' # doctest: +SKIP
500-
>>> dwi_tool.inputs.bval_file = 'im1.bvec' # doctest: +SKIP
501-
>>> dwi_tool.inputs.mask_file = 'im1.bvec' # doctest: +SKIP
502-
>>> dwi_tool.inputs.b0_file = 'b0.nii.gz' # doctest: +SKIP
503-
>>> dwi_tool.inputs.dti_flag = True
501+
>>> from nipype.interfaces import niftyfit
502+
>>> dwi_tool = niftyfit.DwiTool(dti_flag=True)
503+
>>> dwi_tool.inputs.source_file = 'dwi.nii.gz'
504+
>>> dwi_tool.inputs.bvec_file = 'bvals'
505+
>>> dwi_tool.inputs.bval_file = 'bvecs'
506+
>>> dwi_tool.inputs.mask_file = 'mask.nii.gz'
507+
>>> dwi_tool.inputs.b0_file = 'b0.nii.gz'
504508
>>> dwi_tool.inputs.rgbmap_file = 'rgb_map.nii.gz'
505509
>>> dwi_tool.cmdline # doctest: +SKIP
506510
'dwi_tool -source im1.nii.gz -bval im1.val -bvec im1.bvec -dti -mask \
@@ -514,8 +518,6 @@ class DwiTool(NiftyFitCommand):
514518
output_spec = DwiToolOutputSpec
515519
_suffix = '_dwi_tool'
516520

517-
_suffix = '_dwi_tool'
518-
519521
def _format_arg(self, name, trait_spec, value):
520522
if name == 'syn_file':
521523
if not isdefined(self.inputs.bvec_file) or \

nipype/interfaces/niftyfit/qt1.py

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
"""
55
The QT1 module of niftyfit, which wraps the Multi-Echo T1 fitting methods
66
in NiftyFit.
7+
8+
Change directory to provide relative paths for doctests
9+
>>> import os
10+
>>> filepath = os.path.dirname( os.path.realpath( __file__ ) )
11+
>>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data'))
12+
>>> os.chdir(datadir)
713
"""
814

915
from ..base import TraitedSpec, File, traits, isdefined, CommandLineInputSpec
@@ -53,10 +59,10 @@ class FitQt1InputSpec(CommandLineInputSpec):
5359
exists=True,
5460
desc='Filename of parameter prior.',
5561
argstr='-prior %s')
56-
TE = traits.Float(desc='TE Echo Time [0ms!].', argstr='-TE %f',
57-
position=4)
58-
TR = traits.Float(desc='TR Repetition Time [10s!].', argstr='-TR %f',
59-
position=5)
62+
te_value = traits.Float(desc='TE Echo Time [0ms!].', argstr='-TE %f',
63+
position=4)
64+
tr_value = traits.Float(desc='TR Repetition Time [10s!].', argstr='-TR %f',
65+
position=5)
6066
desc = 'Number of components to fit [1] (currently IR/SR only)'
6167
# set position to be ahead of TIs
6268
nb_comp = traits.Int(desc=desc, position=6, argstr='-nc %d')
@@ -74,34 +80,28 @@ class FitQt1InputSpec(CommandLineInputSpec):
7480
position=11)
7581

7682
# IR options:
77-
SR = traits.Bool(desc='Saturation Recovery fitting [default].',
78-
argstr='-SR', position=12)
79-
IR = traits.Bool(desc='Inversion Recovery fitting [default].',
80-
argstr='-SR', position=13)
81-
TIs = traits.List(traits.Float,
83+
sr_flag = traits.Bool(desc='Saturation Recovery fitting [default].',
84+
argstr='-SR', position=12)
85+
ir_flag = traits.Bool(desc='Inversion Recovery fitting [default].',
86+
argstr='-IR', position=13)
87+
tis = traits.List(traits.Float,
8288
position=14,
8389
desc='Inversion times for T1 data [1s,2s,5s].',
8490
argstr='-TIs %s',
8591
sep=' ')
86-
TIList = traits.File(exists=True,
87-
argstr='-TIlist %s',
88-
desc='Filename of list of pre-defined TIs.')
89-
desc = 'Prefined tissue T1 values for mc-estimation \
90-
[400-4000ms, log spaced]'
91-
# T1s = traits.List(traits.Float,
92-
# desc=desc,
93-
# argstr='-T1s %s',
94-
# sep=' ')
95-
T1List = traits.File(exists=True,
96-
argstr='-T1list %s',
97-
desc='Filename of list of pre-defined T1s')
98-
T1min = traits.Float(desc='Minimum tissue T1 value [400ms].',
92+
tis_list = traits.File(exists=True,
93+
argstr='-TIlist %s',
94+
desc='Filename of list of pre-defined TIs.')
95+
t1_list = traits.File(exists=True,
96+
argstr='-T1list %s',
97+
desc='Filename of list of pre-defined T1s')
98+
t1min = traits.Float(desc='Minimum tissue T1 value [400ms].',
9999
argstr='-T1min %f')
100-
T1max = traits.Float(desc='Maximum tissue T1 value [4000ms].',
100+
t1max = traits.Float(desc='Maximum tissue T1 value [4000ms].',
101101
argstr='-T1max %f')
102102

103103
# SPGR options
104-
SPGR = traits.Bool(desc='Spoiled Gradient Echo fitting', argstr='-SPGR')
104+
spgr = traits.Bool(desc='Spoiled Gradient Echo fitting', argstr='-SPGR')
105105
flips = traits.List(traits.Float,
106106
desc='Flip angles',
107107
argstr='-flips %s',
@@ -155,11 +155,11 @@ class FitQt1(NiftyFitCommand):
155155
156156
>>> from nipype.interfaces.niftyfit import FitQt1
157157
>>> fit_qt1 = FitQt1()
158-
>>> fit_qt1.inputs.source_file = 'im1.nii.gz' # doctest: +SKIP
158+
>>> fit_qt1.inputs.source_file = 'TI4D.nii.gz'
159159
>>> fit_qt1.cmdline # doctest: +SKIP
160-
'fit_qt1 -source im1.nii.gz -t1map im1_t1map.nii.gz -m0map \
161-
im1_m0map.nii.gz -mcmap im1_mcmap.nii.gz -error im1_error.nii.gz \
162-
-syn im1_syn.nii.gz -res im1_res.nii.gz'
160+
'fit_qt1 -source TI4D.nii.gz -t1map TI4D_t1map.nii.gz -m0map \
161+
TI4D_m0map.nii.gz -mcmap TI4D_mcmap.nii.gz -error TI4D_error.nii.gz \
162+
-syn TI4D_syn.nii.gz -res TI4D_res.nii.gz'
163163
164164
"""
165165
_cmd = get_custom_path('fit_qt1')
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# -*- coding: utf-8 -*-
2+
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
3+
# vi: set ft=python sts=4 ts=4 sw=4 et:
4+
5+
import os
6+
import pytest
7+
8+
from nipype.interfaces.niftyfit import no_niftyfit, get_custom_path, FitAsl
9+
from nipype.testing import example_data
10+
11+
12+
@pytest.mark.skipif(no_niftyfit(cmd='fit_asl'),
13+
reason="niftyfit is not installed")
14+
def test_fit_asl():
15+
""" Testing FitAsl interface."""
16+
# Create the test node
17+
fit_asl = FitAsl()
18+
19+
# Check if the command is properly defined
20+
assert fit_asl.cmd == get_custom_path('fit_asl')
21+
22+
# test raising error with mandatory args absent
23+
with pytest.raises(ValueError):
24+
fit_asl.run()
25+
26+
# Tests on the interface:
27+
# Runs cbf fitting assuming all tissue is GM!
28+
in_file = example_data('asl.nii.gz')
29+
fit_asl.inputs.source_file = in_file
30+
31+
cmd_tmp = '{cmd} -source {in_file} -cbf {cbf} -error {error} -syn {syn}'
32+
expected_cmd = cmd_tmp.format(
33+
cmd=get_custom_path('fit_asl'),
34+
in_file=in_file,
35+
cbf=os.path.join(os.getcwd(), 'asl_cbf.nii.gz'),
36+
error=os.path.join(os.getcwd(), 'asl_error.nii.gz'),
37+
syn=os.path.join(os.getcwd(), 'asl_syn.nii.gz')
38+
)
39+
40+
assert fit_asl.cmdline == expected_cmd
41+
42+
# Runs cbf fitting using IR/SR T1 data to estimate the local T1 and uses
43+
# the segmentation data to fit tissue specific blood flow parameters
44+
# (lambda,transit times,T1)
45+
fit_asl2 = FitAsl(sig=True)
46+
in_file = example_data('asl.nii.gz')
47+
t1map = example_data('T1map.nii.gz')
48+
seg = example_data('segmentation0.nii.gz')
49+
fit_asl2.inputs.source_file = in_file
50+
fit_asl2.inputs.t1map = t1map
51+
fit_asl2.inputs.seg = seg
52+
53+
cmd_tmp = '{cmd} -source {in_file} -cbf {cbf} -error {error} \
54+
-seg {seg} -sig -syn {syn} -t1map {t1map}'
55+
expected_cmd = cmd_tmp.format(
56+
cmd=get_custom_path('fit_asl'),
57+
in_file=in_file,
58+
t1map=t1map,
59+
seg=seg,
60+
cbf=os.path.join(os.getcwd(), 'asl_cbf.nii.gz'),
61+
error=os.path.join(os.getcwd(), 'asl_error.nii.gz'),
62+
syn=os.path.join(os.getcwd(), 'asl_syn.nii.gz')
63+
)
64+
65+
assert fit_asl2.cmdline == expected_cmd

0 commit comments

Comments
 (0)