Beispiel #1
0
    def shore_convolution_matrix(self, kernel="rank1"):
        """

        Parameters
        ----------
        kernel

        Returns
        -------

        """
        if self.kernel_type != kernel:
            self.set_kernel(kernel)


        # Build matrix that maps ODF+volume fractions to signal
        # in two steps: First, SHORE matrix

        # Ignore division by zero warning
        # dipy.core.geometry.cart2sphere -> theta = np.arccos(z / r)
        with np.errstate(divide='ignore', invalid='ignore'):
            shore_m = shore_matrix(self.order, self.zeta, self.gtab, self.tau)

        # then, convolution
        M_wm = shore.matrix_kernel(self.kernel_wm, self.order)
        M_gm = shore.matrix_kernel(self.kernel_gm, self.order)
        M_csf = shore.matrix_kernel(self.kernel_csf, self.order)
        M = np.hstack((M_wm, M_gm[:, :1], M_csf[:, :1]))

        # now, multiply them together
        return np.dot(shore_m, M)
Beispiel #2
0
    def _fit_helper(self, data, vecs=None, rcond=None, **kwargs):
        """ Fitting is done here

        This function is handed to the MultivoxelFitter, to fit deconv for
        every voxel.

        Parameters
        ----------
        data : ndarray (n)
            Data of a single voxel
        vecs : ndarray (3)
             First eigenvector of the diffusion tensor for a single voxel
        rcond :
            Cut-off ratio for small singular values of the coefficient matrix.
            For further information read documentation of numpy.linalg.lstsq.
        kwargs : dict
            Empty dictionary, not used in this function

        Returns
        -------
        ShoreFit
            Object holding the fitted model parameters

        """

        if vecs is not None:
            with np.errstate(divide='ignore', invalid='ignore'):
                shore_m = shore_matrix(self.order, self.zeta,
                                       gtab_reorient(self.gtab, vecs),
                                       self.tau)

        else:
            shore_m = self.shore_m
        coeffs = la.lstsq(shore_m, data, rcond)[0]
        return ShoreFit(np.array(coeffs))
Beispiel #3
0
    def __init__(self, gtab, order=4, zeta=700, tau=1 / (4 * np.pi ** 2)):
        """ Model the diffusion imaging signal using the shore basis

        Parameters
        ----------
        gtab : dipy.data.GradientTable
            b-values and b-vectors in a GradientTable object
        order : int
            An even integer representing the order of the shore basis
        zeta : float
            Radial scaling factor
        tau : float
            Diffusion time
        """

        super().__init__(gtab)
        self.order = order
        self.zeta = zeta
        self.tau = tau

        # These parameters are saved for reinitalization
        self._params_dict = {'bvals': gtab.bvals, 'bvecs': gtab.bvecs,
                             'order': order, 'zeta': zeta, 'tau': tau}

        # Ignore division by zero warning
        # dipy.core.geometry.cart2sphere -> theta = np.arccos(z / r)
        with np.errstate(divide='ignore', invalid='ignore'):
            self.shore_m = shore_matrix(self.order, self.zeta, self.gtab,
                                        self.tau)
Beispiel #4
0
def return_shore_basis(n,gtab,scale):
    lambdaN = 1e-8
    lambdaL = 1e-8
    radial_order = n

    Lshore = l_shore(radial_order)
    Nshore = n_shore(radial_order)

    M = shore_matrix(n, scale, gtab, 1. / (4 * np.pi ** 2))
    return M
Beispiel #5
0
    def get_shore_coeffs(D, n, scale, input_gtab):
        lambdaN = 1e-8
        lambdaL = 1e-8
        radial_order = n

        Lshore = l_shore(radial_order)
        Nshore = n_shore(radial_order)

        M = shore_matrix(n, scale, input_gtab, 1. / (4 * np.pi ** 2))
        MpseudoInv = np.dot(np.linalg.inv(np.dot(M.T, M) + lambdaN * Nshore + lambdaL * Lshore), M.T)
        shorecoefs = np.dot(D, MpseudoInv.T)
        return shorecoefs
