Exemple #1
0
def test_sphere_cart():
    # test arrays of points
    rs, thetas, phis = cart2sphere(*(sphere_points.T))
    xyz = sphere2cart(rs, thetas, phis)
    yield assert_array_almost_equal, xyz, sphere_points.T
    # test radius estimation
    big_sph_pts = sphere_points * 10.4
    rs, thetas, phis = cart2sphere(*big_sph_pts.T)
    yield assert_array_almost_equal, rs, 10.4
    xyz = sphere2cart(rs, thetas, phis)
    yield assert_array_almost_equal, xyz, big_sph_pts.T, 6
    # test that result shapes match
    x, y, z = big_sph_pts.T
    r, theta, phi = cart2sphere(x[:1], y[:1], z)
    yield assert_equal, r.shape, theta.shape
    yield assert_equal, r.shape, phi.shape
    x, y, z = sphere2cart(r[:1], theta[:1], phi)
    yield assert_equal, x.shape, y.shape
    yield assert_equal, x.shape, z.shape
    # test a scalar point
    pt = sphere_points[3]
    r, theta, phi = cart2sphere(*pt)
    xyz = sphere2cart(r, theta, phi)
    yield assert_array_almost_equal, xyz, pt

    # Test full circle on x=0, y=0, z=0
    x, y, z = sphere2cart(*cart2sphere(0., 0., 0.))
    yield assert_array_equal, (x, y, z), (0., 0., 0.)
Exemple #2
0
def test_sphere_cart():
    # test arrays of points
    rs, thetas, phis = cart2sphere(*(sphere_points.T))
    xyz = sphere2cart(rs, thetas, phis)
    yield assert_array_almost_equal(xyz, sphere_points.T)
    # test radius estimation
    big_sph_pts = sphere_points * 10.4
    rs, thetas, phis = cart2sphere(*big_sph_pts.T)
    yield assert_array_almost_equal(rs, 10.4)
    xyz = sphere2cart(rs, thetas, phis)
    yield assert_array_almost_equal(xyz, big_sph_pts.T, 6)
    # test a scalar point
    pt = sphere_points[3]
    r, theta, phi = cart2sphere(*pt)
    xyz = sphere2cart(r, theta, phi)
    yield assert_array_almost_equal(xyz, pt)
Exemple #3
0
def _check_directions(angles):
    """
    Helper function to check if direction ground truth have the right format
    and are in cartesian coordinates

    Parameters
    -----------
    angles : array (K,2) or (K, 3)
        List of K polar angles (in degrees) for the sticks or array of K
        sticks as unit vectors.

    Returns
    --------
    sticks : (K,3)
        Sticks in cartesian coordinates.
    """
    angles = np.array(angles)
    if angles.shape[-1] == 3:
        sticks = angles
    else:
        sticks = [sphere2cart(1, np.deg2rad(pair[0]), np.deg2rad(pair[1]))
                  for pair in angles]
        sticks = np.array(sticks)

    return sticks
    def _pred_sig(self, theta, phi, beta, lambda1, lambda2):
        """
        The predicted signal for a particular setting of the parameters
        """

        Q = np.array([[lambda1, 0, 0],
                      [0, lambda2, 0],
                      [0, 0, lambda2]])

        # If for some reason this is not symmetrical, then something is wrong
        # (in all likelihood, this means that the optimization process is
        # trying out some crazy value, such as nan). In that case, abort and
        # return a nan:
        if not np.allclose(Q.T, Q):
            return np.nan
        
        response_function = ozt.Tensor(Q,
                                        self.bvecs[:,self.b_idx],
                                        self.bvals[:,self.b_idx])
                                        
        # Convert theta and phi to cartesian coordinates:
        x,y,z = geo.sphere2cart(1, theta, phi)
        bvec = [x,y,z]
        evals, evecs = response_function.decompose

        rot_tensor = ozt.tensor_from_eigs(
            evecs * ozu.calculate_rotation(bvec, evecs[0]),
            evals, self.bvecs[:,self.b_idx], self.bvals[:,self.b_idx])

        iso_sig = np.exp(-self.bvals[self.b_idx][0] * lambda1)
        tensor_sig =  rot_tensor.predicted_signal(1)

        return beta * iso_sig + (1-beta) * tensor_sig
Exemple #5
0
def test_perpendicular_directions():
    num = 35

    vectors_v = np.zeros((4, 3))

    for v in range(4):
        theta = random.uniform(0, np.pi)
        phi = random.uniform(0, 2*np.pi)
        vectors_v[v] = sphere2cart(1., theta, phi)
    vectors_v[3] = [1, 0, 0]

    for vector_v in vectors_v:
        pd = perpendicular_directions(vector_v, num=num, half=False)

        # see if length of pd is equal to the number of intendend samples
        assert_equal(num, len(pd))

        # check if all directions are perpendicular to vector v
        for d in pd:
            cos_angle = np.dot(d, vector_v)
            assert_almost_equal(cos_angle, 0)

        # check if directions are sampled by multiples of 2*pi / num
        delta_a = 2. * np.pi / num
        for d in pd[1:]:
            angle = np.arccos(np.dot(pd[0], d))
            rest = angle % delta_a
            if rest > delta_a * 0.99:  # To correct cases of negative error
                rest = rest - delta_a
            assert_almost_equal(rest, 0)
Exemple #6
0
def plot_ellipsoid_mpl(Tensor, n=60):
    """
    Plot an ellipsoid from a tensor using matplotlib

    Parameters
    ----------

    Tensor: an ozt.Tensor class instance

    n: optional. If an integer is provided, we will plot this for a sphere with
    n (grid) equi-sampled points. Otherwise, we will plot the originally
    provided Tensor's bvecs.

    
    """

    x,y,z = sphere(n=n)
    new_bvecs = np.vstack([x.ravel(), y.ravel(), z.ravel()])
    Tensor = ozt.Tensor(Tensor.Q, new_bvecs,
                        np.ones(new_bvecs.shape[-1]) * Tensor.bvals[0])

    v = Tensor.diffusion_distance.reshape(x.shape)
    
    r, phi, theta = geo.cart2sphere(x,y,z)
    x_plot, y_plot, z_plot = geo.sphere2cart(v, phi, theta)

    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')

    ax.plot_surface(x_plot, y_plot, z_plot,  rstride=2, cstride=2, shade=True)

    return fig
