def mesh_to_sphere(mesh):
    vertices = np.array(mesh.vertex()).astype(np.float64)
    faces = np.array(mesh.polygon()).astype(np.uint16)
    sphere = Sphere(xyz=vertices, faces=faces)
    #step not necessary but just to be sure
    edges = sphere.edges.astype(np.uint16)
    sphere = Sphere(xyz=vertices, faces=faces, edges=edges)
    return sphere
Пример #2
0
def test_sphere_subdivide():
    sphere1 = unit_octahedron.subdivide(4)
    sphere2 = Sphere(xyz=sphere1.vertices)
    nt.assert_equal(sphere1.faces.shape, sphere2.faces.shape)
    nt.assert_equal(array_to_set(sphere1.faces), array_to_set(sphere2.faces))

    sphere1 = unit_icosahedron.subdivide(4)
    sphere2 = Sphere(xyz=sphere1.vertices)
    nt.assert_equal(sphere1.faces.shape, sphere2.faces.shape)
    nt.assert_equal(array_to_set(sphere1.faces), array_to_set(sphere2.faces))
Пример #3
0
def test_sphere_edges_faces():
    nt.assert_raises(ValueError, Sphere, xyz=1, edges=1, faces=None)
    Sphere(xyz=[0, 0, 1], faces=[0, 0, 0])
    Sphere(xyz=[[0, 0, 1],
                [1, 0, 0],
                [0, 1, 0]],
           edges=[[0, 1],
                  [1, 2],
                  [2, 0]],
           faces=[0, 1, 2])
Пример #4
0
def test_sphere_construct():
    s0 = Sphere(xyz=verts)
    s1 = Sphere(theta=theta, phi=phi)
    s2 = Sphere(*verts.T)

    nt.assert_array_almost_equal(s0.theta, s1.theta)
    nt.assert_array_almost_equal(s0.theta, s2.theta)
    nt.assert_array_almost_equal(s0.theta, theta)

    nt.assert_array_almost_equal(s0.phi, s1.phi)
    nt.assert_array_almost_equal(s0.phi, s2.phi)
    nt.assert_array_almost_equal(s0.phi, phi)
Пример #5
0
def test_edges_faces():
    s = Sphere(xyz=verts)
    faces = oct_faces
    nt.assert_equal(array_to_set(s.faces), array_to_set(faces))
    nt.assert_equal(array_to_set(s.edges), array_to_set(edges))

    s = Sphere(xyz=verts, faces=[[0, 1, 2]])
    nt.assert_equal(array_to_set(s.faces), array_to_set([[0, 1, 2]]))
    nt.assert_equal(array_to_set(s.edges),
                    array_to_set([[0, 1], [1, 2], [0, 2]]))

    s = Sphere(xyz=verts, faces=[[0, 1, 2]], edges=[[0, 1]])
    nt.assert_equal(array_to_set(s.faces), array_to_set([[0, 1, 2]]))
    nt.assert_equal(array_to_set(s.edges), array_to_set([[0, 1]]))
Пример #6
0
def dir_compute_peaks(output_dir,
                      relative_peak_threshold=.5,
                      peak_normalize=1,
                      min_separation_angle=45,
                      max_peak_number=5):
    peaks_file = os.path.join(output_dir, 'peaks.npz')
    result_file = os.path.join(output_dir, 'result_raw.pickle')
    result = pickle.load(open(result_file, 'rb'))[0]

    try:
        u_RECON = result['u']
    except KeyError:
        u_RECON = result['u1']

    b_sph = load_b_sph(output_dir)
    sphere = Sphere(xyz=b_sph.v.T)
    f_noisy = reconst_f(output_dir, b_sph)[0]

    l_labels = u_RECON.shape[0]
    imagedims = u_RECON.shape[1:]

    num_peak_coeffs = max_peak_number * 3
    computed_peaks = []
    for odfs in [u_RECON, f_noisy]:
        peaks = compute_peaks(odfs,
                              sphere,
                              relative_peak_threshold=.5,
                              peak_normalize=1,
                              min_separation_angle=45,
                              max_peak_number=5)
        computed_peaks.append(peaks.reshape(imagedims + (peaks.shape[-1], )))

    np.savez_compressed(peaks_file, computed_peaks)
    return computed_peaks