Beispiel #6
0
def test_shore_odf():
    gtab = get_isbi2013_2shell_gtab()

    # load repulsion 724 sphere
    sphere = default_sphere

    # load icosahedron sphere
    sphere2 = create_unit_sphere(5)
    data, golden_directions = sticks_and_ball(gtab,
                                              d=0.0015,
                                              S0=100,
                                              angles=[(0, 0), (90, 0)],
                                              fractions=[50, 50],
                                              snr=None)
    asm = ShoreModel(gtab,
                     radial_order=6,
                     zeta=700,
                     lambdaN=1e-8,
                     lambdaL=1e-8)
    # repulsion724
    asmfit = asm.fit(data)
    odf = asmfit.odf(sphere)
    odf_sh = asmfit.odf_sh()
    odf_from_sh = sh_to_sf(odf_sh, sphere, 6, basis_type=None, legacy=True)
    npt.assert_almost_equal(odf, odf_from_sh, 10)

    expected_phi = shore_matrix(radial_order=6, zeta=700, gtab=gtab)
    npt.assert_array_almost_equal(np.dot(expected_phi, asmfit.shore_coeff),
                                  asmfit.fitted_signal())

    directions, _, _ = peak_directions(odf, sphere, .35, 25)
    npt.assert_equal(len(directions), 2)
    npt.assert_almost_equal(angular_similarity(directions, golden_directions),
                            2, 1)

    # 5 subdivisions
    odf = asmfit.odf(sphere2)
    directions, _, _ = peak_directions(odf, sphere2, .35, 25)
    npt.assert_equal(len(directions), 2)
    npt.assert_almost_equal(angular_similarity(directions, golden_directions),
                            2, 1)

    sb_dummies = sticks_and_ball_dummies(gtab)
    for sbd in sb_dummies:
        data, golden_directions = sb_dummies[sbd]
        asmfit = asm.fit(data)
        odf = asmfit.odf(sphere2)
        directions, _, _ = peak_directions(odf, sphere2, .35, 25)
        if len(directions) <= 3:
            npt.assert_equal(len(directions), len(golden_directions))
        if len(directions) > 3:
            npt.assert_equal(gfa(odf) < 0.1, True)
Beispiel #7
0
def eval_minimized_zeta(D, n, gtab, scale):
    lambdaN = 1e-8
    lambdaL = 1e-8
    radial_order = n

    Lshore = l_shore(radial_order)
    Nshore = n_shore(radial_order)

    M = shore_matrix(n, scale, gtab, 1. / (4 * np.pi ** 2))
    MpseudoInv = np.dot(np.linalg.inv(np.dot(M.T, M) + lambdaN * Nshore + lambdaL * Lshore), M.T)
    shorecoefs = np.dot(D, MpseudoInv.T)

    # shorecoefs = np.dot(D, pinv(Mshore).T)
    shorepred = np.dot(shorecoefs, M.T)
    return np.linalg.norm(D - shorepred) ** 2
Beispiel #8
0
    def eval_shore(D, n, scale, input_gtab):
        lambdaN = 1e-8
        lambdaL = 1e-8
        radial_order = n

        Lshore = l_shore(radial_order)
        Nshore = n_shore(radial_order)

        M_1 = shore_matrix(n, scale, input_gtab, 1. / (4 * np.pi ** 2))
        #M_2 = shore_matrix(n, scale, prov_gtab_1, 1. / (4 * np.pi ** 2))

        MpseudoInv_1 = np.dot(np.linalg.inv(np.dot(M_1.T, M_1) + lambdaN * Nshore + lambdaL * Lshore), M_1.T)
        #MpseudoInv_2 = np.dot(np.linalg.inv(np.dot(M_2.T, M_2) + lambdaN * Nshore + lambdaL * Lshore), M_2.T)

        shorecoefs_1 = np.dot(D, MpseudoInv_1.T)
        #shorecoefs_2 = np.dot(D, MpseudoInv_2.T)

        # shorecoefs = np.dot(D, pinv(Mshore).T)
        shorepred_1 = np.dot(shorecoefs_1, M_1.T)
        #shorepred_2 = np.dot(shorecoefs_2, M_2.T)

        '''
        plt.figure(1, figsize=(12,8))
        plt.subplot(2,3,1)
        plt.plot(D[0, :])
        plt.plot(shorepred[0, :])
        plt.legend(['Original Signal','SHORE Fitted Signal'])

        plt.subplot(2,3,2)
        plt.plot(D[1, :])
        plt.plot(shorepred[1, :])

        plt.subplot(2,3,3)
        plt.plot(D[2, :])
        plt.plot(shorepred[2, :])

        plt.subplot(2,3,4)
        plt.plot(D[3, :])
        plt.plot(shorepred[3, :])

        plt.subplot(2,3,5)
        plt.plot(D[4, :])
        plt.plot(shorepred[4, :])
        plt.show()
        '''
        return np.linalg.norm(D - shorepred_1) ** 2
