Ejemplo n.º 1
0
    def test_gfa(self):
        signal, gtab, expected = make_fake_signal()
        signal = np.ones((2, 3, 4, 1)) * signal
        sphere = hemi_icosahedron.subdivide(3)

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

            model = self.model(gtab, 6, min_signal=1e-5)

        fit = model.fit(signal)
        gfa_shm = fit.gfa

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

            gfa_odf = odf.gfa(fit.odf(sphere))

        assert_array_almost_equal(gfa_shm, gfa_odf, 3)

        # gfa should be 0 if all coefficients are 0 (masked areas)
        mask = np.zeros(signal.shape[:-1])
        fit = model.fit(signal, mask)
        assert_array_equal(fit.gfa, 0)
Ejemplo n.º 2
0
def test_gfa():
    g = gfa(np.ones(100))
    assert_equal(g, 0)

    g = gfa(np.ones((2, 100)))
    assert_equal(g, np.array([0, 0]))

    # The following series follows the rule (sqrt(n-1)/((n-1)^2))
    g = gfa(np.hstack([np.ones((9)), [0]]))
    assert_almost_equal(g, np.sqrt(9./81))
    g = gfa(np.hstack([np.ones((99)), [0]]))
    assert_almost_equal(g, np.sqrt(99./(99.**2)))

    # All-zeros returns a nan with no warning:
    g = gfa(np.zeros(10))
    assert_(np.isnan(g))
Ejemplo n.º 3
0
    def odf(self, sphere):
        r""" Calculates the real discrete odf for a given discrete sphere

        ..math::
            :nowrap:
                \begin{equation}
                    \psi_{DSI}(\hat{\mathbf{u}})=\int_{0}^{\infty}P(r\hat{\mathbf{u}})r^{2}dr
                \end{equation}

        where $\hat{\mathbf{u}}$ is the unit vector which corresponds to a
        sphere point.
        """
        interp_coords = self.model.cache_get('interp_coords',
                                             key=sphere)
        if interp_coords is None:
            interp_coords = pdf_interp_coords(sphere,
                                              self.model.qradius,
                                              self.model.origin)
            self.model.cache_set('interp_coords', sphere, interp_coords)

        Pr = self.pdf()

        #calculate the orientation distribution function
        odf = pdf_odf(Pr, sphere, self.model.qradius, interp_coords)

        # We compute the gfa here, since we have the ODF available and
        # the storage requirements are minimal.  Otherwise, we'd need to
        # recompute the ODF at significant computational expense.
        self._gfa = gfa(odf)
        pk, ind = local_maxima(odf, sphere.edges)

        relative_peak_threshold = self.model.direction_finder._config["relative_peak_threshold"]
        min_separation_angle = self.model.direction_finder._config["min_separation_angle"]

        # Remove small peaks.
        gt_threshold = pk >= (relative_peak_threshold * pk[0])
        pk = pk[gt_threshold]
        ind = ind[gt_threshold]

        # Keep peaks which are unique, which means remove peaks that are too
        # close to a larger peak.
        _, where_uniq = remove_similar_vertices(sphere.vertices[ind],
                                                min_separation_angle,
                                                return_index=True)
        pk = pk[where_uniq]
        ind = ind[where_uniq]

        # Calculate peak metrics
        #global_max = max(global_max, pk[0])
        n = min(self.npeaks, len(pk))
        #qa_array[i, :n] = pk[:n] - odf.min()
        self._peak_values = np.zeros(self.npeaks)
        self._peak_indices = np.zeros(self.npeaks)
        if self.model.normalize_peaks:
            self._peak_values[:n] = pk[:n] / pk[0]
        else:
            self._peak_values[:n] = pk[:n]
        self._peak_indices[:n] = ind[:n]

        return odf
Ejemplo n.º 4
0
def test_peaksFromModel():
    data = np.zeros((10, 2))

    # Test basic case
    model = SimpleOdfModel(_gtab)
    odf_argmax = _odf.argmax()
    pam = peaks_from_model(model, data, _sphere, .5, 45, normalize_peaks=True)

    assert_array_equal(pam.gfa, gfa(_odf))
    assert_array_equal(pam.peak_values[:, 0], 1.)
    assert_array_equal(pam.peak_values[:, 1:], 0.)
    mn, mx = _odf.min(), _odf.max()
    assert_array_equal(pam.qa[:, 0], (mx - mn) / mx)
    assert_array_equal(pam.qa[:, 1:], 0.)
    assert_array_equal(pam.peak_indices[:, 0], odf_argmax)
    assert_array_equal(pam.peak_indices[:, 1:], -1)

    # Test that odf array matches and is right shape
    pam = peaks_from_model(model, data, _sphere, .5, 45, return_odf=True)
    expected_shape = (len(data), len(_odf))
    assert_equal(pam.odf.shape, expected_shape)
    assert_((_odf == pam.odf).all())
    assert_array_equal(pam.peak_values[:, 0], _odf.max())

    # Test mask
    mask = (np.arange(10) % 2) == 1

    pam = peaks_from_model(model,
                           data,
                           _sphere,
                           .5,
                           45,
                           mask=mask,
                           normalize_peaks=True)
    assert_array_equal(pam.gfa[~mask], 0)
    assert_array_equal(pam.qa[~mask], 0)
    assert_array_equal(pam.peak_values[~mask], 0)
    assert_array_equal(pam.peak_indices[~mask], -1)

    assert_array_equal(pam.gfa[mask], gfa(_odf))
    assert_array_equal(pam.peak_values[mask, 0], 1.)
    assert_array_equal(pam.peak_values[mask, 1:], 0.)
    mn, mx = _odf.min(), _odf.max()
    assert_array_equal(pam.qa[mask, 0], (mx - mn) / mx)
    assert_array_equal(pam.qa[mask, 1:], 0.)
    assert_array_equal(pam.peak_indices[mask, 0], odf_argmax)
    assert_array_equal(pam.peak_indices[mask, 1:], -1)
Ejemplo n.º 5
0
def test_TensorModel():
    data, gtab = dsi_voxels()
    dm = dti.TensorModel(gtab, 'LS')
    dtifit = dm.fit(data[0, 0, 0])
    assert_equal(dtifit.fa < 0.5, True)
    dm = dti.TensorModel(gtab, 'WLS')
    dtifit = dm.fit(data[0, 0, 0])
    assert_equal(dtifit.fa < 0.5, True)
    sphere = create_unit_sphere(4)
    assert_equal(len(dtifit.odf(sphere)), len(sphere.vertices))
    assert_almost_equal(dtifit.fa, gfa(dtifit.odf(sphere)), 1)

    # Check that the multivoxel case works:
    dtifit = dm.fit(data)
    assert_equal(dtifit.fa.shape, data.shape[:3])

    # Make some synthetic data
    b0 = 1000.
    bvecs, bvals = read_bvec_file(get_data('55dir_grad.bvec'))
    gtab = grad.gradient_table_from_bvals_bvecs(bvals, bvecs.T)
    # The first b value is 0., so we take the second one:
    B = bvals[1]
    #Scale the eigenvalues and tensor by the B value so the units match
    D = np.array([1., 1., 1., 0., 0., 1., -np.log(b0) * B]) / B
    evals = np.array([2., 1., 0.]) / B
    md = evals.mean()
    tensor = from_lower_triangular(D)
    evecs = np.linalg.eigh(tensor)[1]
    #Design Matrix
    X = dti.design_matrix(bvecs, bvals)
    #Signals
    Y = np.exp(np.dot(X,D))
    assert_almost_equal(Y[0], b0)
    Y.shape = (-1,) + Y.shape

    # Test fitting with different methods: #XXX Add NNLS methods!
    for fit_method in ['OLS', 'WLS']:
        tensor_model = dti.TensorModel(gtab,
                                       fit_method=fit_method)

        tensor_fit = tensor_model.fit(Y)
        assert_true(tensor_fit.model is tensor_model)
        assert_equal(tensor_fit.shape, Y.shape[:-1])
        assert_array_almost_equal(tensor_fit.evals[0], evals)

        assert_array_almost_equal(tensor_fit.quadratic_form[0], tensor,
                                  err_msg =\
        "Calculation of tensor from Y does not compare to analytical solution")

        assert_almost_equal(tensor_fit.md[0], md)
        assert_equal(tensor_fit.directions.shape[-2], 1)
        assert_equal(tensor_fit.directions.shape[-1], 3)

    # Test error-handling:
    assert_raises(ValueError,
                  dti.TensorModel,
                  gtab,
                  fit_method='crazy_method')
Ejemplo n.º 6
0
 def test_gfa(self):
     signal, gtab, expected = make_fake_signal()
     signal = np.ones((2, 3, 4, 1)) * signal
     sphere = hemi_icosahedron.subdivide(3)
     model = self.model(gtab, 6, min_signal=1e-5)
     fit = model.fit(signal)
     gfa_shm = fit.gfa
     gfa_odf = odf.gfa(fit.odf(sphere))
     assert_array_almost_equal(gfa_shm, gfa_odf, 3)