Пример #7
0
def test_fbc():
    """Test the FBC measures on a set of fibers"""

    # Generate two fibers of 10 points
    streamlines = []
    for i in range(2):
        fiber = np.zeros((10, 3))
        for j in range(10):
            fiber[j, 0] = j
            fiber[j, 1] = i*0.2
            fiber[j, 2] = 0
            streamlines.append(fiber)

    # Create lookup table.
    # A fixed set of orientations is used to guarantee deterministic results
    D33 = 1.0
    D44 = 0.04
    t = 1
    sphere = Sphere(xyz=np.array([[0.82819078, 0.51050355, 0.23127074],
                                  [-0.10761926, -0.95554309, 0.27450957],
                                  [0.4101745, -0.07154038, 0.90919682],
                                  [-0.75573448, 0.64854889, 0.09082809],
                                  [-0.56874549, 0.01377562, 0.8223982]]))
    k = EnhancementKernel(D33, D44, t, orientations=sphere,
                          force_recompute=True)

    # run FBC
    fbc = FBCMeasures(streamlines, k, verbose=True)

    # get FBC values
    fbc_sl_orig, clrs_orig, rfbc_orig = \
        fbc.get_points_rfbc_thresholded(0, emphasis=0.01)

    # check mean RFBC against tested value
    npt.assert_almost_equal(np.mean(rfbc_orig), 1.0500466494329224)
def correct_sphere(sphere):
    faces = sphere.faces.copy()
    vertices = sphere.vertices
    o = check_face_orientation(faces, vertices)
    faces[o, :] = faces[o, ::-1]
    new_sphere = Sphere(xyz=vertices, faces=faces)
    return new_sphere
Пример #9
0
def get_2D_sphere(no_phis=None, no_thetas=None):
    """Retrieve evenly distributed 2D sphere out of phi and theta count.


    Parameters
    ----------
    no_phis : int, optional
        The numbers of phis in the sphere, by default as in config file / 16
    no_thetas : int, optional
        The numbers of thetas in the sphere, by default as in config file / 16

    Returns
    -------
    Sphere
        The 2D sphere requested
    """
    if no_thetas is None:
        no_thetas = Config.get_config().getint("2DSphereOptions",
                                               "noThetas",
                                               fallback="16")
    if no_phis is None:
        no_phis = Config.get_config().getint("2DSphereOptions",
                                             "noPhis",
                                             fallback="16")
    xi = np.arange(0, np.pi, (np.pi) / no_thetas)  # theta
    yi = np.arange(-np.pi, np.pi, 2 * (np.pi) / no_phis)  # phi

    basis = np.array(np.meshgrid(yi, xi))

    sphere = Sphere(theta=basis[0, :], phi=basis[1, :])

    return sphere
Пример #10
0
def mrtrix_spherical_functions():
    """Spherical functions represented by spherical harmonic coefficients and
    evaluated on a discrete sphere.

    Returns
    -------
    func_coef : array (2, 3, 4, 45)
        Functions represented by the coefficients associated with the
        mxtrix spherical harmonic basis of order 8.
    func_discrete : array (2, 3, 4, 81)
        Functions evaluated on `sphere`.
    sphere : Sphere
        The discrete sphere, points on the surface of a unit sphere, used to
        evaluate the functions.

    Notes
    -----
    These coefficients were obtained by using the dwi2SH command of mrtrix.

    """
    func_discrete = load(pjoin(DATA_DIR, "func_discrete.nii.gz")).get_data()
    func_coef = load(pjoin(DATA_DIR, "func_coef.nii.gz")).get_data()
    gradients = np.loadtxt(pjoin(DATA_DIR, "sphere_grad.txt"))
    # gradients[0] and the first volume of func_discrete,
    # func_discrete[..., 0], are associated with the b=0 signal.
    # gradients[:, 3] are the b-values for each gradient/volume.
    sphere = Sphere(xyz=gradients[1:, :3])
    return func_coef, func_discrete[..., 1:], sphere