Exemple #7
0
def callnonlin(x0,Sreal,S0,bvals,gradients):
    
    d=x0[0]/10.**4
    if len(x0)==1:
        S=np.zeros(len(gradients))
        for (i,g) in enumerate(gradients[1:]):
            S[i+1]=S0*np.exp(-bvals[i+1]*d)
        S[0]=S0
        return Sreal-S
    if len(x0)==4:
        angles=[(x0[1],x0[2])]
        fractions=[x0[3]/100.]
    if len(x0)==7:
        angles=[(x0[1],x0[2]),(x0[3],x0[4])]
        fractions=[x0[5]/100.,x0[6]/100.]
    if len(x0)==10:
        angles=[(x0[1],x0[2]),(x0[3],x0[4]),(x0[5],x0[6])]
        fractions=[x0[7]/100.,x0[8]/100.,x0[9]/100.]    
    f0=1-np.sum(fractions)    
    S=np.zeros(len(gradients))        
    sticks=[ sphere2cart(1,np.deg2rad(pair[0]),np.deg2rad(pair[1]))  for pair in angles]
    sticks=np.array(sticks)    
    for (i,g) in enumerate(gradients[1:]):
        S[i+1]=f0*np.exp(-bvals[i+1]*d)+ np.sum([fractions[j]*np.exp(-bvals[i+1]*d*np.dot(s,g)**2) for (j,s) in enumerate(sticks)])
        S[i+1]=S0*S[i+1]    
    S[0]=S0
    return Sreal-S
Exemple #8
0
def sticks_and_ball(gtab, d=0.0015, S0=100, angles=[(0, 0), (90, 0)],
                    fractions=[35, 35], snr=20):
    """ Simulate the signal for a Sticks & Ball model.

    Parameters
    -----------
    gtab : GradientTable
        Signal measurement directions.
    d : float
        Diffusivity value.
    S0 : float
        Unweighted signal value.
    angles : array (K,2) or (K, 3)
        List of K polar angles (in degrees) for the sticks or array of K
        sticks as unit vectors.
    fractions : float
        Percentage of each stick.  Remainder to 100 specifies isotropic
        component.
    snr : float
        Signal to noise ratio, assuming Rician noise.  If set to None, no
        noise is added.

    Returns
    --------
    S : (N,) ndarray
        Simulated signal.
    sticks : (M,3)
        Sticks in cartesian coordinates.

    References
    ----------
    .. [1] Behrens et al., "Probabilistic diffusion
           tractography with multiple fiber orientations:  what can we gain?",
           Neuroimage, 2007.

    """
    fractions = [f / 100. for f in fractions]
    f0 = 1 - np.sum(fractions)
    S = np.zeros(len(gtab.bvals))

    angles = np.array(angles)
    if angles.shape[-1] == 3:
        sticks = angles
    else:
        sticks = [sphere2cart(1, np.deg2rad(pair[0]), np.deg2rad(pair[1]))
                  for pair in angles]
        sticks = np.array(sticks)

    for (i, g) in enumerate(gtab.bvecs[1:]):
        S[i + 1] = f0 * np.exp(-gtab.bvals[i + 1] * d) + \
            np.sum([fractions[j] * np.exp(-gtab.bvals[i + 1] * d * np.dot(s, g) ** 2)
                   for (j, s) in enumerate(sticks)])

        S[i + 1] = S0 * S[i + 1]

    S[gtab.b0s_mask] = S0
    S = add_noise(S, snr, S0)

    return S, sticks
Exemple #9
0
def test_invert_transform():
    n = 100.
    theta = np.arange(n)/n * np.pi  # Limited to 0,pi
    phi = (np.arange(n)/n - .5) * 2 * np.pi  # Limited to 0,2pi
    x, y, z = sphere2cart(1, theta, phi)  # Let's assume they're all unit vecs
    r, new_theta, new_phi = cart2sphere(x, y, z)  # Transform back

    yield assert_array_almost_equal, theta, new_theta
    yield assert_array_almost_equal, phi, new_phi
Exemple #10
0
def multi_tensor_odf(odf_verts, mevals, angles, fractions):
    r'''Simulate a Multi-Tensor ODF.

    Parameters
    ----------
    odf_verts : (N,3) ndarray
        Vertices of the reconstruction sphere.
    mevals : sequence of 1D arrays,
        Eigen-values for each tensor.
    angles : sequence of 2d tuples,
        Sequence of principal directions for each tensor in polar angles
        or cartesian unit coordinates.
    fractions : sequence of floats,
        Percentages of the fractions for each tensor.

    Returns
    -------
    ODF : (N,) ndarray
        Orientation distribution function.

    Examples
    --------
    Simulate a MultiTensor ODF with two peaks and calculate its exact ODF.

    >>> import numpy as np
    >>> from dipy.sims.voxel import multi_tensor_odf, all_tensor_evecs
    >>> from dipy.data import get_sphere
    >>> sphere = get_sphere('symmetric724')
    >>> vertices, faces = sphere.vertices, sphere.faces
    >>> mevals = np.array(([0.0015, 0.0003, 0.0003],[0.0015, 0.0003, 0.0003]))
    >>> angles = [(0, 0), (90, 0)]
    >>> odf = multi_tensor_odf(vertices, mevals, angles, [50, 50])

    '''

    mf = [f / 100. for f in fractions]

    angles = np.array(angles)
    if angles.shape[-1] == 3:
        sticks = angles
    else:
        sticks = [sphere2cart(1, np.deg2rad(pair[0]), np.deg2rad(pair[1]))
                  for pair in angles]
        sticks = np.array(sticks)

    odf = np.zeros(len(odf_verts))

    mevecs = []
    for s in sticks:
        mevecs += [all_tensor_evecs(s).T]

    for (j, f) in enumerate(mf):
        odf += f * single_tensor_odf(odf_verts,
                                     evals=mevals[j], evecs=mevecs[j])
    return odf
Exemple #11
0
 def radon_params(self,ang_res=64):
     #calculate radon integration parameters
     phis=np.linspace(0,2*np.pi,ang_res)[:-1]
     planars=[]
     for phi in phis:
         planars.append(sphere2cart(1,np.pi/2,phi))
     planars=np.array(planars)
     planarsR=[]
     for v in self.odf_vertices:
         R=vec2vec_rotmat(np.array([0,0,1]),v)
         planarsR.append(np.dot(R,planars.T).T)
     self.equators=planarsR
     self.equatorn=len(phis)
Exemple #12
0
def multi_tensor_pdf(pdf_points, mevals, angles, fractions,
                     tau=1 / (4 * np.pi ** 2)):
    r'''Simulate a Multi-Tensor ODF.

    Parameters
    ----------
    pdf_points : (N, 3) ndarray
        Points to evaluate the PDF.
    mevals : sequence of 1D arrays,
        Eigen-values for each tensor.  By default, values typical for prolate
        white matter are used.
    angles : sequence,
        Sequence of principal directions for each tensor in polar angles
        or cartesian unit coordinates.
    fractions : sequence of floats,
        Percentages of the fractions for each tensor.
    tau : float,
        diffusion time. By default the value that makes q=sqrt(b).

    Returns
    -------
    pdf : (N,) ndarray,
        Probability density function of the water displacement.

    References
    ----------
    .. [1] Cheng J., "Estimation and Processing of Ensemble Average Propagator
           and its Features in Diffusion MRI", PhD Thesis, 2012.

    '''
    mf = [f / 100. for f in fractions]

    angles = np.array(angles)
    if angles.shape[-1] == 3:
        sticks = angles
    else:
        sticks = [sphere2cart(1, np.deg2rad(pair[0]), np.deg2rad(pair[1]))
                  for pair in angles]
        sticks = np.array(sticks)

    pdf = np.zeros(len(pdf_points))

    mevecs = []
    for s in sticks:
        mevecs += [all_tensor_evecs(s).T]

    for j, f in enumerate(mf):
        pdf += f * single_tensor_pdf(pdf_points,
                                     evals=mevals[j], evecs=mevecs[j], tau=tau)
    return pdf
