Beispiel #1
0
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)
Beispiel #2
0
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)
Beispiel #3
0
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)
Beispiel #4
0
    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
Beispiel #5
0
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)
Beispiel #6
0
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, :])
Beispiel #7
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)
Beispiel #8
0
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)
Beispiel #9
0
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)
Beispiel #10
0
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)
Beispiel #11
0
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
Beispiel #12
0
def _fit(gtab, data, mask=None):
    fwmodel = fwdti.FreeWaterTensorModel(gtab)
    return fwmodel.fit(data, mask=mask)
Beispiel #13
0
                             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)