Пример #11
0
def test_sh_to_sf_matrix():
    sphere = Sphere(xyz=hemi_icosahedron.vertices)

    with warnings.catch_warnings():
        warnings.filterwarnings("ignore",
                                message=descoteaux07_legacy_msg,
                                category=PendingDeprecationWarning)

        B1, invB1 = sh_to_sf_matrix(sphere)

        B2, m, n = real_sh_descoteaux(4, sphere.theta, sphere.phi)

    invB2 = smooth_pinv(B2, L=np.zeros_like(n))

    with warnings.catch_warnings():
        warnings.filterwarnings("ignore",
                                message=descoteaux07_legacy_msg,
                                category=PendingDeprecationWarning)

        B3 = sh_to_sf_matrix(sphere, return_inv=False)

    assert_array_almost_equal(B1, B2.T)
    assert_array_almost_equal(invB1, invB2.T)
    assert_array_almost_equal(B3, B1)
    assert_raises(ValueError, sh_to_sf_matrix, sphere, basis_type="")
Пример #12
0
def test_real_sh_descoteaux2():
    vertices = hemi_icosahedron.subdivide(2).vertices
    mevals = np.array([[0.0015, 0.0003, 0.0003], [0.0015, 0.0003, 0.0003]])
    angles = [(0, 0), (60, 0)]
    odf = multi_tensor_odf(vertices, mevals, angles, [50, 50])

    mevals = np.array([[0.0015, 0.0003, 0.0003]])
    angles = [(0, 0)]
    odf2 = multi_tensor_odf(-vertices, mevals, angles, [100])

    sphere = Sphere(xyz=np.vstack((vertices, -vertices)))
    # Asymmetric spherical function with 162 coefficients
    sf = np.append(odf, odf2)

    # In order for our approximation to be precise enough, we
    # will use a SH basis of orders up to 10 (121 coefficients)

    with warnings.catch_warnings(record=True) as w:
        B, m, n = real_sh_descoteaux(10,
                                     sphere.theta,
                                     sphere.phi,
                                     full_basis=True)

    npt.assert_equal(len(w), 1)
    npt.assert_(issubclass(w[0].category, PendingDeprecationWarning))
    npt.assert_(descoteaux07_legacy_msg in str(w[0].message))

    invB = smooth_pinv(B, L=np.zeros_like(n))
    sh_coefs = np.dot(invB, sf)
    sf_approx = np.dot(B, sh_coefs)

    assert_array_almost_equal(sf_approx, sf, 2)
Пример #13
0
    def resample_dwi(self, directions=None, sh_order=8, smooth=0.006):
        """ Resamples a diffusion signal according to a set of directions using spherical harmonics.
        Parameters
        -----------
        directions : `dipy.core.sphere.Sphere` object, optional
            Directions the diffusion signal will be resampled to. Directions are
            assumed to be on the whole sphere, not the hemisphere like bvecs.
            If omitted, 100 directions evenly distributed on the sphere will be used.
        sh_order : int, optional
            SH order. Default: 8
        smooth : float, optional
            Lambda-regularization in the SH fit. Default: 0.006.
        """
        data_sh = self.get_spherical_harmonics_coefficients(self.dwi,
                                                            self.bvals,
                                                            self.bvecs,
                                                            sh_order=sh_order,
                                                            smooth=smooth)
        sphere = get_sphere('repulsion100')
        if directions is not None:
            sphere = Sphere(xyz=directions)

        sph_harm_basis = sph_harm_lookup.get("tournier07")
        Ba, m, n = sph_harm_basis(sh_order, sphere.theta, sphere.phi)
        data_resampled = np.dot(data_sh, Ba.T)

        return data_resampled
Пример #14
0
    def odf(self, sphere):
        ## Override the odf method to subclass OdfFit

        bvec = self.model.bvec[self.model.bval > 0]
        data = self.data[self.model.bval > 0]
        origin_sphere = Sphere(xyz=bvec)
        discrete_odf = 1. / data
        return interp_rbf(discrete_odf, origin_sphere, sphere)
Пример #15
0
def create_sphere(n_pts):
    theta = np.pi * np.random.rand(n_pts)
    phi = 2 * np.pi * np.random.rand(n_pts)
    hsph_initial = HemiSphere(theta=theta, phi=phi)
    hsph_updated, _ = disperse_charges(hsph_initial, 5000)
    sph = Sphere(xyz=np.vstack((hsph_updated.vertices,
                                -hsph_updated.vertices)))
    return sph
