Example #1
0
def test_dti_xval():
    data = load_nifti_data(fdata)
    gtab = gt.gradient_table(fbval, fbvec)
    dm = dti.TensorModel(gtab, 'LS')
    # The data has 102 directions, so will not divide neatly into 10 bits
    npt.assert_raises(ValueError, xval.kfold_xval, dm, data, 10)

    # In simulation with no noise, COD should be perfect:
    psphere = dpd.get_sphere('symmetric362')
    bvecs = np.concatenate(([[0, 0, 0]], psphere.vertices))
    bvals = np.zeros(len(bvecs)) + 1000
    bvals[0] = 0
    gtab = gt.gradient_table(bvals, bvecs)
    mevals = np.array(([0.0015, 0.0003, 0.0001], [0.0015, 0.0003, 0.0003]))
    mevecs = [
        np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]),
        np.array([[0, 0, 1], [0, 1, 0], [1, 0, 0]])
    ]
    S = sims.single_tensor(gtab, 100, mevals[0], mevecs[0], snr=None)

    dm = dti.TensorModel(gtab, 'LS')
    kf_xval = xval.kfold_xval(dm, S, 2)
    cod = xval.coeff_of_determination(S, kf_xval)
    npt.assert_array_almost_equal(cod, np.ones(kf_xval.shape[:-1]) * 100)

    # Test with 2D data for use of a mask
    S = np.array([[S, S], [S, S]])
    mask = np.ones(S.shape[:-1], dtype=bool)
    mask[1, 1] = 0
    kf_xval = xval.kfold_xval(dm, S, 2, mask=mask)
    cod2d = xval.coeff_of_determination(S, kf_xval)
    npt.assert_array_almost_equal(np.round(cod2d[0, 0]), cod)
Example #2
0
def test_predict():
    """
    Test model prediction API
    """
    psphere = get_sphere('symmetric362')
    bvecs = np.concatenate(([[1, 0, 0]], psphere.vertices))
    bvals = np.zeros(len(bvecs)) + 1000
    bvals[0] = 0
    gtab = grad.gradient_table(bvals, bvecs)
    mevals = np.array(([0.0015, 0.0003, 0.0001], [0.0015, 0.0003, 0.0003]))
    mevecs = [np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]),
              np.array([[0, 0, 1], [0, 1, 0], [1, 0, 0]])]
    S = single_tensor(gtab, 100, mevals[0], mevecs[0], snr=None)

    dm = dti.TensorModel(gtab, 'LS')
    dmfit = dm.fit(S)
    assert_array_almost_equal(dmfit.predict(gtab, S0=100), S)
    assert_array_almost_equal(dm.predict(dmfit.model_params, S0=100), S)

    fdata, fbvals, fbvecs = get_data()
    data = nib.load(fdata).get_data()
    # Make the data cube a bit larger:
    data = np.tile(data.T, 2).T
    gtab = grad.gradient_table(fbvals, fbvecs)
    dtim = dti.TensorModel(gtab)
    dtif = dtim.fit(data)
    S0 = np.mean(data[..., gtab.b0s_mask], -1)
    p = dtif.predict(gtab, S0)
    assert_equal(p.shape, data.shape)
Example #3
0
def test_dti_xval():
    """
    Test k-fold cross-validation
    """
    data = nib.load(fdata).get_data()
    gtab = gt.gradient_table(fbval, fbvec)
    dm = dti.TensorModel(gtab, 'LS')
    # The data has 102 directions, so will not divide neatly into 10 bits
    npt.assert_raises(ValueError, xval.kfold_xval, dm, data, 10)

    # But we can do this with 2 folds:
    kf_xval = xval.kfold_xval(dm, data, 2)

    # In simulation with no noise, COD should be perfect:
    psphere = dpd.get_sphere('symmetric362')
    bvecs = np.concatenate(([[0, 0, 0]], psphere.vertices))
    bvals = np.zeros(len(bvecs)) + 1000
    bvals[0] = 0
    gtab = gt.gradient_table(bvals, bvecs)
    mevals = np.array(([0.0015, 0.0003, 0.0001], [0.0015, 0.0003, 0.0003]))
    mevecs = [
        np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]),
        np.array([[0, 0, 1], [0, 1, 0], [1, 0, 0]])
    ]
    S = sims.single_tensor(gtab, 100, mevals[0], mevecs[0], snr=None)

    dm = dti.TensorModel(gtab, 'LS')
    dmfit = dm.fit(S)

    kf_xval = xval.kfold_xval(dm, S, 2)
    cod = xval.coeff_of_determination(S, kf_xval)
    npt.assert_array_almost_equal(cod, np.ones(kf_xval.shape[:-1]) * 100)