def eval_shore(D, n, scale):
    lambdaN = 1e-8
    lambdaL = 1e-8
    radial_order = n

    Lshore = l_shore(radial_order)
    Nshore = n_shore(radial_order)

    M = shore_matrix(n, scale, fod_gtab)
    MpseudoInv = np.dot(
        np.linalg.inv(np.dot(M.T, M) + lambdaN * Nshore + lambdaL * Lshore),
        M.T)
    shorecoefs = np.dot(D, MpseudoInv.T)
    shorepred = np.dot(shorecoefs, M.T)

    D = np.exp(D)
    shorepred = np.exp(shorepred)

    return np.linalg.norm(D - shorepred)**2
Beispiel #10
0
    def __init__(self, gtab, order=4, zeta=700, tau=1 / (4 * np.pi ** 2)):
        """

        Parameters
        ----------
        gtab : dipy.data.GradientTable
            b-values and b-vectors in a GradientTable object
        order : int
            An even integer representing the order of the shore basis
        zeta : float
            Radial scaling factor
        tau : float
            Diffusion time
        """
        self.gtab = gtab
        self.order = order
        self.zeta = zeta
        self.tau = tau

        # Ignore division by zero warning
        # dipy.core.geometry.cart2sphere -> theta = np.arccos(z / r)
        with np.errstate(divide='ignore', invalid='ignore'):
            self.shore_m = shore_matrix(self.order, self.zeta, self.gtab,
                                        self.tau)
def test_shore_metrics():
    gtab = get_gtab_taiwan_dsi()
    mevals = np.array(([0.0015, 0.0003, 0.0003],
                       [0.0015, 0.0003, 0.0003]))
    angl = [(0, 0), (60, 0)]
    S, sticks = MultiTensor(gtab, mevals, S0=100.0, angles=angl,
                            fractions=[50, 50], snr=None)

    # test shore_indices
    n = 7
    l = 6
    m = -4
    radial_order, c = shore_order(n, l, m)
    n2, l2, m2 = shore_indices(radial_order, c)
    assert_equal(n, n2)
    assert_equal(l, l2)
    assert_equal(m, m2)

    radial_order = 6
    c = 41
    n, l, m = shore_indices(radial_order, c)
    radial_order2, c2 = shore_order(n, l, m)
    assert_equal(radial_order, radial_order2)
    assert_equal(c, c2)

    # since we are testing without noise we can use higher order and lower lambdas, with respect to the default.
    radial_order = 8
    zeta = 700
    lambdaN = 1e-12
    lambdaL = 1e-12
    asm = ShoreModel(gtab, radial_order=radial_order,
                     zeta=zeta, lambdaN=lambdaN, lambdaL=lambdaL)
    asmfit = asm.fit(S)
    c_shore = asmfit.shore_coeff

    cmat = shore_matrix(radial_order, zeta, gtab)
    S_reconst = np.dot(cmat, c_shore)

    # test the signal reconstruction
    S = S / S[0]
    nmse_signal = np.sqrt(np.sum((S - S_reconst) ** 2)) / (S.sum())
    assert_almost_equal(nmse_signal, 0.0, 4)

    # test if the analytical integral of the pdf is equal to one
    integral = 0
    for n in range(int((radial_order)/2 +1)):
        integral += c_shore[n] * (np.pi**(-1.5) * zeta **(-1.5) * genlaguerre(n,0.5)(0)) ** 0.5

    assert_almost_equal(integral, 1.0, 10)

    # test if the integral of the pdf calculated on a discrete grid is equal to one
    pdf_discrete = asmfit.pdf_grid(17, 40e-3)
    integral = pdf_discrete.sum()
    assert_almost_equal(integral, 1.0, 1)

    # compare the shore pdf with the ground truth multi_tensor pdf

    sphere = get_sphere('symmetric724')
    v = sphere.vertices
    radius = 10e-3
    pdf_shore = asmfit.pdf(v * radius)
    pdf_mt = multi_tensor_pdf(v * radius, mevals=mevals,
                              angles=angl, fractions= [50, 50])
    nmse_pdf = np.sqrt(np.sum((pdf_mt - pdf_shore) ** 2)) / (pdf_mt.sum())
    assert_almost_equal(nmse_pdf, 0.0, 2)

    # compare the shore rtop with the ground truth multi_tensor rtop
    rtop_shore_signal = asmfit.rtop_signal()
    rtop_shore_pdf = asmfit.rtop_pdf()
    assert_almost_equal(rtop_shore_signal, rtop_shore_pdf, 9)
    rtop_mt = multi_tensor_rtop([.5, .5], mevals=mevals)
    assert_equal(rtop_mt / rtop_shore_signal <1.10 and rtop_mt / rtop_shore_signal > 0.95, True)

    # compare the shore msd with the ground truth multi_tensor msd
    msd_mt = multi_tensor_msd([.5, .5], mevals=mevals)
    msd_shore = asmfit.msd()
    assert_equal(msd_mt / msd_shore < 1.05 and msd_mt / msd_shore > 0.95, True)
