Ejemplo n.º 1
0
def test_eig_from_lo_tri():
    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 = np.array([[single_tensor(gtab, 100, mevals[0], mevecs[0], snr=None),
                   single_tensor(gtab, 100, mevals[0], mevecs[0], snr=None)]])

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

    lo_tri = lower_triangular(dmfit.quadratic_form)
    assert_array_almost_equal(dti.eig_from_lo_tri(lo_tri), dmfit.model_params)
Ejemplo n.º 2
0
def test_eig_from_lo_tri():
    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 = np.array([[single_tensor(gtab, 100, mevals[0], mevecs[0], snr=None),
                   single_tensor(gtab, 100, mevals[0], mevecs[0], snr=None)]])

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

    lo_tri = lower_triangular(dmfit.quadratic_form)
    assert_array_almost_equal(dti.eig_from_lo_tri(lo_tri), dmfit.model_params)
Ejemplo n.º 3
0
def test_wmti_model_multi_voxel():
    # DKI fit
    dkiM = dki_micro.DiffusionKurtosisModel(gtab_2s, fit_method="WLS")
    dkiF = dkiM.fit(DWIsim)

    # Axonal Water Fraction
    sphere = get_sphere()
    AWF = dki_micro.axonal_water_fraction(dkiF.model_params,
                                          sphere,
                                          mask=None,
                                          gtol=1e-5)
    assert_almost_equal(AWF, FIE)

    # Extra-cellular and intra-cellular components
    edt, idt = dki_micro.diffusion_components(dkiF.model_params, sphere)
    EDT = eig_from_lo_tri(edt)
    IDT = eig_from_lo_tri(idt)

    # check eigenvalues
    assert_array_almost_equal(EDT[..., 0], ADE, decimal=3)
    assert_array_almost_equal(EDT[..., 1], RDE, decimal=3)
    assert_array_almost_equal(EDT[..., 2], RDE, decimal=3)
    assert_array_almost_equal(IDT[..., 0], ADI, decimal=3)
    assert_array_almost_equal(IDT[..., 1], RDI, decimal=3)
    assert_array_almost_equal(IDT[..., 2], RDI, decimal=3)

    # Test methods performance when a signal with all zeros is present
    FIEc = FIE.copy()
    RDIc = RDI.copy()
    ADIc = ADI.copy()
    ADEc = ADE.copy()
    Torc = Tor.copy()
    RDEc = RDE.copy()
    DWIsimc = DWIsim.copy()

    FIEc[0, 0, 0] = 0
    RDIc[0, 0, 0] = 0
    ADIc[0, 0, 0] = 0
    ADEc[0, 0, 0] = 0
    Torc[0, 0, 0] = 0
    RDEc[0, 0, 0] = 0
    DWIsimc[0, 0, 0, :] = 0
    mask = np.ones((2, 2, 2))
    mask[0, 0, 0] = 0

    dkiF = dkiM.fit(DWIsimc)
    awf = dki_micro.axonal_water_fraction(dkiF.model_params, sphere, gtol=1e-5)
    assert_almost_equal(awf, FIEc)

    # Extra-cellular and intra-cellular components
    edt, idt = dki_micro.diffusion_components(dkiF.model_params,
                                              sphere,
                                              awf=awf)
    EDT = eig_from_lo_tri(edt)
    IDT = eig_from_lo_tri(idt)
    assert_array_almost_equal(EDT[..., 0], ADEc, decimal=3)
    assert_array_almost_equal(EDT[..., 1], RDEc, decimal=3)
    assert_array_almost_equal(EDT[..., 2], RDEc, decimal=3)
    assert_array_almost_equal(IDT[..., 0], ADIc, decimal=3)
    assert_array_almost_equal(IDT[..., 1], RDIc, decimal=3)
    assert_array_almost_equal(IDT[..., 2], RDIc, decimal=3)

    # Check when mask is given
    dkiF = dkiM.fit(DWIsim)
    awf = dki_micro.axonal_water_fraction(dkiF.model_params,
                                          sphere,
                                          gtol=1e-5,
                                          mask=mask)
    assert_almost_equal(awf, FIEc, decimal=3)

    # Extra-cellular and intra-cellular components
    edt, idt = dki_micro.diffusion_components(dkiF.model_params,
                                              sphere,
                                              awf=awf,
                                              mask=mask)
    EDT = eig_from_lo_tri(edt)
    IDT = eig_from_lo_tri(idt)
    assert_array_almost_equal(EDT[..., 0], ADEc, decimal=3)
    assert_array_almost_equal(EDT[..., 1], RDEc, decimal=3)
    assert_array_almost_equal(EDT[..., 2], RDEc, decimal=3)
    assert_array_almost_equal(IDT[..., 0], ADIc, decimal=3)
    assert_array_almost_equal(IDT[..., 1], RDIc, decimal=3)
    assert_array_almost_equal(IDT[..., 2], RDIc, decimal=3)

    # Check class object
    wmtiM = dki_micro.KurtosisMicrostructureModel(gtab_2s, fit_method="WLS")
    wmtiF = wmtiM.fit(DWIsim, mask=mask)
    assert_almost_equal(wmtiF.awf, FIEc, decimal=3)
    assert_almost_equal(wmtiF.axonal_diffusivity, ADIc, decimal=3)
    assert_almost_equal(wmtiF.hindered_ad, ADEc, decimal=3)
    assert_almost_equal(wmtiF.hindered_rd, RDEc, decimal=3)
    assert_almost_equal(wmtiF.tortuosity, Torc, decimal=3)