Example #4
0
def test_mask():
    data, gtab = dsi_voxels()
    dm = dti.TensorModel(gtab, 'LS')
    mask = np.zeros(data.shape[:-1], dtype=bool)
    mask[0, 0, 0] = True
    dtifit = dm.fit(data)
    dtifit_w_mask = dm.fit(data, mask=mask)
    # Without a mask it has some value
    assert_(not np.isnan(dtifit.fa[0, 0, 0]))
    # Where mask is False, evals, evecs and fa should all be 0
    assert_array_equal(dtifit_w_mask.evals[~mask], 0)
    assert_array_equal(dtifit_w_mask.evecs[~mask], 0)
    assert_array_equal(dtifit_w_mask.fa[~mask], 0)
    # Except for the one voxel that was selected by the mask:
    assert_almost_equal(dtifit_w_mask.fa[0, 0, 0], dtifit.fa[0, 0, 0])

    # Test with returning S0_hat
    dm = dti.TensorModel(gtab, 'LS', return_S0_hat=True)
    mask = np.zeros(data.shape[:-1], dtype=bool)
    mask[0, 0, 0] = True
    dtifit = dm.fit(data)
    dtifit_w_mask = dm.fit(data, mask=mask)
    # Without a mask it has some value
    assert_(not np.isnan(dtifit.fa[0, 0, 0]))
    # Where mask is False, evals, evecs and fa should all be 0
    assert_array_equal(dtifit_w_mask.evals[~mask], 0)
    assert_array_equal(dtifit_w_mask.evecs[~mask], 0)
    assert_array_equal(dtifit_w_mask.fa[~mask], 0)
    assert_array_equal(dtifit_w_mask.S0_hat[~mask], 0)
    # Except for the one voxel that was selected by the mask:
    assert_almost_equal(dtifit_w_mask.fa[0, 0, 0], dtifit.fa[0, 0, 0])
    assert_almost_equal(dtifit_w_mask.S0_hat[0, 0, 0], dtifit.S0_hat[0, 0, 0])
Example #5
0
def test_predict():
    """
    Test model prediction API
    """
    psphere = get_sphere('symmetric362')
    bvecs = np.concatenate(([[1, 0, 0]], psphere.vertices))
    bvals = np.zeros(len(bvecs)) + 1000
    bvals[0] = 0
    gtab = grad.gradient_table(bvals, bvecs)
    mevals = np.array(([0.0015, 0.0003, 0.0001], [0.0015, 0.0003, 0.0003]))
    mevecs = [
        np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]),
        np.array([[0, 0, 1], [0, 1, 0], [1, 0, 0]])
    ]
    S = single_tensor(gtab, 100, mevals[0], mevecs[0], snr=None)

    dm = dti.TensorModel(gtab, 'LS')
    dmfit = dm.fit(S)
    assert_array_almost_equal(dmfit.predict(gtab, S0=100), S)
    assert_array_almost_equal(dm.predict(dmfit.model_params, S0=100), S)

    data, gtab = dsi_voxels()
    dtim = dti.TensorModel(gtab)
    dtif = dtim.fit(data)
    S0 = np.mean(data[..., gtab.b0s_mask], -1)
    p = dtif.predict(gtab, S0)
Example #6
0
def test_restore():
    """
    Test the implementation of the RESTORE algorithm
    """
    b0 = 1000.
    bvecs, bval = read_bvec_file(get_data('55dir_grad.bvec'))
    gtab = grad.gradient_table(bval, bvecs)
    B = bval[1]

    # Scale the eigenvalues and tensor by the B value so the units match
    D = np.array([1., 1., 1., 0., 0., 1., -np.log(b0) * B]) / B
    evals = np.array([2., 1., 0.]) / B
    tensor = from_lower_triangular(D)

    # Design Matrix
    X = dti.design_matrix(gtab)

    # Signals
    Y = np.exp(np.dot(X, D))
    Y.shape = (-1, ) + Y.shape
    for drop_this in range(1, Y.shape[-1]):
        for jac in [True, False]:
            # RESTORE estimates should be robust to dropping
            this_y = Y.copy()
            this_y[:, drop_this] = 1.0
            for sigma in [67.0, np.ones(this_y.shape[-1]) * 67.0]:
                tensor_model = dti.TensorModel(gtab,
                                               fit_method='restore',
                                               jac=jac,
                                               sigma=67.0)

                tensor_est = tensor_model.fit(this_y)
                assert_array_almost_equal(tensor_est.evals[0],
                                          evals,
                                          decimal=3)
                assert_array_almost_equal(tensor_est.quadratic_form[0],
                                          tensor,
                                          decimal=3)

    # If sigma is very small, it still needs to work:
    tensor_model = dti.TensorModel(gtab, fit_method='restore', sigma=0.0001)
    tensor_model.fit(Y.copy())

    # Test return_S0_hat
    tensor_model = dti.TensorModel(gtab,
                                   fit_method='restore',
                                   sigma=0.0001,
                                   return_S0_hat=True)
    tmf = tensor_model.fit(Y.copy())
    assert_almost_equal(tmf[0].S0_hat, b0)
