def test_fwdti_errors(): # 1st error - if a unknown fit method is given to the FWTM assert_raises(ValueError, fwdti.FreeWaterTensorModel, gtab_2s, fit_method="pKT") # 2nd error - if incorrect mask is given fwdtiM = fwdti.FreeWaterTensorModel(gtab_2s) incorrect_mask = np.array([[True, True, False], [True, False, False]]) assert_raises(ValueError, fwdtiM.fit, DWI, mask=incorrect_mask) # 3rd error - if data with only one non zero b-value is given assert_raises(ValueError, fwdti.FreeWaterTensorModel, gtab) # Testing the correct usage fwdtiM = fwdti.FreeWaterTensorModel(gtab_2s, min_signal=1) correct_mask = np.zeros((2, 2, 2)) correct_mask[0, :, :] = 1 correct_mask = correct_mask > 0 fwdtiF = fwdtiM.fit(DWI, mask=correct_mask) assert_array_almost_equal(fwdtiF.fa, FAref) assert_array_almost_equal(fwdtiF.f, GTF) # 4th error - if a sigma is selected by no value of sigma is given fwdm = fwdti.FreeWaterTensorModel(gtab_2s, 'NLS', weighting='sigma') assert_raises(ValueError, fwdm.fit, DWI)
def test_negative_s0(): # single voxel gtf = 0.55 mevals = np.array([[0.0017, 0.0003, 0.0003], [0.003, 0.003, 0.003]]) S_conta, peaks = multi_tensor(gtab_2s, mevals, S0=100, angles=[(90, 0), (90, 0)], fractions=[(1 - gtf) * 100, gtf * 100], snr=None) S_conta[gtab_2s.bvals == 0] = -100 fwdm = fwdti.FreeWaterTensorModel(gtab_2s, 'NLS') fwefit = fwdm.fit(S_conta) assert_array_almost_equal(fwefit.fa, 0.0) assert_array_almost_equal(fwefit.md, 0.0) assert_array_almost_equal(fwefit.f, 0.0) # multi voxel DWI[0, 0, 1, gtab_2s.bvals == 0] = -100 GTF[0, 0, 1] = 0 FAref[0, 0, 1] = 0 MDref[0, 0, 1] = 0 fwefit = fwdm.fit(DWI) assert_array_almost_equal(fwefit.fa, FAref) assert_array_almost_equal(fwefit.md, MDref) assert_array_almost_equal(fwefit.f, GTF)
def test_md_regularization(): # single voxel gtf = 0.97 # for this ground truth value, md is larger than 2.7e-3 mevals = np.array([[0.0017, 0.0003, 0.0003], [0.003, 0.003, 0.003]]) S_conta, peaks = multi_tensor(gtab_2s, mevals, S0=100, angles=[(90, 0), (90, 0)], fractions=[(1 - gtf) * 100, gtf * 100], snr=None) fwdm = fwdti.FreeWaterTensorModel(gtab_2s, 'NLS') fwefit = fwdm.fit(S_conta) assert_array_almost_equal(fwefit.fa, 0.0) assert_array_almost_equal(fwefit.md, 0.0) assert_array_almost_equal(fwefit.f, 1.0) # multi voxel DWI[0, 1, 1] = S_conta GTF[0, 1, 1] = 1 FAref[0, 1, 1] = 0 MDref[0, 1, 1] = 0 fwefit = fwdm.fit(DWI) assert_array_almost_equal(fwefit.fa, FAref) assert_array_almost_equal(fwefit.md, MDref) assert_array_almost_equal(fwefit.f, GTF)
def fit(self, data, mask): self.model = fwdti.FreeWaterTensorModel(self.gradient_table) self.f = self.model.fit(data, mask=mask) self.FA = self.f.fa self.MD = self.f.md return self
def test_fwdti_predictions(): # single voxel case gtf = 0.50 # ground truth volume fraction angles = [(90, 0), (90, 0)] mevals = np.array([[0.0017, 0.0003, 0.0003], [0.003, 0.003, 0.003]]) S_conta, peaks = multi_tensor(gtab_2s, mevals, S0=100, angles=angles, fractions=[(1 - gtf) * 100, gtf * 100], snr=None) R = all_tensor_evecs(peaks[0]) R = R.reshape((9)) model_params = np.concatenate(([0.0017, 0.0003, 0.0003], R, [gtf]), axis=0) S_pred1 = fwdti_prediction(model_params, gtab_2s, S0=100) assert_array_almost_equal(S_pred1, S_conta) # Testing in model class fwdm = fwdti.FreeWaterTensorModel(gtab_2s) S_pred2 = fwdm.predict(model_params, S0=100) assert_array_almost_equal(S_pred2, S_conta) # Testing in fit class fwefit = fwdm.fit(S_conta) S_pred3 = fwefit.predict(gtab_2s, S0=100) assert_array_almost_equal(S_pred3, S_conta, decimal=5) # Multi voxel simulation S_pred1 = fwdti_prediction(model_params_mv, gtab_2s, S0=100) # function assert_array_almost_equal(S_pred1, DWI) S_pred2 = fwdm.predict(model_params_mv, S0=100) # Model class assert_array_almost_equal(S_pred2, DWI) fwefit = fwdm.fit(DWI) # Fit class S_pred3 = fwefit.predict(gtab_2s, S0=100) assert_array_almost_equal(S_pred3, DWI)
def test_fwdti_jac_multi_voxel(): fwdm = fwdti.FreeWaterTensorModel(gtab_2s, 'WLS') fwdm.fit(DWI[0, :, :]) # no f transform fwdm = fwdti.FreeWaterTensorModel(gtab_2s, 'NLS', f_transform=False, jac=True) fwefit = fwdm.fit(DWI[0, :, :]) Ffwe = fwefit.f assert_array_almost_equal(Ffwe, GTF[0, :]) # with f transform fwdm = fwdti.FreeWaterTensorModel(gtab_2s, 'NLS', f_transform=True, jac=True) fwefit = fwdm.fit(DWI[0, :, :]) Ffwe = fwefit.f assert_array_almost_equal(Ffwe, GTF[0, :])
def test_fwdti_restore(): # Restore has to work well even in nonproblematic cases # Simulate a signal corrupted by free water diffusion contamination gtf = 0.50 # ground truth volume fraction mevals = np.array([[0.0017, 0.0003, 0.0003], [0.003, 0.003, 0.003]]) S_conta, peaks = multi_tensor(gtab_2s, mevals, S0=100, angles=[(90, 0), (90, 0)], fractions=[(1-gtf) * 100, gtf*100], snr=None) fwdm = fwdti.FreeWaterTensorModel(gtab_2s, 'NLS', weighting='sigma', sigma=4) fwdtiF = fwdm.fit(S_conta) assert_array_almost_equal(fwdtiF.fa, FAdti) assert_array_almost_equal(fwdtiF.f, gtf) fwdm2 = fwdti.FreeWaterTensorModel(gtab_2s, 'NLS', weighting='gmm') fwdtiF2 = fwdm2.fit(S_conta) assert_array_almost_equal(fwdtiF2.fa, FAdti) assert_array_almost_equal(fwdtiF2.f, gtf)
def test_fwdti_singlevoxel(): # Simulation when water contamination is added gtf = 0.44444 # ground truth volume fraction mevals = np.array([[0.0017, 0.0003, 0.0003], [0.003, 0.003, 0.003]]) S_conta, peaks = multi_tensor(gtab_2s, mevals, S0=100, angles=[(90, 0), (90, 0)], fractions=[(1 - gtf) * 100, gtf * 100], snr=None) fwdm = fwdti.FreeWaterTensorModel(gtab_2s, 'WLS') fwefit = fwdm.fit(S_conta) FAfwe = fwefit.fa Ffwe = fwefit.f MDfwe = fwefit.md assert_almost_equal(FAdti, FAfwe, decimal=3) assert_almost_equal(Ffwe, gtf, decimal=3) assert_almost_equal(MDfwe, MDdti, decimal=3) # Test non-linear fit fwdm = fwdti.FreeWaterTensorModel(gtab_2s, 'NLS', cholesky=False) fwefit = fwdm.fit(S_conta) FAfwe = fwefit.fa Ffwe = fwefit.f MDfwe = fwefit.md assert_almost_equal(FAdti, FAfwe) assert_almost_equal(Ffwe, gtf) assert_almost_equal(MDfwe, MDdti) # Test cholesky fwdm = fwdti.FreeWaterTensorModel(gtab_2s, 'NLS', cholesky=True) fwefit = fwdm.fit(S_conta) FAfwe = fwefit.fa Ffwe = fwefit.f MDfwe = fwefit.md assert_almost_equal(FAdti, FAfwe) assert_almost_equal(Ffwe, gtf) assert_almost_equal(MDfwe, MDfwe)
def test_fwdti_multi_voxel(): fwdm = fwdti.FreeWaterTensorModel(gtab_2s, 'NLS', cholesky=False) fwefit = fwdm.fit(DWI) FAfwe = fwefit.fa Ffwe = fwefit.f MDfwe = fwefit.md assert_almost_equal(FAfwe, FAref) assert_almost_equal(Ffwe, GTF) assert_almost_equal(MDfwe, MDref) # Test cholesky fwdm = fwdti.FreeWaterTensorModel(gtab_2s, 'NLS', cholesky=True) fwefit = fwdm.fit(DWI) FAfwe = fwefit.fa Ffwe = fwefit.f MDfwe = fwefit.md assert_almost_equal(FAfwe, FAref) assert_almost_equal(Ffwe, GTF) assert_almost_equal(MDfwe, MDref)
def test_fwdti_precision(): # Simulation when water contamination is added gtf = 0.63416 # ground truth volume fraction mevals = np.array([[0.0017, 0.0003, 0.0003], [0.003, 0.003, 0.003]]) S_conta, peaks = multi_tensor(gtab_2s, mevals, S0=100, angles=[(90, 0), (90, 0)], fractions=[(1-gtf) * 100, gtf*100], snr=None) fwdm = fwdti.FreeWaterTensorModel(gtab_2s, 'WLS', piterations=5) fwefit = fwdm.fit(S_conta) FAfwe = fwefit.fa Ffwe = fwefit.f MDfwe = fwefit.md assert_almost_equal(FAdti, FAfwe, decimal=5) assert_almost_equal(Ffwe, gtf, decimal=5) assert_almost_equal(MDfwe, MDdti, decimal=5)
def fit_fwdti(data_files, bval_files, bvec_files, mask=None, out_dir=None, b0_threshold=50): """ Fit the free water DTI model [1]_, save files with derived maps Parameters ---------- data_files : str or list Files containing DWI data. If this is a str, that's the full path to a single file. If it's a list, each entry is a full path. bval_files : str or list Equivalent to `data_files`. bvec_files : str or list Equivalent to `data_files`. mask : ndarray, optional Binary mask, set to True or 1 in voxels to be processed. Default: Process all voxels. out_dir : str, optional A full path to a directory to store the maps that get computed. Default: maps get stored in the same directory as the last DWI file in `data_files`. b0_threshold : float Returns ------- file_paths : a dict with the derived maps that were computed and full-paths to the files containing these maps. Note ---- ..[1] R. Neto Henriques, A. Rokem, E. Garyfallidis, S. St-Jean, E.T. Peterson, M. Correia (2017). [Re] Optimization of a free water elimination two-compartment model for diffusion tensor imaging. *ReScience* """ img, data, gtab, mask = ut.prepare_data(data_files, bval_files, bvec_files, mask=mask, b0_threshold=b0_threshold) fwmodel = fwdti.FreeWaterTensorModel(gtab) fwfit = fwmodel.fit(data, mask=mask) FA = fwfit.fa MD = fwfit.md AD = fwfit.ad RD = fwfit.rd fwvf = fwfit.f params = fwfit.model_params maps = [FA, MD, AD, RD, fwvf, params] names = ['FA', 'MD', 'AD', 'RD', 'FWVF', 'params'] if out_dir is None: if isinstance(data_files, list): out_dir = op.join(op.split(data_files[0])[0], 'fwdti') else: out_dir = op.join(op.split(data_files)[0], 'fwdti') if not op.exists(out_dir): os.makedirs(out_dir) aff = img.affine file_paths = {} for m, n in zip(maps, names): file_paths[n] = op.join(out_dir, 'fwdti_%s.nii.gz' % n) nib.save(nib.Nifti1Image(m, aff), file_paths[n]) return file_paths
def _fit(gtab, data, mask=None): fwmodel = fwdti.FreeWaterTensorModel(gtab) return fwmodel.fit(data, mask=mask)
dilate=1) """ Moreover, for illustration purposes we process only an axial slice of the data. """ axial_slice = 40 mask_roi = np.zeros(data.shape[:-1], dtype=bool) mask_roi[:, :, axial_slice] = mask[:, :, axial_slice] """ The free water elimination model fit can then be initialized by instantiating a FreeWaterTensorModel class object: """ fwdtimodel = fwdti.FreeWaterTensorModel(gtab) """ The data can then be fitted using the ``fit`` function of the defined model object: """ fwdtifit = fwdtimodel.fit(data, mask=mask_roi) """ This 2-steps procedure will create a FreeWaterTensorFit object which contains all the diffusion tensor statistics free for free water contaminations. Below we extract the fractional anisotropy (FA) and the mean diffusivity (MD) of the free water diffusion tensor.""" FA = fwdtifit.fa MD = fwdtifit.md """
def fit_fwdti_dipy(input_dwi, input_bval, input_bvec, output_dir, fit_method='', mask=''): import dipy.reconst.fwdti as fwdti if not os.path.exists(output_dir): os.makedirs(output_dir) if fit_method == '': fit_method = 'WLS' img = nib.load(input_dwi) data = img.get_data() bvals, bvecs = read_bvals_bvecs( input_bval, input_bvec, ) gtab = gradient_table(bvals, bvecs) if mask != '': mask_data = nib.load(mask).get_data() values = np.array(bvals) ii = np.where(values == bvals.min())[0] b0_average = np.mean(data[:, :, :, ii], axis=3) fwidtimodel = fwdti.FreeWaterTensorModel(gtab, fit_method) if mask != '': fwidti_fit = fwidtimodel.fit(data, mask_data) else: fwidti_fit = fwidtimodel.fit(data) if not os.path.exists(output_dir): os.makedirs(output_dir) output_evecs = output_dir + '/fwe_dti_eigenvectors.nii.gz' output_evals = output_dir + '/fwe_dti_eigenvalues.nii.gz' output_fa = output_dir + '/fwe_dti_FA.nii.gz' output_md = output_dir + '/fwe_dti_MD.nii.gz' output_rd = output_dir + '/fwe_dti_RD.nii.gz' output_ad = output_dir + '/fwe_dti_AD.nii.gz' output_f = output_dir + '/fwe_dti_F.nii.gz' #Calculate Parameters for FWDTI Model evals_img = nib.Nifti1Image(fwidti_fit.evals.astype(np.float32), img.get_affine(), img.header) nib.save(evals_img, output_evals) evecs_img = nib.Nifti1Image(fwidti_fit.evecs.astype(np.float32), img.get_affine(), img.header) nib.save(evecs_img, output_evecs) fwidti_fa = fwidti_fit.fa fwidti_fa_img = nib.Nifti1Image(fwidti_fa.astype(np.float32), img.get_affine(), img.header) nib.save(fwidti_fa_img, output_fa) fwidti_md = fwidti_fit.md fwidti_md_img = nib.Nifti1Image(fwidti_md.astype(np.float32), img.get_affine(), img.header) nib.save(fwidti_md_img, output_md) fwidti_ad = fwidti_fit.ad fwidti_ad_img = nib.Nifti1Image(fwidti_ad.astype(np.float32), img.get_affine(), img.header) nib.save(fwidti_ad_img, output_ad) fwidti_rd = fwidti_fit.rd fwidti_rd_img = nib.Nifti1Image(fwidti_rd.astype(np.float32), img.get_affine(), img.header) nib.save(fwidti_rd_img, output_rd) fwidti_f = fwidti_fit.f fwidti_f_img = nib.Nifti1Image(fwidti_f.astype(np.float32), img.get_affine(), img.header) nib.save(fwidti_f_img, output_f)