Ejemplo n.º 4
0
def test_single_fiber_model():
    # single fiber simulate (which is the assumption of our model)
    fie = 0.49
    ADi = 0.00099
    ADe = 0.00226
    RDi = 0
    RDe = 0.00087

    # prepare simulation:
    theta = random.uniform(0, 180)
    phi = random.uniform(0, 320)
    angles = [(theta, phi), (theta, phi)]
    mevals = np.array([[ADi, RDi, RDi], [ADe, RDe, RDe]])
    frac = [fie * 100, (1 - fie) * 100]
    signal, dt, kt = multi_tensor_dki(gtab_2s,
                                      mevals,
                                      angles=angles,
                                      fractions=frac,
                                      snr=None)
    # DKI fit
    dkiM = dki_micro.DiffusionKurtosisModel(gtab_2s, fit_method="WLS")
    dkiF = dkiM.fit(signal)

    # Axonal Water Fraction
    sphere = get_sphere('symmetric724')
    AWF = dki_micro.axonal_water_fraction(dkiF.model_params,
                                          sphere,
                                          mask=None,
                                          gtol=1e-5)
    assert_almost_equal(AWF, fie)

    # Extra-cellular and intra-cellular components
    edt, idt = dki_micro.diffusion_components(dkiF.model_params, sphere)
    EDT = eig_from_lo_tri(edt)
    IDT = eig_from_lo_tri(idt)

    # check eigenvalues
    assert_array_almost_equal(EDT[0:3], np.array([ADe, RDe, RDe]))
    assert_array_almost_equal(IDT[0:3], np.array([ADi, RDi, RDi]))
    # first eigenvalue should be the direction of the fibers
    fiber_direction = _check_directions([(theta, phi)])
    f_norm = abs(np.dot(fiber_direction, np.array((EDT[3], EDT[6], EDT[9]))))
    assert_almost_equal(f_norm, 1.)
    f_norm = abs(np.dot(fiber_direction, np.array((IDT[3], IDT[6], IDT[9]))))
    assert_almost_equal(f_norm, 1.)

    # Test model and fit objects
    wmtiM = dki_micro.KurtosisMicrostructureModel(gtab_2s, fit_method="WLS")
    wmtiF = wmtiM.fit(signal)
    assert_almost_equal(wmtiF.awf, AWF)
    assert_array_almost_equal(wmtiF.hindered_evals, np.array([ADe, RDe, RDe]))
    assert_array_almost_equal(wmtiF.restricted_evals, np.array([ADi, RDi,
                                                                RDi]))
    assert_almost_equal(wmtiF.hindered_ad, ADe)
    assert_almost_equal(wmtiF.hindered_rd, RDe)
    assert_almost_equal(wmtiF.axonal_diffusivity, ADi)
    assert_almost_equal(wmtiF.tortuosity, ADe / RDe, decimal=4)

    # Test diffusion_components when a kurtosis tensors is associated with
    # negative kurtosis values. E.g of this cases is given below:
    dkiparams = np.array([
        1.67135726e-03, 5.03651205e-04, 9.35365328e-05, -7.11167583e-01,
        6.23186820e-01, -3.25390313e-01, -1.75247376e-02, -4.78415563e-01,
        -8.77958674e-01, 7.02804064e-01, 6.18673368e-01, -3.51154825e-01,
        2.18384153, -2.76378153e-02, 2.22893297, -2.68306546e-01, -1.28411610,
        -1.56557645e-01, -1.80850619e-01, -8.33152110e-01, -3.62410766e-01,
        1.57775442e-01, 8.73775381e-01, 2.77188975e-01, -3.67415502e-02,
        -1.56330984e-01, -1.62295407e-02
    ])
    edt, idt = dki_micro.diffusion_components(dkiparams)
    assert_(np.all(np.isfinite(edt)))