Example #7
0
def test_nlls_fit_tensor():
     """
     Test the implementation of NLLS and RESTORE
     """

     b0 = 1000.
     bvecs, bval = read_bvec_file(get_data('55dir_grad.bvec'))
     gtab = grad.gradient_table(bval, bvecs)
     B = bval[1]

     #Scale the eigenvalues and tensor by the B value so the units match
     D = np.array([1., 1., 1., 0., 0., 1., -np.log(b0) * B]) / B
     evals = np.array([2., 1., 0.]) / B
     md = evals.mean()
     tensor = from_lower_triangular(D)

     #Design Matrix
     X = dti.design_matrix(bvecs, bval)

     #Signals
     Y = np.exp(np.dot(X,D))
     Y.shape = (-1,) + Y.shape

     #Estimate tensor from test signals and compare against expected result
     #using non-linear least squares:
     tensor_model = dti.TensorModel(gtab, fit_method='NLLS')
     tensor_est = tensor_model.fit(Y)
     assert_equal(tensor_est.shape, Y.shape[:-1])
     assert_array_almost_equal(tensor_est.evals[0], evals)
     assert_array_almost_equal(tensor_est.quadratic_form[0], tensor)
     assert_almost_equal(tensor_est.md[0], md)

     # Using the gmm weighting scheme:
     tensor_model = dti.TensorModel(gtab, fit_method='NLLS', weighting='gmm')
     assert_equal(tensor_est.shape, Y.shape[:-1])
     assert_array_almost_equal(tensor_est.evals[0], evals)
     assert_array_almost_equal(tensor_est.quadratic_form[0], tensor)
     assert_almost_equal(tensor_est.md[0], md)

     # Use NLLS with some actual 4D data:
     data, bvals, bvecs = get_data('small_25')
     gtab = grad.gradient_table(bvals, bvecs)
     tm1 = dti.TensorModel(gtab, fit_method='NLLS')
     dd = nib.load(data).get_data()
     tf1 = tm1.fit(dd)
     tm2 = dti.TensorModel(gtab)
     tf2 = tm2.fit(dd)

     assert_array_almost_equal(tf1.fa, tf2.fa, decimal=1)
Example #8
0
def test_all_zeros():
    bvecs, bvals = read_bvec_file(get_data('55dir_grad.bvec'))
    gtab = grad.gradient_table_from_bvals_bvecs(bvals, bvecs.T)
    fit_methods = ['LS', 'OLS', 'NNLS', 'RESTORE']
    for fit_method in fit_methods:
        dm = dti.TensorModel(gtab)
        assert_raises(ValueError, dm.fit, np.zeros(bvals.shape[0]))
Example #9
0
def tensor_fitting(data, bvals, bvecs, mask_file=None):
    """
    Use dipy to fit DTI

    Parameters
    ----------
    in_file : str
        Full path to a DWI data file.
    bvals : str
        Full path to a file containing gradient magnitude information (b-values).
    bvecs : str
        Full path to a file containing gradient direction information (b-vectors).
    mask_file : str, optional
        Full path to a file containing a binary mask. Defaults to use the entire volume.

    Returns
    -------
    TensorFit object, affine
    """
    img = nb.load(in_file).get_data()
    data = img.get_data()
    affine = img.get_affine()
    if mask_file is not None:
        mask = nb.load(self.inputs.mask_file).get_data()
    else:
        mask = None

    # Load information about the gradients:
    gtab = grad.gradient_table(self.inputs.bvals, self.inputs.bvecs)

    # Fit it
    tenmodel = dti.TensorModel(gtab)
    return tenmodel.fit(data, mask), affine
Example #10
0
def D_init(Sk, S0, bval, bvecs, f0, Diso):
    """ initializes the tensor components with regular DTI """
    # Correcting Sk for fwater
    A_water = np.exp(-bval * Diso)
    C_water = (1 - f0) * A_water
    # At = (Ak - C_water[..., np.newaxis]) / f0[..., np.newaxis]
    # At = np.clip(At, 0.0001, 1 - 0.0001)
    St = Sk - S0 * C_water[..., np.newaxis]  # using alternative init

    # creating new gtab and data
    x, y, z, k = St.shape
    bvals = bval * np.ones(k)
    bvals = np.insert(bvals, 0, 0)
    bvecs = np.insert(bvecs, 0, np.array([0, 0, 0]), axis=0)
    gtab = gradient_table(bvals, bvecs)

    init_data = np.zeros((x, y, z, k + 1))
    init_data[..., 0] = S0[..., 0]
    init_data[..., 1:] = St

    # fitting
    model = dti.TensorModel(gtab)
    fit = model.fit(init_data)
    qform = fit.quadratic_form

    Dxx = qform[..., 0, 0]
    Dyy = qform[..., 1, 1]
    Dzz = qform[..., 2, 2]
    Dxy = qform[..., 0, 1]
    Dxz = qform[..., 0, 2]
    Dyz = qform[..., 1, 2]

    return (Dxx, Dyy, Dzz, Dxy, Dxz, Dyz)
Example #11
0
def get_FA_MD():
    time0 = time.time()

    data, affine = load_nifti('normalized_pDWI.nii.gz')
    bvals, bvecs = read_bvals_bvecs('DWI.bval', 'DWI.bvec')
    gtab = gradient_table(bvals, bvecs)
    #head_mask = load_nifti_data(data_path + '/' + brain_mask)

    print(data.shape)
    print('begin modeling!, time:', time.time() - time0)

    tenmodel = dti.TensorModel(gtab)
    tenfit = tenmodel.fit(data)

    from dipy.reconst.dti import fractional_anisotropy
    print('begin calculating FA!, time:', time.time() - time0)

    FA = fractional_anisotropy(tenfit.evals)

    FA[np.isnan(FA)] = 0
    #FA = FA * head_mask
    save_nifti('FA.nii.gz', FA.astype(np.float32), affine)

    # print('begin calculating MD!, time:', time.time() - time0)
    MD1 = dti.mean_diffusivity(tenfit.evals)
    #MD1 = MD1*head_mask
    save_nifti('MD.nii.gz', MD1.astype(np.float32), affine)

    print('Over!, time:', time.time() - time0)

    return FA, MD1