Beispiel #12
0
def test_shore_metrics():
    gtab = get_gtab_taiwan_dsi()
    mevals = np.array(([0.0015, 0.0003, 0.0003],
                       [0.0015, 0.0003, 0.0003]))
    angl = [(0, 0), (60, 0)]
    S, _ = multi_tensor(gtab, mevals, S0=100.0, angles=angl,
                        fractions=[50, 50], snr=None)

    # test shore_indices
    n = 7
    l = 6
    m = -4
    radial_order, c = shore_order(n, l, m)
    n2, l2, m2 = shore_indices(radial_order, c)
    npt.assert_equal(n, n2)
    npt.assert_equal(l, l2)
    npt.assert_equal(m, m2)

    radial_order = 6
    c = 41
    n, l, m = shore_indices(radial_order, c)
    radial_order2, c2 = shore_order(n, l, m)
    npt.assert_equal(radial_order, radial_order2)
    npt.assert_equal(c, c2)

    npt.assert_raises(ValueError, shore_indices, 6, 100)
    npt.assert_raises(ValueError, shore_order, m, n, l)
    # since we are testing without noise we can use higher order and lower
    # lambdas, with respect to the default.
    radial_order = 8
    zeta = 700
    lambdaN = 1e-12
    lambdaL = 1e-12
    asm = ShoreModel(gtab, radial_order=radial_order,
                     zeta=zeta, lambdaN=lambdaN, lambdaL=lambdaL)
    asmfit = asm.fit(S)
    c_shore = asmfit.shore_coeff

    cmat = shore_matrix(radial_order, zeta, gtab)
    S_reconst = np.dot(cmat, c_shore)

    # test the signal reconstruction
    S = S / S[0]
    nmse_signal = np.sqrt(np.sum((S - S_reconst) ** 2)) / (S.sum())
    npt.assert_almost_equal(nmse_signal, 0.0, 4)

    # test if the analytical integral of the pdf is equal to one
    integral = 0
    for n in range(int((radial_order)/2 + 1)):
        integral += c_shore[n] * (np.pi**(-1.5) * zeta ** (-1.5) *
                                  genlaguerre(n, 0.5)(0)) ** 0.5

    npt.assert_almost_equal(integral, 1.0, 10)

    # test if the integral of the pdf calculated on a discrete grid is
    # equal to one
    pdf_discrete = asmfit.pdf_grid(17, 40e-3)
    integral = pdf_discrete.sum()
    npt.assert_almost_equal(integral, 1.0, 1)

    # compare the shore pdf with the ground truth multi_tensor pdf

    sphere = get_sphere('symmetric724')
    v = sphere.vertices
    radius = 10e-3
    pdf_shore = asmfit.pdf(v * radius)
    pdf_mt = multi_tensor_pdf(v * radius, mevals=mevals,
                              angles=angl, fractions=[50, 50])

    nmse_pdf = np.sqrt(np.sum((pdf_mt - pdf_shore) ** 2)) / (pdf_mt.sum())
    npt.assert_almost_equal(nmse_pdf, 0.0, 2)

    # compare the shore rtop with the ground truth multi_tensor rtop
    rtop_shore_signal = asmfit.rtop_signal()
    rtop_shore_pdf = asmfit.rtop_pdf()
    npt.assert_almost_equal(rtop_shore_signal, rtop_shore_pdf, 9)
    rtop_mt = multi_tensor_rtop([.5, .5], mevals=mevals)
    npt.assert_equal(rtop_mt / rtop_shore_signal < 1.10 and
                     rtop_mt / rtop_shore_signal > 0.95, True)

    # compare the shore msd with the ground truth multi_tensor msd
    msd_mt = multi_tensor_msd([.5, .5], mevals=mevals)
    msd_shore = asmfit.msd()
    npt.assert_equal(msd_mt / msd_shore < 1.05 and msd_mt / msd_shore > 0.95,
                     True)