Ejemplo n.º 7
0
def test_mapmri_odf(radial_order=6):
    gtab = get_gtab_taiwan_dsi()

    # load repulsion 724 sphere
    sphere = default_sphere

    # load icosahedron sphere
    l1, l2, l3 = [0.0015, 0.0003, 0.0003]
    data, golden_directions = generate_signal_crossing(gtab,
                                                       l1,
                                                       l2,
                                                       l3,
                                                       angle2=90)
    mapmod = MapmriModel(gtab,
                         radial_order=radial_order,
                         laplacian_regularization=True,
                         laplacian_weighting=0.01)
    # repulsion724
    sphere2 = create_unit_sphere(5)
    mapfit = mapmod.fit(data)
    odf = mapfit.odf(sphere)

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

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

    sb_dummies = sticks_and_ball_dummies(gtab)
    for sbd in sb_dummies:
        data, golden_directions = sb_dummies[sbd]
        asmfit = mapmod.fit(data)
        odf = asmfit.odf(sphere2)
        directions, _, _ = peak_directions(odf, sphere2, .35, 25)
        if len(directions) <= 3:
            assert_equal(len(directions), len(golden_directions))
        if len(directions) > 3:
            assert_equal(gfa(odf) < 0.1, True)

    # for the isotropic implementation check if the odf spherical harmonics
    # actually represent the discrete sphere function.
    mapmod = MapmriModel(gtab,
                         radial_order=radial_order,
                         laplacian_regularization=True,
                         laplacian_weighting=0.01,
                         anisotropic_scaling=False)
    mapfit = mapmod.fit(data)
    odf = mapfit.odf(sphere)
    odf_sh = mapfit.odf_sh()
    odf_from_sh = sh_to_sf(odf_sh, sphere, radial_order, basis_type=None)
    assert_almost_equal(odf, odf_from_sh, 10)
Ejemplo n.º 8
0
def test_peaksFromModel():
    data = np.zeros((10, 2))

    # Test basic case
    model = SimpleOdfModel(_gtab)
    odf_argmax = _odf.argmax()
    pam = peaks_from_model(model, data, _sphere, .5, 45, normalize_peaks=True)

    assert_array_equal(pam.gfa, gfa(_odf))
    assert_array_equal(pam.peak_values[:, 0], 1.)
    assert_array_equal(pam.peak_values[:, 1:], 0.)
    mn, mx = _odf.min(), _odf.max()
    assert_array_equal(pam.qa[:, 0], (mx - mn) / mx)
    assert_array_equal(pam.qa[:, 1:], 0.)
    assert_array_equal(pam.peak_indices[:, 0], odf_argmax)
    assert_array_equal(pam.peak_indices[:, 1:], -1)

    # Test that odf array matches and is right shape
    pam = peaks_from_model(model, data, _sphere, .5, 45, return_odf=True)
    expected_shape = (len(data), len(_odf))
    assert_equal(pam.odf.shape, expected_shape)
    assert_((_odf == pam.odf).all())
    assert_array_equal(pam.peak_values[:, 0], _odf.max())

    # Test mask
    mask = (np.arange(10) % 2) == 1

    pam = peaks_from_model(model, data, _sphere, .5, 45, mask=mask,
                           normalize_peaks=True)
    assert_array_equal(pam.gfa[~mask], 0)
    assert_array_equal(pam.qa[~mask], 0)
    assert_array_equal(pam.peak_values[~mask], 0)
    assert_array_equal(pam.peak_indices[~mask], -1)

    assert_array_equal(pam.gfa[mask], gfa(_odf))
    assert_array_equal(pam.peak_values[mask, 0], 1.)
    assert_array_equal(pam.peak_values[mask, 1:], 0.)
    mn, mx = _odf.min(), _odf.max()
    assert_array_equal(pam.qa[mask, 0], (mx - mn) / mx)
    assert_array_equal(pam.qa[mask, 1:], 0.)
    assert_array_equal(pam.peak_indices[mask, 0], odf_argmax)
    assert_array_equal(pam.peak_indices[mask, 1:], -1)
Ejemplo n.º 9
0
def peaks_from_odfs(odf4d,
                    sphere,
                    relative_peak_threshold,
                    min_separation_angle,
                    mask=None,
                    gfa_thr=0,
                    normalize_peaks=False,
                    npeaks=5):

    shape = odf4d.shape[:-1]
    if mask is None:
        mask = np.ones(shape, dtype='bool')
    else:
        if mask.shape != shape:
            raise ValueError("Mask is not the same shape as data.")

    gfa_array = np.zeros(shape)
    qa_array = np.zeros((shape + (npeaks, )))

    peak_dirs = np.zeros((shape + (npeaks, 3)))
    peak_values = np.zeros((shape + (npeaks, )))
    peak_indices = np.zeros((shape + (npeaks, )), dtype='int')
    peak_indices.fill(-1)

    global_max = -np.inf
    for idx in ndindex(shape):
        if not mask[idx]:
            continue
        odf = odf4d[idx]
        gfa_array[idx] = gfa(odf)
        if gfa_array[idx] < gfa_thr:
            global_max = max(global_max, odf.max())
            continue
        # Get peaks of odf
        direction, pk, ind = peak_directions(odf, sphere,
                                             relative_peak_threshold,
                                             min_separation_angle)
        # Calculate peak metrics
        if pk.shape[0] != 0:
            global_max = max(global_max, pk[0])
            n = min(npeaks, pk.shape[0])
            qa_array[idx][:n] = pk[:n] - odf.min()
            peak_dirs[idx][:n] = direction[:n]
            peak_indices[idx][:n] = ind[:n]
            peak_values[idx][:n] = pk[:n]

            if normalize_peaks:
                peak_values[idx][:n] /= pk[0]
                peak_dirs[idx] *= peak_values[idx][:, None]

    qa_array /= global_max

    return peak_dirs, peak_values
Ejemplo n.º 10
0
def test_shore_odf():
    gtab = get_isbi2013_2shell_gtab()

    # load repulsion 724 sphere
    sphere = default_sphere

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

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

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

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

    sb_dummies = sticks_and_ball_dummies(gtab)
    for sbd in sb_dummies:
        data, golden_directions = sb_dummies[sbd]
        asmfit = asm.fit(data)
        odf = asmfit.odf(sphere2)
        directions, _, _ = peak_directions(odf, sphere2, .35, 25)
        if len(directions) <= 3:
            npt.assert_equal(len(directions), len(golden_directions))
        if len(directions) > 3:
            npt.assert_equal(gfa(odf) < 0.1, True)
Ejemplo n.º 11
0
def test_mapmri_odf(radial_order=6):
    gtab = get_gtab_taiwan_dsi()

    # load symmetric 724 sphere
    sphere = get_sphere('symmetric724')

    # load icosahedron sphere
    l1, l2, l3 = [0.0015, 0.0003, 0.0003]
    data, golden_directions = generate_signal_crossing(gtab, l1, l2, l3,
                                                       angle2=90)
    mapmod = MapmriModel(gtab, radial_order=radial_order,
                         laplacian_regularization=True,
                         laplacian_weighting=0.01)
    # symmetric724
    sphere2 = create_unit_sphere(5)
    mapfit = mapmod.fit(data)
    odf = mapfit.odf(sphere)

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

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

    sb_dummies = sticks_and_ball_dummies(gtab)
    for sbd in sb_dummies:
        data, golden_directions = sb_dummies[sbd]
        asmfit = mapmod.fit(data)
        odf = asmfit.odf(sphere2)
        directions, _, _ = peak_directions(odf, sphere2, .35, 25)
        if len(directions) <= 3:
            assert_equal(len(directions), len(golden_directions))
        if len(directions) > 3:
            assert_equal(gfa(odf) < 0.1, True)

    # for the isotropic implementation check if the odf spherical harmonics
    # actually represent the discrete sphere function.
    mapmod = MapmriModel(gtab, radial_order=radial_order,
                         laplacian_regularization=True,
                         laplacian_weighting=0.01,
                         anisotropic_scaling=False)
    mapfit = mapmod.fit(data)
    odf = mapfit.odf(sphere)
    odf_sh = mapfit.odf_sh()
    odf_from_sh = sh_to_sf(odf_sh, sphere, radial_order, basis_type=None)
    assert_almost_equal(odf, odf_from_sh, 10)
Ejemplo n.º 12
0
    def test_gfa(self):
        signal, gtab, expected = make_fake_signal()
        signal = np.ones((2, 3, 4, 1)) * signal
        sphere = hemi_icosahedron.subdivide(3)
        model = self.model(gtab, 6, min_signal=1e-5)
        fit = model.fit(signal)
        gfa_shm = fit.gfa
        gfa_odf = odf.gfa(fit.odf(sphere))
        assert_array_almost_equal(gfa_shm, gfa_odf, 3)

        # gfa should be 0 if all coefficients are 0 (masked areas)
        mask = np.zeros(signal.shape[:-1])
        fit = model.fit(signal, mask)
        assert_array_equal(fit.gfa, 0)
Ejemplo n.º 13
0
    def test_gfa(self):
        signal, gtab, expected = make_fake_signal()
        signal = np.ones((2, 3, 4, 1)) * signal
        sphere = hemi_icosahedron.subdivide(3)
        model = self.model(gtab, 6, min_signal=1e-5)
        fit = model.fit(signal)
        gfa_shm = fit.gfa
        gfa_odf = odf.gfa(fit.odf(sphere))
        assert_array_almost_equal(gfa_shm, gfa_odf, 3)

        # gfa should be 0 if all coefficients are 0 (masked areas)
        mask = np.zeros(signal.shape[:-1])
        fit = model.fit(signal, mask)
        assert_array_equal(fit.gfa, 0)
Ejemplo n.º 14
0
def test_shore_odf():
    gtab = get_isbi2013_2shell_gtab()

    # load symmetric 724 sphere
    sphere = get_sphere('symmetric724')

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

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

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

    sb_dummies = sticks_and_ball_dummies(gtab)
    for sbd in sb_dummies:
        data, golden_directions = sb_dummies[sbd]
        asmfit = asm.fit(data)
        odf = asmfit.odf(sphere2)
        directions, _, _ = peak_directions(odf, sphere2, .35, 25)
        if len(directions) <= 3:
            assert_equal(len(directions), len(golden_directions))
        if len(directions) > 3:
            assert_equal(gfa(odf) < 0.1, True)