Example #12
0
def test_adc():
    """
    Test the implementation of the calculation of apparent diffusion
    coefficient
    """
    data, gtab = dsi_voxels()
    dm = dti.TensorModel(gtab, 'LS')
    mask = np.zeros(data.shape[:-1], dtype=bool)
    mask[0, 0, 0] = True
    dtifit = dm.fit(data)
    # The ADC in the principal diffusion direction should be equal to the AD in
    # each voxel:

    pdd0 = dtifit.evecs[0, 0, 0, 0]
    sphere_pdd0 = dps.Sphere(x=pdd0[0], y=pdd0[1], z=pdd0[2])
    npt.assert_array_almost_equal(dtifit.adc(sphere_pdd0)[0, 0, 0],
                                  dtifit.ad[0, 0, 0],
                                  decimal=5)

    # Test that it works for cases in which the data is 1D
    dtifit = dm.fit(data[0, 0, 0])
    sphere_pdd0 = dps.Sphere(x=pdd0[0], y=pdd0[1], z=pdd0[2])
    npt.assert_array_almost_equal(dtifit.adc(sphere_pdd0),
                                  dtifit.ad,
                                  decimal=5)
def fit_dti(dwi):
    """Fit a DTI model to a DWI, applying a mask if provided.

    Parameters
    ---------
    dwi : DiffusionWeightedImage 
        DWI data to fit to the model.
    blur : bool, optional
        True if the image should be blurred before the model fit.

    Returns
    -------
    dwifit : TensorFit
        A fit from which parameter maps can be generated
    """

    dtimodel = dti.TensorModel(dwi.gtab)

    data = dwi.get_image()

    try:
        mask = dwi.mask
    except AttributeError:
        mask = np.ones(data.shape[:3])

    return dtimodel.fit(data, mask)
Example #14
0
def main(dti_file, bvals_file, bvecs_file, b_ss=1000):

    # Load the image data
    nii = nib.load(dti_file)
    img_data = nii.get_data()

    # Read in the b-shell values and gradient directions
    bvals, bvecs = read_bvals_bvecs(bvals_file, bvecs_file)

    # Boolean array to identify entries with either b = 0 or b = b_ss
    bvals_eq_0_b_ss = (bvals == 0) | (bvals == b_ss)

    # Extract info needed to run single-compartment dti model
    dti_bvals = bvals[bvals_eq_0_b_ss].copy()
    dti_bvecs = bvecs[bvals_eq_0_b_ss].copy()
    dti_img_data = img_data[:, :, :, bvals_eq_0_b_ss].copy()

    # Compute gradient table
    grad_table = gradient_table(dti_bvals, dti_bvecs)

    # Extract brain so we don't fit the background
    brain_img_data, brain_mask = median_otsu(dti_img_data, 2, 1)

    # Run the dti model and fit it to the brain extracted image data
    ten_model = dti.TensorModel(grad_table)
    ten_fit = ten_model.fit(brain_img_data)
Example #15
0
    def model_params(self):
        """
        The diffusion tensor parameters estimated from the data, using dipy.
        If this calculation has already occurred, just load the data from a
        nifti file, which has shape x by y by z by 12, where the last dimension
        is the model params:

        evecs (9) + evals (3)
        
        """
        out = ozu.nans((self.data.shape[:3] + (12, )))

        flat_params = np.empty((self._flat_S0.shape[0], 12))

        # The file already exists:
        if os.path.isfile(self.params_file):
            if self.verbose:
                print("Loading TensorModel params from: %s" % self.params_file)
            out[self.mask] = ni.load(self.params_file).get_data()[self.mask]
        else:
            if self.verbose:
                print("Fitting TensorModel params using dipy")
            tensor_model = dti.TensorModel(self.gtab,
                                           fit_method=self.fit_method)
            for vox, vox_data in enumerate(self.data[self.mask]):
                flat_params[vox] = tensor_model.fit(vox_data).model_params

            out[self.mask] = flat_params
            # Save the params for future use:
            params_ni = ni.Nifti1Image(out, self.affine)
            # If we asked it to be temporary, no need to save anywhere:
            if self.params_file != 'temp':
                params_ni.to_filename(self.params_file)
        # And return the params for current use:
        return out
Example #16
0
    def _run_interface(self, runtime):
        ## Load the 4D image files
        img = nb.load(self.inputs.in_file)
        data = img.get_data()
        affine = img.get_affine()

        ## Load the gradient strengths and directions
        bvals = np.loadtxt(self.inputs.bvals)
        gradients = np.loadtxt(self.inputs.bvecs).T

        ## Place in Dipy's preferred format
        gtab = GradientTable(gradients)
        gtab.bvals = bvals

        ## Mask the data so that tensors are not fit for
        ## unnecessary voxels
        mask = data[..., 0] > 50

        ## Fit the tensors to the data
        tenmodel = dti.TensorModel(gtab)
        tenfit = tenmodel.fit(data, mask)

        ## Calculate the mode of each voxel's tensor
        mode_data = tenfit.mode

        ## Write as a 3D Nifti image with the original affine
        img = nb.Nifti1Image(mode_data, affine)
        out_file = op.abspath(self._gen_outfilename())
        nb.save(img, out_file)
        iflogger.info('Tensor mode image saved as {i}'.format(i=out_file))
        return runtime