Ejemplo n.º 5
0
def initial_fit(dwis,
                bvals,
                bvecs,
                mask,
                wm_roi,
                csf_roi,
                MD,
                csf_percentile=95,
                wm_percentile=5,
                lmin=0.1e-3,
                lmax=2.5e-3,
                evals_lmin=0.1e-3,
                evals_lmax=2.5e-3,
                md_value=0.6e-3,
                interpolate=True,
                fixed_MD=False):
    '''
    Produce the initial estimate of the volume fraction and the initial tensor image
    '''
    print(" - Compute baseline image and DW attenuation.")
    dim_x, dim_y, dim_z = mask.shape
    indices_dwis = (bvals > 0)
    nb_dwis = np.count_nonzero(indices_dwis)
    indices_b0 = (bvals == 0)
    nb_b0 = np.count_nonzero(indices_b0)
    # TO DO : address this line for multi-shell dwi
    b = bvals.max()
    b0 = dwis[..., indices_b0].mean(-1)
    # signal attenuation
    signal = dwis[..., indices_dwis] / b0[..., None]
    np.clip(signal, 1.0e-6, 1 - 1.0e-6, signal)
    signal[np.logical_not(mask)] = 0.
    # tissue b0 references
    csf_b0 = np.percentile(b0[csf_roi], csf_percentile)
    print("\t{0:2d}th percentile of b0 signal in CSF: {1}.".format(
        csf_percentile, csf_b0))
    wm_b0 = np.percentile(b0[wm_roi], wm_percentile)
    print("\t{0:2d}th percentile of b0 signal in WM : {1}.".format(
        wm_percentile, wm_b0))

    print(" - Compute initial volume fraction ...")
    # Eq. 7 from Pasternak 2009 MRM
    epsi = 1e-12  # only used to prevent log(0)
    init_f = 1 - np.log(b0 / wm_b0 + epsi) / np.log(csf_b0 / wm_b0)
    np.clip(init_f, 0.0, 1.0, init_f)
    alpha = init_f.copy()  # exponent for interpolation

    print(" - Compute fixed MD VF map")
    init_f_MD = (np.exp(-b * MD) - np.exp(-b * d)) / (np.exp(-b * md_value) -
                                                      np.exp(-b * d))
    np.clip(init_f_MD, 0.01, 0.99, init_f_MD)

    print(" - Compute min_f and max_f from lmin, lmax")
    ### This was following Pasternak 2009 although with an error
    ### Amin = exp(-b*lmax)   and Amax = exp(-b*lmin)  in that paper
    # min_f = (signal.min(-1)-np.exp(-b*d)) / (np.exp(-b*lmin)-np.exp(-b*d))
    # max_f = (signal.max(-1)-np.exp(-b*d)) / (np.exp(-b*lmax)-np.exp(-b*d))
    ### From Pasternak 2009 method, Amin < At implies that the
    ### term with signal.min(-1) in numerator is the upper bound of f
    ### although in that paper the equation 6 has fmin and fmax reversed.
    ### With lmin, lmax=0.1e-3, 2.5e-3, Amin = 0.08, Awater = 0.04
    ### and one can see that max_f here will usually be >> 1
    min_f = (signal.max(-1) - np.exp(-b * d)) / (np.exp(-b * lmin) -
                                                 np.exp(-b * d))
    max_f = (signal.min(-1) - np.exp(-b * d)) / (np.exp(-b * lmax) -
                                                 np.exp(-b * d))
    # If MD of a voxel is > 3.0e-3, min_f and max_f can be negative.
    # These voxels should be initialized as 0
    np.clip(min_f, 0.0, 1.0, min_f)
    np.clip(max_f, 0.0, 1.0, max_f)
    np.clip(init_f, min_f, max_f, init_f)

    if interpolate:
        print(" - Interpolate two estimates of volume fraction")
        # f = tissue fraction. with init_f high, alpha will be ~1 and init_f_MD will be weighted
        init_f = (np.power(init_f, (1 - alpha))) * (np.power(init_f_MD, alpha))
    elif fixed_MD:
        print(
            " - Using fixed MD value of {0} for inital volume fraction".format(
                md_value))
        init_f = init_f_MD
    else:
        print(" - Using lmin and lmax for initial volume fraction")

    np.clip(init_f, 0.05, 0.99, init_f)  # want minimum 5% of tissue
    init_f[np.isnan(init_f)] = 0.5
    init_f[np.logical_not(mask)] = 0.5

    print(" - Compute initial tissue tensor ...")
    signal[np.isnan(signal)] = 0
    bvecs = bvecs[indices_dwis]
    bvals = bvals[indices_dwis]
    signal_free_water = np.exp(-bvals * d)
    corrected_signal = (signal - (1 - init_f[..., np.newaxis]) \
                     * signal_free_water[np.newaxis, np.newaxis, np.newaxis, :]) \
                     / (init_f[..., np.newaxis])
    np.clip(corrected_signal, 1.0e-3, 1. - 1.0e-3, corrected_signal)
    log_signal = np.log(corrected_signal)
    gtab = gradient_table_from_bvals_bvecs(bvals, bvecs)
    H = dti.design_matrix(gtab)[:, :6]
    pseudo_inv = np.dot(np.linalg.inv(np.dot(H.T, H)), H.T)
    init_tensor = np.dot(log_signal, pseudo_inv.T)

    dti_params = dti.eig_from_lo_tri(init_tensor).reshape(
        (dim_x, dim_y, dim_z, 4, 3))
    evals = dti_params[..., 0, :]
    evecs = dti_params[..., 1:, :]
    if evals_lmin > 0.1e-3:
        print(" - Fatten tensor to {}".format(evals_lmin))
    lower_triangular = clip_tensor_evals(evals, evecs, evals_lmin, evals_lmax)
    lower_triangular[np.logical_not(mask)] = [
        evals_lmin, 0, evals_lmin, 0, 0, evals_lmin
    ]
    nan_mask = np.any(np.isnan(lower_triangular), axis=-1)
    lower_triangular[nan_mask] = [evals_lmin, 0, evals_lmin, 0, 0, evals_lmin]

    init_tensor = lower_triangular[:, :, :, np.newaxis, :]
    return init_f, init_tensor