Ejemplo n.º 15
0
def test_dsi():
    # load repulsion 724 sphere
    sphere = default_sphere
    # load icosahedron sphere
    sphere2 = create_unit_sphere(5)
    btable = np.loadtxt(get_fnames('dsi515btable'))
    gtab = gradient_table(btable[:, 0], btable[:, 1:])
    data, golden_directions = sticks_and_ball(gtab,
                                              d=0.0015,
                                              S0=100,
                                              angles=[(0, 0), (90, 0)],
                                              fractions=[50, 50],
                                              snr=None)

    ds = DiffusionSpectrumDeconvModel(gtab)

    # repulsion724
    dsfit = ds.fit(data)
    odf = dsfit.odf(sphere)
    directions, _, _ = peak_directions(odf, sphere, .35, 25)
    assert_equal(len(directions), 2)
    assert_almost_equal(angular_similarity(directions, golden_directions), 2,
                        1)

    # 5 subdivisions
    dsfit = ds.fit(data)
    odf2 = dsfit.odf(sphere2)
    directions, _, _ = peak_directions(odf2, sphere2, .35, 25)
    assert_equal(len(directions), 2)
    assert_almost_equal(angular_similarity(directions, golden_directions), 2,
                        1)

    assert_equal(dsfit.pdf().shape, 3 * (ds.qgrid_size, ))
    sb_dummies = sticks_and_ball_dummies(gtab)
    for sbd in sb_dummies:
        data, golden_directions = sb_dummies[sbd]
        odf = ds.fit(data).odf(sphere2)
        directions, _, _ = peak_directions(odf, sphere2, .35, 25)
        if len(directions) <= 3:
            assert_equal(len(directions), len(golden_directions))
        if len(directions) > 3:
            assert_equal(gfa(odf) < 0.1, True)

    assert_raises(ValueError,
                  DiffusionSpectrumDeconvModel,
                  gtab,
                  qgrid_size=16)
Ejemplo n.º 16
0
def test_dsi():
    #load symmetric 724 sphere
    sphere = get_sphere('symmetric724')
    #load icosahedron sphere
    sphere2 = create_unit_sphere(5)
    btable = np.loadtxt(get_data('dsi515btable'))    
    bvals = btable[:,0]
    bvecs = btable[:,1:]        
    data, golden_directions = SticksAndBall(bvals, bvecs, d=0.0015, 
                               S0=100, angles=[(0, 0), (90, 0)], 
                               fractions=[50, 50], snr=None) 
    gtab = gradient_table(bvals, bvecs) 
    ds = DiffusionSpectrumModel(gtab)
    #symmetric724
    ds.direction_finder.config(sphere=sphere, min_separation_angle=25,
                               relative_peak_threshold=.35)
    dsfit = ds.fit(data)
    odf = dsfit.odf(sphere)
    directions = dsfit.directions
    assert_equal(len(directions), 2)
    assert_almost_equal(angular_similarity(directions, golden_directions), 
                            2, 1)
    #5 subdivisions
    ds.direction_finder.config(sphere=sphere2, min_separation_angle=25,
                              relative_peak_threshold=.35)
    dsfit = ds.fit(data)
    odf2 = dsfit.odf(sphere2)
    directions = dsfit.directions
    assert_equal(len(directions), 2)
    assert_almost_equal(angular_similarity(directions, golden_directions), 
                            2, 1)
    #from dipy.viz._show_odfs import show_odfs
    #show_odfs(odf[None,None,None,:], (sphere.vertices, sphere.faces))
    #show_odfs(odf2[None,None,None,:], (sphere2.vertices, sphere2.faces))
    assert_equal(dsfit.pdf.shape, 3 * (ds.qgrid_size, ))
    sb_dummies=sticks_and_ball_dummies(gtab)
    for sbd in sb_dummies:
        data, golden_directions = sb_dummies[sbd]
        odf = ds.fit(data).odf(sphere2)
        directions = ds.fit(data).directions
        #show_odfs(odf[None, None, None, :], (sphere2.vertices, sphere2.faces))
        if len(directions) <= 3:
            assert_equal(len(ds.fit(data).directions), len(golden_directions))
        if len(directions) > 3:
            assert_equal(gfa(ds.fit(data).odf(sphere2)) < 0.1, True)
Ejemplo n.º 17
0
def maps_from_sh_parallel(args):
    shm_coeff = args[0]
    peak_dirs = args[1]
    peak_values = args[2]
    peak_indices = args[3]
    B = args[4]
    sphere = args[5]
    gfa_thr = args[6]
    chunk_id = args[7]

    data_shape = shm_coeff.shape[0]
    nufo_map = np.zeros(data_shape)
    afd_max = np.zeros(data_shape)
    afd_sum = np.zeros(data_shape)
    rgb_map = np.zeros((data_shape, 3))
    gfa_map = np.zeros(data_shape)
    qa_map = np.zeros((data_shape, peak_values.shape[1]))

    max_odf = 0
    global_max = -np.inf
    for idx in range(len(shm_coeff)):
        if shm_coeff[idx].any():
            odf = np.dot(shm_coeff[idx], B)
            odf = odf.clip(min=0)
            sum_odf = np.sum(odf)
            max_odf = np.maximum(max_odf, sum_odf)
            if sum_odf > 0:
                rgb_map[idx] = np.dot(np.abs(sphere.vertices).T, odf)
                rgb_map[idx] /= np.linalg.norm(rgb_map[idx])
                rgb_map[idx] *= sum_odf
            gfa_map[idx] = gfa(odf)
            if gfa_map[idx] < gfa_thr:
                global_max = max(global_max, odf.max())
            elif np.sum(peak_indices[idx] > -1):
                nufo_map[idx] = np.sum(peak_indices[idx] > -1)
                afd_max[idx] = peak_values[idx].max()
                afd_sum[idx] = np.sqrt(np.dot(shm_coeff[idx], shm_coeff[idx]))
                qa_map = peak_values[idx] - odf.min()
                global_max = max(global_max, peak_values[idx][0])

    rgb_map /= max_odf
    rgb_map *= 255
    qa_map /= global_max

    return chunk_id, nufo_map, afd_max, afd_sum, rgb_map, gfa_map, qa_map
Ejemplo n.º 18
0
def test_dsi():
    # load symmetric 724 sphere
    sphere = get_sphere('symmetric724')

    # load icosahedron sphere
    sphere2 = create_unit_sphere(5)
    btable = np.loadtxt(get_data('dsi515btable'))
    gtab = gradient_table(btable[:, 0], btable[:, 1:])
    data, golden_directions = SticksAndBall(gtab, d=0.0015,
                                            S0=100, angles=[(0, 0), (90, 0)],
                                            fractions=[50, 50], snr=None)

    ds = DiffusionSpectrumModel(gtab)

    # symmetric724
    dsfit = ds.fit(data)
    odf = dsfit.odf(sphere)

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

    # 5 subdivisions
    dsfit = ds.fit(data)
    odf2 = dsfit.odf(sphere2)
    directions, _, _ = peak_directions(odf2, sphere2)
    assert_equal(len(directions), 2)
    assert_almost_equal(angular_similarity(directions, golden_directions),
                        2, 1)

    assert_equal(dsfit.pdf().shape, 3 * (ds.qgrid_size, ))
    sb_dummies = sticks_and_ball_dummies(gtab)
    for sbd in sb_dummies:
        data, golden_directions = sb_dummies[sbd]
        odf = ds.fit(data).odf(sphere2)
        directions, _, _ = peak_directions(odf, sphere2)
        if len(directions) <= 3:
            assert_equal(len(directions), len(golden_directions))
        if len(directions) > 3:
            assert_equal(gfa(odf) < 0.1, True)

    assert_raises(ValueError, DiffusionSpectrumModel, gtab, qgrid_size=16)
Ejemplo n.º 19
0
def test_shore_odf():
    gtab = get_isbi2013_2shell_gtab()

    # load symmetric 724 sphere
    sphere = get_sphere('symmetric724')

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

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

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

    sb_dummies = sticks_and_ball_dummies(gtab)
    for sbd in sb_dummies:
        data, golden_directions = sb_dummies[sbd]
        asmfit = asm.fit(data)
        odf = asmfit.odf(sphere2)
        directions, _ , _ = peak_directions(odf, sphere2, .35, 25)
        if len(directions) <= 3:
            assert_equal(len(directions), len(golden_directions))
        if len(directions) > 3:
            assert_equal(gfa(odf) < 0.1, True)