Example #17
0
def model_building_stand_alone_tf(path):
    img = nib.load(path + "/100307_data_tiny.nii.gz")
    data = img.get_data()
    img_mask = nib.load(path + "/100307_mask.nii.gz")
    mask = img_mask.get_data().astype(np.bool)

    gtab = dpg.gradient_table(path + '/100307_bvals_tiny',
                              path + '/100307_bvecs_tiny',
                              b0_threshold=10)
    data_in_mask = np.reshape(data[mask], (-1, data.shape[-1]))
    data_in_mask = np.maximum(data_in_mask, MIN_POSITIVE_SIGNAL)

    ten_model = dti.TensorModel(gtab)

    design_matrix = ten_model.design_matrix

    print(data_in_mask.shape, design_matrix.shape)

    sess = tf.InteractiveSession()
    params_in_mask = model_building(data_in_mask, design_matrix).eval()

    params_in_mask = params_in_mask.reshape(params_in_mask.shape[0], 12)
    dti_params = np.zeros(data.shape[:-1] + (12, ))
    dti_params[mask, :] = params_in_mask

    evals = dti_params[..., :3]

    evals = _roll_evals(evals, -1)

    all_zero = (evals == 0).all(axis=0)
    ev1, ev2, ev3 = evals
    fa = np.sqrt(0.5 * ((ev1 - ev2)**2 + (ev2 - ev3)**2 + (ev3 - ev1)**2) /
                 ((evals * evals).sum(0) + all_zero))

    return fa
Example #18
0
    def _init_odf(self, odf_mode):
        print("Initialising ODF")
        # fit DTI model to data
        if odf_mode == "DTI":
            print("DTI-based ODF computation")
            dti_model = dti.TensorModel(self.dataset.gtab, fit_method='LS')
            dti_fit = dti_model.fit(self.dataset.dwi,
                                    mask=self.dataset.binary_mask)
            # compute ODF
            odf = dti_fit.odf(self.sphere)
        elif odf_mode == "CSD":
            print("CSD-based ODF computation")
            mask = mask_for_response_ssst(self.dataset.gtab,
                                          self.dataset.dwi,
                                          roi_radii=10,
                                          fa_thr=0.7)
            response, ratio = response_from_mask_ssst(self.dataset.gtab,
                                                      self.dataset.dwi, mask)
            dti_model = ConstrainedSphericalDeconvModel(
                self.dataset.gtab, response)
            dti_fit = dti_model.fit(self.dataset.dwi)
            odf = dti_fit.odf(self.sphere)
        else:
            raise NotImplementedError("ODF mode not found")
        # -- set up interpolator for odf evaluation
        odf = torch.from_numpy(odf).to(device=self.device).float()

        self.odf_interpolator = TorchGridInterpolator(odf)
Example #19
0
def to_estimate_dti(file_in, file_inMask, outPath, fbval, fbvec):
    print(d.separador + 'building DTI Model...')

    ref_name = utils.to_extract_filename(file_in)

    if (
            not (os.path.exists(outPath + ref_name + d.id_evecs + d.extension))
    ) | (not (os.path.exists(outPath + ref_name + d.id_evals + d.extension))):
        try:
            os.remove(outPath + ref_name + d.id_evecs + d.extension)
            os.remove(outPath + ref_name + d.id_evals + d.extension)
        except:
            print("Unexpected error:", sys.exc_info()[0])

        img = nib.load(file_in)
        data = img.get_data()
        mask = nib.load(file_inMask)
        mask = mask.get_data()

        bvals, bvecs = read_bvals_bvecs(fbval, fbvec)
        gtab = gradient_table(bvals, bvecs)

        tensor_model = dti.TensorModel(gtab)
        tensor_fitted = tensor_model.fit(data, mask)

        nib.save(
            nib.Nifti1Image(tensor_fitted.evecs.astype(np.float32),
                            img.affine),
            outPath + ref_name + d.id_evecs + d.extension)
        nib.save(
            nib.Nifti1Image(tensor_fitted.evals.astype(np.float32),
                            img.affine),
            outPath + ref_name + d.id_evals + d.extension)

    return outPath + ref_name + d.id_evecs + d.extension, outPath + ref_name + d.id_evals + d.extension
    def _init_odf(self):
        print("Initialising ODF")
        # fit DTI model to data
        if self.odf_mode == "DTI":
            print("DTI-based ODF computation")
            self.dti_model = dti.TensorModel(self.dataset.gtab,
                                             fit_method='LS')
            self.dti_fit = self.dti_model.fit(self.dataset.dwi,
                                              mask=self.dataset.binary_mask)
            # compute ODF
            odf = self.dti_fit.odf(self.sphere_odf)
        elif self.odf_mode == "CSD":
            print("CSD-based ODF computation")
            mask = mask_for_response_ssst(self.dataset.gtab,
                                          self.dataset.dwi,
                                          roi_radii=10,
                                          fa_thr=0.7)
            num_voxels = np.sum(mask)
            print(num_voxels)
            response, ratio = response_from_mask_ssst(self.dataset.gtab,
                                                      self.dataset.dwi, mask)
            print(response)
            self.dti_model = ConstrainedSphericalDeconvModel(
                self.dataset.gtab, response)
            self.dti_fit = self.dti_model.fit(self.dataset.dwi)
            odf = self.dti_fit.odf(self.sphere_odf)

        # -- set up interpolator for odf evaluation
        x_range = np.arange(odf.shape[0])
        y_range = np.arange(odf.shape[1])
        z_range = np.arange(odf.shape[2])

        self.odf_interpolator = RegularGridInterpolator(
            (x_range, y_range, z_range), odf)
