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)
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)
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))
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))
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))
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
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]))
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'