Ejemplo n.º 20
0
def test_gqi():
    #load symmetric 724 sphere
    sphere = get_sphere('symmetric724')
    #load icosahedron sphere
    sphere2 = create_unit_sphere(5)
    btable = np.loadtxt(get_data('dsi515btable'))
    bvals = btable[:, 0]
    bvecs = btable[:, 1:]
    gtab = gradient_table(bvals, bvecs)
    data, golden_directions = SticksAndBall(gtab,
                                            d=0.0015,
                                            S0=100,
                                            angles=[(0, 0), (90, 0)],
                                            fractions=[50, 50],
                                            snr=None)
    gq = GeneralizedQSamplingModel(gtab, method='gqi2', sampling_length=1.4)

    #symmetric724
    gqfit = gq.fit(data)
    odf = gqfit.odf(sphere)
    directions, values, indices = peak_directions(odf, sphere, .35, 25)
    assert_equal(len(directions), 2)
    assert_almost_equal(angular_similarity(directions, golden_directions), 2,
                        1)

    #5 subdivisions
    gqfit = gq.fit(data)
    odf2 = gqfit.odf(sphere2)
    directions, values, indices = peak_directions(odf2, sphere2, .35, 25)
    assert_equal(len(directions), 2)
    assert_almost_equal(angular_similarity(directions, golden_directions), 2,
                        1)

    sb_dummies = sticks_and_ball_dummies(gtab)
    for sbd in sb_dummies:
        data, golden_directions = sb_dummies[sbd]
        odf = gq.fit(data).odf(sphere2)
        directions, values, indices = peak_directions(odf, sphere2, .35, 25)
        if len(directions) <= 3:
            assert_equal(len(directions), len(golden_directions))
        if len(directions) > 3:
            assert_equal(gfa(odf) < 0.1, True)
Ejemplo n.º 21
0
def test_gqi():
    #load symmetric 724 sphere
    sphere = get_sphere('symmetric724')
    #load icosahedron sphere
    sphere2 = create_unit_sphere(5)
    btable = np.loadtxt(get_data('dsi515btable'))    
    bvals = btable[:,0]
    bvecs = btable[:,1:]        
    data, golden_directions = SticksAndBall(bvals, bvecs, d=0.0015, 
                               S0=100, angles=[(0, 0), (90, 0)], 
                               fractions=[50, 50], snr=None) 
    gtab = gradient_table(bvals, bvecs) 
    gq = GeneralizedQSamplingModel(gtab, method='gqi2', sampling_length=1.4)
    #symmetric724
    gq.direction_finder.config(sphere=sphere, min_separation_angle=25,
                               relative_peak_threshold=.35)
    gqfit = gq.fit(data)
    odf = gqfit.odf(sphere)
    #from dipy.viz._show_odfs import show_odfs
    #show_odfs(odf[None,None,None,:], (sphere.vertices, sphere.faces))
    directions = gqfit.directions
    assert_equal(len(directions), 2)
    assert_almost_equal(angular_similarity(directions, golden_directions), 2, 1)
    #5 subdivisions
    gq.direction_finder.config(sphere=sphere2, min_separation_angle=25,
                              relative_peak_threshold=.35)
    gqfit = gq.fit(data)
    odf2 = gqfit.odf(sphere2)
    directions = gqfit.directions
    assert_equal(len(directions), 2)
    assert_almost_equal(angular_similarity(directions, golden_directions), 2, 1)
    #show_odfs(odf[None,None,None,:], (sphere.vertices, sphere.faces))
    sb_dummies=sticks_and_ball_dummies(gtab)
    for sbd in sb_dummies:
        data, golden_directions = sb_dummies[sbd]
        odf = gq.fit(data).odf(sphere2)
        directions = gq.fit(data).directions
        #show_odfs(odf[None, None, None, :], (sphere2.vertices, sphere2.faces))
        if len(directions) <= 3:
            assert_equal(len(gq.fit(data).directions), len(golden_directions))
        if len(directions) > 3:
            assert_equal(gfa(gq.fit(data).odf(sphere2)) < 0.1, True)
Ejemplo n.º 22
0
def test_gqi():
    # load symmetric 724 sphere
    sphere = get_sphere('symmetric724')
    # load icosahedron sphere
    sphere2 = create_unit_sphere(5)
    btable = np.loadtxt(get_fnames('dsi515btable'))
    bvals = btable[:, 0]
    bvecs = btable[:, 1:]
    gtab = gradient_table(bvals, bvecs)
    data, golden_directions = SticksAndBall(gtab, d=0.0015,
                                            S0=100, angles=[(0, 0), (90, 0)],
                                            fractions=[50, 50], snr=None)
    gq = GeneralizedQSamplingModel(gtab, method='gqi2', sampling_length=1.4)

    # symmetric724
    gqfit = gq.fit(data)
    odf = gqfit.odf(sphere)
    directions, values, indices = peak_directions(odf, sphere, .35, 25)
    assert_equal(len(directions), 2)
    assert_almost_equal(angular_similarity(directions, golden_directions), 2,
                        1)

    # 5 subdivisions
    gqfit = gq.fit(data)
    odf2 = gqfit.odf(sphere2)
    directions, values, indices = peak_directions(odf2, sphere2, .35, 25)
    assert_equal(len(directions), 2)
    assert_almost_equal(angular_similarity(directions, golden_directions), 2,
                        1)

    sb_dummies = sticks_and_ball_dummies(gtab)
    for sbd in sb_dummies:
        data, golden_directions = sb_dummies[sbd]
        odf = gq.fit(data).odf(sphere2)
        directions, values, indices = peak_directions(odf, sphere2, .35, 25)
        if len(directions) <= 3:
            assert_equal(len(directions), len(golden_directions))
        if len(directions) > 3:
            assert_equal(gfa(odf) < 0.1, True)