Exemple #13
0
def plot_tensor_3d(Tensor, cmap='jet', mode='ADC', file_name=None,
                   origin=[0,0,0], colorbar=False, figure=None, vmin=None,
                   vmax=None, offset=0, azimuth=60, elevation=90, roll=0,
                   scale_factor=1.0, rgb_pdd=False):

    """

    mode: either "ADC", "ellipse" or "pred_sig"

    """
    
    Q = Tensor.Q
    sphere = create_unit_sphere(5)
    vertices = sphere.vertices
    faces = sphere.faces
    x,y,z = vertices.T 

    new_bvecs = np.vstack([x.ravel(), y.ravel(), z.ravel()])
    Tensor = ozt.Tensor(Q, new_bvecs,
                        Tensor.bvals[0] * np.ones(new_bvecs.shape[-1]))

    if mode == 'ADC':
        v = Tensor.ADC * scale_factor
    elif mode == 'ellipse':
        v = Tensor.diffusion_distance * scale_factor
    elif mode == 'pred_sig':
        v = Tensor.predicted_signal(1) * scale_factor
    else:
        raise ValueError("Mode not recognized")
        
    r, phi, theta = geo.cart2sphere(x,y,z)
    x_plot, y_plot, z_plot = geo.sphere2cart(v, phi, theta)

    if rgb_pdd:
        evals, evecs = Tensor.decompose
        xyz = evecs[0]
        r = np.abs(xyz[0])/np.sum(np.abs(xyz))
        g = np.abs(xyz[1])/np.sum(np.abs(xyz))
        b = np.abs(xyz[2])/np.sum(np.abs(xyz))

        color = (r, g, b)
    else:
        color = None
    # Call and return straightaway:
    return _display_maya_voxel(x_plot, y_plot, z_plot, faces, v, origin,
                               cmap=cmap, colorbar=colorbar, color=color,
                               figure=figure,
                               vmin=vmin, vmax=vmax, file_name=file_name,
                               azimuth=azimuth, elevation=elevation)
Exemple #14
0
def scale_bvecs_by_sig(bvecs, sig):
    """
    Helper function to rescale your bvecs according to some signal, so that
    they don't fall on the unit sphere, but instead are represented in space as
    distance from the origin.
    """

    x,y,z = bvecs

    r, theta, phi = geo.cart2sphere(x, y, z)

    # Simply replace r with sig:
    x,y,z = geo.sphere2cart(sig, theta, phi)

    return x,y,z
Exemple #15
0
def random_uniform_on_sphere(n=1, coords='xyz'):
    r'''Random unit vectors from a uniform distribution on the sphere.

    Parameters
    -----------
    n : int
        Number of random vectors
    coords : {'xyz', 'radians', 'degrees'}
        'xyz' for cartesian form
        'radians' for spherical form in rads
        'degrees' for spherical form in degrees

    Notes
    ------
    The uniform distribution on the sphere, parameterized by spherical
    coordinates $(\theta, \phi)$, should verify $\phi\sim U[0,2\pi]$, while
    $z=\cos(\theta)\sim U[-1,1]$.

    References
    -----------
    .. [1] http://mathworld.wolfram.com/SpherePointPicking.html.

    Returns
    --------
    X : array, shape (n,3) if coords='xyz' or shape (n,2) otherwise
        Uniformly distributed vectors on the unit sphere.

    Examples
    ---------
    >>> from dipy.core.sphere_stats import random_uniform_on_sphere
    >>> X = random_uniform_on_sphere(4, 'radians')
    >>> X.shape == (4, 2)
    True
    >>> X = random_uniform_on_sphere(4, 'xyz')
    >>> X.shape == (4, 3)
    True
    '''
    z = np.random.uniform(-1, 1, n)
    theta = np.arccos(z)
    phi = np.random.uniform(0, 2*np.pi, n)
    if coords == 'xyz':
        r = np.ones(n)
        return np.vstack(geometry.sphere2cart(r, theta, phi)).T
    angles = np.vstack((theta, phi)).T
    if coords == 'radians':
        return angles
    if coords == 'degrees':
        return np.rad2deg(angles)
Exemple #16
0
def simulations_dipy(bvals,gradients,d=0.0015,S0=100,angles=[(0,0),(90,0)],fractions=[35,35],snr=20):
    
    fractions=[f/100. for f in fractions]    
    f0=1-np.sum(fractions)    
    S=np.zeros(len(gradients))        
    sticks=[ sphere2cart(1,np.deg2rad(pair[0]),np.deg2rad(pair[1]))  for pair in angles]
    sticks=np.array(sticks)    
    for (i,g) in enumerate(gradients[1:]):
        S[i+1]=f0*np.exp(-bvals[i+1]*d)+ np.sum([fractions[j]*np.exp(-bvals[i+1]*d*np.dot(s,g)**2) for (j,s) in enumerate(sticks)])
        S[i+1]=S0*S[i+1]    
    S[0]=S0
    
    if snr!=None:
        std=S0/snr
        S=S+np.random.randn(len(S))*std
    
    return S,sticks
Exemple #17
0
 def _tensor_helper(self, theta, phi):
         """
         This code is used in all three error functions, so we write it out
         only once here
         """
         # Convert to cartesian coordinates:
         x,y,z = geo.sphere2cart(1, theta, phi)
         bvec = [x,y,z]
         # decompose is an auto-attr of the tensor object, so is only run once
         # and then cached:
         evals, evecs = self.response_function.decompose
         rot = ozu.calculate_rotation(bvec, evecs[0])
         rot_evecs = evecs * rot
         rot_tensor = ozt.tensor_from_eigs(rot_evecs,
                                           evals,
                                           self.bvecs[:,self.b_idx],
                                           self.bvals[:,self.b_idx])
         return rot_tensor
Exemple #18
0
def SticksAndBall(bvals,gradients,d=0.0015,S0=100,angles=[(0,0),(90,0)],fractions=[35,35],snr=20):
    """ Simulating the signal for a Sticks & Ball model 
    
    Based on the paper by Tim Behrens, H.J. Berg, S. Jbabdi, "Probabilistic Diffusion Tractography with multiple fiber orientations
    what can we gain?", Neuroimage, 2007. 
    
    Parameters
    -----------
    bvals : array, shape (N,)
    gradients : array, shape (N,3) also known as bvecs
    d : diffusivity value 
    S0 : unweighted signal value
    angles : array (K,2) list of polar angles (in degrees) for the sticks
        or array (K,3) with sticks as Cartesian unit vectors and K the number of sticks
    fractions : percentage of each stick
    snr : signal to noise ration assuming gaussian noise. Provide None for no noise.
    
    Returns
    --------
    S : simulated signal
    sticks : sticks in cartesian coordinates 
    
    """
    
    fractions=[f/100. for f in fractions]    
    f0=1-np.sum(fractions)    
    S=np.zeros(len(gradients))
    
    angles=np.array(angles)
    if angles.shape[-1]==3:
        sticks=angles
    if angles.shape[-1]==2:
        sticks=[ sphere2cart(1,np.deg2rad(pair[0]),np.deg2rad(pair[1]))  for pair in angles]    
        sticks=np.array(sticks)
    
    for (i,g) in enumerate(gradients[1:]):
        S[i+1]=f0*np.exp(-bvals[i+1]*d)+ np.sum([fractions[j]*np.exp(-bvals[i+1]*d*np.dot(s,g)**2) for (j,s) in enumerate(sticks)])
        S[i+1]=S0*S[i+1]    
    S[0]=S0    
    if snr!=None:
        std=S0/snr
        S=S+np.random.randn(len(S))*std
    
    return S,sticks