def test_bdg_initial_direction():
    """This test the number of inital direction."
    """

    hsph_updated = HemiSphere.from_sphere(unit_icosahedron).subdivide(2)
    vertices = hsph_updated.vertices
    bvecs = vertices
    bvals = np.ones(len(vertices)) * 1000
    bvecs = np.insert(bvecs, 0, np.array([0, 0, 0]), axis=0)
    bvals = np.insert(bvals, 0, 0)
    gtab = gradient_table(bvals, bvecs)

    # test that we get one direction when we have a single tensor
    voxel = single_tensor(gtab).reshape([1, 1, 1, -1])
    dti_model = dti.TensorModel(gtab)
    boot_dg = BootDirectionGetter.from_data(voxel, dti_model, 30, sh_order=6)
    initial_direction = boot_dg.initial_direction(np.zeros(3))
    npt.assert_equal(len(initial_direction), 1)
    npt.assert_allclose(initial_direction[0], [1, 0, 0], atol=0.1)

    # test that we get multiple directions when we have a multi-tensor
    mevals = np.array([[1.5, 0.4, 0.4], [1.5, 0.4, 0.4]]) * 1e-3
    fracs = [60, 40]
    voxel, primary_evecs = multi_tensor(gtab, mevals, fractions=fracs,
                                        snr=None)
    voxel = voxel.reshape([1, 1, 1, -1])
    response = (np.array([0.0015, 0.0004, 0.0004]), 1)
    csd_model = ConstrainedSphericalDeconvModel(gtab, response=response,
                                                sh_order=4)
    boot_dg = BootDirectionGetter.from_data(voxel, csd_model, 30)
    initial_direction = boot_dg.initial_direction(np.zeros(3))

    npt.assert_equal(len(initial_direction), 2)
    npt.assert_allclose(initial_direction, primary_evecs, atol=0.1)
Example #22
0
    def _run_interface(self, runtime):
        gtab = self._get_gtab()
        dwi_img = nb.load(self.inputs.dwi_file)
        dwi_data = dwi_img.get_fdata(dtype=np.float32)
        mask_img, mask_array = self._get_mask(dwi_img, gtab)

        # Fit it
        tenmodel = dti.TensorModel(gtab)
        ten_fit = tenmodel.fit(dwi_data, mask_array)
        lower_triangular = ten_fit.lower_triangular()
        tensor_img = nifti1_symmat(lower_triangular, dwi_img.affine)
        output_tensor_file = fname_presuffix(self.inputs.dwi_file,
                                             suffix='tensor',
                                             newpath=runtime.cwd,
                                             use_ext=True)
        tensor_img.to_filename(output_tensor_file)

        # FA MD RD and AD
        for metric in ["fa", "md", "rd", "ad", "color_fa"]:
            data = getattr(ten_fit, metric).astype("float32")
            out_name = fname_presuffix(self.inputs.dwi_file,
                                       suffix=metric,
                                       newpath=runtime.cwd,
                                       use_ext=True)
            nb.Nifti1Image(data, dwi_img.affine).to_filename(out_name)
            self._results[metric + "_image"] = out_name

        return runtime
Example #23
0
    def _init_odf(self):
        print("Initialising ODF")
        # fit DTI model to data
        if self.odf_mode == "DTI":
            print("DTI-based ODF computation")
            self.dti_model = dti.TensorModel(self.dataset.gtab,
                                             fit_method='LS')
            self.dti_fit = self.dti_model.fit(self.dataset.dwi,
                                              mask=self.dataset.binary_mask)
            # compute ODF
            odf = self.dti_fit.odf(self.sphere_odf)
        elif self.odf_mode == "CSD":
            print("CSD-based ODF computation")
            mask = mask_for_response_ssst(self.dataset.gtab,
                                          self.dataset.dwi,
                                          roi_radii=10,
                                          fa_thr=0.7)
            num_voxels = np.sum(mask)
            print(num_voxels)
            response, ratio = response_from_mask_ssst(self.dataset.gtab,
                                                      self.dataset.dwi, mask)
            print(response)
            self.dti_model = ConstrainedSphericalDeconvModel(
                self.dataset.gtab, response)
            self.dti_fit = self.dti_model.fit(self.dataset.dwi)
            odf = self.dti_fit.odf(self.sphere_odf)

        # -- set up interpolator for odf evaluation
        odf = torch.from_numpy(odf).to(device=self.device).float()
        self.odf_interpolator = TorchGridInterpolator(odf)
        print("..done!")
