Ejemplo n.º 1
0
    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
Ejemplo n.º 2
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
Ejemplo n.º 3
0
    def _pred_sig_ball_and_stick(self, params, check_constraints=False):
        """
            This is the signal prediction for the ball-and-stick model
            """
        theta, phi, w, d = params

        if check_constraints:
            if self._check_constraints([
                [theta, 0, np.pi],
                [phi, -np.pi, np.pi],
                [w, 0, 1],  # Weights are 0-1
                [d, 0, np.inf]
            ]):  # Diffusivity is
                # non-negative
                return np.inf

        # In each one we have a different axial diffusivity for the response
        # function. Simply multiply it by the current d:
        # Need to replace the canonical tensor with a
        self.response_function = ozt.Tensor(np.diag([1, 0, 0]),
                                            self.bvecs[:, self.b_idx],
                                            self.bvals[self.b_idx])

        self.response_function.Q = self.response_function.Q * d
        rot_tensor = self._tensor_helper(theta, phi)
        return (1 - w) * d + w * rot_tensor.predicted_signal(1)
Ejemplo n.º 4
0
def test_Tensor_decompose():
    """
    Test the eigen-vector/value decomposition of the tensor:
    """
    q = np.array([
        [1.5, 0, 0],
        [0, 0.5, 0],  # This needs to be slightly higher, so that
        # there is no ambiguity about the order of the
        # evals
        [0, 0, 0.5]
    ])

    # And the bvecs are unit vectors:
    bvecs = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
    bvals = [1, 1, 1]

    T1 = mtt.Tensor(q, bvecs, bvals)
    vals, vecs = T1.decompose

    npt.assert_equal(vecs, np.eye(3))
    npt.assert_equal(vals, np.diag(q))

    T2 = mtt.tensor_from_eigs(vecs, vals, bvecs, bvals)

    npt.assert_equal(T2.Q, q)
Ejemplo n.º 5
0
 def response_function(self):
     """
     A canonical tensor that describes the presumed response of a single
     fiber 
     """
     bvecs = self.bvecs[:, self.b_idx]
     bvals = self.bvals[self.b_idx]
     return ozt.Tensor(np.diag([self.ad, self.rd, self.rd]), bvecs, bvals)
Ejemplo n.º 6
0
def test_Tensor():
    """
    Test initialization of tensor objects
    """
    bvecs = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
    bvals = [1, 1, 1]

    npt.assert_raises(ValueError, mtt.Tensor, np.arange(20), bvecs, bvals)

    Q1 = [0, 1, 2, 3, 4, 5]
    t1 = mtt.Tensor(Q1, bvecs, bvals)

    # Follows conventions from vistasoft's dt6to33:
    npt.assert_equal(t1.Q, [[0, 3, 4], [3, 1, 5], [4, 5, 2]])

    # This should not be an acceptable input (would lead to asymmetric output):
    Q2 = [0, 1, 2, 3, 4, 5, 6, 7, 8]
    npt.assert_raises(ValueError, mtt.Tensor, Q2, bvecs, bvals)

    # Same here:
    Q3 = [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
    npt.assert_raises(ValueError, mtt.Tensor, Q2, bvecs, bvals)

    # No problem here:
    Q4 = [[0, 3, 4], [3, 1, 5], [4, 5, 2]]
    mtt.Tensor(Q4, bvecs, bvals)

    # More error handling:
    # bvecs and bvals need to be the same length:
    Q5 = npt.assert_raises(ValueError, mtt.Tensor, Q4, bvecs[:2], bvals)

    # bvecs needs to be 3 by n:
    Q6 = npt.assert_raises(
        ValueError, mtt.Tensor, Q4,
        [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]], bvals)

    # bvecs need to be unit length!
    Q7 = npt.assert_raises(ValueError, mtt.Tensor, Q4,
                           [[1, 0, 0], [0, 1, 0], [0, 1, 1]], bvals)

    # bvecs and bvals need to have the same length!
    Q8 = npt.assert_raises(ValueError, mtt.Tensor, Q4,
                           [[1, 0, 0], [0, 1, 0], [0, 0, 1]],
                           np.hstack([bvals, 1]))
