def tracking_prob(dir_src, dir_out, verbose=False): wm_name = 'wm_mask_' + par_b_tag + '_' + par_dim_tag + '.nii.gz' wm_mask, affine = load_nifti(pjoin(dir_src, wm_name), verbose) sh_name = 'sh_' + par_b_tag + '_' + par_dim_tag + '.nii.gz' sh, _ = load_nifti(pjoin(dir_src, sh_name), verbose) sphere = get_sphere('symmetric724') classifier = ThresholdTissueClassifier(wm_mask.astype('f8'), .5) classifier = BinaryTissueClassifier(wm_mask) max_dg = ProbabilisticDirectionGetter.from_shcoeff(sh, max_angle=par_trk_max_angle, sphere=sphere) seeds = utils.seeds_from_mask(wm_mask, density=2, affine=affine) streamlines = LocalTracking(max_dg, classifier, seeds, affine, step_size=par_trk_step_size) streamlines = list(streamlines) trk_name = 'tractogram_' + par_b_tag + '_' + par_dim_tag + '_' + par_trk_prob_tag + '.trk' trk_out = os.path.join(dir_out, trk_name) save_trk(trk_out, streamlines, affine, wm_mask.shape) dpy_out = trk_out.replace('.trk', '.dpy') dpy = Dpy(dpy_out, 'w') dpy.write_tracks(streamlines) dpy.close()
def runStream(csd_peaks, roi_file, roi_label=1, ang_thr=45., a_low=0.2, step_size=0.1, seeds_per_voxel=30, out_name=None): img = nib.load(roi_file) affine = img.get_affine() mask_data = img.get_data() p = np.asarray(np.where(mask_data == roi_label)) p = p.transpose() # seed_points = None # for i in p: # points = np.random.uniform(size=[seeds_per_voxel,3]) + (i-0.5) # if seed_points is None: # seed_points = points # else: # seed_points = np.concatenate([seed_points, points], axis=0) import dipy.tracking.utils as utils seeds = utils.seeds_from_mask(mask_data==1, density=seeds_per_voxel) print '# of seeds: ',len(seeds) sphere = get_sphere('symmetric724') print "seed eudx tractography" eu = EuDX(csd_peaks.peak_values, csd_peaks.peak_indices, odf_vertices=sphere.vertices, step_sz=step_size, seeds=seeds, ang_thr=ang_thr, a_low=a_low) csa_streamlines_mult_peaks = [streamline for streamline in eu] out_file = 'tracts.dipy' if out_name: out_file = out_name+'_'+out_file from dipy.io.trackvis import save_trk save_trk(out_file, csa_streamlines_mult_peaks, affine, mask.shape) dpw = Dpy(out_file, 'w') dpw.write_tracks(csa_streamlines_mult_peaks) print 'write tracts to %s' % out_file return (csa_streamlines_mult_peaks, out_file)
def tracking_maxodf(dir_src, dir_out, verbose=False): wm_name = 'wm_mask_' + par_b_tag + '_' + par_dim_tag + '.nii.gz' wm_mask, affine = load_nifti(pjoin(dir_src, wm_name), verbose) sh_name = 'sh_' + par_b_tag + '_' + par_dim_tag + '.nii.gz' sh, _ = load_nifti(pjoin(dir_src, sh_name), verbose) sphere = get_sphere('symmetric724') classifier = ThresholdTissueClassifier(wm_mask.astype('f8'), .5) classifier = BinaryTissueClassifier(wm_mask) max_dg = DeterministicMaximumDirectionGetter.from_shcoeff(sh, max_angle=par_trk_max_angle, sphere=sphere) seeds = utils.seeds_from_mask(wm_mask, density=2, affine=affine) streamlines = LocalTracking(max_dg, classifier, seeds, affine, step_size=par_trk_step_size) streamlines = list(streamlines) trk_name = 'tractogram_' + par_b_tag + '_' + par_dim_tag + '_' + par_trk_odf_tag + '.trk' save_trk(pjoin(dir_out, trk_name), streamlines, affine, wm_mask.shape)
""" .. figure:: deterministic.png :align: center **Corpus Callosum Deterministic** We've created a deterministic set of streamlines, so called because if you repeat the fiber tracking (keeping all the inputs the same) you will get exactly the same set of streamlines. We can save the streamlines as a Trackvis file so it can be loaded into other software for visualization or further analysis. """ from dipy.io.trackvis import save_trk save_trk("CSA_detr.trk", streamlines, affine, labels.shape) """ Next let's try some probabilistic fiber tracking. For this, we'll be using the Constrained Spherical Deconvolution (CSD) Model. This model represents each voxel in the data set as a collection of small white matter fibers with different orientations. The density of fibers along each orientation is known as the Fiber Orientation Distribution (FOD). In order to perform probabilistic fiber tracking, we pick a fiber from the FOD at random at each new location along the streamline. Note: one could use this model to perform deterministic fiber tracking by always tracking along the directions that have the most fibers. Let's begin probabilistic fiber tracking by fitting the data to the CSD model. """
renderer.add(actor.line(streamlines, line_colors(streamlines))) window.record(renderer, out_path='bootstrap_dg_CSD.png', size=(600, 600)) """ .. figure:: bootstrap_dg_CSD.png :align: center **Corpus Callosum Bootstrap Probabilistic Direction Getter** We have created a bootstrapped probabilistic set of streamlines. If you repeat the fiber tracking (keeping all inputs the same) you will NOT get exactly the same set of streamlines. We can save the streamlines as a Trackvis file so it can be loaded into other software for visualization or further analysis. """ save_trk("bootstrap_dg_CSD.trk", streamlines, affine, labels.shape) """ Example #2: Closest peak direction getter with CSD Model """ from dipy.direction import ClosestPeakDirectionGetter pmf = csd_fit.odf(small_sphere).clip(min=0) peak_dg = ClosestPeakDirectionGetter.from_pmf(pmf, max_angle=30., sphere=small_sphere) peak_streamline_generator = LocalTracking(peak_dg, classifier, seeds, affine, step_size=.5) streamlines = Streamlines(peak_streamline_generator) renderer.clear()
import dipy.reconst.dti as dti from dipy.reconst.dti import fractional_anisotropy tensor_model = dti.TensorModel(gtab) tenfit = tensor_model.fit(data, mask=white_matter) FA = fractional_anisotropy(tenfit.evals) classifier = ThresholdTissueClassifier(FA, .2) """ The Fiber Orientation Distribution (FOD) of the CSD model estimates the distribution of small fiber bundles within each voxel. This distribution can be used for deterministic fiber tracking. As for probabilistic tracking, there are many ways to provide those distributions to the deterministic maximum direction getter. Here, the spherical harmonic representation of the FOD is used. """ from dipy.data import default_sphere from dipy.direction import DeterministicMaximumDirectionGetter from dipy.io.trackvis import save_trk detmax_dg = DeterministicMaximumDirectionGetter.from_shcoeff(csd_fit.shm_coeff, max_angle=30., sphere=default_sphere) streamlines = LocalTracking(detmax_dg, classifier, seeds, affine, step_size=.5) save_trk("deterministic_maximum_shm_coeff.trk", streamlines, affine, labels.shape)
# Particle Filtering Tractography pft_streamline_generator = ParticleFilteringTracking(dg, cmc_classifier, seeds, affine, max_cross=1, step_size=step_size, maxlen=1000, pft_back_tracking_dist=2, pft_front_tracking_dist=1, particle_count=15, return_all=False) #streamlines = list(pft_streamline_generator) streamlines = Streamlines(pft_streamline_generator) save_trk("pft_streamline.trk", streamlines, affine, shape) renderer.clear() renderer.add(actor.line(streamlines, line_colors(streamlines))) window.record(renderer, out_path='pft_streamlines.png', size=(600, 600)) """ .. figure:: pft_streamlines.png :align: center **Particle Filtering Tractography** """ # Local Probabilistic Tractography prob_streamline_generator = LocalTracking(dg,
def _run_interface(self, runtime): import numpy as np import nibabel as nib from dipy.io import read_bvals_bvecs from dipy.core.gradients import gradient_table from nipype.utils.filemanip import split_filename # Loading the data fname = self.inputs.in_file img = nib.load(fname) data = img.get_data() affine = img.get_affine() FA_fname = self.inputs.FA_file FA_img = nib.load(FA_fname) fa = FA_img.get_data() affine = FA_img.get_affine() affine = np.matrix.round(affine) mask_fname = self.inputs.brain_mask mask_img = nib.load(mask_fname) mask = mask_img.get_data() bval_fname = self.inputs.bval bvals = np.loadtxt(bval_fname) bvec_fname = self.inputs.bvec bvecs = np.loadtxt(bvec_fname) bvecs = np.vstack([bvecs[0,:],bvecs[1,:],bvecs[2,:]]).T gtab = gradient_table(bvals, bvecs) # Creating a white matter mask fa = fa*mask white_matter = fa >= 0.2 # Creating a seed mask from dipy.tracking import utils seeds = utils.seeds_from_mask(white_matter, density=[2, 2, 2], affine=affine) # Fitting the CSA model from dipy.reconst.shm import CsaOdfModel from dipy.data import default_sphere from dipy.direction import peaks_from_model csa_model = CsaOdfModel(gtab, sh_order=8) csa_peaks = peaks_from_model(csa_model, data, default_sphere, relative_peak_threshold=.8, min_separation_angle=45, mask=white_matter) from dipy.tracking.local import ThresholdTissueClassifier classifier = ThresholdTissueClassifier(csa_peaks.gfa, .25) # CSD model from dipy.reconst.csdeconv import (ConstrainedSphericalDeconvModel, auto_response) response, ratio = auto_response(gtab, data, roi_radius=10, fa_thr=0.7) csd_model = ConstrainedSphericalDeconvModel(gtab, response, sh_order=8) csd_fit = csd_model.fit(data, mask=white_matter) from dipy.direction import ProbabilisticDirectionGetter prob_dg = ProbabilisticDirectionGetter.from_shcoeff(csd_fit.shm_coeff, max_angle=45., sphere=default_sphere) # Tracking from dipy.tracking.local import LocalTracking streamlines = LocalTracking(prob_dg, classifier, seeds, affine, step_size=.5, maxlen=200, max_cross=1) # Compute streamlines and store as a list. streamlines = list(streamlines) # Saving the trackfile from dipy.io.trackvis import save_trk _, base, _ = split_filename(fname) save_trk(base + '_CSDprob.trk', streamlines, affine, fa.shape) return runtime
classifier. """ import dipy.reconst.dti as dti from dipy.reconst.dti import fractional_anisotropy tensor_model = dti.TensorModel(gtab) tenfit = tensor_model.fit(data, mask=white_matter) FA = fractional_anisotropy(tenfit.evals) classifier = ThresholdTissueClassifier(FA, .2) """ The fiber orientation distribution (FOD) of the CSD model estimates the distribution of small fiber bundles within each voxel. This distribution can be used for deterministic fiber tracking. As for probabilistic tracking, there are many ways to provide those distributions to the deterministic maximum direction getter. Here, the spherical harmonic representation of the FOD is used. """ from dipy.data import default_sphere from dipy.direction import DeterministicMaximumDirectionGetter from dipy.io.trackvis import save_trk detmax_dg = DeterministicMaximumDirectionGetter.from_shcoeff( csd_fit.shm_coeff, max_angle=30., sphere=default_sphere) streamlines = LocalTracking(detmax_dg, classifier, seeds, affine, step_size=.5) save_trk("deterministic_maximum_shm_coeff.trk", streamlines, affine, labels.shape)
need to clip the FOD to use it as a PMF because the latter cannot have negative values. (Ideally the FOD should be strictly positive, but because of noise and/or model failures sometimes it can have negative values). """ from dipy.direction import ProbabilisticDirectionGetter from dipy.data import small_sphere from dipy.io.trackvis import save_trk fod = csd_fit.odf(small_sphere) pmf = fod.clip(min=0) prob_dg = ProbabilisticDirectionGetter.from_pmf(pmf, max_angle=30., sphere=small_sphere) streamlines = LocalTracking(prob_dg, classifier, seeds, affine, step_size=.5) save_trk("probabilistic_small_sphere.trk", streamlines, affine, labels.shape) """ One disadvantage of using a discrete PMF to represent possible tracking directions is that it tends to take up a lot of memory (RAM). The size of the PMF, the FOD in this case, must be equal to the number of possible tracking directions on the hemisphere, and every voxel has a unique PMF. In this case the data is ``(81, 106, 76)`` and ``small_sphere`` has 181 directions so the FOD is ``(81, 106, 76, 181)``. One way to avoid sampling the PMF and holding it in memory is to build the direction getter directly from the spherical harmonic representation of the FOD. By using this approach, we can also use a larger sphere, like ``default_sphere`` which has 362 directions on the hemisphere, without having to worry about memory limitations. """ from dipy.data import default_sphere
renderer.clear() renderer.add(actor.line(streamlines, cmap.line_colors(streamlines))) window.record(renderer, out_path='bootstrap_dg_CSD.png', size=(600, 600)) """ .. figure:: bootstrap_dg_CSD.png :align: center **Corpus Callosum Bootstrap Probabilistic Direction Getter** We have created a bootstrapped probabilistic set of streamlines. If you repeat the fiber tracking (keeping all inputs the same) you will NOT get exactly the same set of streamlines. We can save the streamlines as a Trackvis file so it can be loaded into other software for visualization or further analysis. """ save_trk("bootstrap_dg_CSD.trk", streamlines, affine, labels.shape) """ Example #2: Closest peak direction getter with CSD Model """ from dipy.direction import ClosestPeakDirectionGetter pmf = csd_fit.odf(small_sphere).clip(min=0) peak_dg = ClosestPeakDirectionGetter.from_pmf(pmf, max_angle=30., sphere=small_sphere) peak_streamline_generator = LocalTracking(peak_dg, classifier, seeds, affine, step_size=.5)
# In[ ]: print len(streamlines) print len(results) print len(streamlines[0]) print len(results[0]) for j in range(0, len(streamlines)): for i in range(0,len(streamlines[j])): print streamlines[j][i]==results[j][i] # In[ ]: from dipy.io.trackvis import save_trk save_trk("CSA_detr.trk", streamlines, affine, labels.shape) # In[ ]: # In[ ]: from dipy.reconst.csdeconv import (ConstrainedSphericalDeconvModel, auto_response) response, ratio = auto_response(gtab, data, roi_radius=10, fa_thr=0.7) csd_model = ConstrainedSphericalDeconvModel(gtab, response, sh_order=6) csd_fit = csd_model.fit(data, mask=white_matter)
cmc_classifier = CmcTissueClassifier.from_pve(img_pve_wm.get_data(), img_pve_gm.get_data(), img_pve_csf.get_data(), step_size=step_size, average_voxel_size=voxel_size) # seeds are place in voxel of the corpus callosum containing only white matter seed_mask = labels == 2 seed_mask[img_pve_wm.get_data() < 0.5] = 0 seeds = utils.seeds_from_mask(seed_mask, density=2, affine=affine) # Particle Filtering Tractography pft_streamline_generator = ParticleFilteringTracking(dg, cmc_classifier, seeds, affine, max_cross=1, step_size=step_size, maxlen=1000, pft_back_tracking_dist=2, pft_front_tracking_dist=1, particle_count=15, return_all=False) # streamlines = list(pft_streamline_generator) streamlines = Streamlines(pft_streamline_generator) save_trk("pft_streamline.trk", streamlines, affine, shape) renderer.clear() renderer.add(actor.line(streamlines, cmap.line_colors(streamlines))) window.record(renderer, out_path='pft_streamlines.png', size=(600, 600))
csa_model = CsaOdfModel(g_tab, sh_order=6) csa_peaks = peaks_from_model(csa_model, dwi_data, default_sphere, sh_order=6, relative_peak_threshold=.85, min_separation_angle=35, mask=dwi_mask_data.astype(bool)) classifier = ThresholdTissueClassifier(csa_peaks.gfa, .2) seeds = utils.seeds_from_mask(dwi_mask_data.astype(bool), density=[1, 1, 1], affine=dwi_affine) streamlines = LocalTracking(csa_peaks, classifier, seeds, dwi_affine, step_size=3) streamlines = [s for s in streamlines if s.shape[0] > 30] streamlines = list(streamlines) save_trk(os.path.join(path_output, '_tractography_CsaOdf' + '.trk'), streamlines, dwi_affine, dwi_mask_data.shape) print(' - Ending reconstruction of Tractography...') print(path_input)
ren.add(vol_actor) ren.add(vol_actor2) window.record(ren, out_path='sfm_streamlines.png', size=(800, 800)) if interactive: window.show(ren) """ .. figure:: sfm_streamlines.png :align: center **Sparse Fascicle Model tracks** Finally, we can save these streamlines to a 'trk' file, for use in other software, or for further analysis. """ from dipy.io.trackvis import save_trk save_trk("sfm_detr.trk", streamlines, affine, labels.shape) """ References ---------- .. [Rokem2015] Ariel Rokem, Jason D. Yeatman, Franco Pestilli, Kendrick N. Kay, Aviv Mezer, Stefan van der Walt, Brian A. Wandell (2015). Evaluating the accuracy of diffusion MRI models in white matter. PLoS ONE 10(4): e0123272. doi:10.1371/journal.pone.0123272 """
Probabilistic Direction Getter as a PMF for sampling tracking directions. We need to clip the FOD to use it as a PMF because the latter cannot have negative values. (Ideally the FOD should be strictly positive, but because of noise and/or model failures sometimes it can have negative values). """ from dipy.direction import ProbabilisticDirectionGetter from dipy.data import small_sphere from dipy.io.trackvis import save_trk fod = csd_fit.odf(small_sphere) pmf = fod.clip(min=0) prob_dg = ProbabilisticDirectionGetter.from_pmf(pmf, max_angle=30., sphere=small_sphere) streamlines = LocalTracking(prob_dg, classifier, seeds, affine, step_size=.5) save_trk("probabilistic_small_sphere.trk", streamlines, affine, labels.shape) """ One disadvantage of using a discrete PMF to represent possible tracking directions is that it tends to take up a lot of memory (RAM). The size of the PMF, the FOD in this case, must be equal to the number of possible tracking directions on the hemisphere, and every voxel has a unique PMF. In this case the data is ``(81, 106, 76)`` and ``small_sphere`` has 181 directions so the FOD is ``(81, 106, 76, 181)``. One way to avoid sampling the PMF and holding it in memory is to build the direction getter directly from the spherical harmonic representation of the FOD. By using this approach, we can also use a larger sphere, like ``default_sphere`` which has 362 directions on the hemisphere, without having to worry about memory limitations. """ from dipy.data import default_sphere
ren = window.Renderer() ren.add(streamlines_actor) ren.add(vol_actor) ren.add(vol_actor2) window.record(ren, out_path='sfm_streamlines.png', size=(800, 800)) if interactive: window.show(ren) """ .. figure:: sfm_streamlines.png :align: center **Sparse Fascicle Model tracks** Finally, we can save these streamlines to a 'trk' file, for use in other software, or for further analysis. """ from dipy.io.trackvis import save_trk save_trk("sfm_detr.trk", streamlines, affine, labels.shape) """ References ---------- .. [Rokem2015] Ariel Rokem, Jason D. Yeatman, Franco Pestilli, Kendrick N. Kay, Aviv Mezer, Stefan van der Walt, Brian A. Wandell (2015). Evaluating the accuracy of diffusion MRI models in white matter. PLoS ONE 10(4): e0123272. doi:10.1371/journal.pone.0123272 """
""" .. figure:: threshold_fa.png :align: center **Thresholded fractional anisotropy map.** """ all_streamlines_threshold_classifier = LocalTracking(dg, threshold_classifier, seeds, affine, step_size=.5, return_all=True) save_trk("deterministic_threshold_classifier_all.trk", all_streamlines_threshold_classifier, affine, labels.shape) streamlines = [sl for sl in all_streamlines_threshold_classifier] fvtk.clear(ren) fvtk.add(ren, fvtk.line(streamlines, line_colors(streamlines))) fvtk.record(ren, out_path='all_streamlines_threshold_classifier.png', size=(600, 600)) """ .. figure:: all_streamlines_threshold_classifier.png :align: center **Deterministic tractography using a thresholded fractional anisotropy.** """
fig.savefig('threshold_fa.png') """ .. figure:: threshold_fa.png :align: center **Thresholded fractional anisotropy map.** """ all_streamlines_threshold_classifier = LocalTracking(dg, threshold_classifier, seeds, affine, step_size=.5, return_all=True) save_trk("deterministic_threshold_classifier_all.trk", all_streamlines_threshold_classifier, affine, labels.shape) streamlines = [sl for sl in all_streamlines_threshold_classifier] fvtk.clear(ren) fvtk.add(ren, fvtk.line(streamlines, line_colors(streamlines))) fvtk.record(ren, out_path='all_streamlines_threshold_classifier.png', size=(600, 600)) """ .. figure:: all_streamlines_threshold_classifier.png :align: center **Deterministic tractography using a thresholded fractional anisotropy.** """ """