def main():
    # Base Path of all the given files for DDE Part
    base_path = r'/nfs/masi/nathv/memento_2020/signal_forecast_data/files_project_2927_session_1436088/1-SignalForecast-ProvidedData/PGSE_shells'
    base_path = os.path.normpath(base_path)

    save_path = r'/nfs/masi/nathv/memento_2020/pgse_shells_submissions'
    save_path = os.path.normpath(save_path)

    # Read files via numpy load txt
    acq_params_file = np.loadtxt(
        os.path.join(base_path, 'PGSE_shells_provided_acq_params.txt'))
    pgse_provided_signals = np.loadtxt(
        os.path.join(base_path, 'PGSE_shells_provided_signals.txt'))
    pgse_unprovided_signals = np.loadtxt(
        os.path.join(base_path, 'PGSE_shells_unprovided_acq_params.txt'))

    # Transposing the provided signals for fitting to SHORE
    prov_signals = pgse_provided_signals.transpose()

    print('All Relevant Files Read ...')

    # Extract the acquisition parameters from provided and
    # unprovided to form the two different basis sets for SHORE
    prov_bvecs = acq_params_file[:, 1:4]
    prov_bvals = acq_params_file[:, 9]

    unprov_bvecs = pgse_unprovided_signals[:, 1:4]
    unprov_bvals = pgse_unprovided_signals[:, 9]

    print('Removing the B0 signals for signal modelling')
    # Detect B0 indices

    # Remove the B0's from the prior modelling
    non_b0_idxs = np.where(prov_bvals != 0)[0]
    prov_bvals = prov_bvals[non_b0_idxs]
    prov_bvecs = prov_bvecs[non_b0_idxs, :]
    pgse_provided_signals = pgse_provided_signals[non_b0_idxs, :]

    # Transposing the provided signals for fitting to SHORE
    prov_signals = pgse_provided_signals.transpose()

    prov_gtab = gradient_table(prov_bvals, prov_bvecs)
    unprov_gtab = gradient_table(unprov_bvals, unprov_bvecs)

    print('Gradient Tables formed ...')
    # Default SHORE parameters are
    zeta = 200
    lambda_n = 1e-8
    lambda_l = 1e-8
    radial_order = 6

    # SHORE Regularization Matrix Initialization

    def l_shore(radial_order):
        "Returns the angular regularisation matrix for SHORE basis"
        F = radial_order / 2
        n_c = int(np.round(1 / 6.0 * (F + 1) * (F + 2) * (4 * F + 3)))
        diagL = np.zeros(n_c)
        counter = 0
        for l in range(0, radial_order + 1, 2):
            for n in range(l, int((radial_order + l) / 2) + 1):
                for m in range(-l, l + 1):
                    diagL[counter] = (l * (l + 1))**2
                    counter += 1

        return np.diag(diagL)

    def n_shore(radial_order):
        "Returns the angular regularisation matrix for SHORE basis"
        F = radial_order / 2
        n_c = int(np.round(1 / 6.0 * (F + 1) * (F + 2) * (4 * F + 3)))
        diagN = np.zeros(n_c)
        counter = 0
        for l in range(0, radial_order + 1, 2):
            for n in range(l, int((radial_order + l) / 2) + 1):
                for m in range(-l, l + 1):
                    diagN[counter] = (n * (n + 1))**2
                    counter += 1

        return np.diag(diagN)

    print('Minimizing the zeta scale Parameter for Input Data ...')

    def eval_shore(D, n, scale):
        lambdaN = 1e-8
        lambdaL = 1e-8
        radial_order = n

        Lshore = l_shore(radial_order)
        Nshore = n_shore(radial_order)

        M = shore_matrix(n, scale, prov_gtab, 1. / (4 * np.pi**2))
        MpseudoInv = np.dot(
            np.linalg.inv(
                np.dot(M.T, M) + lambdaN * Nshore + lambdaL * Lshore), M.T)
        shorecoefs = np.dot(D, MpseudoInv.T)

        # shorecoefs = np.dot(D, pinv(Mshore).T)
        shorepred = np.dot(shorecoefs, M.T)
        '''
        plt.figure(1, figsize=(12,8))
        plt.subplot(2,3,1)
        plt.plot(D[0, :])
        plt.plot(shorepred[0, :])
        plt.legend(['Original Signal','SHORE Fitted Signal'])

        plt.subplot(2,3,2)
        plt.plot(D[1, :])
        plt.plot(shorepred[1, :])

        plt.subplot(2,3,3)
        plt.plot(D[2, :])
        plt.plot(shorepred[2, :])

        plt.subplot(2,3,4)
        plt.plot(D[3, :])
        plt.plot(shorepred[3, :])

        plt.subplot(2,3,5)
        plt.plot(D[4, :])
        plt.plot(shorepred[4, :])
        plt.show()
        '''
        return np.linalg.norm(D - shorepred)**2

    def get_shore_coeffs(D, n, scale):
        lambdaN = 1e-8
        lambdaL = 1e-8
        radial_order = n

        Lshore = l_shore(radial_order)
        Nshore = n_shore(radial_order)

        M = shore_matrix(n, scale, prov_gtab, 1. / (4 * np.pi**2))
        MpseudoInv = np.dot(
            np.linalg.inv(
                np.dot(M.T, M) + lambdaN * Nshore + lambdaL * Lshore), M.T)
        shorecoefs = np.dot(D, MpseudoInv.T)
        return shorecoefs

    zeta_optimized = minimize(
        lambda x: eval_shore(prov_signals, radial_order, x), zeta)['x']
    print(
        'The guess zeta value is: {} and the optimal zeta value is: {}'.format(
            zeta, zeta_optimized))

    guess_prov_mse = eval_shore(prov_signals, radial_order, zeta)
    optim_prov_mse = eval_shore(prov_signals, radial_order, zeta_optimized)

    guess_shore_coeffs = get_shore_coeffs(prov_signals, radial_order, zeta)
    optim_shore_coeffs = get_shore_coeffs(prov_signals, radial_order,
                                          zeta_optimized)

    print(
        'MSE for guessed zeta is: {} and MSE for optimized zeta is: {}'.format(
            guess_prov_mse, optim_prov_mse))

    print('Obtaining signal measurements for unprovided data')
    #M_unprov_zeta = shore_matrix(radial_order, zeta, unprov_gtab, 1. / (4 * np.pi ** 2))
    M_unprov_zeta_optim = shore_matrix(radial_order, zeta_optimized,
                                       unprov_gtab, 1. / (4 * np.pi**2))

    #guess_shore_preds = np.dot(guess_shore_coeffs, M_unprov_zeta.T)
    optim_shore_preds = np.dot(optim_shore_coeffs, M_unprov_zeta_optim.T)

    #guess_shore_preds = guess_shore_preds.T
    optim_shore_preds = optim_shore_preds.T

    #np.savetxt(os.path.join(save_path, 'sub_1.txt'), guess_shore_preds)
    np.savetxt(os.path.join(save_path, 'sub_3.txt'), optim_shore_preds)
    '''
    prov_ShoreModel = ShoreModel(gtab=prov_gtab,
                                 radial_order=radial_order,
                                 zeta=zeta,
                                 lambdaN=lambda_n,
                                 lambdaL=lambda_l)

    print('Shore Basis Constructed, Fitting Data ...')
    prov_ShoreFit = prov_ShoreModel.fit(pgse_provided_signals.transpose())
    '''

    print('Debug here')

    return None