""" ============================================================================ Tracking with Robust Unbiased Model-BAsed Spherical Deconvolution (RUMBA-SD) ============================================================================ Here, we demonstrate fiber tracking using a probabilistic direction getter and RUMBA-SD, a model introduced in [CanalesRodriguez2015]_. This model adapts Richardson-Lucy deconvolution by assuming Rician or Noncentral Chi noise instead of Gaussian, which more accurately reflects the noise from MRI scanners (see also :ref:`example_reconst_rumba`). This tracking tutorial is an extension on :ref:`example_tracking_probabilistic`. We start by loading sample data and identifying a fiber response function. """ from numpy.linalg import inv from dipy.core.gradients import gradient_table from dipy.data import get_fnames, small_sphere from dipy.io.gradients import read_bvals_bvecs from dipy.io.image import load_nifti, load_nifti_data from dipy.reconst.csdeconv import auto_response_ssst from dipy.tracking import utils from dipy.tracking.local_tracking import LocalTracking from dipy.tracking.streamline import Streamlines, transform_streamlines from dipy.tracking.stopping_criterion import ThresholdStoppingCriterion from dipy.viz import window, actor, colormap from dipy.reconst.rumba import RumbaSDModel # Enables/disables interactive visualization interactive = False hardi_fname, hardi_bval_fname, hardi_bvec_fname = get_fnames('stanford_hardi') label_fname = get_fnames('stanford_labels') t1_fname = get_fnames('stanford_t1') data, affine, hardi_img = load_nifti(hardi_fname, return_img=True) labels = load_nifti_data(label_fname) t1_data, t1_aff = load_nifti(t1_fname) bvals, bvecs = read_bvals_bvecs(hardi_bval_fname, hardi_bvec_fname) gtab = gradient_table(bvals, bvecs) seed_mask = (labels == 2) white_matter = (labels == 1) | (labels == 2) seeds = utils.seeds_from_mask(seed_mask, affine, density=2) response, ratio = auto_response_ssst(gtab, data, roi_radii=10, fa_thr=0.7) sphere = small_sphere """ We can now initialize a `RumbaSdModel` model and fit it globally by setting `voxelwise` to `False`. For this example, TV regularization (`use_tv`) will be turned off for efficiency, although its usage can provide more coherent results in fiber tracking. The fit will take about 5 minutes to complete. """ rumba = RumbaSDModel(gtab, wm_response=response[0], n_iter=200, voxelwise=False, use_tv=False, sphere=sphere) rumba_fit = rumba.fit(data, mask=white_matter) odf = rumba_fit.odf() # fODF f_wm = rumba_fit.f_wm # white matter volume fractions """ To establish stopping criterion, a common technique is to use the Generalized Fractional Anisotropy (GFA). One point of caution is that RUMBA-SD by default separates the fODF from an isotropic compartment. This can bias GFA results computed on the fODF, although it will still generally be an effective criterion. However, an alternative stopping criterion that takes advantage of this feature is to use RUMBA-SD's white matter volume fraction map. """ stopping_criterion = ThresholdStoppingCriterion(f_wm, .25) """ We can visualize a slice of this mask. """ import matplotlib.pyplot as plt sli = f_wm.shape[2] // 2 plt.figure() plt.subplot(1, 2, 1).set_axis_off() plt.imshow(f_wm[:, :, sli].T, cmap='gray', origin='lower') plt.subplot(1, 2, 2).set_axis_off() plt.imshow((f_wm[:, :, sli] > 0.25).T, cmap='gray', origin='lower') plt.savefig('f_wm_tracking_mask.png') """ .. figure:: f_wm_tracking_mask.png :align: center White matter volume fraction slice """ """ These discrete fODFs can be used as a PMF in the `ProbabilisticDirectionGetter` for sampling tracking directions. The PMF must be strictly non-negative; RUMBA-SD already adheres to this constraint so no further manipulation of the fODFs is necessary. """ from dipy.direction import ProbabilisticDirectionGetter from dipy.io.stateful_tractogram import Space, StatefulTractogram from dipy.io.streamline import save_trk prob_dg = ProbabilisticDirectionGetter.from_pmf(odf, max_angle=30., sphere=sphere) streamline_generator = LocalTracking(prob_dg, stopping_criterion, seeds, affine, step_size=.5) streamlines = Streamlines(streamline_generator) color = colormap.line_colors(streamlines) streamlines_actor = actor.streamtube( list(transform_streamlines(streamlines, inv(t1_aff))), color, linewidth=0.1) vol_actor = actor.slicer(t1_data) vol_actor.display(x=40) vol_actor2 = vol_actor.copy() vol_actor2.display(z=35) scene = window.Scene() scene.add(vol_actor) scene.add(vol_actor2) scene.add(streamlines_actor) if interactive: window.show(scene) window.record(scene, out_path='tractogram_probabilistic_rumba.png', size=(800, 800)) sft = StatefulTractogram(streamlines, hardi_img, Space.RASMM) save_trk(sft, "tractogram_probabilistic_rumba.trk") """ .. figure:: tractogram_probabilistic_rumba.png :align: center RUMBA-SD tractogram """ """ References ---------- .. [CanalesRodriguez2015] Canales-Rodríguez, E. J., Daducci, A., Sotiropoulos, S. N., Caruyer, E., Aja-Fernández, S., Radua, J., Mendizabal, J. M. Y., Iturria-Medina, Y., Melie-García, L., Alemán-Gómez, Y., Thiran, J.-P., Sarró, S., Pomarol-Clotet, E., & Salvador, R. (2015). Spherical Deconvolution of Multichannel Diffusion MRI Data with Non-Gaussian Noise Models and Spatial Regularization. PLOS ONE, 10(10), e0138910. https://doi.org/10.1371/journal.pone.0138910 .. include:: ../links_names.inc """