|
1 | 1 | # coding: utf-8
|
2 | 2 |
|
3 | 3 | import nipype.pipeline.engine as pe
|
4 |
| -import nipype.interfaces.utility as util |
5 |
| -import nipype.interfaces.fsl as fsl |
| 4 | +from nipype.interfaces import utility as niu |
| 5 | +from nipype.interfaces import fsl |
6 | 6 | import os
|
7 | 7 |
|
8 | 8 | #backwards compatibility
|
9 | 9 | from epi import create_eddy_correct_pipeline
|
10 | 10 |
|
| 11 | + |
11 | 12 | def transpose(samples_over_fibres):
|
12 | 13 | import numpy as np
|
13 | 14 | a = np.array(samples_over_fibres)
|
14 |
| - if len(a.shape) == 1: |
15 |
| - a = a.reshape(-1, 1) |
16 |
| - return a.T.tolist() |
| 15 | + return np.squeeze(a.T).tolist() |
| 16 | + |
17 | 17 |
|
18 |
| -def create_bedpostx_pipeline(name="bedpostx"): |
19 |
| - """Creates a pipeline that does the same as bedpostx script from FSL - |
| 18 | +def create_bedpostx_pipeline(name='bedpostx', params={}): |
| 19 | + """ |
| 20 | + Creates a pipeline that does the same as bedpostx script from FSL - |
20 | 21 | calculates diffusion model parameters (distributions not MLE) voxelwise for
|
21 | 22 | the whole volume (by splitting it slicewise).
|
22 | 23 |
|
23 | 24 | Example
|
24 | 25 | -------
|
25 | 26 |
|
26 |
| - >>> nipype_bedpostx = create_bedpostx_pipeline("nipype_bedpostx") |
27 |
| - >>> nipype_bedpostx.inputs.inputnode.dwi = 'diffusion.nii' |
28 |
| - >>> nipype_bedpostx.inputs.inputnode.mask = 'mask.nii' |
29 |
| - >>> nipype_bedpostx.inputs.inputnode.bvecs = 'bvecs' |
30 |
| - >>> nipype_bedpostx.inputs.inputnode.bvals = 'bvals' |
31 |
| - >>> nipype_bedpostx.inputs.xfibres.n_fibres = 2 |
32 |
| - >>> nipype_bedpostx.inputs.xfibres.fudge = 1 |
33 |
| - >>> nipype_bedpostx.inputs.xfibres.burn_in = 1000 |
34 |
| - >>> nipype_bedpostx.inputs.xfibres.n_jumps = 1250 |
35 |
| - >>> nipype_bedpostx.inputs.xfibres.sample_every = 25 |
36 |
| - >>> nipype_bedpostx.run() # doctest: +SKIP |
| 27 | + >>> from nipype.workflows.dmri.fsl.dti import create_bedpostx_pipeline |
| 28 | + >>> params = dict(n_fibres = 2, fudge = 1, burn_in = 1000, |
| 29 | + ... n_jumps = 1250, sample_every = 25) |
| 30 | + >>> bpwf = create_bedpostx_pipeline('nipype_bedpostx', params) |
| 31 | + >>> bpwf.inputs.inputnode.dwi = 'diffusion.nii' |
| 32 | + >>> bpwf.inputs.inputnode.mask = 'mask.nii' |
| 33 | + >>> bpwf.inputs.inputnode.bvecs = 'bvecs' |
| 34 | + >>> bpwf.inputs.inputnode.bvals = 'bvals' |
| 35 | + >>> bpwf.run() # doctest: +SKIP |
37 | 36 |
|
38 | 37 | Inputs::
|
39 | 38 |
|
40 | 39 | inputnode.dwi
|
41 | 40 | inputnode.mask
|
| 41 | + inputnode.bvecs |
| 42 | + inputnode.bvals |
42 | 43 |
|
43 | 44 | Outputs::
|
44 | 45 |
|
45 |
| - outputnode.thsamples |
46 |
| - outputnode.phsamples |
47 |
| - outputnode.fsamples |
48 |
| - outputnode.mean_thsamples |
49 |
| - outputnode.mean_phsamples |
50 |
| - outputnode.mean_fsamples |
51 |
| - outputnode.dyads |
52 |
| - outputnode.dyads_dispersion |
| 46 | + outputnode wraps all XFibres outputs |
53 | 47 |
|
54 | 48 | """
|
55 | 49 |
|
56 |
| - inputnode = pe.Node( |
57 |
| - interface=util.IdentityInterface(fields=["dwi", "mask"]), |
58 |
| - name="inputnode") |
| 50 | + inputnode = pe.Node(niu.IdentityInterface(fields=['dwi', 'mask', |
| 51 | + 'bvecs', 'bvals']), name='inputnode') |
59 | 52 |
|
60 |
| - mask_dwi = pe.Node(interface=fsl.ImageMaths(op_string="-mas"), |
61 |
| - name="mask_dwi") |
62 |
| - slice_dwi = pe.Node(interface=fsl.Split(dimension="z"), name="slice_dwi") |
63 |
| - slice_mask = pe.Node(interface=fsl.Split(dimension="z"), |
64 |
| - name="slice_mask") |
| 53 | + slice_dwi = pe.Node(fsl.Split(dimension='z'), name='slice_dwi') |
| 54 | + slice_msk = pe.Node(fsl.Split(dimension='z'), name='slice_msk') |
| 55 | + mask_dwi = pe.MapNode(fsl.ImageMaths(op_string='-mas'), |
| 56 | + iterfield=['in_file', 'in_file2'], name='mask_dwi') |
65 | 57 |
|
66 |
| - preproc = pe.Workflow(name="preproc") |
67 |
| - |
68 |
| - preproc.connect([(inputnode, mask_dwi, [('dwi', 'in_file')]), |
69 |
| - (inputnode, mask_dwi, [('mask', 'in_file2')]), |
70 |
| - (mask_dwi, slice_dwi, [('out_file', 'in_file')]), |
71 |
| - (inputnode, slice_mask, [('mask', 'in_file')]) |
72 |
| - ]) |
73 |
| - |
74 |
| - xfibres = pe.MapNode(interface=fsl.OldXFibres(), name="xfibres", |
| 58 | + xfib_if = fsl.XFibres(**params) |
| 59 | + xfibres = pe.MapNode(xfib_if, name='xfibres', |
75 | 60 | iterfield=['dwi', 'mask'])
|
76 | 61 |
|
77 |
| - # Normal set of parameters |
78 |
| - xfibres.inputs.n_fibres = 2 |
79 |
| - xfibres.inputs.fudge = 1 |
80 |
| - xfibres.inputs.burn_in = 1000 |
81 |
| - xfibres.inputs.n_jumps = 1250 |
82 |
| - xfibres.inputs.sample_every = 25 |
83 |
| - xfibres.inputs.model = 1 |
84 |
| - xfibres.inputs.non_linear = True |
85 |
| - xfibres.inputs.update_proposal_every = 24 |
86 |
| - |
87 |
| - inputnode = pe.Node(interface=util.IdentityInterface(fields=["thsamples", |
88 |
| - "phsamples", |
89 |
| - "fsamples", |
90 |
| - "dyads", |
91 |
| - "mean_dsamples", |
92 |
| - "mask"]), |
93 |
| - name="inputnode") |
94 |
| - |
95 |
| - merge_thsamples = pe.MapNode(fsl.Merge(dimension="z"), |
96 |
| - name="merge_thsamples", iterfield=['in_files']) |
97 |
| - merge_phsamples = pe.MapNode(fsl.Merge(dimension="z"), |
98 |
| - name="merge_phsamples", iterfield=['in_files']) |
99 |
| - merge_fsamples = pe.MapNode(fsl.Merge(dimension="z"), |
100 |
| - name="merge_fsamples", iterfield=['in_files']) |
101 |
| - |
102 |
| - merge_mean_dsamples = pe.Node(fsl.Merge(dimension="z"), |
103 |
| - name="merge_mean_dsamples") |
104 |
| - |
105 |
| - mean_thsamples = pe.MapNode(fsl.ImageMaths(op_string="-Tmean"), |
106 |
| - name="mean_thsamples", iterfield=['in_file']) |
107 |
| - mean_phsamples = pe.MapNode(fsl.ImageMaths(op_string="-Tmean"), |
108 |
| - name="mean_phsamples", iterfield=['in_file']) |
109 |
| - mean_fsamples = pe.MapNode(fsl.ImageMaths(op_string="-Tmean"), |
110 |
| - name="mean_fsamples", iterfield=['in_file']) |
111 |
| - make_dyads = pe.MapNode(fsl.MakeDyadicVectors(), name="make_dyads", |
112 |
| - iterfield=['theta_vol', 'phi_vol']) |
113 |
| - |
114 |
| - postproc = pe.Workflow(name="postproc") |
115 |
| - |
116 |
| - postproc.connect( |
117 |
| - [(inputnode, merge_thsamples, [(('thsamples', transpose), 'in_files')]), |
118 |
| - (inputnode, merge_phsamples, [(( |
119 |
| - 'phsamples', transpose), 'in_files')]), |
120 |
| - (inputnode, merge_fsamples, [(( |
121 |
| - 'fsamples', transpose), 'in_files')]), |
122 |
| - (inputnode, merge_mean_dsamples, [ |
123 |
| - ('mean_dsamples', 'in_files')]), |
124 |
| - |
125 |
| - (merge_thsamples, mean_thsamples, [ |
126 |
| - ('merged_file', 'in_file')]), |
127 |
| - (merge_phsamples, mean_phsamples, [ |
128 |
| - ('merged_file', 'in_file')]), |
129 |
| - (merge_fsamples, mean_fsamples, [ |
130 |
| - ('merged_file', 'in_file')]), |
131 |
| - (merge_thsamples, make_dyads, [ |
132 |
| - ('merged_file', 'theta_vol')]), |
133 |
| - (merge_phsamples, make_dyads, [ |
134 |
| - ('merged_file', 'phi_vol')]), |
135 |
| - (inputnode, make_dyads, [('mask', 'mask')]), |
136 |
| - ]) |
137 |
| - |
138 |
| - inputnode = pe.Node(interface=util.IdentityInterface(fields=["dwi", |
139 |
| - "mask", |
140 |
| - "bvecs", |
141 |
| - "bvals"]), |
142 |
| - name="inputnode") |
143 |
| - |
144 |
| - bedpostx = pe.Workflow(name=name) |
145 |
| - bedpostx.connect([(inputnode, preproc, [('mask', 'inputnode.mask')]), |
146 |
| - (inputnode, preproc, [('dwi', 'inputnode.dwi')]), |
147 |
| - |
148 |
| - (preproc, xfibres, [('slice_dwi.out_files', 'dwi'), |
149 |
| - ('slice_mask.out_files', 'mask')]), |
150 |
| - (inputnode, xfibres, [('bvals', 'bvals')]), |
151 |
| - (inputnode, xfibres, [('bvecs', 'bvecs')]), |
152 |
| - |
153 |
| - (inputnode, postproc, [('mask', 'inputnode.mask')]), |
154 |
| - (xfibres, postproc, [ |
155 |
| - ('thsamples', 'inputnode.thsamples'), |
156 |
| - ('phsamples', |
157 |
| - 'inputnode.phsamples'), |
158 |
| - ('fsamples', 'inputnode.fsamples'), |
159 |
| - ('dyads', 'inputnode.dyads'), |
160 |
| - ('mean_dsamples', 'inputnode.mean_dsamples')]), |
| 62 | + out_fields = xfib_if.output_spec().get().keys() |
| 63 | + |
| 64 | + outputnode = pe.Node(niu.IdentityInterface(fields=out_fields), |
| 65 | + name='outputnode') |
| 66 | + |
| 67 | + wf = pe.Workflow(name=name) |
| 68 | + wf.connect([ |
| 69 | + (inputnode, slice_dwi, [('dwi', 'in_file')]), |
| 70 | + (inputnode, slice_msk, [('mask', 'in_file')]), |
| 71 | + (slice_dwi, mask_dwi, [('out_files', 'in_file')]), |
| 72 | + (slice_msk, mask_dwi, [('out_files', 'in_file2')]), |
| 73 | + (slice_dwi, xfibres, [('out_files', 'dwi')]), |
| 74 | + (mask_dwi, xfibres, [('out_file', 'mask')]), |
| 75 | + (inputnode, xfibres, [('bvecs', 'bvecs'), |
| 76 | + ('bvals', 'bvals')]), |
| 77 | + (xfibres, outputnode, [((f, transpose), f) for f in out_fields]) |
161 | 78 | ])
|
162 | 79 |
|
163 |
| - outputnode = pe.Node( |
164 |
| - interface=util.IdentityInterface(fields=["thsamples", |
165 |
| - "phsamples", |
166 |
| - "fsamples", |
167 |
| - "mean_thsamples", |
168 |
| - "mean_phsamples", |
169 |
| - "mean_fsamples", |
170 |
| - "dyads", |
171 |
| - "dyads_dispersion"]), |
172 |
| - name="outputnode") |
173 |
| - bedpostx.connect( |
174 |
| - [(postproc, outputnode, [("merge_thsamples.merged_file", "thsamples"), |
175 |
| - ("merge_phsamples.merged_file", |
176 |
| - "phsamples"), |
177 |
| - ("merge_fsamples.merged_file", |
178 |
| - "fsamples"), |
179 |
| - ("mean_thsamples.out_file", |
180 |
| - "mean_thsamples"), |
181 |
| - ("mean_phsamples.out_file", |
182 |
| - "mean_phsamples"), |
183 |
| - ("mean_fsamples.out_file", |
184 |
| - "mean_fsamples"), |
185 |
| - ("make_dyads.dyads", "dyads"), |
186 |
| - ("make_dyads.dispersion", "dyads_dispersion")]) |
187 |
| - ]) |
188 |
| - return bedpostx |
189 |
| - |
| 80 | + return wf |
0 commit comments