Ejemplo n.º 6
0
def gradient_descent(dwis, bvals, bvecs, mask, init_f, init_tensor, niters=50):
    '''
    Optimize the volume fraction and the tensor via gradient descent.
    '''
    dim_x, dim_y, dim_z = mask.shape
    indices_dwis = (bvals > 0)
    nb_dwis = np.count_nonzero(indices_dwis)
    indices_b0 = (bvals == 0)
    nb_b0 = np.count_nonzero(indices_b0)
    b = bvals.max()
    b0 = dwis[..., indices_b0].mean(-1)
    signal = dwis[..., indices_dwis] / b0[..., None]
    np.clip(signal, 1.0e-6, 1 - 1.0e-6, signal)
    bvals = bvals[indices_dwis]
    bvecs = bvecs[indices_dwis]
    gtab = gradient_table_from_bvals_bvecs(bvals, bvecs)
    H = dti.design_matrix(gtab)[:, :6]
    signal[np.logical_not(mask)] = 0.
    signal = signal[mask]
    lower_triangular = init_tensor[mask, 0]
    volume_fraction = init_f[mask]
    print(" - Begin gradient descent.")
    mask_nvoxels = np.count_nonzero(mask)
    step_size = 1.0e-7
    weight = 100.0
    l_min_loop, l_max_loop = 0.1e-3, 2.5e-3

    for i in range(niters):
        print(" - Iteration {0:d} out of {1:d}.".format(i + 1, niters))

        grad1, predicted_signal_tissue, predicted_signal_water = \
            grad_data_fit_tensor(lower_triangular, signal, H, bvals,
                                 volume_fraction)
        print("\tgrad1 avg: {0:0.4e}".format(np.mean(np.abs(grad1))))
        predicted_signal = volume_fraction[..., None] * predicted_signal_tissue + \
                           (1-volume_fraction[..., None]) * predicted_signal_water
        prediction_error = np.sqrt(((predicted_signal - signal)**2).mean(-1))
        print("\tpref error avg: {0:0.4e}".format(np.mean(prediction_error)))

        gradf = (bvals * (predicted_signal - signal) \
                           * (predicted_signal_tissue - predicted_signal_water)).sum(-1)
        print("\tgradf avg: {0:0.4e}".format(np.mean(np.abs(gradf))))
        volume_fraction -= weight * step_size * gradf

        grad1[np.isnan(grad1)] = 0
        # np.clip(grad1, -1.e5, 1.e5, grad1)
        np.clip(volume_fraction, 0.01, 0.99, volume_fraction)
        lower_triangular -= step_size * grad1
        lower_triangular[np.isnan(lower_triangular)] = 0

        dti_params = dti.eig_from_lo_tri(lower_triangular).reshape(
            (mask_nvoxels, 4, 3))
        evals = dti_params[..., 0, :]
        evecs = dti_params[..., 1:, :]
        lower_triangular = clip_tensor_evals(evals, evecs, l_min_loop,
                                             l_max_loop)
        del dti_params, evals, evecs

    final_tensor = np.zeros((dim_x, dim_y, dim_z, 1, 6), dtype=np.float32)
    final_tensor[mask, 0] = lower_triangular
    final_f = np.zeros((dim_x, dim_y, dim_z), dtype=np.float32)
    final_f[mask] = 1 - volume_fraction

    return final_f, final_tensor