Ejemplo n.º 7
0
def test_response_function():
    rf_bvec = np.reshape(bvecs_t[:, 4], (3, 1))
    tensor_t = ozt.Tensor(np.diag([1.5, 0.5, 0.5]), rf_bvec, np.array([1000]))

    evals_a, evecs_a = mb.response_function(1000, rf_bvec).decompose
    evals_t, evecs_t = tensor_t.decompose

    npt.assert_equal(evals_t, evals_a)
    npt.assert_equal(evecs_t, evecs_a)

    return evals_t, evecs_t
Ejemplo n.º 8
0
def test_Tensor_ADC():
    # If we have a diagonal tensor:
    Q1_diag = np.random.rand(3)
    Q1 = np.diag(Q1_diag)

    # And the bvecs are unit vectors:
    bvecs = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
    bvals = [1, 1, 1]
    # Initialize:
    T1 = mtt.Tensor(Q1, bvecs, bvals)
    # We should simply get back the diagonal elements of the tensor:
    npt.assert_equal(T1.ADC, Q1_diag)
Ejemplo n.º 9
0
    def response_function(self):
        """
        A canonical tensor that describes the presumed response of a single
        fiber 
        """
        if self.response_file is None:
            if self.verbose:
                print("Using tensor-based response function")
            return ozt.Tensor(np.diag([self.ad, self.rd,
                                       self.rd]), self.bvecs[:, self.b_idx],
                              self.bvals[self.b_idx])

        else:
            return _SphericalHarmonicResponseFunction(self)
Ejemplo n.º 10
0
def test_diffusion_distance():
    """
    Test for regression on the calculation of diffusion distance
    """

    Q1 = np.array([[0.53343911, 0., 0.], [0., 0.61706389, 0.],
                   [0., 0., 0.64934378]])

    bvecs = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1],
                      [-0.24187, 0.10309, -0.96482]]).T
    bvals = [1, 1, 1, 1]

    T1 = mtt.Tensor(Q1, bvecs, bvals)

    npt.assert_almost_equal(
        T1.diffusion_distance,
        np.array([0.73036916, 0.78553414, 0.8058187, 0.80052344]))
Ejemplo n.º 11
0
def test_Tensor_predicted_signal():
    """
    Test prediction of the signal from the Tensor:
    """
    Q1_diag = np.random.rand(3)
    Q1 = np.diag(Q1_diag)

    # And the bvecs are unit vectors:
    bvecs = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
    bvals = [1, 1, 1]

    T1 = mtt.Tensor(Q1, bvecs, bvals)

    # Should be possible to provide a value of S0 per bvec:
    S0_1 = [1, 1, 1]

    # In this case, that should give the same answer as just providing a single
    # scalar value:
    S0_2 = [1]

    npt.assert_equal(T1.predicted_signal(S0_1), T1.predicted_signal(S0_2))
Ejemplo n.º 12
0
def test_convlove_odf():
    """
    Test convolution of a tensor with a fiber orientation distribution function
    (odf)
    """
    Q1_diag = np.random.rand(3)
    Q1 = np.diag(Q1_diag)

    # And the bvecs are unit vectors (one's taken from actual data, so that we
    # have a 3 by 4):
    bvecs = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1],
                      [-0.24187, 0.10309, -0.96482]]).T
    bvals = [1, 1, 1, 1]

    T1 = mtt.Tensor(Q1, bvecs, bvals)

    S0 = 1000

    # Has the same length as the number of bvecs:
    odf = [0.1, 0.2, 0.3, 0.4]

    # This performs the convolution
    T1.convolve_odf(odf, S0)
Ejemplo n.º 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)