Пример #16
0
def plot_signal(bvecs,
                signal,
                origin=[0, 0, 0],
                maya=True,
                cmap='jet',
                file_name=None,
                colorbar=False,
                figure=None,
                vmin=None,
                vmax=None,
                offset=0,
                azimuth=60,
                elevation=90,
                roll=0,
                non_neg=False):
    """

    Interpolate a measured signal, using RBF interpolation.

    Parameters
    ----------
    signal:

    bvecs: array (3,n)
        the x,y,z locations where the signal was measured 

    offset : float
        where to place the plotted voxel (on the z axis)

    
    """

    s0 = Sphere(xyz=bvecs.T)
    vertices = s0.vertices
    faces = s0.faces
    x, y, z = vertices.T

    r, phi, theta = geo.cart2sphere(x, y, z)
    x_plot, y_plot, z_plot = geo.sphere2cart(signal, phi, theta)

    if non_neg:
        signal[np.where(signal < 0)] = 0

    # Call and return straightaway:
    return _display_maya_voxel(x_plot,
                               y_plot,
                               z_plot,
                               faces,
                               signal,
                               origin,
                               cmap=cmap,
                               colorbar=colorbar,
                               figure=figure,
                               vmin=vmin,
                               vmax=vmax,
                               file_name=file_name,
                               azimuth=azimuth,
                               elevation=elevation)
Пример #17
0
def resample_dwi(dwi,
                 bvals,
                 bvecs,
                 directions=None,
                 sh_order=8,
                 smooth=0.006,
                 mean_centering=True):
    """ Resamples a diffusion signal according to a set of directions using spherical harmonics.

    Parameters
    -----------
    dwi : `nibabel.NiftiImage` object
        Diffusion signal as weighted images (4D).
    bvals : ndarray shape (N,)
        B-values used with each direction.
    bvecs : ndarray shape (N, 3)
        Directions of the diffusion signal. Directions are
        assumed to be only on the hemisphere.
    directions : `dipy.core.sphere.Sphere` object, optional
        Directions the diffusion signal will be resampled to. Directions are
        assumed to be on the whole sphere, not the hemisphere like bvecs.
        If omitted, 100 directions evenly distributed on the sphere will be used.
    sh_order : int, optional
        SH order. Default: 8
    smooth : float, optional
        Lambda-regularization in the SH fit. Default: 0.006.
    mean_centering : bool
        If True, signal will have zero mean in each direction for all nonzero voxels

    Returns
    -------
    ndarray
        Diffusion weights resampled according to `sphere`.
    """
    data_sh = get_spherical_harmonics_coefficients(dwi,
                                                   bvals,
                                                   bvecs,
                                                   sh_order=sh_order,
                                                   smooth=smooth,
                                                   mean_centering=False)

    sphere = get_sphere('repulsion100')
    # sphere = get_sphere('repulsion724')
    if directions is not None:
        sphere = Sphere(xyz=bvecs[1:])

    sph_harm_basis = sph_harm_lookup.get('mrtrix')
    Ba, m, n = sph_harm_basis(sh_order, sphere.theta, sphere.phi)
    data_resampled = np.dot(data_sh, Ba.T)

    if mean_centering:
        # Normalization in each direction (zero mean)
        idx = data_resampled.sum(axis=-1).nonzero()
        means = data_resampled[idx].mean(axis=0)
        data_resampled[idx] -= means

    return data_resampled
Пример #18
0
def sph_peaks_t(power_map,
                theta_look,
                phi_look,
                max_n_peaks=20,
                audio_length_seconds=None,
                **kwargs):

    N_frames = power_map.shape[1]

    # set up sphere object for peak finding
    sph = Sphere(theta=phi_look, phi=theta_look)

    # set up output arrays for DOAs
    y_t = np.zeros((N_frames, max_n_peaks))
    x_t = np.zeros((N_frames, max_n_peaks))

    for i in range(N_frames):
        # peak finding in spherical data
        _, _, peaks = peak_directions(power_map[:, i], sph, **kwargs)
        # relative_peak_threshold=.5,
        # min_separation_angle=5)

        # save peaks to arrays
        xdirs = theta_look[peaks]
        ydirs = phi_look[peaks]

        # get rid of any extra peaks
        xdirs = xdirs[:max_n_peaks - 1]
        ydirs = ydirs[:max_n_peaks - 1]

        x_t[i, 0] = i
        y_t[i, 0] = i
        x_t[i, 1:len(xdirs) + 1] += xdirs
        y_t[i, 1:len(xdirs) + 1] += ydirs

    # rearranging data to a useful format
    for i in range(np.min(x_t.shape) - 1):

        xyi = np.append(np.append(x_t[:, [0]], x_t[:, [i + 1]], 1),
                        y_t[:, [i + 1]], 1)

        if 'xy_t' not in locals():
            xy_t = xyi
        else:
            xy_t = np.append(xy_t, xyi, 0)

    # remove zeros
    xy_t = xy_t[np.where(xy_t[:, 2] != 0)]

    if audio_length_seconds is not None:
        # replace frame numbers with time in seconds
        n_frames = len(power_map.T)
        time_index = np.linspace(0, audio_length_seconds, n_frames)
        # time_points = time_index[xy_t[:,0].astype(int)]
        xy_t[:, 0] = time_index[xy_t[:, 0].astype(int)]

    return xy_t
