예제 #1
0
def test_ClosestDirectionTracker():
    class MyModel(object):
        def fit(self, data):
            return MyFit()

    class MyFit(object):
        pass

    class MyDirectionFinder(object):

        directions = np.array([[1., 0, 0], [0, 1., 0], [0, 0., 1]])

        def __call__(self, fit):
            return self.directions

    data = np.ones((10, 10, 10, 65))
    data_interp = NearestNeighborInterpolator(data, (1, 1, 1))

    mask = np.ones((10, 10, 10), 'bool')
    mask[0, 0, 0] = False
    cdt = ClosestDirectionTracker(model=MyModel(),
                                  interpolator=data_interp,
                                  mask=mask,
                                  take_step=None,
                                  angle_limit=90.,
                                  seeds=None)

    # We're going to use a silly set of directions for the test
    cdt._get_directions = MyDirectionFinder()

    prev_step = np.array([[.9, .1, .1], [.1, .9, .1], [.1, .1, .9]])
    prev_step /= np.sqrt((prev_step * prev_step).sum(-1))[:, None]
    a, b, c = prev_step
    assert_array_equal(cdt._next_step([1., 1., 1.], a), [1, 0, 0])
    assert_array_equal(cdt._next_step([1., 1., 1.], b), [0, 1, 0])
    assert_array_equal(cdt._next_step([1., 1., 1.], c), [0, 0, 1])
    # Assert raises outside image
    assert_raises(OutsideImage, cdt._next_step, [-1., 1., 1.], c)
    # Returns None when mask is False
    assert_equal(cdt._next_step([0, 0, 0], c), None)

    # Test Angle limit
    cdt = ClosestDirectionTracker(model=MyModel(),
                                  interpolator=data_interp,
                                  mask=mask,
                                  take_step=None,
                                  angle_limit=45,
                                  seeds=None)

    # We're going to use a silly set of directions for the test
    cdt._get_directions = MyDirectionFinder()
    sq3 = np.sqrt(3)
    a = np.array([sq3 / 2, 1. / 2, 0])
    b = np.array([1. / 2, sq3 / 2, 0])
    c = np.array([1, 1, 1]) / sq3

    assert_array_equal(cdt._next_step([1., 1., 1.], a), [1, 0, 0])
    assert_array_equal(cdt._next_step([1., 1., 1.], b), [0, 1, 0])
    assert_array_equal(cdt._next_step([1., 1., 1.], c), None)
예제 #2
0
def test_MarkovIntegrator():
    class KeepGoing(MarkovIntegrator):
        def _next_step(self, location, prev_step):
            if prev_step is None:
                return np.array([[1., 0, 0], [0, 1., 0], [0, 0., 1]])
            if not self._mask[location]:
                return None
            else:
                return prev_step

    data = np.ones((10, 10, 10, 65))
    data_interp = NearestNeighborInterpolator(data, (1, 1, 1))

    seeds = [np.array([5.2, 5.2, 5.2])]
    stepper = FixedSizeStepper(.5)
    mask = np.ones((10, 10, 10), 'bool')
    gen = KeepGoing(model=None,
                    interpolator=data_interp,
                    mask=mask,
                    take_step=stepper,
                    angle_limit=0.,
                    seeds=seeds)
    streamlines = list(gen)
    assert_equal(len(streamlines), 3)

    expected = np.zeros((20, 3))
    for i in range(3):
        expected[:] = 5.2
        expected[:, i] = np.arange(.2, 10, .5)
        assert_array_almost_equal(streamlines[i], expected)

    # Track only the first (largest) peak for each seed
    gen = KeepGoing(model=None,
                    interpolator=data_interp,
                    mask=mask,
                    take_step=stepper,
                    angle_limit=0.,
                    seeds=seeds,
                    max_cross=1)
    streamlines = list(gen)
    assert_equal(len(streamlines), 1)

    expected = np.zeros((20, 3))
    expected[:] = 5.2
    expected[:, 0] = np.arange(.2, 10, .5)
    assert_array_almost_equal(streamlines[0], expected)

    mask = np.ones((20, 20, 20), 'bool')
    gen = KeepGoing(model=None,
                    interpolator=data_interp,
                    mask=mask,
                    take_step=stepper,
                    angle_limit=0.,
                    seeds=seeds,
                    max_cross=1,
                    mask_voxel_size=(.5, .5, .5))
    streamlines = list(gen)
    assert_equal(len(streamlines), 1)
    assert_array_almost_equal(streamlines[0], expected)
