|
25 | 25 | have_dipy = False
|
26 | 26 | else:
|
27 | 27 | import dipy.reconst.dti as dti
|
28 |
| - from dipy.core.gradients import GradientTable |
| 28 | + from dipy.core.gradients import gradient_table |
| 29 | + from dipy.io.utils import nifti1_symmat |
29 | 30 |
|
30 | 31 |
|
| 32 | +def tensor_fitting(data, bvals, bvecs, mask_file=None): |
| 33 | + """ |
| 34 | + Use dipy to fit DTI |
| 35 | + |
| 36 | + Parameters |
| 37 | + ---------- |
| 38 | + in_file : str |
| 39 | + Full path to a DWI data file. |
| 40 | + bvals : str |
| 41 | + Full path to a file containing gradient magnitude information (b-values). |
| 42 | + bvecs : str |
| 43 | + Full path to a file containing gradient direction information (b-vectors). |
| 44 | + mask_file : str, optional |
| 45 | + Full path to a file containing a binary mask. Defaults to use the entire volume. |
| 46 | +
|
| 47 | + Returns |
| 48 | + ------- |
| 49 | + TensorFit object, affine |
| 50 | + """ |
| 51 | + img = nb.load(in_file).get_data() |
| 52 | + data = img.get_data() |
| 53 | + affine = img.get_affine() |
| 54 | + if mask_file is not None: |
| 55 | + mask = nb.load(self.inputs.mask_file).get_data() |
| 56 | + else: |
| 57 | + mask=None |
| 58 | + |
| 59 | + # Load information about the gradients: |
| 60 | + gtab = grad.gradient_table(self.inputs.bvals, self.inputs.bvecs) |
| 61 | + |
| 62 | + # Fit it |
| 63 | + tenmodel = dti.TensorModel(gtab) |
| 64 | + return tenmodel.fit(data, mask), affine |
| 65 | + |
| 66 | + |
| 67 | +class DTIInputSpec(TraitedSpec): |
| 68 | + in_file = File(exists=True, mandatory=True, |
| 69 | + desc='The input 4D diffusion-weighted image file') |
| 70 | + bvecs = File(exists=True, mandatory=True, |
| 71 | + desc='The input b-vector text file') |
| 72 | + bvals = File(exists=True, mandatory=True, |
| 73 | + desc='The input b-value text file') |
| 74 | + mask_file = File(exists=True, mandatory=False, |
| 75 | + desc='An optional white matter mask') |
| 76 | + out_filename = File( |
| 77 | + genfile=True, desc='The output filename for the DTI parameters image') |
| 78 | + |
| 79 | + |
| 80 | +class DTIOutputSpec(TraitedSpec): |
| 81 | + out_file = File(exists=True) |
| 82 | + |
| 83 | + |
| 84 | +class DTI(BaseInterface): |
| 85 | + """ |
| 86 | + Calculates the diffusion tensor model parameters |
| 87 | + |
| 88 | + Example |
| 89 | + ------- |
| 90 | +
|
| 91 | + >>> import nipype.interfaces.dipy as dipy |
| 92 | + >>> dti = dipy.DTI() |
| 93 | + >>> dti.inputs.in_file = 'diffusion.nii' |
| 94 | + >>> dti.inputs.bvecs = 'bvecs' |
| 95 | + >>> dti.inputs.bvals = 'bvals' |
| 96 | + >>> dti.run() # doctest: +SKIP |
| 97 | + """ |
| 98 | + input_spec = DTIInputSpec |
| 99 | + output_spec = DTIOutputSpec |
| 100 | + |
| 101 | + def _run_interface(self, runtime): |
| 102 | + ten_fit, affine = tensor_fitting(self.inputs.in_file, |
| 103 | + self.inputs.bvals, |
| 104 | + self.inputs.bvecs, |
| 105 | + self.inputs.mask_file) |
| 106 | + lower_triangular = tenfit.lower_triangular() |
| 107 | + img = nifti1_symmat(lower_triangular, affine) |
| 108 | + out_file = op.abspath(self._gen_outfilename()) |
| 109 | + nb.save(img, out_file) |
| 110 | + iflogger.info('DTI parameters image saved as {i}'.format(i=out_file)) |
| 111 | + return runtime |
| 112 | + |
| 113 | + def _list_outputs(self): |
| 114 | + outputs = self._outputs().get() |
| 115 | + outputs['out_file'] = op.abspath(self._gen_outfilename()) |
| 116 | + return outputs |
| 117 | + |
| 118 | + def _gen_filename(self, name): |
| 119 | + if name is 'out_filename': |
| 120 | + return self._gen_outfilename() |
| 121 | + else: |
| 122 | + return None |
| 123 | + |
| 124 | + def _gen_outfilename(self): |
| 125 | + _, name, _ = split_filename(self.inputs.in_file) |
| 126 | + return name + '_dti.nii' |
| 127 | + |
| 128 | + |
31 | 129 | class TensorModeInputSpec(TraitedSpec):
|
32 | 130 | in_file = File(exists=True, mandatory=True,
|
33 | 131 | desc='The input 4D diffusion-weighted image file')
|
34 | 132 | bvecs = File(exists=True, mandatory=True,
|
35 | 133 | desc='The input b-vector text file')
|
36 | 134 | bvals = File(exists=True, mandatory=True,
|
37 | 135 | desc='The input b-value text file')
|
| 136 | + mask_file = File(exists=True, mandatory=False, |
| 137 | + desc='An optional white matter mask') |
38 | 138 | out_filename = File(
|
39 | 139 | genfile=True, desc='The output filename for the Tensor mode image')
|
40 | 140 |
|
@@ -69,32 +169,11 @@ class TensorMode(BaseInterface):
|
69 | 169 | output_spec = TensorModeOutputSpec
|
70 | 170 |
|
71 | 171 | def _run_interface(self, runtime):
|
72 |
| - ## Load the 4D image files |
73 |
| - img = nb.load(self.inputs.in_file) |
74 |
| - data = img.get_data() |
75 |
| - affine = img.get_affine() |
76 |
| - |
77 |
| - ## Load the gradient strengths and directions |
78 |
| - bvals = np.loadtxt(self.inputs.bvals) |
79 |
| - gradients = np.loadtxt(self.inputs.bvecs).T |
80 |
| - |
81 |
| - ## Place in Dipy's preferred format |
82 |
| - gtab = GradientTable(gradients) |
83 |
| - gtab.bvals = bvals |
84 |
| - |
85 |
| - ## Mask the data so that tensors are not fit for |
86 |
| - ## unnecessary voxels |
87 |
| - mask = data[..., 0] > 50 |
88 |
| - |
89 |
| - ## Fit the tensors to the data |
90 |
| - tenmodel = dti.TensorModel(gtab) |
91 |
| - tenfit = tenmodel.fit(data, mask) |
92 |
| - |
93 |
| - ## Calculate the mode of each voxel's tensor |
94 |
| - mode_data = tenfit.mode |
| 172 | + ten_fit = tensor_fitting(self.inputs.in_file, self.inputs.bvals, self.inputs.bvecs, |
| 173 | + self.inputs.mask_file) |
95 | 174 |
|
96 | 175 | ## Write as a 3D Nifti image with the original affine
|
97 |
| - img = nb.Nifti1Image(mode_data, affine) |
| 176 | + img = nb.Nifti1Image(tenfit.mode, affine) |
98 | 177 | out_file = op.abspath(self._gen_outfilename())
|
99 | 178 | nb.save(img, out_file)
|
100 | 179 | iflogger.info('Tensor mode image saved as {i}'.format(i=out_file))
|
|
0 commit comments