Пример #19
0
    def process(self, data_container, points, dwi):
        raw_sphere = Sphere(xyz=data_container.bvecs)

        real_sh, _, n = real_sym_sh_mrtrix(self.sh_order, raw_sphere.theta,
                                           raw_sphere.phi)
        l = -n * (n + 1)
        inv_b = smooth_pinv(real_sh, np.sqrt(self.smooth) * l)
        data_sh = np.dot(dwi, inv_b.T)

        return data_sh
Пример #20
0
def test_apparent_kurtosis_coef():
    """ Apparent kurtosis coeficients are tested for a spherical kurtosis
    tensor """

    sph = Sphere(xyz=gtab.bvecs[gtab.bvals > 0])
    AKC = dki.apparent_kurtosis_coef(params_sph, sph)

    # check all direction
    for d in range(len(gtab.bvecs[gtab.bvals > 0])):
        assert_array_almost_equal(AKC[d], Kref_sphere)
Пример #21
0
def peak_dist(_, u, b_sph):
    sphere = Sphere(xyz=b_sph.v.T)
    peaks = compute_peaks(u,
                          sphere,
                          relative_peak_threshold=.5,
                          peak_normalize=1,
                          min_separation_angle=25,
                          max_peak_number=5)
    _, _, _, AE = compute_err(peaks, load_gt_img())
    return AE
Пример #22
0
def test_sh_to_sf_matrix():
    sphere = Sphere(xyz=hemi_icosahedron.vertices)
    B1, invB1 = sh_to_sf_matrix(sphere)
    B2, m, n = real_sym_sh_basis(4, sphere.theta, sphere.phi)
    invB2 = smooth_pinv(B2, L=np.zeros_like(n))
    B3 = sh_to_sf_matrix(sphere, return_inv=False)

    assert_array_almost_equal(B1, B2.T)
    assert_array_almost_equal(invB1, invB2.T)
    assert_array_almost_equal(B3, B1)
    assert_raises(ValueError, sh_to_sf_matrix, sphere, basis_type="")
Пример #23
0
def test_basic_cache():
    t = DummyModel()
    s = Sphere(theta=[0], phi=[0])

    assert_(t.cache_get("design_matrix", s) is None)

    m = [[1, 0], [0, 1]]

    t.cache_set("design_matrix", key=s, value=m)
    assert_equal(t.cache_get("design_matrix", s), m)

    t.cache_clear()
    assert_(t.cache_get("design_matrix", s) is None)
Пример #24
0
def test_single_voxel_DKI_stats():
    # tests if AK and RK are equal to expected values for a single fiber
    # simulate randomly oriented
    ADi = 0.00099
    ADe = 0.00226
    RDi = 0
    RDe = 0.00087
    # Reference values
    AD = fie * ADi + (1 - fie) * ADe
    AK = 3 * fie * (1 - fie) * ((ADi - ADe) / AD)**2
    RD = fie * RDi + (1 - fie) * RDe
    RK = 3 * fie * (1 - fie) * ((RDi - RDe) / RD)**2
    ref_vals = np.array([AD, AK, RD, RK])

    # simulate fiber randomly oriented
    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,
                                      S0=100,
                                      angles=angles,
                                      fractions=frac,
                                      snr=None)
    evals, evecs = decompose_tensor(from_lower_triangular(dt))
    dki_par = np.concatenate((evals, evecs[0], evecs[1], evecs[2], kt), axis=0)

    # Estimates using dki functions
    ADe1 = dti.axial_diffusivity(evals)
    RDe1 = dti.radial_diffusivity(evals)
    AKe1 = axial_kurtosis(dki_par)
    RKe1 = radial_kurtosis(dki_par)
    e1_vals = np.array([ADe1, AKe1, RDe1, RKe1])
    assert_array_almost_equal(e1_vals, ref_vals)

    # Estimates using the kurtosis class object
    dkiM = dki.DiffusionKurtosisModel(gtab_2s)
    dkiF = dkiM.fit(signal)
    e2_vals = np.array([dkiF.ad, dkiF.ak(), dkiF.rd, dkiF.rk()])
    assert_array_almost_equal(e2_vals, ref_vals)

    # test MK (note this test correspond to the MK singularity L2==L3)
    MK_as = dkiF.mk()
    sph = Sphere(xyz=gtab.bvecs[gtab.bvals > 0])
    MK_nm = np.mean(dkiF.akc(sph))

    assert_array_almost_equal(MK_as, MK_nm, decimal=1)