예제 #3
0
def test_ResidualBootstrapWrapper():
    B = np.array([[4, 5, 7, 4, 2.], [4, 6, 2, 3, 6.]])
    B = B.T
    H = hat(B)
    d = np.arange(10) / 8.
    d.shape = (2, 5)
    dhat = np.dot(d, H)
    signal_object = NearestNeighborInterpolator(dhat, (1, ))
    ms = .2
    where_dwi = np.ones(len(H), dtype=bool)

    boot_obj = ResidualBootstrapWrapper(signal_object, B, where_dwi, ms)
    assert_array_almost_equal(boot_obj[0], dhat[0].clip(ms, 1))
    assert_array_almost_equal(boot_obj[1], dhat[1].clip(ms, 1))

    dhat = np.column_stack([[.6, .7], dhat])
    signal_object = NearestNeighborInterpolator(dhat, (1, ))
    where_dwi = np.concatenate([[False], where_dwi])
    boot_obj = ResidualBootstrapWrapper(signal_object, B, where_dwi, ms)
    assert_array_almost_equal(boot_obj[0], dhat[0].clip(ms, 1))
    assert_array_almost_equal(boot_obj[1], dhat[1].clip(ms, 1))
예제 #4
0
def test_NearestNeighborInterpolator():
    a, b, c = np.ogrid[0:6, 0:6, 0:6]
    data = a + b + c

    nni = NearestNeighborInterpolator(data, (1, 1, 1))
    a, b, c = np.mgrid[0:6:.6, 0:6:.6, .0:6:.6]
    for ii in xrange(a.size):
        x = a.flat[ii]
        y = b.flat[ii]
        z = c.flat[ii]
        expected_result = int(x) + int(y) + int(z)
        assert nni[x, y, z] == expected_result
        ind = np.array([x, y, z])
        assert nni[ind] == expected_result
    assert_raises(IndexError, nni.__getitem__, (-.1, 0, 0))
예제 #5
0
def test_NearestNeighborInterpolator():
    # Place integers values at the center of every voxel
    l, m, n, o = np.ogrid[0:6.01, 0:6.01, 0:6.01, 0:4]
    data = l + m + n + o

    nni = NearestNeighborInterpolator(data, (1, 1, 1))
    a, b, c = np.mgrid[.5:6.5:1.6, .5:6.5:2.7, .5:6.5:3.8]
    for ii in xrange(a.size):
        x = a.flat[ii]
        y = b.flat[ii]
        z = c.flat[ii]
        expected_result = int(x) + int(y) + int(z) + o.ravel()
        assert_array_equal(nni[x, y, z], expected_result)
        ind = np.array([x, y, z])
        assert_array_equal(nni[ind], expected_result)
    assert_raises(OutsideImage, nni.__getitem__, (-.1, 0, 0))
    assert_raises(OutsideImage, nni.__getitem__, (0, 8.2, 0))
예제 #6
0
def simple_tracking_function(data, fa, bval, bvec, seed_mask, start_steps,
                             voxel_size, density):
    """An example of a simple traking function using the tools in dipy

    This tracking function uses the SlowAdcOpdfModel to fit diffusion data. By
    using the ClosestPeakSelector, the function tracks along the peak of Opdf
    closest to the incoming direction. It also uses the BoundryIntegrator to
    integrate the streamlines and NearestNeighborInterpolator to interpolate
    the data. The ResidualBootstrap means the tracks are probabilistic, not
    deterministic.
    """

    #the interpolator allows us to index the dwi data in continous space
    data_mask = fa > .2
    normalized_data = normalize_data(data, bval)
    interpolator = NearestNeighborInterpolator(normalized_data, voxel_size,
                                               data_mask)

    #the model fits the dwi data, this model can resolve crossing fibers
    #see documentation of SlowAdcOpdfModel for more info
    model = SlowAdcOpdfModel(6, bval, bvec, .006)
    vert, edges, faces = create_half_unit_sphere(4)
    model.set_sampling_points(vert, edges)

    #this residual bootstrap wrapper returns a sample from the bootstrap
    #distribution istead of returning the raw data
    min_signal = normalized_data.min()
    B = model.B
    wrapped_interp = ResidualBootstrapWrapper(interpolator, B, min_signal)

    #the peakselector returns the closest peak to the incoming direction when
    #in voxels with multiple peaks
    peak_finder = ClosestPeakSelector(model, wrapped_interp)
    peak_finder.angle_limit = 60

    seeds = seeds_from_mask(seed_mask, density, voxel_size)

    #the propagator is used to integrate the streamlines
    propogator = BoundryIntegrator(voxel_size)
    tracks = generate_streamlines(peak_finder, propogator, seeds, start_steps)

    return tracks
