def test_coordinate_transformation():
    # test for a vector of size 3
    cartesian_vector = np.random.rand(3)
    spherical_vector = utils.cart2sphere(cartesian_vector)
    recovered_cartesian_vector = utils.sphere2cart(spherical_vector)
    assert_almost_equal(cartesian_vector, recovered_cartesian_vector)

    # test for a vector of size N x 3
    cartesian_vector = np.random.rand(10, 3)
    spherical_vector = utils.cart2sphere(cartesian_vector)
    recovered_cartesian_vector = utils.sphere2cart(spherical_vector)
    assert_almost_equal(cartesian_vector, recovered_cartesian_vector)
Esempio n. 2
0
def test_rotation_on_bingham_tensor():
    # test 5: does combined rotation rotate Bingham well?
    kappa_ = np.random.rand()
    beta_ = kappa_ / 2.  # beta<kappa
    Bdiag_ = np.diag(np.r_[kappa_, beta_, 0])

    theta_ = np.random.rand() * np.pi
    phi_ = (np.random.rand() - .5) * np.pi
    psi_ = np.random.rand() * np.pi * 0
    R_ = rotation_matrix_100_to_theta_phi_psi(theta_, phi_, psi_)

    B_ = R_.dot(Bdiag_).dot(R_.T)
    eigvals, eigvecs = np.linalg.eigh(B_)
    main_evec = eigvecs[:, np.argmax(eigvals)]
    _, theta_rec0, phi_rec0 = utils.cart2sphere(main_evec)

    # checking if the angles are antipodal to each other
    if abs(theta_ - theta_rec0) > 1e-5:
        theta_rec = np.pi - theta_rec0
        if phi_rec0 > 0:
            phi_rec = phi_rec0 - np.pi
        elif phi_rec0 < 0:
            phi_rec = phi_rec0 + np.pi
    else:
        theta_rec = theta_rec0
        phi_rec = phi_rec0
    assert_almost_equal(theta_, theta_rec)
    assert_almost_equal(phi_, phi_rec)
    assert_almost_equal(np.diag(Bdiag_), np.sort(eigvals)[::-1])
Esempio n. 3
0
def test_rotation_100_to_theta_phi():
    # test 1: does R100_to_theta_phi rotate a vector theta_phi?
    theta_ = np.random.rand() * np.pi
    phi_ = (np.random.rand() - .5) * np.pi
    R100_to_theta_pi = rotation_matrix_100_to_theta_phi(theta_, phi_)
    xyz = np.dot(R100_to_theta_pi, np.r_[1, 0, 0])
    _, theta_rec, phi_rec = utils.cart2sphere(xyz)
    assert_almost_equal(theta_, theta_rec)
    assert_almost_equal(phi_, phi_rec)
Esempio n. 4
0
def test_psi_insensitivity_when_doing_psi_theta_phi_rotation():
    # test 3: does psi still have no influence on main eigenvector when doing
    # both rotations?
    theta_ = np.random.rand() * np.pi
    phi_ = (np.random.rand() - .5) * np.pi
    psi_ = np.random.rand() * np.pi
    R_ = rotation_matrix_100_to_theta_phi_psi(theta_, phi_, psi_)
    xyz = np.dot(R_, np.r_[1, 0, 0])
    _, theta_rec, phi_rec = utils.cart2sphere(xyz)
    assert_almost_equal(theta_, theta_rec)
    assert_almost_equal(phi_, phi_rec)
Esempio n. 5
0
def test_watson_orienting():
    # test for orienting the axis of the Watson distribution mu for k>0
    # first test to see if Wn is highest along mu
    sphere = get_sphere('repulsion724')
    n = sphere.vertices
    indices = np.array(range(n.shape[0]))
    np.random.shuffle(indices)
    mu_index = indices[0]
    mu_cart = n[mu_index]
    mu_sphere = utils.cart2sphere(mu_cart)[1:]
    odi = np.random.rand()
    watson = distributions.SD1Watson(mu=mu_sphere, odi=odi)
    Wn_vector = watson(n=n)
    assert_almost_equal(Wn_vector[mu_index], max(Wn_vector))

    # second test to see if Wn is lowest prependicular to mu
    mu_perp = utils.perpendicular_vector(mu_cart)
    Wn_perp = watson(n=mu_perp)
    assert_equal(np.all(Wn_perp < Wn_vector), True)