Ejemplo n.º 7
0
def test_single_fiber_model():
    # single fiber simulate (which is the assumption of our model)
    fie = 0.49
    ADi = 0.00099
    ADe = 0.00226
    RDi = 0
    RDe = 0.00087

    # prepare simulation:
    theta = random.uniform(0, 180)
    phi = random.uniform(0, 320)
    angles = [(theta, phi), (theta, phi)]
    mevals = np.array([[ADi, RDi, RDi], [ADe, RDe, RDe]])
    frac = [fie*100, (1 - fie)*100]
    signal, dt, kt = multi_tensor_dki(gtab_2s, mevals, angles=angles,
                                      fractions=frac, snr=None)
    # DKI fit
    dkiM = dki_micro.DiffusionKurtosisModel(gtab_2s, fit_method="WLS")
    dkiF = dkiM.fit(signal)

    # Axonal Water Fraction
    sphere = get_sphere('symmetric724')
    AWF = dki_micro.axonal_water_fraction(dkiF.model_params, sphere, mask=None,
                                          gtol=1e-5)
    assert_almost_equal(AWF, fie)

    # Extra-cellular and intra-cellular components
    edt, idt = dki_micro.diffusion_components(dkiF.model_params, sphere)
    EDT = eig_from_lo_tri(edt)
    IDT = eig_from_lo_tri(idt)

    # check eigenvalues
    assert_array_almost_equal(EDT[0:3], np.array([ADe, RDe, RDe]))
    assert_array_almost_equal(IDT[0:3], np.array([ADi, RDi, RDi]))
    # first eigenvalue should be the direction of the fibers
    fiber_direction = _check_directions([(theta, phi)])
    f_norm = abs(np.dot(fiber_direction, np.array((EDT[3], EDT[6], EDT[9]))))
    assert_almost_equal(f_norm, 1.)
    f_norm = abs(np.dot(fiber_direction, np.array((IDT[3], IDT[6], IDT[9]))))
    assert_almost_equal(f_norm, 1.)

    # Test model and fit objects
    wmtiM = dki_micro.KurtosisMicrostructureModel(gtab_2s, fit_method="WLS")
    wmtiF = wmtiM.fit(signal)
    assert_almost_equal(wmtiF.awf, AWF)
    assert_array_almost_equal(wmtiF.hindered_evals,
                              np.array([ADe, RDe, RDe]))
    assert_array_almost_equal(wmtiF.restricted_evals,
                              np.array([ADi, RDi, RDi]))
    assert_almost_equal(wmtiF.hindered_ad, ADe)
    assert_almost_equal(wmtiF.hindered_rd, RDe)
    assert_almost_equal(wmtiF.axonal_diffusivity, ADi)
    assert_almost_equal(wmtiF.tortuosity, ADe/RDe, decimal=4)

    # Test diffusion_components when a kurtosis tensors is associated with
    # negative kurtosis values. E.g of this cases is given below:
    dkiparams = np.array([1.67135726e-03, 5.03651205e-04, 9.35365328e-05,
                          -7.11167583e-01, 6.23186820e-01, -3.25390313e-01,
                          -1.75247376e-02, -4.78415563e-01, -8.77958674e-01,
                          7.02804064e-01, 6.18673368e-01, -3.51154825e-01,
                          2.18384153, -2.76378153e-02, 2.22893297,
                          -2.68306546e-01, -1.28411610, -1.56557645e-01,
                          -1.80850619e-01, -8.33152110e-01, -3.62410766e-01,
                          1.57775442e-01, 8.73775381e-01, 2.77188975e-01,
                          -3.67415502e-02, -1.56330984e-01, -1.62295407e-02])
    edt, idt = dki_micro.diffusion_components(dkiparams)
    assert_(np.all(np.isfinite(edt)))