Ejemplo n.º 23
0
        nib.save(fa_img, os.getcwd() + '/zhibiao/' + f_name + '_FA.nii.gz')
        print('Saving "DTI_tensor_fa.nii.gz" sucessful.')
        evecs_img = nib.Nifti1Image(tenfit.evecs.astype(np.float32), affine)
        nib.save(
            evecs_img,
            os.getcwd() + '/zhibiao/' + f_name + '_DTI_tensor_evecs.nii.gz')
        print('Saving "DTI_tensor_evecs.nii.gz" sucessful.')
        MD = mean_diffusivity(tenfit.evals)
        print MD.shape
        print('Saving "MD.nii.gz" sucessful.')
        nib.save(nib.Nifti1Image(MD.astype(np.float32), img.get_affine()),
                 os.getcwd() + '/zhibiao/' + f_name + '_MD.nii.gz')

        tensor_odfs = tenmodel.fit(data[20:50, 55:85, 38:39]).odf(sphere)
        from dipy.reconst.odf import gfa
        dti_gfa = gfa(tensor_odfs)
        """
        wm_mask = (np.logical_or(FA >= 0.4, (np.logical_and(FA >= 0.15, MD >= 0.0011))))
        
        response = recursive_response(gtab, data, mask=wm_mask, sh_order=8,
                                      peak_thr=0.01, init_fa=0.08,
                                      init_trace=0.0021, iter=8, convergence=0.001,
                                      parallel=False)
        from dipy.reconst.csdeconv import ConstrainedSphericalDeconvModel
        csd_model = ConstrainedSphericalDeconvModel(gtab, response)
        
        csd_fit = csd_model.fit(data)
        csd_odf = csd_fit.odf(sphere)
        
        
        csd_peaks = peaks_from_model(model=csd_model,
Ejemplo n.º 24
0
def peaks_from_model(model, data, sphere, relative_peak_threshold,
                     min_separation_angle, mask=None, return_odf=False,
                     return_sh=True, gfa_thr=0, normalize_peaks=False,
                     sh_order=8, sh_basis_type=None, npeaks=5, B=None,
                     invB=None, parallel=False, nbr_processes=None):
    """Fit the model to data and computes peaks and metrics

    Parameters
    ----------
    model : a model instance
        `model` will be used to fit the data.
    sphere : Sphere
        The Sphere providing discrete directions for evaluation.
    relative_peak_threshold : float
        Only return peaks greater than ``relative_peak_threshold * m`` where m
        is the largest peak.
    min_separation_angle : float in [0, 90] The minimum distance between
        directions. If two peaks are too close only the larger of the two is
        returned.
    mask : array, optional
        If `mask` is provided, voxels that are False in `mask` are skipped and
        no peaks are returned.
    return_odf : bool
        If True, the odfs are returned.
    return_sh : bool
        If True, the odf as spherical harmonics coefficients is returned
    gfa_thr : float
        Voxels with gfa less than `gfa_thr` are skipped, no peaks are returned.
    normalize_peaks : bool
        If true, all peak values are calculated relative to `max(odf)`.
    sh_order : int, optional
        Maximum SH order in the SH fit.  For `sh_order`, there will be
        ``(sh_order + 1) * (sh_order + 2) / 2`` SH coefficients (default 8).
    sh_basis_type : {None, 'mrtrix', 'fibernav'}
        ``None`` for the default dipy basis which is the fibernav basis,
        ``mrtrix`` for the MRtrix basis, and
        ``fibernav`` for the FiberNavigator basis
    sh_smooth : float, optional
        Lambda-regularization in the SH fit (default 0.0).
    npeaks : int
        Maximum number of peaks found (default 5 peaks).
    B : ndarray, optional
        Matrix that transforms spherical harmonics to spherical function
        ``sf = np.dot(sh, B)``.
    invB : ndarray, optional
        Inverse of B.
    parallel: bool
        If True, use multiprocessing to compute peaks and metric
        (default False). Temporary files are saved in the default temporary
        directory of the system. It can be changed using ``import tempfile``
        and ``tempfile.tempdir = '/path/to/tempdir'``.
    nbr_processes: int
        If `parallel` is True, the number of subprocesses to use
        (default multiprocessing.cpu_count()).

    Returns
    -------
    pam : PeaksAndMetrics
        An object with ``gfa``, ``peak_directions``, ``peak_values``,
        ``peak_indices``, ``odf``, ``shm_coeffs`` as attributes
    """
    if return_sh and (B is None or invB is None):
        B, invB = sh_to_sf_matrix(
            sphere, sh_order, sh_basis_type, return_inv=True)

    if parallel:
        # It is mandatory to provide B and invB to the parallel function.
        # Otherwise, a call to np.linalg.pinv is made in a subprocess and
        # makes it timeout on some system.
        # see https://github.com/nipy/dipy/issues/253 for details
        return _peaks_from_model_parallel(model,
                                          data, sphere,
                                          relative_peak_threshold,
                                          min_separation_angle,
                                          mask, return_odf,
                                          return_sh,
                                          gfa_thr,
                                          normalize_peaks,
                                          sh_order,
                                          sh_basis_type,
                                          npeaks,
                                          B,
                                          invB,
                                          nbr_processes)

    shape = data.shape[:-1]
    if mask is None:
        mask = np.ones(shape, dtype='bool')
    else:
        if mask.shape != shape:
            raise ValueError("Mask is not the same shape as data.")

    gfa_array = np.zeros(shape)
    qa_array = np.zeros((shape + (npeaks,)))

    peak_dirs = np.zeros((shape + (npeaks, 3)))
    peak_values = np.zeros((shape + (npeaks,)))
    peak_indices = np.zeros((shape + (npeaks,)), dtype='int')
    peak_indices.fill(-1)

    if return_sh:
        n_shm_coeff = (sh_order + 2) * (sh_order + 1) // 2
        shm_coeff = np.zeros((shape + (n_shm_coeff,)))

    if return_odf:
        odf_array = np.zeros((shape + (len(sphere.vertices),)))

    global_max = -np.inf
    for idx in ndindex(shape):
        if not mask[idx]:
            continue

        odf = model.fit(data[idx]).odf(sphere)

        if return_sh:
            shm_coeff[idx] = np.dot(odf, invB)

        if return_odf:
            odf_array[idx] = odf

        gfa_array[idx] = gfa(odf)
        if gfa_array[idx] < gfa_thr:
            global_max = max(global_max, odf.max())
            continue

        # Get peaks of odf
        direction, pk, ind = peak_directions(odf, sphere,
                                             relative_peak_threshold,
                                             min_separation_angle)

        # Calculate peak metrics
        if pk.shape[0] != 0:
            global_max = max(global_max, pk[0])

            n = min(npeaks, pk.shape[0])
            qa_array[idx][:n] = pk[:n] - odf.min()

            peak_dirs[idx][:n] = direction[:n]
            peak_indices[idx][:n] = ind[:n]
            peak_values[idx][:n] = pk[:n]

            if normalize_peaks:
                peak_values[idx][:n] /= pk[0]
                peak_dirs[idx] *= peak_values[idx][:, None]

    qa_array /= global_max

    return _pam_from_attrs(PeaksAndMetrics,
                           sphere,
                           peak_indices,
                           peak_values,
                           peak_dirs,
                           gfa_array,
                           qa_array,
                           shm_coeff if return_sh else None,
                           B if return_sh else None,
                           odf_array if return_odf else None)
Ejemplo n.º 25
0
fvtk.add(r, fvtk.sphere_funcs(odfs, sphere, colormap='jet'))
fvtk.show(r)
fvtk.clear(r)

# min-max normalization
csa_mm = minmax_normalize(odfs)
r = fvtk.ren()
fvtk.add(r, fvtk.sphere_funcs(csa_mm, sphere, colormap='jet', norm=False))
fvtk.show(r)
fvtk.clear(r)


# Three ways to get the GFA
GFA = csapeaks.gfa
GFA_sh = csa_fit.gfa
GFA_odf = gfa(odfs)
coeff = csa_fit._shm_coef

nib.save(nib.Nifti1Image(GFA.astype('float32'), affine), 'gfa_small.nii.gz')    
nib.save(nib.Nifti1Image(GFA_sh.astype('float32'), affine), 'gfa_sh_small.nii.gz')
nib.save(nib.Nifti1Image(GFA_sh.astype('float32'), affine), 'gfa_odf_small.nii.gz')    
nib.save(nib.Nifti1Image(coeff.astype('float32'), affine), 'csa_sh_small.nii.gz')    

# If you want the full brain SH coefs or GFA
csa_fit = csamodel.fit(data)
GFA_sh = csa_fit.gfa
csa_sh_coeffs = csa_fit._shm_coef
nib.save(nib.Nifti1Image(GFA_sh.astype('float32'), affine), 'gfa_fullbrain.nii.gz')
nib.save(nib.Nifti1Image(csa_sh_coeffs.astype('float32'), affine), 'csa_sh_fullbrain.nii.gz')    

Ejemplo n.º 26
0
for index in ndindex(dataslice.shape[:2]):
    pdf = dsmodel.fit(dataslice[index]).pdf()
"""
If you really want to save the PDFs of a full dataset on the disc we recommend
using memory maps (``numpy.memmap``) but still have in mind that even if you do 
that for example for a dataset of volume size ``(96, 96, 60)`` you will need about 
2.5 GBytes which can take less space when reasonable spheres (with < 1000 vertices) 
are used.

Let's now calculate a map of Generalized Fractional Anisotropy (GFA) [Tuch04]_ 
using the DSI ODFs.
"""

from dipy.reconst.odf import gfa

GFA = gfa(ODF)

import matplotlib.pyplot as plt

fig_hist, ax = plt.subplots(1)
ax.set_axis_off()
plt.imshow(GFA.T)
plt.savefig('dsi_gfa.png', bbox_inches='tight', origin='lower', cmap='gray')
"""
.. figure:: dsi_gfa.png
   :align: center

See also :ref:`example_reconst_dsi_metrics` for calculating different types 
of DSI maps.

Ejemplo n.º 27
0
fodf_spheres = fvtk.sphere_funcs(csd_odf, sphere, scale=1.3, norm=False)

fodf_spheres.SetPosition(15, 15, 1)

fodf_spheres.SetScale(0.78)

fvtk.add(ren, fodf_spheres)

"""
Additionally, we can visualize the ODFs together with a GFA slice
"""

from dipy.reconst.odf import gfa

GFA = gfa(csd_odf)

fvtk.add(ren, fvtk.slicer(GFA, plane_k=[0]))

print('Saving illustration as csd_odfs.png')
fvtk.record(ren, out_path='csd_odfs.png', size=(600, 600))