Exemple #19
0
def rotate_needles(needles=[(0,0),(90,0),(90,90)],angles=(90,0,90)):

    theta,phi,psi=angles
    
    rot_theta = np.deg2rad(theta)
    rot_phi = np.deg2rad(phi)
    rot_psi = np.deg2rad(psi)
    #ANGLES FOR ROTATION IN EULER 
    
    v = np.array([np.cos(rot_phi)*np.sin(rot_theta),np.sin(rot_phi)*np.sin(rot_theta),np.cos(rot_theta)])
    #print v
    k_cross = np.array([[0,-v[2],v[1]],[v[2],0,-v[0]],[-v[1],v[0],0]])
    #print k_cross
    #rot = rotation_vec2mat(r)
    rot = np.eye(3)+np.sin(rot_psi)*k_cross+(1-np.cos(rot_psi))*np.dot(k_cross,k_cross)
    #print rot
    
    #needles=[(0,0),(90,0),(90,90)]
    #INITIAL NEEDLES in (theta, phi)
    
    needle_rads = []
    for n in needles:
        needle_rads+=[[1]+list(np.deg2rad(n))]
    #print needle_rads 
    #initial needles in (r, theta, phi)
    
    rad_needles=[]
    for n in needle_rads:
        rad_needles+=[cart2sphere(*tuple(np.dot(rot,sphere2cart(*n))))[1:3]]
    #print rad_needles
    #ROTATED NEEDLES IN SPHERICAL COORDS (RADIANS)
    
    deg_angles = []
    for n in rad_needles:
        a = []
        for c in n:
            a+=[np.rad2deg(c)]
        deg_angles += [a]
    #print deg_angles
    #ROTATED NEEDLES IN SPHERICAL COORDS (DEGREES)
    
    return deg_angles