Example #24
0
def test_all_zeros():
    bvecs, bvals = read_bvec_file(get_data('55dir_grad.bvec'))
    gtab = grad.gradient_table_from_bvals_bvecs(bvals, bvecs.T)
    fit_methods = ['LS', 'OLS', 'NNLS', 'RESTORE']
    for fit_method in fit_methods:
        dm = dti.TensorModel(gtab)
        assert_array_almost_equal(dm.fit(np.zeros(bvals.shape[0])).evals, 0)
Example #25
0
 def track(self):
     SeedBasedTracker.track(self)
     if self.streamlines is not None:
         return
     roi_r = Config.get_config().getint("CSDTracking", "autoResponseRoiRadius",
                                        fallback="10")
     fa_thr = Config.get_config().getfloat("CSDTracking", "autoResponseFaThreshold",
                                           fallback="0.7")
     response, _ = auto_response_ssst(self.data.gtab, self.data.dwi, roi_radii=roi_r, fa_thr=fa_thr)
     csd_model = ConstrainedSphericalDeconvModel(self.data.gtab, response)
     relative_peak_thr = Config.get_config().getfloat("CSDTracking", "relativePeakTreshold",
                                                      fallback="0.5")
     min_separation_angle = Config.get_config().getfloat("CSDTracking", "minimumSeparationAngle",
                                                         fallback="25")
     direction_getter = peaks_from_model(model=csd_model,
                                         data=self.data.dwi,
                                         sphere=get_sphere('symmetric724'),
                                         mask=self.data.binarymask,
                                         relative_peak_threshold=relative_peak_thr,
                                         min_separation_angle=min_separation_angle,
                                         parallel=False)
     dti_fit = dti.TensorModel(self.data.gtab, fit_method='LS')
     dti_fit = dti_fit.fit(self.data.dwi, mask=self.data.binarymask)
     self._track(ThresholdStoppingCriterion(dti_fit.fa, self.options.fa_threshold),
                 direction_getter)
     Cache.get_cache().set(self.id, self.streamlines)
Example #26
0
def test_diffusivities():
    psphere = get_sphere('symmetric362')
    bvecs = np.concatenate(([[0, 0, 0]], psphere.vertices))
    bvals = np.zeros(len(bvecs)) + 1000
    bvals[0] = 0
    gtab = grad.gradient_table(bvals, bvecs)
    mevals = np.array(([0.0015, 0.0003, 0.0001], [0.0015, 0.0003, 0.0003]))
    mevecs = [np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]),
              np.array([[0, 0, 1], [0, 1, 0], [1, 0, 0]])]
    S = single_tensor(gtab, 100, mevals[0], mevecs[0], snr=None)

    dm = dti.TensorModel(gtab, 'LS')
    dmfit = dm.fit(S)

    md = mean_diffusivity(dmfit.evals)
    Trace = trace(dmfit.evals)
    rd = radial_diffusivity(dmfit.evals)
    ad = axial_diffusivity(dmfit.evals)
    lin = linearity(dmfit.evals)
    plan = planarity(dmfit.evals)
    spher = sphericity(dmfit.evals)

    assert_almost_equal(md, (0.0015 + 0.0003 + 0.0001) / 3)
    assert_almost_equal(Trace, (0.0015 + 0.0003 + 0.0001))
    assert_almost_equal(ad, 0.0015)
    assert_almost_equal(rd, (0.0003 + 0.0001) / 2)
    assert_almost_equal(lin, (0.0015 - 0.0003)/Trace)
    assert_almost_equal(plan, 2 * (0.0003 - 0.0001)/Trace)
    assert_almost_equal(spher, (3 * 0.0001)/Trace)
Example #27
0
    def _run_interface(self, runtime):
        from dipy.reconst import dti
        from dipy.io.utils import nifti1_symmat
        gtab = self._get_gradient_table()

        img = nb.load(self.inputs.in_file)
        data = img.get_data()
        affine = img.affine
        mask = None
        if isdefined(self.inputs.mask_file):
            mask = nb.load(self.inputs.mask_file).get_data()

        # Fit it
        tenmodel = dti.TensorModel(gtab)
        ten_fit = tenmodel.fit(data, mask)
        lower_triangular = ten_fit.lower_triangular()
        img = nifti1_symmat(lower_triangular, affine)
        out_file = self._gen_filename('dti')
        nb.save(img, out_file)
        IFLOGGER.info('DTI parameters image saved as %s', out_file)

        # FA MD RD and AD
        for metric in ["fa", "md", "rd", "ad", "color_fa"]:
            data = getattr(ten_fit, metric).astype("float32")
            out_name = self._gen_filename(metric)
            nb.Nifti1Image(data, affine).to_filename(out_name)
            IFLOGGER.info('DTI %s image saved as %s', metric, out_name)

        return runtime