"""
.. figure:: csd_odfs.png
   :align: center

   **CSD ODFs**.

.. [Tournier2007] J-D. Tournier, F. Calamante and A. Connelly, "Robust determination of the fibre orientation distribution in diffusion MRI: Non-negativity constrained super-resolved spherical deconvolution", Neuroimage, vol. 35, no. 4, pp. 1459-1472, 2007.

.. include:: ../links_names.inc
Ejemplo n.º 28
0
data = img.get_data()
affine = img.get_affine()
print('data.shape (%d, %d, %d, %d)' % data.shape)


mask = data[..., 0] > 50

mask_small  = mask[20:50,55:85, 38:40]
data_small  = data[20:50,55:85, 38:40]

csamodel = CsaOdfModel(gtab, 4, smooth=0.006)
csa_fit = csamodel.fit(data_small)

sphere = get_sphere('symmetric724')
csa_odf = csa_fit.odf(sphere)
gfa_csa = gfa(csa_odf)

odfs = csa_odf.clip(0)
gfa_csa_wo_zeros = gfa(odfs)

csa_mm = minmax_normalize(odfs) 
gfa_csa_mm = gfa(csa_mm)

qballmodel = QballModel(gtab, 6, smooth=0.006)
qball_fit = qballmodel.fit(data_small)
qball_odf = qball_fit.odf(sphere)
gfa_qball = gfa(qball_odf)
gfa_qball_mm = gfa(minmax_normalize(qball_odf))


print 'Saving GFAs...'
Ejemplo n.º 29
0
from dipy.data import get_sphere
from dipy.viz.mayavi.spheres import show_odfs
from load_data import get_train_dsi


data, affine, gtab = get_train_dsi(30)

gqi_model = GeneralizedQSamplingModel(gtab,
                                      method='gqi2',
                                      sampling_length=3,
                                      normalize_peaks=True)

crop = 20
gqi_fit = gqi_model.fit(data[crop:29,crop:29,crop:29])
sphere = get_sphere('symmetric724')
gqi_odf = gqi_fit.odf(sphere)
gqi_gfa = gfa(gqi_odf)

import nibabel as nib

affine[:3,3] +=  crop 
print affine
nib.save(nib.Nifti1Image(gqi_odf, affine), 'gqi_odf_norm.nii.gz')
nib.save(nib.Nifti1Image(gqi_gfa, affine), 'gfa_norm.nii.gz')

import numpy as np


np.savetxt('sphere724.txt', sphere.vertices)

Ejemplo n.º 30
0
def peaks_from_model(model, data, sphere, relative_peak_threshold,
                     min_separation_angle, mask=None, return_odf=False,
                     return_sh=True, gfa_thr=0, normalize_peaks=False,
                     sh_order=8, sh_basis_type=None, npeaks=5, B=None,
                     invB=None, parallel=False, num_processes=None):
    """Fit the model to data and computes peaks and metrics

    Parameters
    ----------
    model : a model instance
        `model` will be used to fit the data.
    data : ndarray
        Diffusion data.
    sphere : Sphere
        The Sphere providing discrete directions for evaluation.
    relative_peak_threshold : float
        Only return peaks greater than ``relative_peak_threshold * m`` where m
        is the largest peak.
    min_separation_angle : float in [0, 90] The minimum distance between
        directions. If two peaks are too close only the larger of the two is
        returned.
    mask : array, optional
        If `mask` is provided, voxels that are False in `mask` are skipped and
        no peaks are returned.
    return_odf : bool
        If True, the odfs are returned.
    return_sh : bool
        If True, the odf as spherical harmonics coefficients is returned
    gfa_thr : float
        Voxels with gfa less than `gfa_thr` are skipped, no peaks are returned.
    normalize_peaks : bool
        If true, all peak values are calculated relative to `max(odf)`.
    sh_order : int, optional
        Maximum SH order in the SH fit.  For `sh_order`, there will be
        ``(sh_order + 1) * (sh_order + 2) / 2`` SH coefficients (default 8).
    sh_basis_type : {None, 'tournier07', 'descoteaux07'}
        ``None`` for the default DIPY basis,
        ``tournier07`` for the Tournier 2007 [2]_ basis, and
        ``descoteaux07`` for the Descoteaux 2007 [1]_ basis
        (``None`` defaults to ``descoteaux07``).
    npeaks : int
        Maximum number of peaks found (default 5 peaks).
    B : ndarray, optional
        Matrix that transforms spherical harmonics to spherical function
        ``sf = np.dot(sh, B)``.
    invB : ndarray, optional
        Inverse of B.
    parallel: bool
        If True, use multiprocessing to compute peaks and metric
        (default False). Temporary files are saved in the default temporary
        directory of the system. It can be changed using ``import tempfile``
        and ``tempfile.tempdir = '/path/to/tempdir'``.
    num_processes: int, optional
        If `parallel` is True, the number of subprocesses to use
        (default multiprocessing.cpu_count()). If < 0 the maximal number of
        cores minus ``num_processes + 1`` is used (enter -1 to use as many
        cores as possible). 0 raises an error.

    Returns
    -------
    pam : PeaksAndMetrics
        An object with ``gfa``, ``peak_directions``, ``peak_values``,
        ``peak_indices``, ``odf``, ``shm_coeffs`` as attributes

    References
    ----------
    .. [1] Descoteaux, M., Angelino, E., Fitzgibbons, S. and Deriche, R.
           Regularized, Fast, and Robust Analytical Q-ball Imaging.
           Magn. Reson. Med. 2007;58:497-510.
    .. [2] Tournier J.D., Calamante F. and Connelly A. Robust determination
           of the fibre orientation distribution in diffusion MRI:
           Non-negativity constrained super-resolved spherical deconvolution.
           NeuroImage. 2007;35(4):1459-1472.

    """
    if return_sh and (B is None or invB is None):
        B, invB = sh_to_sf_matrix(
            sphere, sh_order, sh_basis_type, return_inv=True)

    num_processes = determine_num_processes(num_processes)

    if parallel and num_processes > 1:
        # It is mandatory to provide B and invB to the parallel function.
        # Otherwise, a call to np.linalg.pinv is made in a subprocess and
        # makes it timeout on some system.
        # see https://github.com/dipy/dipy/issues/253 for details
        return _peaks_from_model_parallel(model,
                                          data, sphere,
                                          relative_peak_threshold,
                                          min_separation_angle,
                                          mask, return_odf,
                                          return_sh,
                                          gfa_thr,
                                          normalize_peaks,
                                          sh_order,
                                          sh_basis_type,
                                          npeaks,
                                          B,
                                          invB,
                                          num_processes)

    shape = data.shape[:-1]
    if mask is None:
        mask = np.ones(shape, dtype='bool')
    else:
        if mask.shape != shape:
            raise ValueError("Mask is not the same shape as data.")

    gfa_array = np.zeros(shape)
    qa_array = np.zeros((shape + (npeaks,)))

    peak_dirs = np.zeros((shape + (npeaks, 3)))
    peak_values = np.zeros((shape + (npeaks,)))
    peak_indices = np.zeros((shape + (npeaks,)), dtype='int')
    peak_indices.fill(-1)

    if return_sh:
        n_shm_coeff = (sh_order + 2) * (sh_order + 1) // 2
        shm_coeff = np.zeros((shape + (n_shm_coeff,)))

    if return_odf:
        odf_array = np.zeros((shape + (len(sphere.vertices),)))

    global_max = -np.inf
    for idx in ndindex(shape):
        if not mask[idx]:
            continue

        odf = model.fit(data[idx]).odf(sphere)

        if return_sh:
            shm_coeff[idx] = np.dot(odf, invB)

        if return_odf:
            odf_array[idx] = odf

        gfa_array[idx] = gfa(odf)
        if gfa_array[idx] < gfa_thr:
            global_max = max(global_max, odf.max())
            continue

        # Get peaks of odf
        direction, pk, ind = peak_directions(odf, sphere,
                                             relative_peak_threshold,
                                             min_separation_angle)

        # Calculate peak metrics
        if pk.shape[0] != 0:
            global_max = max(global_max, pk[0])

            n = min(npeaks, pk.shape[0])
            qa_array[idx][:n] = pk[:n] - odf.min()

            peak_dirs[idx][:n] = direction[:n]
            peak_indices[idx][:n] = ind[:n]
            peak_values[idx][:n] = pk[:n]

            if normalize_peaks:
                peak_values[idx][:n] /= pk[0]
                peak_dirs[idx] *= peak_values[idx][:, None]

    qa_array /= global_max

    return _pam_from_attrs(PeaksAndMetrics,
                           sphere,
                           peak_indices,
                           peak_values,
                           peak_dirs,
                           gfa_array,
                           qa_array,
                           shm_coeff if return_sh else None,
                           B if return_sh else None,
                           odf_array if return_odf else None)
 fa_img = nib.Nifti1Image(FA.astype(np.float32), affine)
 print FA.shape
 nib.save(fa_img,os.getcwd()+'/zhibiao/'+f_name+'_FA.nii.gz')
 print('Saving "DTI_tensor_fa.nii.gz" sucessful.')
 evecs_img = nib.Nifti1Image(tenfit.evecs.astype(np.float32), affine)
 nib.save(evecs_img, os.getcwd()+'/zhibiao/'+f_name+'_DTI_tensor_evecs.nii.gz')
 print('Saving "DTI_tensor_evecs.nii.gz" sucessful.')
 MD = mean_diffusivity(tenfit.evals)
 print MD.shape
 print('Saving "MD.nii.gz" sucessful.')
 nib.save(nib.Nifti1Image(MD.astype(np.float32), img.get_affine()), os.getcwd()+'/zhibiao/'+f_name+'_MD.nii.gz')
 
 
 tensor_odfs = tenmodel.fit(data[20:50, 55:85, 38:39]).odf(sphere)
 from dipy.reconst.odf import gfa
 dti_gfa=gfa(tensor_odfs)
 """
 wm_mask = (np.logical_or(FA >= 0.4, (np.logical_and(FA >= 0.15, MD >= 0.0011))))
 
 response = recursive_response(gtab, data, mask=wm_mask, sh_order=8,
                               peak_thr=0.01, init_fa=0.08,
                               init_trace=0.0021, iter=8, convergence=0.001,
                               parallel=False)
 from dipy.reconst.csdeconv import ConstrainedSphericalDeconvModel
 csd_model = ConstrainedSphericalDeconvModel(gtab, response)
 
 csd_fit = csd_model.fit(data)
 csd_odf = csd_fit.odf(sphere)
 
 
 csd_peaks = peaks_from_model(model=csd_model,
Ejemplo n.º 32
0
def test_TensorModel():
    data, gtab = dsi_voxels()
    dm = dti.TensorModel(gtab, 'LS')
    dtifit = dm.fit(data[0, 0, 0])
    assert_equal(dtifit.fa < 0.5, True)
    dm = dti.TensorModel(gtab, 'WLS')
    dtifit = dm.fit(data[0, 0, 0])
    assert_equal(dtifit.fa < 0.5, True)
    sphere = create_unit_sphere(4)
    assert_equal(len(dtifit.odf(sphere)), len(sphere.vertices))
    assert_almost_equal(dtifit.fa, gfa(dtifit.odf(sphere)), 1)

    # Check that the multivoxel case works:
    dtifit = dm.fit(data)

    # And smoke-test that all these operations return sensibly-shaped arrays:
    assert_equal(dtifit.fa.shape, data.shape[:3])
    assert_equal(dtifit.ad.shape, data.shape[:3])
    assert_equal(dtifit.md.shape, data.shape[:3])
    assert_equal(dtifit.rd.shape, data.shape[:3])
    assert_equal(dtifit.trace.shape, data.shape[:3])
    assert_equal(dtifit.mode.shape, data.shape[:3])
    assert_equal(dtifit.linearity.shape, data.shape[:3])
    assert_equal(dtifit.planarity.shape, data.shape[:3])
    assert_equal(dtifit.sphericity.shape, data.shape[:3])

    # Test for the shape of the mask
    assert_raises(ValueError, dm.fit, np.ones((10, 10, 3)), np.ones((3, 3)))

    # Make some synthetic data
    b0 = 1000.
    bvecs, bvals = read_bvec_file(get_data('55dir_grad.bvec'))
    gtab = grad.gradient_table_from_bvals_bvecs(bvals, bvecs.T)
    # The first b value is 0., so we take the second one:
    B = bvals[1]
    # Scale the eigenvalues and tensor by the B value so the units match
    D = np.array([1., 1., 1., 0., 0., 1., -np.log(b0) * B]) / B
    evals = np.array([2., 1., 0.]) / B
    md = evals.mean()
    tensor = from_lower_triangular(D)
    A_squiggle = tensor - (1 / 3.0) * np.trace(tensor) * np.eye(3)
    mode = 3 * np.sqrt(6) * np.linalg.det(
        A_squiggle / np.linalg.norm(A_squiggle))
    evecs = np.linalg.eigh(tensor)[1]
    # Design Matrix
    X = dti.design_matrix(gtab)
    # Signals
    Y = np.exp(np.dot(X, D))
    assert_almost_equal(Y[0], b0)
    Y.shape = (-1, ) + Y.shape

    # Test fitting with different methods:
    for fit_method in ['OLS', 'WLS', 'NLLS']:
        tensor_model = dti.TensorModel(gtab, fit_method=fit_method)

        tensor_fit = tensor_model.fit(Y)
        assert_true(tensor_fit.model is tensor_model)
        assert_equal(tensor_fit.shape, Y.shape[:-1])
        assert_array_almost_equal(tensor_fit.evals[0], evals)

        assert_array_almost_equal(tensor_fit.quadratic_form[0], tensor,
                                  err_msg=\
        "Calculation of tensor from Y does not compare to analytical solution")

        assert_almost_equal(tensor_fit.md[0], md)
        assert_array_almost_equal(tensor_fit.mode, mode, decimal=5)
        assert_equal(tensor_fit.directions.shape[-2], 1)
        assert_equal(tensor_fit.directions.shape[-1], 3)

    # Test error-handling:
    assert_raises(ValueError, dti.TensorModel, gtab, fit_method='crazy_method')
Ejemplo n.º 33
0
					
					# Convert result to dir format
					t = time.time()
					print('... convert peaks to dir format')
					dsidir = prepare_dir(dsipeaks, sphere, 0, 0, 1)
					name = os.path.join(main_dir,tp,'CMP','scalars','dsideconv_dir.nii.gz')
					nib.save(nib.Nifti1Image(dsidir, affine), name)
					elapsed = time.time() - t
					print('    time %d' %elapsed)

					# Classic DSI reconstruction
					t = time.time()
					print('... perform classic DSI reconstruction')
					dsmodel_dsi = DiffusionSpectrumModel(gtab)
					dsifit = dsmodel_dsi.fit(data)
					odfs = dsifit.odf(sphere)
					GFA = gfa(odfs)
					name = os.path.join(main_dir,tp,'CMP','scalars','dsidipy_gfa.nii.gz')
					nib.save(nib.Nifti1Image(GFA, affine), name)
					name = os.path.join(main_dir,tp,'CMP','scalars','dsidipy_odf.nii.gz')
					nib.save(nib.Nifti1Image(odfs, affine), name)						
					elapsed = time.time() - t
					print('    time %d' %elapsed)







Ejemplo n.º 34
0
def test_TensorModel():
    data, gtab = dsi_voxels()
    dm = dti.TensorModel(gtab, 'LS')
    dtifit = dm.fit(data[0, 0, 0])
    assert_equal(dtifit.fa < 0.5, True)
    dm = dti.TensorModel(gtab, 'WLS')
    dtifit = dm.fit(data[0, 0, 0])
    assert_equal(dtifit.fa < 0.5, True)
    sphere = create_unit_sphere(4)
    assert_equal(len(dtifit.odf(sphere)), len(sphere.vertices))
    assert_almost_equal(dtifit.fa, gfa(dtifit.odf(sphere)), 1)

    # Check that the multivoxel case works:
    dtifit = dm.fit(data)

    # And smoke-test that all these operations return sensibly-shaped arrays:
    assert_equal(dtifit.fa.shape, data.shape[:3])
    assert_equal(dtifit.ad.shape, data.shape[:3])
    assert_equal(dtifit.md.shape, data.shape[:3])
    assert_equal(dtifit.rd.shape, data.shape[:3])
    assert_equal(dtifit.trace.shape, data.shape[:3])
    assert_equal(dtifit.mode.shape, data.shape[:3])
    assert_equal(dtifit.linearity.shape, data.shape[:3])
    assert_equal(dtifit.planarity.shape, data.shape[:3])
    assert_equal(dtifit.sphericity.shape, data.shape[:3])

    # Test for the shape of the mask
    assert_raises(ValueError, dm.fit, np.ones((10, 10, 3)), np.ones((3,3)))

    # Make some synthetic data
    b0 = 1000.
    bvecs, bvals = read_bvec_file(get_data('55dir_grad.bvec'))
    gtab = grad.gradient_table_from_bvals_bvecs(bvals, bvecs.T)
    # The first b value is 0., so we take the second one:
    B = bvals[1]
    # Scale the eigenvalues and tensor by the B value so the units match
    D = np.array([1., 1., 1., 0., 0., 1., -np.log(b0) * B]) / B
    evals = np.array([2., 1., 0.]) / B
    md = evals.mean()
    tensor = from_lower_triangular(D)
    A_squiggle = tensor - (1 / 3.0) * np.trace(tensor) * np.eye(3)
    mode = 3 * np.sqrt(6) * np.linalg.det(A_squiggle / np.linalg.norm(A_squiggle))
    evecs = np.linalg.eigh(tensor)[1]
    # Design Matrix
    X = dti.design_matrix(gtab)
    # Signals
    Y = np.exp(np.dot(X, D))
    assert_almost_equal(Y[0], b0)
    Y.shape = (-1,) + Y.shape

    # Test fitting with different methods:
    for fit_method in ['OLS', 'WLS', 'NLLS']:
        tensor_model = dti.TensorModel(gtab,
                                       fit_method=fit_method)

        tensor_fit = tensor_model.fit(Y)
        assert_true(tensor_fit.model is tensor_model)
        assert_equal(tensor_fit.shape, Y.shape[:-1])
        assert_array_almost_equal(tensor_fit.evals[0], evals)

        assert_array_almost_equal(tensor_fit.quadratic_form[0], tensor,
                                  err_msg=\
        "Calculation of tensor from Y does not compare to analytical solution")

        assert_almost_equal(tensor_fit.md[0], md)
        assert_array_almost_equal(tensor_fit.mode, mode, decimal=5)
        assert_equal(tensor_fit.directions.shape[-2], 1)
        assert_equal(tensor_fit.directions.shape[-1], 3)

    # Test error-handling:
    assert_raises(ValueError,
                  dti.TensorModel,
                  gtab,
                  fit_method='crazy_method')
Ejemplo n.º 35
0
    pdf = dsmodel.fit(dataslice[index]).pdf()

"""
If you really want to save the PDFs of a full dataset on the disc we recommend
using memory maps (``numpy.memmap``) but still have in mind that even if you do 
that for example for a dataset of volume size ``(96, 96, 60)`` you will need about 
2.5 GBytes which can take less space when reasonable spheres (with < 1000 vertices) 
are used.

Let's now calculate a map of Generalized Fractional Anisotropy (GFA) [Tuch04]_ 
using the DSI ODFs.
"""

from dipy.reconst.odf import gfa

GFA = gfa(ODF)

import matplotlib.pyplot as plt

fig_hist, ax = plt.subplots(1)
ax.set_axis_off()
plt.imshow(GFA.T)
plt.savefig('dsi_gfa.png', bbox_inches='tight', origin='lower', cmap='gray')

"""
.. figure:: dsi_gfa.png
   :align: center

See also :ref:`example_reconst_dsi_metrics` for calculating different types 
of DSI maps.
Ejemplo n.º 36
0
def test_peaksFromModel():
    data = np.zeros((10, 2))

    for sphere in [_sphere, get_sphere('symmetric642')]:
        # Test basic case
        model = SimpleOdfModel(_gtab)
        _odf = (sphere.vertices * [1, 2, 3]).sum(-1)
        odf_argmax = _odf.argmax()
        pam = peaks_from_model(model,
                               data,
                               sphere,
                               .5,
                               45,
                               normalize_peaks=True)

        assert_array_equal(pam.gfa, gfa(_odf))
        assert_array_equal(pam.peak_values[:, 0], 1.)
        assert_array_equal(pam.peak_values[:, 1:], 0.)
        mn, mx = _odf.min(), _odf.max()
        assert_array_equal(pam.qa[:, 0], (mx - mn) / mx)
        assert_array_equal(pam.qa[:, 1:], 0.)
        assert_array_equal(pam.peak_indices[:, 0], odf_argmax)
        assert_array_equal(pam.peak_indices[:, 1:], -1)

        # Test that odf array matches and is right shape
        pam = peaks_from_model(model, data, sphere, .5, 45, return_odf=True)
        expected_shape = (len(data), len(_odf))
        assert_equal(pam.odf.shape, expected_shape)
        assert_((_odf == pam.odf).all())
        assert_array_equal(pam.peak_values[:, 0], _odf.max())

        # Test mask
        mask = (np.arange(10) % 2) == 1

        pam = peaks_from_model(model,
                               data,
                               sphere,
                               .5,
                               45,
                               mask=mask,
                               normalize_peaks=True)
        assert_array_equal(pam.gfa[~mask], 0)
        assert_array_equal(pam.qa[~mask], 0)
        assert_array_equal(pam.peak_values[~mask], 0)
        assert_array_equal(pam.peak_indices[~mask], -1)

        assert_array_equal(pam.gfa[mask], gfa(_odf))
        assert_array_equal(pam.peak_values[mask, 0], 1.)
        assert_array_equal(pam.peak_values[mask, 1:], 0.)
        mn, mx = _odf.min(), _odf.max()
        assert_array_equal(pam.qa[mask, 0], (mx - mn) / mx)
        assert_array_equal(pam.qa[mask, 1:], 0.)
        assert_array_equal(pam.peak_indices[mask, 0], odf_argmax)
        assert_array_equal(pam.peak_indices[mask, 1:], -1)

        # Test serialization and deserialization:
        for normalize_peaks in [True, False]:
            for return_odf in [True, False]:
                for return_sh in [True, False]:
                    pam = peaks_from_model(model,
                                           data,
                                           sphere,
                                           .5,
                                           45,
                                           normalize_peaks=normalize_peaks,
                                           return_odf=return_odf,
                                           return_sh=return_sh)

                    b = BytesIO()
                    pickle.dump(pam, b)
                    b.seek(0)
                    new_pam = pickle.load(b)
                    b.close()

                    for attr in [
                            'peak_dirs', 'peak_values', 'peak_indices', 'gfa',
                            'qa', 'shm_coeff', 'B', 'odf'
                    ]:
                        assert_array_equal(getattr(pam, attr),
                                           getattr(new_pam, attr))
                        assert_array_equal(pam.sphere.vertices,
                                           new_pam.sphere.vertices)
Ejemplo n.º 37
0
def peaks_from_model(model, data, sphere, relative_peak_threshold,
                     min_separation_angle, mask=None, return_odf=False,
                     return_sh=True, gfa_thr=0, normalize_peaks=False,
                     sh_order=8, sh_basis_type=None, npeaks=5, B=None,
                     invB=None, parallel=False, nbr_processes=None):
    """Fit the model to data and computes peaks and metrics

    Parameters
    ----------
    model : a model instance
        `model` will be used to fit the data.
    sphere : Sphere
        The Sphere providing discrete directions for evaluation.
    relative_peak_threshold : float
        Only return peaks greater than ``relative_peak_threshold * m`` where m
        is the largest peak.
    min_separation_angle : float in [0, 90] The minimum distance between
        directions. If two peaks are too close only the larger of the two is
        returned.
    mask : array, optional
        If `mask` is provided, voxels that are False in `mask` are skipped and
        no peaks are returned.
    return_odf : bool
        If True, the odfs are returned.
    return_sh : bool
        If True, the odf as spherical harmonics coefficients is returned
    gfa_thr : float
        Voxels with gfa less than `gfa_thr` are skipped, no peaks are returned.
    normalize_peaks : bool
        If true, all peak values are calculated relative to `max(odf)`.
    sh_order : int, optional
        Maximum SH order in the SH fit.  For `sh_order`, there will be
        ``(sh_order + 1) * (sh_order + 2) / 2`` SH coefficients (default 8).
    sh_basis_type : {None, 'mrtrix', 'fibernav'}
        ``None`` for the default dipy basis which is the fibernav basis,
        ``mrtrix`` for the MRtrix basis, and
        ``fibernav`` for the FiberNavigator basis
    sh_smooth : float, optional
        Lambda-regularization in the SH fit (default 0.0).
    npeaks : int
        Maximum number of peaks found (default 5 peaks).
    B : ndarray, optional
        Matrix that transforms spherical harmonics to spherical function
        ``sf = np.dot(sh, B)``.
    invB : ndarray, optional
        Inverse of B.
    parallel: bool
        If True, use multiprocessing to compute peaks and metric
        (default False). Temporary files are saved in the default temporary
        directory of the system. It can be changed using ``import tempfile``
        and ``tempfile.tempdir = '/path/to/tempdir'``.
    nbr_processes: int
        If `parallel` is True, the number of subprocesses to use
        (default multiprocessing.cpu_count()).

    Returns
    -------
    pam : PeaksAndMetrics
        An object with ``gfa``, ``peak_directions``, ``peak_values``,
        ``peak_indices``, ``odf``, ``shm_coeffs`` as attributes
    """
    if return_sh and (B is None or invB is None):
        B, invB = sh_to_sf_matrix(
            sphere, sh_order, sh_basis_type, return_inv=True)

    if parallel:
        # It is mandatory to provide B and invB to the parallel function.
        # Otherwise, a call to np.linalg.pinv is made in a subprocess and
        # makes it timeout on some system.
        # see https://github.com/nipy/dipy/issues/253 for details
        return _peaks_from_model_parallel(model,
                                          data, sphere,
                                          relative_peak_threshold,
                                          min_separation_angle,
                                          mask, return_odf,
                                          return_sh,
                                          gfa_thr,
                                          normalize_peaks,
                                          sh_order,
                                          sh_basis_type,
                                          npeaks,
                                          B,
                                          invB,
                                          nbr_processes)

    shape = data.shape[:-1]
    if mask is None:
        mask = np.ones(shape, dtype='bool')
    else:
        if mask.shape != shape:
            raise ValueError("Mask is not the same shape as data.")

    gfa_array = np.zeros(shape)
    qa_array = np.zeros((shape + (npeaks,)))

    peak_dirs = np.zeros((shape + (npeaks, 3)))
    peak_values = np.zeros((shape + (npeaks,)))
    peak_indices = np.zeros((shape + (npeaks,)), dtype='int')
    peak_indices.fill(-1)

    if return_sh:
        n_shm_coeff = (sh_order + 2) * (sh_order + 1) // 2
        shm_coeff = np.zeros((shape + (n_shm_coeff,)))

    if return_odf:
        odf_array = np.zeros((shape + (len(sphere.vertices),)))

    global_max = -np.inf
    for idx in ndindex(shape):
        if not mask[idx]:
            continue

        odf = model.fit(data[idx]).odf(sphere)

        if return_sh:
            shm_coeff[idx] = np.dot(odf, invB)

        if return_odf:
            odf_array[idx] = odf

        gfa_array[idx] = gfa(odf)
        if gfa_array[idx] < gfa_thr:
            global_max = max(global_max, odf.max())
            continue

        # Get peaks of odf
        direction, pk, ind = peak_directions(odf, sphere,
                                             relative_peak_threshold,
                                             min_separation_angle)

        # Calculate peak metrics
        if pk.shape[0] != 0:
            global_max = max(global_max, pk[0])

            n = min(npeaks, pk.shape[0])
            qa_array[idx][:n] = pk[:n] - odf.min()

            peak_dirs[idx][:n] = direction[:n]
            peak_indices[idx][:n] = ind[:n]
            peak_values[idx][:n] = pk[:n]

            if normalize_peaks:
                peak_values[idx][:n] /= pk[0]
                peak_dirs[idx] *= peak_values[idx][:, None]

    qa_array /= global_max

    return _pam_from_attrs(PeaksAndMetrics,
                           sphere,
                           peak_indices,
                           peak_values,
                           peak_dirs,
                           gfa_array,
                           qa_array,
                           shm_coeff if return_sh else None,
                           B if return_sh else None,
                           odf_array if return_odf else None)
Ejemplo n.º 38
0
def test_peaksFromModel():
    data = np.zeros((10, 2))

    for sphere in [_sphere, get_sphere('symmetric642')]:
        # Test basic case
        model = SimpleOdfModel(_gtab)
        _odf = (sphere.vertices * [1, 2, 3]).sum(-1)
        odf_argmax = _odf.argmax()
        pam = peaks_from_model(model, data, sphere, .5, 45,
                               normalize_peaks=True)

        assert_array_equal(pam.gfa, gfa(_odf))
        assert_array_equal(pam.peak_values[:, 0], 1.)
        assert_array_equal(pam.peak_values[:, 1:], 0.)
        mn, mx = _odf.min(), _odf.max()
        assert_array_equal(pam.qa[:, 0], (mx - mn) / mx)
        assert_array_equal(pam.qa[:, 1:], 0.)
        assert_array_equal(pam.peak_indices[:, 0], odf_argmax)
        assert_array_equal(pam.peak_indices[:, 1:], -1)

        # Test that odf array matches and is right shape
        pam = peaks_from_model(model, data, sphere, .5, 45, return_odf=True)
        expected_shape = (len(data), len(_odf))
        assert_equal(pam.odf.shape, expected_shape)
        assert_((_odf == pam.odf).all())
        assert_array_equal(pam.peak_values[:, 0], _odf.max())

        # Test mask
        mask = (np.arange(10) % 2) == 1

        pam = peaks_from_model(model, data, sphere, .5, 45, mask=mask,
                            normalize_peaks=True)
        assert_array_equal(pam.gfa[~mask], 0)
        assert_array_equal(pam.qa[~mask], 0)
        assert_array_equal(pam.peak_values[~mask], 0)
        assert_array_equal(pam.peak_indices[~mask], -1)

        assert_array_equal(pam.gfa[mask], gfa(_odf))
        assert_array_equal(pam.peak_values[mask, 0], 1.)
        assert_array_equal(pam.peak_values[mask, 1:], 0.)
        mn, mx = _odf.min(), _odf.max()
        assert_array_equal(pam.qa[mask, 0], (mx - mn) / mx)
        assert_array_equal(pam.qa[mask, 1:], 0.)
        assert_array_equal(pam.peak_indices[mask, 0], odf_argmax)
        assert_array_equal(pam.peak_indices[mask, 1:], -1)

        # Test serialization and deserialization:
        for normalize_peaks in [True, False]:
            for return_odf in [True, False]:
                for return_sh in [True, False]:
                    pam = peaks_from_model(model, data, sphere, .5, 45,
                                        normalize_peaks=normalize_peaks,
                                        return_odf=return_odf,
                                        return_sh=return_sh)

                    b = BytesIO()
                    pickle.dump(pam, b)
                    b.seek(0)
                    new_pam = pickle.load(b)
                    b.close()

                    for attr in ['peak_dirs', 'peak_values', 'peak_indices',
                                'gfa', 'qa', 'shm_coeff', 'B', 'odf']:
                        assert_array_equal(getattr(pam, attr),
                                        getattr(new_pam, attr))
                        assert_array_equal(pam.sphere.vertices,
                                        new_pam.sphere.vertices)