예제 #7
0
def test_ProbabilisticOdfWeightedTracker():
    sphere = HemiSphere.from_sphere(unit_octahedron)

    # A simple image with three possible configurations, a vertical tract,
    # a horizontal tract and a crossing
    odf_list = [
        np.array([0., 0., 0.]),
        np.array([1., 0., 0.]),
        np.array([0., 1., 0.]),
        np.array([1., 1., 0.]),
    ]
    simple_image = np.array([
        [0, 1, 0, 0, 0, 0],
        [0, 1, 0, 0, 0, 0],
        [0, 3, 2, 2, 2, 0],
        [0, 1, 0, 0, 0, 0],
        [0, 1, 0, 0, 0, 0],
    ])
    # Make the image 4d
    simple_image = simple_image[..., None, None]

    # Simple model and fit for this image
    class MyModel():
        def fit(self, data):
            return MyFit(data)

    class MyFit(object):
        def __init__(self, n):
            self.n = int(n)

        def odf(self, sphere):
            return odf_list[self.n]

    seeds = [np.array([1.5, 1.5, .5])] * 30
    model = MyModel()
    mask = np.ones([5, 6, 1], dtype="bool")
    stepper = FixedSizeStepper(1.)
    interpolator = NearestNeighborInterpolator(simple_image, (1, 1, 1))

    # These are the only two possible paths though the simple_image
    pwt = ProbabilisticOdfWeightedTracker(model, interpolator, mask, stepper,
                                          90, seeds, sphere)
    expected = [
        np.array([[0.5, 1.5, 0.5], [1.5, 1.5, 0.5], [2.5, 1.5, 0.5],
                  [2.5, 2.5, 0.5], [2.5, 3.5, 0.5], [2.5, 4.5, 0.5],
                  [2.5, 5.5, 0.5]]),
        np.array([[0.5, 1.5, 0.5], [1.5, 1.5, 0.5], [2.5, 1.5, 0.5],
                  [3.5, 1.5, 0.5], [4.5, 1.5, 0.5]])
    ]

    def allclose(x, y):
        return x.shape == y.shape and np.allclose(x, y)

    path = [False, False]
    for streamline in pwt:
        if allclose(streamline, expected[0]):
            path[0] = True
        elif allclose(streamline, expected[1]):
            path[1] = True
        else:
            raise AssertionError()
    assert_(all(path))

    # The first path is not possible if 90 degree turns are excluded
    pwt = ProbabilisticOdfWeightedTracker(model, interpolator, mask, stepper,
                                          80, seeds, sphere)
    for streamline in pwt:
        assert_(np.allclose(streamline, expected[1]))
예제 #8
0
from dipy.tracking.utils import seeds_from_mask

stepper = FixedSizeStepper(1)
"""
Read the voxel size from the image header:
"""

zooms = img.get_header().get_zooms()[:3]
"""
Randomly select some seed points from the mask:
"""

seeds = seeds_from_mask(mask, [1, 1, 1], zooms)
seeds = seeds[:2000]

interpolator = NearestNeighborInterpolator(maskdata, zooms)

pwt = ProbabilisticOdfWeightedTracker(csamodel, interpolator, mask, stepper,
                                      20, seeds, sphere)
csa_streamlines = list(pwt)
"""
Now that we have our streamlines in memory we can save the results to disk.
For this purpose we can use the TrackVis format (``*.trk``). First, we need to
create a header.
"""

import nibabel as nib

hdr = nib.trackvis.empty_header()
hdr['voxel_size'] = (2., 2., 2.)
hdr['voxel_order'] = 'LAS'