Ejemplo n.º 8
0
def test_wmti_model_multi_voxel():
    # DKI fit
    dkiM = dki_micro.DiffusionKurtosisModel(gtab_2s, fit_method="WLS")
    dkiF = dkiM.fit(DWIsim)

    # Axonal Water Fraction
    sphere = get_sphere()
    AWF = dki_micro.axonal_water_fraction(dkiF.model_params, sphere, mask=None,
                                          gtol=1e-5)
    assert_almost_equal(AWF, FIE)

    # Extra-cellular and intra-cellular components
    edt, idt = dki_micro.diffusion_components(dkiF.model_params, sphere)
    EDT = eig_from_lo_tri(edt)
    IDT = eig_from_lo_tri(idt)

    # check eigenvalues
    assert_array_almost_equal(EDT[..., 0], ADE, decimal=3)
    assert_array_almost_equal(EDT[..., 1], RDE, decimal=3)
    assert_array_almost_equal(EDT[..., 2], RDE, decimal=3)
    assert_array_almost_equal(IDT[..., 0], ADI, decimal=3)
    assert_array_almost_equal(IDT[..., 1], RDI, decimal=3)
    assert_array_almost_equal(IDT[..., 2], RDI, decimal=3)

    # Test methods performance when a signal with all zeros is present
    FIEc = FIE.copy()
    RDIc = RDI.copy()
    ADIc = ADI.copy()
    ADEc = ADE.copy()
    Torc = Tor.copy()
    RDEc = RDE.copy()
    DWIsimc = DWIsim.copy()

    FIEc[0, 0, 0] = 0
    RDIc[0, 0, 0] = 0
    ADIc[0, 0, 0] = 0
    ADEc[0, 0, 0] = 0
    Torc[0, 0, 0] = 0
    RDEc[0, 0, 0] = 0
    DWIsimc[0, 0, 0, :] = 0
    mask = np.ones((2, 2, 2))
    mask[0, 0, 0] = 0

    dkiF = dkiM.fit(DWIsimc)
    awf = dki_micro.axonal_water_fraction(dkiF.model_params, sphere,
                                          gtol=1e-5)
    assert_almost_equal(awf, FIEc)

    # Extra-cellular and intra-cellular components
    edt, idt = dki_micro.diffusion_components(dkiF.model_params, sphere,
                                              awf=awf)
    EDT = eig_from_lo_tri(edt)
    IDT = eig_from_lo_tri(idt)
    assert_array_almost_equal(EDT[..., 0], ADEc, decimal=3)
    assert_array_almost_equal(EDT[..., 1], RDEc, decimal=3)
    assert_array_almost_equal(EDT[..., 2], RDEc, decimal=3)
    assert_array_almost_equal(IDT[..., 0], ADIc, decimal=3)
    assert_array_almost_equal(IDT[..., 1], RDIc, decimal=3)
    assert_array_almost_equal(IDT[..., 2], RDIc, decimal=3)

    # Check when mask is given
    dkiF = dkiM.fit(DWIsim)
    awf = dki_micro.axonal_water_fraction(dkiF.model_params, sphere,
                                          gtol=1e-5, mask=mask)
    assert_almost_equal(awf, FIEc, decimal=3)

    # Extra-cellular and intra-cellular components
    edt, idt = dki_micro.diffusion_components(dkiF.model_params, sphere,
                                              awf=awf, mask=mask)
    EDT = eig_from_lo_tri(edt)
    IDT = eig_from_lo_tri(idt)
    assert_array_almost_equal(EDT[..., 0], ADEc, decimal=3)
    assert_array_almost_equal(EDT[..., 1], RDEc, decimal=3)
    assert_array_almost_equal(EDT[..., 2], RDEc, decimal=3)
    assert_array_almost_equal(IDT[..., 0], ADIc, decimal=3)
    assert_array_almost_equal(IDT[..., 1], RDIc, decimal=3)
    assert_array_almost_equal(IDT[..., 2], RDIc, decimal=3)

    # Check class object
    wmtiM = dki_micro.KurtosisMicrostructureModel(gtab_2s, fit_method="WLS")
    wmtiF = wmtiM.fit(DWIsim, mask=mask)
    assert_almost_equal(wmtiF.awf, FIEc, decimal=3)
    assert_almost_equal(wmtiF.axonal_diffusivity, ADIc, decimal=3)
    assert_almost_equal(wmtiF.hindered_ad, ADEc, decimal=3)
    assert_almost_equal(wmtiF.hindered_rd, RDEc, decimal=3)
    assert_almost_equal(wmtiF.tortuosity, Torc, decimal=3)