Example #28
0
    def _run_interface(self, runtime):
        from dipy.reconst import dti

        # Load the 4D image files
        img = nb.load(self.inputs.in_file)
        data = img.get_data()
        affine = img.affine

        # Load the gradient strengths and directions
        gtab = self._get_gradient_table()

        # Mask the data so that tensors are not fit for
        # unnecessary voxels
        mask = data[..., 0] > 50

        # Fit the tensors to the data
        tenmodel = dti.TensorModel(gtab)
        tenfit = tenmodel.fit(data, mask)

        # Calculate the mode of each voxel's tensor
        mode_data = tenfit.mode

        # Write as a 3D Nifti image with the original affine
        img = nb.Nifti1Image(mode_data, affine)
        out_file = self._gen_filename('mode')
        nb.save(img, out_file)
        IFLOGGER.info('Tensor mode image saved as %s', out_file)
        return runtime
def dMRI2ODF_DTI(PATH):
    '''
    Input the dMRI data
    return the ODF
    '''
    print(PATH)
    if os.path.exists(PATH + 'processed_data.npz'):
        return None
    dMRI_path = PATH + 'data.nii.gz'
    mask_path = PATH + 'nodif_brain_mask.nii.gz'
    dMRI_img = nib.load(dMRI_path)
    dMRI_data = dMRI_img.get_fdata()
    mask_img = nib.load(mask_path)
    mask = mask_img.get_fdata()

    ########## subsample ##########
    # in the main paper, to train the full 3D brain
    # We downsample the data into around 32x32x32
    # If not downsample, it can process the full-size brain image
    # but cannot fit into GPU memory
    dMRI_data = dMRI_data[::4, ::4, ::4, ...]
    mask = mask[::4, ::4, ::4, ...]

    bval = PATH + "bvals"
    bvec = PATH + "bvecs"

    radial_order = 6
    zeta = 700
    lambdaN = 1e-8
    lambdaL = 1e-8

    ###### process the ODF data ######
    # size is 32x32x32x(362)
    gtab = gradient_table(bvals=bval, bvecs=bvec)
    asm = ShoreModel(gtab,
                     radial_order=radial_order,
                     zeta=zeta,
                     lambdaN=lambdaN,
                     lambdaL=lambdaL)
    asmfit = asm.fit(dMRI_data, mask=mask)
    sphere = get_sphere('symmetric362')
    dMRI_odf = asmfit.odf(sphere)
    dMRI_odf[dMRI_odf <= 0] = 0  # remove the numerical issue

    ###### process the DTI data ######
    # size is 32x32x32x(3x3)
    tenmodel = dti.TensorModel(gtab)
    dMRI_dti = tenmodel.fit(dMRI_data, mask)
    dMRI_dti = dMRI_dti.quadratic_form

    name = PATH.split('/')[2]  # here, might be affected by the path
    # change the [2] here for the correct index
    np.savez(PATH + 'processed_data.npz',
             DTI=dMRI_dti,
             ODF=dMRI_odf,
             mask=mask,
             name=name)

    return None
Example #30
0
    def _init_odf(self):
        print("Initialising ODF")
        # fit DTI model to data
        if self.odf_mode == "DTI" or self.odf_mode == "CSD":
            if self.odf_mode == "DTI":
                print("DTI-based ODF computation")
                self.dti_model = dti.TensorModel(self.dataset.gtab,
                                                 fit_method='LS')
                self.dti_fit = self.dti_model.fit(
                    self.dataset.dwi, mask=self.dataset.binary_mask)
                # compute ODF
                odf = self.dti_fit.odf(self.sphere_odf)
            elif self.odf_mode == "CSD":
                print("CSD-based ODF computation")
                mask = mask_for_response_ssst(self.dataset.gtab,
                                              self.dataset.dwi,
                                              roi_radii=10,
                                              fa_thr=0.7)
                num_voxels = np.sum(mask)
                print(num_voxels)
                response, ratio = response_from_mask_ssst(
                    self.dataset.gtab, self.dataset.dwi, mask)
                print(response)
                self.dti_model = ConstrainedSphericalDeconvModel(
                    self.dataset.gtab, response)
                self.dti_fit = self.dti_model.fit(self.dataset.dwi)
                odf = self.dti_fit.odf(self.sphere_odf)

            # -- set up interpolator for odf evaluation
            x_range = np.arange(odf.shape[0])
            y_range = np.arange(odf.shape[1])
            z_range = np.arange(odf.shape[2])

            self.odf_interpolator = RegularGridInterpolator(
                (x_range, y_range, z_range), odf)

        elif self.odf_mode == "NN":
            print("Neural-Network-based ODF computation")
            print(
                "Warning: The currently used model was trained with 1x1x1 normalised and cropped DWI data from HCP."
            )
            print(
                "Only use this mode if you know that the model is compatible with the DWI data you are using"
            )
            script = torch.jit.load("1x1x1_model3.pt",
                                    map_location=self.device)

            def interpolate(coords_ijk):
                with torch.no_grad():
                    new_shape = (*coords_ijk.shape[:-1], -1)

                    dwi = torch.from_numpy(self.dataset.get_interpolated_dwi(self.dataset.to_ras(coords_ijk),
                                                                             postprocessing=Resample100()))\
                        .float().to(self.device)

                    odf_value = script(dwi).reshape(new_shape)
                    return odf_value.numpy()

            self.odf_interpolator = interpolate