def create_symmetric_repulsion_sphere(n_points, n_iter):
    """
	Create a full Sphere object using electrostatic repulsion.
	params:
	npoints: number of points in the electrostatic repulsion
	n_iter: number of iterations to optimise energy
	return: Sphere object with 2*npoints vertices
	"""
    theta = np.pi * np.random.rand(n_points)
    phi = 2 * np.pi * np.random.rand(n_points)
    hsph_initial = HemiSphere(theta=theta, phi=phi)
    hsph_updated, energy = disperse_charges(hsph_initial, iters=n_iter)
    sph = Sphere(xyz=np.vstack((hsph_updated.vertices,
                                -hsph_updated.vertices)))
    return sph
Пример #26
0
def main():
    odf_file = sys.argv[1]
    bvec_file = sys.argv[2]
    basis = sys.argv[3]

    odf = nib.load(odf_file)
    odf_sh = odf.get_fdata()
    bvec = np.loadtxt(bvec_file)
    bvec = bvec[1:, :]

    sph_gtab = Sphere(xyz=np.vstack(bvec))
    print(odf_sh.shape)

    odf_sf = sh_to_sf(odf_sh, sph_gtab, basis_type=basis, sh_order=8)
    visu_odf(bvec, odf_sf)
Пример #27
0
def test_MK_singularities():
    # To test MK in case that analytical solution was a singularity not covered
    # by other tests

    dkiM = dki.DiffusionKurtosisModel(gtab_2s)

    # test singularity L1 == L2 - this is the case of a prolate diffusion
    # tensor for crossing fibers at 90 degrees
    angles_all = np.array([[(90, 0), (90, 0), (0, 0), (0, 0)],
                           [(89.9, 0), (89.9, 0), (0, 0), (0, 0)]])
    for angles_90 in angles_all:
        s_90, dt_90, kt_90 = multi_tensor_dki(gtab_2s,
                                              mevals_cross,
                                              S0=100,
                                              angles=angles_90,
                                              fractions=frac_cross,
                                              snr=None)
        dkiF = dkiM.fit(s_90)
        MK = dkiF.mk()

        sph = Sphere(xyz=gtab.bvecs[gtab.bvals > 0])

        MK_nm = np.mean(dkiF.akc(sph))

        assert_almost_equal(MK, MK_nm, decimal=2)

        # test singularity L1 == L3 and L1 != L2
        # since L1 is defined as the larger eigenvalue and L3 the smallest
        # eigenvalue, this singularity teoretically will never be called,
        # because for L1 == L3, L2 have also to be  = L1 and L2.
        # Nevertheless, I decided to include this test since this singularity
        # is revelant for cases that eigenvalues are not ordered

        # artificially revert the eigenvalue and eigenvector order
        dki_params = dkiF.model_params.copy()
        dki_params[1] = dkiF.model_params[2]
        dki_params[2] = dkiF.model_params[1]
        dki_params[4] = dkiF.model_params[5]
        dki_params[5] = dkiF.model_params[4]
        dki_params[7] = dkiF.model_params[8]
        dki_params[8] = dkiF.model_params[7]
        dki_params[10] = dkiF.model_params[11]
        dki_params[11] = dkiF.model_params[10]

        MK = dki.mean_kurtosis(dki_params)
        MK_nm = np.mean(dki.apparent_kurtosis_coef(dki_params, sph))

        assert_almost_equal(MK, MK_nm, decimal=2)