Ejemplo n.º 9
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()

        if self.inputs.lower_triangular_input:
            try:
                dti_params = dti.eig_from_lo_tri(data)
            except:
                dti_params = dti.tensor_eig_from_lo_tri(data)

        else:
            data = np.asarray(data)
            data_flat = data.reshape((-1, data.shape[-1]))
            dti_params = np.empty((len(data_flat), 4, 3))

            for ii in range(len(data_flat)):
                tensor = from_upper_triangular(data_flat[ii])
                evals, evecs = dti.decompose_tensor(tensor)
                dti_params[ii, 0] = evals
                dti_params[ii, 1:] = evecs

            dti_params.shape = data.shape[:-1] + (12, )

        evals = dti_params[..., :3]
        evecs = dti_params[..., 3:]

        evecs = evecs.reshape(np.shape(evecs)[:3] + (3, 3))

        # Estimate electrical conductivity

        evals = abs(self.inputs.eigenvalue_scaling_factor * evals)

        if self.inputs.volume_normalized_mapping:
            # Calculate the cube root of the product of the three eigenvalues (for
            # normalization)
            denominator = np.power(
                (evals[..., 0] * evals[..., 1] * evals[..., 2]), (1 / 3))
            # Calculate conductivity and normalize the eigenvalues
            evals = self.inputs.sigma_white_matter * evals / denominator
            evals[denominator < 0.0001] = self.inputs.sigma_white_matter

        # Threshold outliers that show unusually high conductivity
        if self.inputs.use_outlier_correction:
            evals[evals > 0.4] = 0.4

        conductivity_quadratic = np.array(vec_val_vect(evecs, evals))

        if self.inputs.lower_triangular_output:
            conductivity_data = dti.lower_triangular(conductivity_quadratic)
        else:
            conductivity_data = upper_triangular(conductivity_quadratic)

        # Write as a 4D Nifti tensor image with the original affine
        img = nb.Nifti1Image(conductivity_data, affine=affine)
        out_file = op.abspath(self._gen_outfilename())
        nb.save(img, out_file)
        IFLOGGER.info(
            'Conductivity tensor image saved as {i}'.format(i=out_file))
        return runtime