Exemple #20
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):

    """

    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)


    # 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)
Exemple #21
0
 def vertices(self):
     return np.column_stack(sphere2cart(1, self.theta, self.phi))
Exemple #22
0
def multi_tensor(gtab, mevals, S0=100, angles=[(0, 0), (90, 0)],
                 fractions=[50, 50], snr=20):
    r"""Simulate a Multi-Tensor signal.

    Parameters
    -----------
    gtab : GradientTable
    mevals : array (K, 3)
        each tensor's eigenvalues in each row
    S0 : float
        Unweighted signal value (b0 signal).
    angles : array (K,2) or (K,3)
        List of K tensor directions in polar angles (in degrees) or unit vectors
    fractions : float
        Percentage of the contribution of each tensor. The sum of fractions
        should be equal to 100%.
    snr : float
        Signal to noise ratio, assuming Rician noise.  If set to None, no
        noise is added.

    Returns
    --------
    S : (N,) ndarray
        Simulated signal.
    sticks : (M,3)
        Sticks in cartesian coordinates.

    Examples
    --------
    >>> import numpy as np
    >>> from dipy.sims.voxel import multi_tensor
    >>> from dipy.data import get_data
    >>> from dipy.core.gradients import gradient_table
    >>> from dipy.io.gradients import read_bvals_bvecs
    >>> fimg, fbvals, fbvecs = get_data('small_101D')
    >>> bvals, bvecs = read_bvals_bvecs(fbvals, fbvecs)
    >>> gtab = gradient_table(bvals, bvecs)
    >>> mevals=np.array(([0.0015, 0.0003, 0.0003],[0.0015, 0.0003, 0.0003]))
    >>> e0 = np.array([1, 0, 0.])
    >>> e1 = np.array([0., 1, 0])
    >>> S = multi_tensor(gtab, mevals)

    """
    if np.round(np.sum(fractions), 2) != 100.0:
        raise ValueError('Fractions should sum to 100')

    fractions = [f / 100. for f in fractions]

    S = np.zeros(len(gtab.bvals))

    angles = np.array(angles)
    if angles.shape[-1] == 3:
        sticks = angles
    else:
        sticks = [sphere2cart(1, np.deg2rad(pair[0]), np.deg2rad(pair[1]))
                  for pair in angles]
        sticks = np.array(sticks)

    for i in range(len(fractions)):
            S = S + fractions[i] * single_tensor(gtab, S0=S0, evals=mevals[i],
                                                 evecs=all_tensor_evecs(
                                                     sticks[i]).T,
                                                 snr=None)

    return add_noise(S, snr, S0), sticks
Exemple #23
0
def compare_sdni_eitl():
    
    btable=np.loadtxt(get_data('dsi515btable'))
    bvals=btable[:,0]
    bvecs=btable[:,1:]   
    
    type=3
    axesn=200
    SNR=20
    
    data,gold,angs,anglesn,axesn,angles=generate_gold_data(bvals,bvecs,fibno=type,axesn=axesn,SNR=SNR)
    
    ei=EquatorialInversion(data,bvals,bvecs,odf_sphere='symmetric642',
                           auto=False,save_odfs=True,fast=True)    
    ei.radius=np.arange(0,5,0.1)
    ei.gaussian_weight=None
    ei.set_operator('laplacian')
    #{'reflect','constant','nearest','mirror', 'wrap'}
    ei.set_mode(order=1,zoom=1,mode='constant')    
    ei.update()
    ei.fit()

    dn=DiffusionNabla(data,bvals,bvecs,odf_sphere='symmetric642',
                      auto=False,save_odfs=True,fast=False)    
    dn.radius=np.arange(0,5,0.1)
    dn.gaussian_weight=None
    dn.update()
    dn.fit()
    
    vts=ei.odf_vertices
    
    def simple_peaks(ODF,faces,thr):
        x,g=ODF.shape
        PK=np.zeros((x,5))
        IN=np.zeros((x,5))
        for (i,odf) in enumerate(ODF):
            peaks,inds=peak_finding(odf,faces)
            ibigp=np.where(peaks>thr*peaks[0])[0]
            l=len(ibigp)
            if l>3:
                l=3
            PK[i,:l]=peaks[:l]
            IN[i,:l]=inds[:l]
        return PK,IN
    
    print "test0"
    thresh=0.5
    PK,IN=simple_peaks(ei.ODF,ei.odf_faces,thresh)
    res,me,st =do_compare(gold,vts,PK,IN,0,anglesn,axesn,type)
    #PKG,ING=simple_peaks(eig.ODF,ei.odf_faces,thresh)
    #resg,meg,stg =do_compare(gold,vts,PKG,ING,0,anglesn,axesn,type)
    PK,IN=simple_peaks(dn.ODF,dn.odf_faces,thresh)
    res2,me2,st2 =do_compare(gold,vts,PK,IN,0,anglesn,axesn,type)
    if type==3:
            x,y,z=sphere2cart(np.ones(len(angles)),np.deg2rad(angles),np.zeros(len(angles)))
            x2,y2,z2=sphere2cart(np.ones(len(angles)),np.deg2rad(angles),np.deg2rad(120*np.ones(len(angles))))
            angles2=[]
            for i in range(len(x)):
                angles2.append(np.rad2deg(np.arccos(np.dot([x[i],y[i],z[i]],[x2[i],y2[i],z2[i]]))))
            angles=angles2
    print "test1"
    plt.figure(1)
    plt.plot(angles,me,'k:',linewidth=3.,label='EITL')
    plt.plot(angles,me2,'k--',linewidth=3.,label='sDNI')
    #plt.plot(angles,me7,'r--',linewidth=3.,label='EITL2')
    plt.xlabel('angle')
    plt.ylabel('similarity')
    title='Angular similarity of ' + str(type) + '-fibres crossing with SNR ' + str(SNR)
    plt.title(title)
    plt.legend(loc='center right')
    plt.savefig('/tmp/test.png',dpi=300)
    plt.show()
Exemple #24
0
def sig_on_sphere(bvecs, val, fig=None, sphere_dim=1000, r_from_val=False,
                  **kwargs):
    """
    Presente values on a sphere.

    Parameters
    ----------
    bvecs: co-linear to the array with data, the theta, phi on the circle
        from which the data was taken

    val: array with data

    fig: matplotlib figure, optional. Default: make new figure

    sphere_dim: The data will be interpolated into a sphere_dim by sphere_dim
        grid 

    r_from_val: Whether to double-code the values both by color and by the
        distance from the center

    cmap: Specify a matplotlib colormap to use for coloring the data. 

    Additional kwargs can be passed to the matplotlib.pyplot.plot3D command.

    """

    # We don't need the r output
    _, theta, phi = geo.cart2sphere(bvecs[0], bvecs[1], bvecs[2])

    if fig is None:
        fig = plt.figure()
        ax = fig.add_subplot(1,1,1, projection='3d')

    # Get the cmap argument out of your kwargs, or use the default:
    cmap = kwargs.pop('cmap', matplotlib.cm.RdBu)
    
    u = np.linspace(0, 2 * np.pi, sphere_dim)
    v = np.linspace(0, np.pi, sphere_dim)

    x_inter = 10 * np.outer(np.cos(u), np.sin(v))
    y_inter = 10 * np.outer(np.sin(u), np.sin(v))
    inter_val = np.zeros(x_inter.shape).ravel()
    z_inter = np.outer(np.ones(np.size(u)), np.cos(v))
    grid_r, grid_theta, grid_phi = geo.cart2sphere(x_inter, y_inter, z_inter)
    for idx, this in enumerate(zip(grid_theta.ravel(), grid_phi.ravel())):
        this_theta = np.abs(theta - np.array(this[0]))
        this_phi = np.abs(phi - np.array(this[1]))
        # The closest theta and phi:
        min_idx = np.argmin(this_theta + this_phi)
        inter_val[idx] = val[min_idx]

    # Calculate the values from the colormap that will be used for the
    # face-colors: 
    c = np.array(color_from_val(inter_val,
                                min_val=np.min(val),
                                max_val=np.max(val),
                                cmap_or_lut=cmap))
    
    new_shape = (x_inter.shape + (3,))

    c = np.reshape(c, new_shape)

    if r_from_val:
        # Use the interpolated values to set z: 
        new_x, new_y, new_z = geo.sphere2cart(inter_val.reshape(x_inter.shape),
                                              grid_theta, grid_phi)

        ax.plot_surface(new_x, new_y, new_z, rstride=4, cstride=4,
                        facecolors=c, **kwargs)
    else: 
        ax.plot_surface(x_inter, y_inter, z_inter, rstride=4, cstride=4,
                        facecolors=c, **kwargs)

    return fig
Exemple #25
0
def generate_gold_data(bvals,bvecs,fibno=1,axesn=10,SNR=None):
        
    #1 fiber case
    if fibno==1:
        data=np.zeros((axesn,len(bvals)))
        gold=np.zeros((axesn,3))    
        X=random_uniform_on_sphere(axesn,'xyz')        
        for (j,x) in enumerate(X):
            S,sticks=SticksAndBall(bvals,bvecs,d=0.0015,S0=100,angles=np.array([x]),fractions=[100],snr=SNR)
            data[j,:]=S[:]
            gold[j,:3]=x
        return data,gold,None,None,axesn,None

    #2 fibers case
    if fibno==2:        
        angles=np.arange(0,92,2.5)#5
        u=np.array([0,0,1])    
        anglesn=len(angles)        
        data=np.zeros((anglesn*axesn,len(bvals)))
        gold=np.zeros((anglesn*axesn,6))
        angs=[]
        for (i,a) in enumerate(angles):        
            v=sphere2cart(1,np.deg2rad(a),0)
            X=random_uniform_on_sphere(axesn,'xyz')        
            for (j,x) in enumerate(X):
                R=rodriguez_axis_rotation(x,360*np.random.rand())                
                ur=np.dot(R,u)
                vr=np.dot(R,v)                        
                S,sticks=SticksAndBall(bvals,bvecs,d=0.0015,S0=100,angles=np.array([ur,vr]),fractions=[50,50],snr=SNR)
                data[i*axesn+j,:]=S[:]
                gold[i*axesn+j,:3]=ur
                gold[i*axesn+j,3:]=vr
                angs.append(a)
        return data,gold,angs,anglesn,axesn,angles
               
    #3 fibers case
    if fibno==3:    
        #phis=np.array([0.,120.,240.])
        #angles=np.arange(0,92,5)
        angles=np.linspace(0,54.73,40)#20           
        anglesn=len(angles)        
        data=np.zeros((anglesn*axesn,len(bvals)))
        gold=np.zeros((anglesn*axesn,9))
        angs=[]
        for (i,a) in enumerate(angles): 
            u=sphere2cart(1,np.deg2rad(a),np.deg2rad(0))
            v=sphere2cart(1,np.deg2rad(a),np.deg2rad(120))
            w=sphere2cart(1,np.deg2rad(a),np.deg2rad(240))        
            X=random_uniform_on_sphere(axesn,'xyz')        
            for (j,x) in enumerate(X):
                R=rodriguez_axis_rotation(x,360*np.random.rand())
                ur=np.dot(R,u)
                vr=np.dot(R,v)
                wr=np.dot(R,w)         
                S,sticks=SticksAndBall(bvals,bvecs,d=0.0015,S0=100,angles=np.array([ur,vr,wr]),fractions=[33,33,33],snr=SNR)
                print i,j
                data[i*axesn+j,:]=S[:]
                gold[i*axesn+j,:3]=ur
                gold[i*axesn+j,3:6]=vr
                gold[i*axesn+j,6:]=wr                                        
                angs.append(a)
                
        return data,gold,angs,anglesn,axesn,angles
Exemple #26
0
def compare_dni_dsi_gqi_gqi2_eit():

    #stop
    
    btable=np.loadtxt(get_data('dsi515btable'))
    bvals=btable[:,0]
    bvecs=btable[:,1:]
    
    type=3
    axesn=200
    SNR=20
    
    data,gold,angs,anglesn,axesn,angles=generate_gold_data(bvals,bvecs,fibno=type,axesn=axesn,SNR=SNR)
    
    gq=GeneralizedQSampling(data,bvals,bvecs,1.2,odf_sphere='symmetric642',squared=False,save_odfs=True)    
    gq2=GeneralizedQSampling(data,bvals,bvecs,3.,odf_sphere='symmetric642',squared=True,save_odfs=True)
    
    ds=DiffusionSpectrum(data,bvals,bvecs,odf_sphere='symmetric642',auto=False,save_odfs=True)
    ds.filter_width=32.    
    ds.update()
    ds.fit()
    
    ei=EquatorialInversion(data,bvals,bvecs,odf_sphere='symmetric642',auto=False,save_odfs=True,fast=True)    
    ei.radius=np.arange(0,5,0.1)
    ei.gaussian_weight=None#0.01
    ei.set_operator('laplacian')
    ei.update()
    ei.fit()
    
    ei2=EquatorialInversion(data,bvals,bvecs,odf_sphere='symmetric642',auto=False,save_odfs=True,fast=True)    
    ei2.radius=np.arange(0,5,0.1)
    ei2.gaussian_weight=None
    ei2.set_operator('laplap')
    ei2.update()
    ei2.fit()
    
    ei3=EquatorialInversion(data,bvals,bvecs,odf_sphere='symmetric642',auto=False,save_odfs=True,fast=True)    
    ei3.radius=np.arange(0,5,0.1)
    ei3.gaussian_weight=None
    ei3.set_operator('signal')
    ei3.update()
    ei3.fit()    
    
    """
    blobs=np.zeros((2,4,642))
    
    no=200
    blobs[0,0,:]=gq.ODF[no]
    blobs[0,1,:]=gq2.ODF[no]
    blobs[0,2,:]=ds.ODF[no]
    blobs[0,3,:]=ei.ODF[no]
    no=399
    blobs[1,0,:]=gq.ODF[no]
    blobs[1,1,:]=gq2.ODF[no]
    blobs[1,2,:]=ds.ODF[no]
    blobs[1,3,:]=ei.ODF[no]       
    show_blobs(blobs[None,:,:,:],ei.odf_vertices,ei.odf_faces,1.2)
    """
    #stop
    
    vts=gq.odf_vertices
    
    def simple_peaks(ODF,faces,thr):
        x,g=ODF.shape
        PK=np.zeros((x,5))
        IN=np.zeros((x,5))
        for (i,odf) in enumerate(ODF):
            peaks,inds=peak_finding(odf,faces)
            ibigp=np.where(peaks>thr*peaks[0])[0]
            l=len(ibigp)
            if l>3:
                l=3
            PK[i,:l]=peaks[:l]
            IN[i,:l]=inds[:l]
        return PK,IN
    
    
    thresh=0.5
    
    PK,IN=simple_peaks(ds.ODF,ds.odf_faces,thresh)
    res,me,st =do_compare(gold,vts,PK,IN,0,anglesn,axesn,type)
    
    PK,IN=simple_peaks(gq.ODF,ds.odf_faces,thresh)
    res2,me2,st2 =do_compare(gold,vts,PK,IN,0,anglesn,axesn,type)
    
    PK,IN=simple_peaks(gq2.ODF,ds.odf_faces,thresh)
    res3,me3,st3 =do_compare(gold,vts,PK,IN,0,anglesn,axesn,type)
    
    PK,IN=simple_peaks(ei.ODF,ds.odf_faces,thresh)
    res4,me4,st4 =do_compare(gold,vts,PK,IN,0,anglesn,axesn,type)
        
    PK,IN=simple_peaks(ei2.ODF,ds.odf_faces,thresh)
    res5,me5,st5 =do_compare(gold,vts,PK,IN,0,anglesn,axesn,type)
      
    PK,IN=simple_peaks(ei3.ODF,ei3.odf_faces,thresh)
    res6,me6,st6 =do_compare(gold,vts,PK,IN,0,anglesn,axesn,type)
    
    #res7,me7,st7 =do_compare(ei2.PK,ei2.IN,0,anglesn,axesn,type)
    
    if type==1:    
        plt.figure(1)       
        plt.plot(res,'r',label='DSI')
        plt.plot(res2,'g',label='GQI')
        plt.plot(res3,'b',label='GQI2')
        plt.plot(res4,'k',label='EITL')
        plt.plot(res5,'k--',label='EITL2')
        plt.plot(res6,'k-.',label='EITS')
        #plt.xlabel('angle')
        #plt.ylabel('resolution')
        #plt.title('Angular accuracy')
        plt.legend()
        plt.show()   
    else:
        
        if type==3:
            x,y,z=sphere2cart(np.ones(len(angles)),np.deg2rad(angles),np.zeros(len(angles)))
            x2,y2,z2=sphere2cart(np.ones(len(angles)),np.deg2rad(angles),np.deg2rad(120*np.ones(len(angles))))
            angles2=[]        
            for i in range(len(x)):
                angles2.append(np.rad2deg(np.arccos(np.dot([x[i],y[i],z[i]],[x2[i],y2[i],z2[i]]))))
            angles=angles2    
            
        plt.figure(1)
        plt.plot(angles,me,'r',linewidth=3.,label='DSI')
        plt.plot(angles,me2,'g',linewidth=3.,label='GQI')
        plt.plot(angles,me3,'b',linewidth=3.,label='GQI2')
        plt.plot(angles,me4,'k',linewidth=3.,label='EITL')
        plt.plot(angles,me5,'k--',linewidth=3.,label='EITL2')
        plt.plot(angles,me6,'k-.',linewidth=3.,label='EITS')
        #plt.plot(angles,me7,'r--',linewidth=3.,label='EITL2')
        plt.xlabel('angle')
        plt.ylabel('similarity')
        
        title='Angular similarity of ' + str(type) + '-fibres crossing with SNR ' + str(SNR)
        plt.title(title)
        plt.legend(loc='center right')
        plt.savefig('/tmp/test.png',dpi=300)
        plt.show()
Exemple #27
0
def sticks_and_ball(bvals, gradients, d=0.0015, S0=100, angles=[(0,0), (90,0)],
                    fractions=[35,35], snr=20):
    """ Simulate the signal for a Sticks & Ball model.

    Parameters
    -----------
    bvals : (N,) ndarray
        B-values for measurements.
    gradients : (N,3) ndarray
        Also known as b-vectors.
    d : float
        Diffusivity value.
    S0 : float
        Unweighted signal value.
    angles : array (K,2) or (M,3)
        List of K polar angles (in degrees) for the sticks or array of M
        sticks as Cartesian unit vectors.
    fractions : float
        Percentage of each stick.
    snr : float
        Signal to noise ratio, assuming gaussian noise.  If set to None, no
        noise is added.

    Returns
    --------
    S : (N,) ndarray
        Simulated signal.
    sticks : (M,3)
        Sticks in cartesian coordinates.

    References
    ----------
    .. [1] Behrens et al., "Probabilistic diffusion
           tractography with multiple fiber orientations:  what can we gain?",
           Neuroimage, 2007.

    """

    fractions = [f / 100. for f in fractions]
    f0 = 1 - np.sum(fractions)
    S = np.zeros(len(gradients))

    angles=np.array(angles)
    if angles.shape[-1] == 3:
        sticks = angles
    else:
        sticks = [sphere2cart(1, np.deg2rad(pair[0]), np.deg2rad(pair[1]))
                  for pair in angles]
        sticks = np.array(sticks)

    for (i, g) in enumerate(gradients[1:]):
        S[i + 1] = f0 * np.exp(-bvals[i+1] * d) + \
                   np.sum([
            fractions[j] * np.exp(-bvals[i + 1] * d * np.dot(s, g)**2)
            for (j,s) in enumerate(sticks)
                          ])

        S[i + 1] = S0 * S[i + 1]

    S[0] = S0
    if snr is not None:
        std = S0 / snr
        S = S + np.random.randn(len(S)) * std

    return S, sticks
Exemple #28
0
def test():

    # img=nib.load('/home/eg309/Data/project01_dsi/connectome_0001/tp1/RAWDATA/OUT/mr000001.nii.gz')
    btable = np.loadtxt(get_data("dsi515btable"))
    # volume size
    sz = 16
    # shifting
    origin = 8
    # hanning width
    filter_width = 32.0
    # number of signal sampling points
    n = 515
    # odf radius
    radius = np.arange(2.1, 6, 0.2)
    # create q-table
    bv = btable[:, 0]
    bmin = np.sort(bv)[1]
    bv = np.sqrt(bv / bmin)
    qtable = np.vstack((bv, bv, bv)).T * btable[:, 1:]
    qtable = np.floor(qtable + 0.5)
    # copy bvals and bvecs
    bvals = btable[:, 0]
    bvecs = btable[:, 1:]
    # S=img.get_data()[38,50,20]#[96/2,96/2,20]
    S, stics = SticksAndBall(
        bvals, bvecs, d=0.0015, S0=100, angles=[(0, 0), (60, 0), (90, 90)], fractions=[0, 0, 0], snr=None
    )

    S2 = S.copy()
    S2 = S2.reshape(1, len(S))
    dn = DiffusionNabla(S2, bvals, bvecs, auto=False)
    pR = dn.equators
    odf = dn.odf(S)
    # Xs=dn.precompute_interp_coords()
    peaks, inds = peak_finding(odf.astype("f8"), dn.odf_faces.astype("uint16"))
    print peaks
    print peaks / peaks.min()
    # print dn.PK
    dn.fit()
    print dn.PK

    # """
    ren = fvtk.ren()
    colors = fvtk.colors(odf, "jet")
    fvtk.add(ren, fvtk.point(dn.odf_vertices, colors, point_radius=0.05, theta=8, phi=8))
    fvtk.show(ren)
    # """

    stop

    # ds=DiffusionSpectrum(S2,bvals,bvecs)
    # tpr=ds.pdf(S)
    # todf=ds.odf(tpr)

    """
    #show projected signal
    Bvecs=np.concatenate([bvecs[1:],-bvecs[1:]])
    X0=np.dot(np.diag(np.concatenate([S[1:],S[1:]])),Bvecs)    
    ren=fvtk.ren()
    fvtk.add(ren,fvtk.point(X0,fvtk.yellow,1,2,16,16))    
    fvtk.show(ren)
    """
    # qtable=5*matrix[:,1:]

    # calculate radius for the hanning filter
    r = np.sqrt(qtable[:, 0] ** 2 + qtable[:, 1] ** 2 + qtable[:, 2] ** 2)

    # setting hanning filter width and hanning
    hanning = 0.5 * np.cos(2 * np.pi * r / filter_width)

    # center and index in q space volume
    q = qtable + origin
    q = q.astype("i8")

    # apply the hanning filter
    values = S * hanning

    """
    #plot q-table
    ren=fvtk.ren()
    colors=fvtk.colors(values,'jet')
    fvtk.add(ren,fvtk.point(q,colors,1,0.1,6,6))
    fvtk.show(ren)
    """

    # create the signal volume
    Sq = np.zeros((sz, sz, sz))
    for i in range(n):
        Sq[q[i][0], q[i][1], q[i][2]] += values[i]

    # apply fourier transform
    Pr = fftshift(np.abs(np.real(fftn(fftshift(Sq), (sz, sz, sz)))))

    # """
    ren = fvtk.ren()
    vol = fvtk.volume(Pr)
    fvtk.add(ren, vol)
    fvtk.show(ren)
    # """

    """
    from enthought.mayavi import mlab
    mlab.pipeline.volume(mlab.pipeline.scalar_field(Sq))
    mlab.show()
    """

    # vertices, edges, faces  = create_unit_sphere(5)
    vertices, faces = sphere_vf_from("symmetric362")
    odf = np.zeros(len(vertices))

    for m in range(len(vertices)):

        xi = origin + radius * vertices[m, 0]
        yi = origin + radius * vertices[m, 1]
        zi = origin + radius * vertices[m, 2]
        PrI = map_coordinates(Pr, np.vstack((xi, yi, zi)), order=1)
        for i in range(len(radius)):
            odf[m] = odf[m] + PrI[i] * radius[i] ** 2

    """
    ren=fvtk.ren()
    colors=fvtk.colors(odf,'jet')
    fvtk.add(ren,fvtk.point(vertices,colors,point_radius=.05,theta=8,phi=8))
    fvtk.show(ren)
    """

    """
    #Pr[Pr<500]=0    
    ren=fvtk.ren()
    #ren.SetBackground(1,1,1)
    fvtk.add(ren,fvtk.volume(Pr))
    fvtk.show(ren)
    """

    peaks, inds = peak_finding(odf.astype("f8"), faces.astype("uint16"))

    Eq = np.zeros((sz, sz, sz))
    for i in range(n):
        Eq[q[i][0], q[i][1], q[i][2]] += S[i] / S[0]

    LEq = laplace(Eq)

    # Pr[Pr<500]=0
    ren = fvtk.ren()
    # ren.SetBackground(1,1,1)
    fvtk.add(ren, fvtk.volume(Eq))
    fvtk.show(ren)

    phis = np.linspace(0, 2 * np.pi, 100)

    planars = []
    for phi in phis:
        planars.append(sphere2cart(1, np.pi / 2, phi))
    planars = np.array(planars)

    planarsR = []
    for v in vertices:
        R = vec2vec_rotmat(np.array([0, 0, 1]), v)
        planarsR.append(np.dot(R, planars.T).T)

    """
    ren=fvtk.ren()
    fvtk.add(ren,fvtk.point(planarsR[0],fvtk.green,1,0.1,8,8))
    fvtk.add(ren,fvtk.point(2*planarsR[1],fvtk.red,1,0.1,8,8))
    fvtk.show(ren)
    """

    azimsums = []
    for disk in planarsR:
        diskshift = 4 * disk + origin
        # Sq0=map_coordinates(Sq,diskshift.T,order=1)
        # azimsums.append(np.sum(Sq0))
        # Eq0=map_coordinates(Eq,diskshift.T,order=1)
        # azimsums.append(np.sum(Eq0))
        LEq0 = map_coordinates(LEq, diskshift.T, order=1)
        azimsums.append(np.sum(LEq0))

    azimsums = np.array(azimsums)

    # """
    ren = fvtk.ren()
    colors = fvtk.colors(azimsums, "jet")
    fvtk.add(ren, fvtk.point(vertices, colors, point_radius=0.05, theta=8, phi=8))
    fvtk.show(ren)
    # """

    # for p in planarsR[0]:
    """
Exemple #29
0
def test_kurtosis_maximum():
    # TEST 1
    # simulate a crossing fibers interserting at 70 degrees. The first fiber
    # is aligned to the x-axis while the second fiber is aligned to the x-z
    # plane with an angular deviation of 70 degrees from the first one.
    # According to Neto Henriques et al, 2015 (NeuroImage 111: 85-99), the
    # kurtosis tensor of this simulation will have a maxima aligned to axis y
    angles = [(90, 0), (90, 0), (20, 0), (20, 0)]
    signal_70, dt_70, kt_70 = multi_tensor_dki(gtab_2s, mevals_cross, S0=100,
                                               angles=angles,
                                               fractions=frac_cross, snr=None)
    # prepare inputs
    dkiM = dki.DiffusionKurtosisModel(gtab_2s, fit_method="WLS")
    dkiF = dkiM.fit(signal_70)
    MD = dkiF.md
    kt = dkiF.kt
    R = dkiF.evecs
    evals = dkiF.evals
    dt = lower_triangular(np.dot(np.dot(R, np.diag(evals)), R.T))
    sphere = get_sphere('symmetric724')

    # compute maxima
    k_max_cross, max_dir = dki._voxel_kurtosis_maximum(dt, MD, kt, sphere,
                                                       gtol=1e-5)

    yaxis = np.array([0., 1., 0.])
    cos_angle = np.abs(np.dot(max_dir[0], yaxis))
    assert_almost_equal(cos_angle, 1.)

    # TEST 2
    # test the function on cases of well aligned fibers oriented in a random
    # defined direction. According to Neto Henriques et al, 2015 (NeuroImage
    # 111: 85-99), the maxima of kurtosis is any direction perpendicular to the
    # fiber direction. Moreover, according to multicompartmetal simulations,
    # kurtosis in this direction has to be equal to:
    fie = 0.49
    ADi = 0.00099
    ADe = 0.00226
    RDi = 0
    RDe = 0.00087
    RD = fie*RDi + (1-fie)*RDe
    RK = 3 * fie * (1-fie) * ((RDi-RDe) / RD) ** 2

    # 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)

    # prepare inputs
    dkiM = dki.DiffusionKurtosisModel(gtab_2s, fit_method="WLS")
    dkiF = dkiM.fit(signal)
    MD = dkiF.md
    kt = dkiF.kt
    R = dkiF.evecs
    evals = dkiF.evals
    dt = lower_triangular(np.dot(np.dot(R, np.diag(evals)), R.T))

    # compute maxima
    k_max, max_dir = dki._voxel_kurtosis_maximum(dt, MD, kt, sphere, gtol=1e-5)

    # check if max direction is perpendicular to fiber direction
    fdir = np.array([sphere2cart(1., np.deg2rad(theta), np.deg2rad(phi))])
    cos_angle = np.abs(np.dot(max_dir[0], fdir[0]))
    assert_almost_equal(cos_angle, 0., decimal=5)

    # check if max direction is equal to expected value
    assert_almost_equal(k_max, RK)

    # According to Neto Henriques et al., 2015 (NeuroImage 111: 85-99),
    # e.g. see figure 1 of this article, kurtosis maxima for the first test is
    # also equal to the maxima kurtosis value of well-aligned fibers, since
    # simulations parameters (apart from fiber directions) are equal
    assert_almost_equal(k_max_cross, RK)

    # Test 3 - Test performance when kurtosis is spherical - this case, can be
    # problematic since a spherical kurtosis does not have an maximum
    k_max, max_dir = dki._voxel_kurtosis_maximum(dt_sph, np.mean(evals_sph),
                                                 kt_sph, sphere, gtol=1e-2)
    assert_almost_equal(k_max, Kref_sphere)

    # Test 4 - Test performance when kt have all elements zero - this case, can
    # be problematic this case does not have an maximum
    k_max, max_dir = dki._voxel_kurtosis_maximum(dt_sph, np.mean(evals_sph),
                                                 np.zeros(15), sphere,
                                                 gtol=1e-2)
    assert_almost_equal(k_max, 0.0)
Exemple #30
0
#needles = np.array([-np.pi/4,np.pi/4])
needles2d = np.array([0,np.pi/4.,np.pi/2.])

angles2d = np.linspace(-np.pi, np.pi,100)

def signal2d(S0,f,b,d,needles2d,angles2d):
    return S0*np.array([(1-f[0]-f[1]-f[2])*np.exp(-b*d) + \
                      f[0]*np.exp(-b*d*(np.cos(needles2d[0]-gradient))**2) + \
                      f[1]*np.exp(-b*d*(np.cos(needles2d[1]-gradient))**2) + \
                      f[2]*np.exp(-b*d*(np.cos(needles2d[2]-gradient))**2) \
                      for gradient in angles2d])


#needles3d = [sphere2cart(1,0,0),sphere2cart(1,np.pi/2.,0),sphere2cart(1,np.pi/2.,np.pi/2.)]
needles3d = np.array([sphere2cart(1,0,0),sphere2cart(1,np.pi/2.,0),sphere2cart(1,np.pi/2.,np.pi/2.)])

angles2d = np.linspace(-np.pi, np.pi,100)

def signal3d(S0,f,b0,d,needles3d,bvals,gradients):
    S = S0*np.array([(1-f[0]-f[1]-f[2])*np.exp(-b0*d) + \
                      f[0]*np.exp(-bvals[i]*d*(np.dot(needles3d[0],gradient))**2) + \
                      f[1]*np.exp(-bvals[i]*d*(np.dot(needles3d[1],gradient))**2) + \
                      f[2]*np.exp(-bvals[i]*d*(np.dot(needles3d[2],gradient))**2) \
                      for (i,gradient) in enumerate(gradients)])
    return S, np.dot(np.diag(S),gradients)

#dsi202 = np.row_stack((dsi102[1:,:],-dsi102[1:,:]))
#print dsi202.shape

#print bvals102.shape