Пример #28
0
def test_sf_to_sh():
    # Subdividing a hemi_icosahedron twice produces 81 unique points, which
    # is more than enough to fit a order 8 (45 coefficients) spherical harmonic
    hemisphere = hemi_icosahedron.subdivide(2)
    mevals = np.array([[0.0015, 0.0003, 0.0003], [0.0015, 0.0003, 0.0003]])
    angles = [(0, 0), (60, 0)]
    odf = multi_tensor_odf(hemisphere.vertices, mevals, angles, [50, 50])

    # 1D case with the 2 symmetric bases functions
    odf_sh = sf_to_sh(odf, hemisphere, 8, "tournier07")
    odf_reconst = sh_to_sf(odf_sh, hemisphere, 8, "tournier07")
    assert_array_almost_equal(odf, odf_reconst, 2)

    odf_sh = sf_to_sh(odf, hemisphere, 8, "descoteaux07")
    odf_reconst = sh_to_sf(odf_sh, hemisphere, 8, "descoteaux07")
    assert_array_almost_equal(odf, odf_reconst, 2)

    # We now create an asymmetric signal
    # to try out our full SH basis
    mevals = np.array([[0.0015, 0.0003, 0.0003]])
    angles = [(0, 0)]
    odf2 = multi_tensor_odf(hemisphere.vertices, mevals, angles, [100])

    # We simulate our asymmetric signal by using a different ODF
    # per hemisphere. The sphere used is a concatenation of the
    # vertices of our hemisphere, for a total of 162 vertices.
    sphere = Sphere(xyz=np.vstack((hemisphere.vertices, -hemisphere.vertices)))
    asym_odf = np.append(odf, odf2)

    # Try out full bases with order 10 (121 coefficients)
    odf_sh = sf_to_sh(asym_odf, sphere, 10, "tournier07_full")
    odf_reconst = sh_to_sf(odf_sh, sphere, 10, "tournier07_full")
    assert_array_almost_equal(odf_reconst, asym_odf, 2)

    odf_sh = sf_to_sh(asym_odf, sphere, 10, "descoteaux07_full")
    odf_reconst = sh_to_sf(odf_sh, sphere, 10, "descoteaux07_full")
    assert_array_almost_equal(odf_reconst, asym_odf, 2)

    # An invalid basis name should raise an error
    assert_raises(ValueError, sh_to_sf, odf, hemisphere, basis_type="")
    assert_raises(ValueError, sf_to_sh, odf_sh, hemisphere, basis_type="")

    # 2D case
    odf2d = np.vstack((odf, odf))
    odf2d_sh = sf_to_sh(odf2d, hemisphere, 8)
    odf2d_sf = sh_to_sf(odf2d_sh, hemisphere, 8)
    assert_array_almost_equal(odf2d, odf2d_sf, 2)
Пример #29
0
def test_compare_MK_method():
    # tests if analytical solution of MK is equal to the average of directional
    # kurtosis sampled from a sphere

    # DKI Model fitting
    dkiM = dki.DiffusionKurtosisModel(gtab_2s)
    dkiF = dkiM.fit(signal_cross)

    # MK analytical solution
    MK_as = dkiF.mk()

    # MK numerical method
    sph = Sphere(xyz=gtab.bvecs[gtab.bvals > 0])
    MK_nm = np.mean(dki.apparent_kurtosis_coef(dkiF.model_params, sph),
                    axis=-1)

    assert_array_almost_equal(MK_as, MK_nm, decimal=1)
Пример #30
0
def test_compare_RK_methods():
    # tests if analytical solution of RK is equal to the perpendicular kurtosis
    # relative to the first diffusion axis

    # DKI Model fitting
    dkiM = dki.DiffusionKurtosisModel(gtab_2s)
    dkiF = dkiM.fit(signal_cross)

    # MK analytical solution
    RK_as = dkiF.rk()

    # MK numerical method
    evecs = dkiF.evecs
    p_dir = perpendicular_directions(evecs[:, 0], num=30, half=True)
    ver = Sphere(xyz=p_dir)
    RK_nm = np.mean(dki.apparent_kurtosis_coef(dkiF.model_params, ver),
                    axis=-1)

    assert_array_almost_equal(RK_as, RK_nm)