def test_spherical_convolution_watson_sh(sh_order=4):
    sphere = get_sphere('symmetric724')

    n = sphere.vertices
    bval = np.tile(1e9, len(n))
    scheme = acquisition_scheme_from_bvalues(bval, n, delta, Delta)
    indices_sphere_orientations = np.arange(sphere.vertices.shape[0])
    np.random.shuffle(indices_sphere_orientations)
    mu_index = indices_sphere_orientations[0]
    mu_watson = sphere.vertices[mu_index]
    mu_watson_sphere = utils.cart2sphere(mu_watson)[1:]

    watson = distributions.SD1Watson(mu=mu_watson_sphere, odi=.3)
    f_sf = watson(n=sphere.vertices)
    f_sh = sf_to_sh(f_sf, sphere, sh_order)

    lambda_par = 2e-9
    stick = cylinder_models.C1Stick(mu=[0, 0], lambda_par=lambda_par)
    k_sf = stick(scheme)
    sh_matrix, m, n = real_sym_sh_mrtrix(sh_order, sphere.theta, sphere.phi)
    sh_matrix_inv = np.linalg.pinv(sh_matrix)
    k_sh = np.dot(sh_matrix_inv, k_sf)
    k_rh = k_sh[m == 0]

    fk_convolved_sh = sh_convolution(f_sh, k_rh)
    fk_convolved_sf = sh_to_sf(fk_convolved_sh, sphere, sh_order)

    # assert if spherical mean is the same between kernel and convolved kernel
    assert_almost_equal(abs(np.mean(k_sf) - np.mean(fk_convolved_sf)), 0., 2)
    # assert if the lowest signal attenuation (E(b,n)) is orientation along
    # the orientation of the watson distribution.
    min_position = np.argmin(fk_convolved_sf)

    if min_position == mu_index:
        assert_equal(min_position, mu_index)
    else:  # then it's the opposite direction
        sphere_positions = np.arange(sphere.vertices.shape[0])
        opposite_index = np.all(
            np.round(sphere.vertices - mu_watson, 2) == 0, axis=1
        )
        min_position_opposite = sphere_positions[opposite_index]
        assert_equal(min_position_opposite, mu_index)
Esempio n. 7
0
    def __call__(self, n, **kwargs):
        r"""Returns the sphere function at cartesian orientations n given
        spherical harmonic coefficients.

        Parameters
        ----------
        n : array of shape(N x 3),
            sampled orientations of the Watson distribution.

        Returns
        -------
        SHn: array of shape(N),
            Probability density at orientations n, given sh coeffs.
        """
        # calculate SHT matrix
        _, theta, phi = utils.cart2sphere(n).T
        SHT = real_sym_sh_mrtrix(self.sh_order, theta, phi)[0]
        # transform coefficients to sphere values
        sh_coeff = kwargs.get('sh_coeff', self.sh_coeff)
        SHn = SHT.dot(sh_coeff)
        return SHn
Esempio n. 8
0
from scipy import interpolate
from dmipy.core.modeling_framework import ModelProperties
from dipy.utils.optpkg import optional_package
from dipy.data import get_sphere, HemiSphere
sphere = get_sphere('symmetric724')
hemisphere = HemiSphere(phi=sphere.phi, theta=sphere.theta)

numba, have_numba, _ = optional_package("numba")

GRADIENT_TABLES_PATH = pkg_resources.resource_filename('dmipy',
                                                       'data/gradient_tables')
SIGNAL_MODELS_PATH = pkg_resources.resource_filename('dmipy', 'signal_models')
DATA_PATH = pkg_resources.resource_filename('dmipy', 'data')
SPHERE_CARTESIAN = np.loadtxt(join(GRADIENT_TABLES_PATH,
                                   'sphere_with_cap.txt'))
SPHERE_SPHERICAL = utils.cart2sphere(SPHERE_CARTESIAN)
log_bingham_normalization_splinefit = np.load(join(
    DATA_PATH, "bingham_normalization_splinefit.npz"),
                                              encoding='bytes')['arr_0']

inverse_sh_matrix_kernel = {
    sh_order: np.linalg.pinv(
        real_sym_sh_mrtrix(sh_order, hemisphere.theta, hemisphere.phi)[0])
    for sh_order in np.arange(0, 15, 2)
}
BETA_SCALING = 1e-6

__all__ = [
    'get_sh_order_from_odi', 'SD1Watson', 'SD2Bingham', 'DD1Gamma',
    'odi2kappa', 'kappa2odi'
]