def csa_mod_est(gtab, data, B0_mask, sh_order=8): ''' Estimate a Constant Solid Angle (CSA) model from dwi data. Parameters ---------- gtab : Obj DiPy object storing diffusion gradient information data : array 4D numpy array of diffusion image data. B0_mask : str File path to B0 brain mask. sh_order : int The order of the SH model. Default is 8. Returns ------- csa_mod : ndarray Coefficients of the csa reconstruction. model : obj Fitted csa model. References ---------- .. [1] Aganj, I., et al. 2009. ODF Reconstruction in Q-Ball Imaging with Solid Angle Consideration. ''' from dipy.reconst.shm import CsaOdfModel print('Fitting CSA model...') model = CsaOdfModel(gtab, sh_order=sh_order) B0_mask_data = np.asarray(nib.load(B0_mask).dataobj).astype('bool') csa_mod = model.fit(data, B0_mask_data).shm_coeff del B0_mask_data return csa_mod, model
def probal(Threshold=.2, data_list=None, seed='.', one_node=False, two_node=False): time0 = time.time() print("begin loading data, time:", time.time() - time0) data = data_list['DWI'] affine = data_list['affine'] img = data_list['img'] labels = data_list['labels'] gtab = data_list['gtab'] head_mask = data_list['head_mask'] if type(seed) != str: seed_mask = seed else: seed_mask = (labels == 2) * (head_mask == 1) white_matter = (labels == 2) * (head_mask == 1) seeds = utils.seeds_from_mask(seed_mask, affine, density=1) print("begin reconstruction, time:", time.time() - time0) response, ratio = auto_response_ssst(gtab, data, roi_radii=10, fa_thr=0.7) csd_model = ConstrainedSphericalDeconvModel(gtab, response, sh_order=6) csd_fit = csd_model.fit(data, mask=white_matter) csa_model = CsaOdfModel(gtab, sh_order=6) gfa = csa_model.fit(data, mask=white_matter).gfa stopping_criterion = ThresholdStoppingCriterion(gfa, Threshold) print("begin tracking, time:", time.time() - time0) fod = csd_fit.odf(small_sphere) pmf = fod.clip(min=0) prob_dg = ProbabilisticDirectionGetter.from_pmf(pmf, max_angle=30., sphere=small_sphere) streamline_generator = LocalTracking(prob_dg, stopping_criterion, seeds, affine, step_size=.5) streamlines = Streamlines(streamline_generator) sft = StatefulTractogram(streamlines, img, Space.RASMM) if one_node or two_node: sft.to_vox() streamlines = reduct_seed_ROI(sft.streamlines, seed_mask, one_node, two_node) sft = StatefulTractogram(streamlines, img, Space.VOX) sft._vox_to_rasmm() print("begin saving, time:", time.time() - time0) output = 'tractogram_probabilistic.trk' save_trk(sft, output) print("finished, time:", time.time() - time0)
def csa_mod_est(gtab, data, B0_mask): ''' Estimate a Constant Solid Angle (CSA) model from dwi data. Parameters ---------- gtab : Obj DiPy object storing diffusion gradient information data : array 4D numpy array of diffusion image data. B0_mask : str File path to B0 brain mask. Returns ------- csa_mod : obj Spherical harmonics coefficients of the CSA-estimated reconstruction model. ''' from dipy.reconst.shm import CsaOdfModel print('Fitting CSA model...') model = CsaOdfModel(gtab, sh_order=6) csa_mod = model.fit(data, nib.load(B0_mask).get_fdata().astype('bool')).shm_coeff del model return csa_mod
def csa_mod_est(gtab, data, wm_in_dwi): from dipy.reconst.shm import CsaOdfModel print('Fitting CSA model...') wm_in_dwi_mask = nib.load(wm_in_dwi).get_fdata().astype('bool') model = CsaOdfModel(gtab, sh_order=6) mod = model.fit(data, wm_in_dwi_mask) return mod.shm_coeff
def reconst_f(output_dir, b_sph=None): params_file = os.path.join(output_dir, 'params.pickle') data_file = os.path.join(output_dir, 'data.pickle') baseparams = pickle.load(open(params_file, 'rb')) data = pickle.load(open(data_file, 'rb')) gtab = data.gtab S_data = data.raw[data.slice] S_data_list = [S_data] if hasattr(data, 'ground_truth'): S_data_list.append(data.ground_truth[data.slice]) l_labels = np.sum(gtab.bvals > 0) imagedims = S_data.shape[:-1] b_vecs = gtab.bvecs[gtab.bvals > 0,...] if b_sph is None: b_sph = load_sphere(vecs=b_vecs.T) qball_sphere = dipy.core.sphere.Sphere(xyz=b_vecs) basemodel = CsaOdfModel(gtab, **baseparams['base']) fs = [] for S in S_data_list: f = basemodel.fit(S).odf(qball_sphere) f = np.clip(f, 0, np.max(f, -1)[..., None]) f = np.array(f.reshape(-1, l_labels).T, order='C') normalize_odf(f, b_sph.b) fs.append(f) return tuple(fs)
def PFT_tracking(name=None, data_path=None, output_path='.', Threshold=.20): time0 = time.time() print("begin loading data, time:", time.time() - time0) data, affine, img, labels, gtab, head_mask = get_data(name, data_path) seed_mask = (labels == 2) * (head_mask == 1) white_matter = (labels == 2) * (head_mask == 1) seeds = utils.seeds_from_mask(seed_mask, affine, density=1) print('begin reconstruction, time:', time.time() - time0) response, ratio = auto_response_ssst(gtab, data, roi_radii=10, fa_thr=0.7) csd_model = ConstrainedSphericalDeconvModel(gtab, response) csd_fit = csd_model.fit(data, mask=white_matter) csa_model = CsaOdfModel(gtab, sh_order=6) gfa = csa_model.fit(data, mask=white_matter).gfa stopping_criterion = ThresholdStoppingCriterion(gfa, Threshold) dg = ProbabilisticDirectionGetter.from_shcoeff(csd_fit.shm_coeff, max_angle=20., sphere=default_sphere) #seed_mask = (labels == 2) #seed_mask[pve_wm_data < 0.5] = 0 seeds = utils.seeds_from_mask(seed_mask, affine, density=1) #voxel_size = np.average(voxel_size[1:4]) step_size = 0.2 #cmc_criterion = CmcStoppingCriterion.from_pve(pve_wm_data, # pve_gm_data, # pve_csf_data, # step_size=step_size, # average_voxel_size=voxel_size) # Particle Filtering Tractography pft_streamline_generator = ParticleFilteringTracking( dg, stopping_criterion, 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 = Streamlines(pft_streamline_generator) sft = StatefulTractogram(streamlines, img, Space.RASMM) output = output_path + '/tractogram_pft_' + name + '.trk'
def test_peaks_shm_coeff(): SNR = 100 S0 = 100 _, fbvals, fbvecs = get_data('small_64D') from dipy.data import get_sphere sphere = get_sphere('repulsion724') bvals = np.load(fbvals) bvecs = np.load(fbvecs) gtab = gradient_table(bvals, bvecs) mevals = np.array(([0.0015, 0.0003, 0.0003], [0.0015, 0.0003, 0.0003])) data, _ = multi_tensor(gtab, mevals, S0, angles=[(0, 0), (60, 0)], fractions=[50, 50], snr=SNR) from dipy.reconst.shm import CsaOdfModel model = CsaOdfModel(gtab, 4) pam = peaks_from_model(model, data[None, :], sphere, .5, 45, return_odf=True, return_sh=True) # Test that spherical harmonic coefficients return back correctly odf2 = np.dot(pam.shm_coeff, pam.B) assert_array_almost_equal(pam.odf, odf2) assert_equal(pam.shm_coeff.shape[-1], 45) pam = peaks_from_model(model, data[None, :], sphere, .5, 45, return_odf=True, return_sh=False) assert_equal(pam.shm_coeff, None) pam = peaks_from_model(model, data[None, :], sphere, .5, 45, return_odf=True, return_sh=True, sh_basis_type='mrtrix') odf2 = np.dot(pam.shm_coeff, pam.B) assert_array_almost_equal(pam.odf, odf2)
def tractography(brain, affine_brain, labels, diff, affine_diff, gtab, img): # Tractography reconstruction based on EuDX determinist algorithm labels = segmentation(brain, affine_brain, diff, affine_diff) white_matter = (labels == 3) csa_model = CsaOdfModel(gtab, sh_order=2) csa_peaks = peaks_from_model(csa_model, diff, default_sphere, relative_peak_threshold=.8, min_separation_angle=45, mask=white_matter) stopping_criterion = dipy.tracking.stopping_criterion.ThresholdStoppingCriterion( csa_peaks.gfa, .25) seeds = utils.seeds_from_mask(white_matter, affine_diff, density=1) streamlines_generator = LocalTracking(csa_peaks, stopping_criterion, seeds, affine=affine_diff, step_size=.5) streamlines = Streamlines(streamlines_generator) if has_fury: color = colormap.line_colors(streamlines) streamlines_actor = actor.line(streamlines, color) r = window.Renderer() r.add(streamlines_actor) window.record(r, out_path='tractogram.png', size=(800, 800)) window.show(r) sft = StatefulTractogram(streamlines, img, Space.RASMM) save_trk(sft, "tractogram.trk", streamlines) return streamlines
def test_torch_gfa(datas_dwi, gtabs): rtol = 1e-04 atol = 1e-08 idx = 0 data_dwi = datas_dwi[idx][100:140, 100:140, 28:29] gtab = gtabs[idx] csamodel = CsaOdfModel(gtab, 4) csamodel = csamodel.fit(data_dwi) data_sh = csamodel.shm_coeff true_gfa = csamodel.gfa torch_gfa = metrics.torch_gfa(torch.FloatTensor(data_sh)).numpy() assert np.isclose(true_gfa, torch_gfa, rtol=rtol, atol=atol).all()
def loc_track(path, default_sphere): data, affine = load_nifti(path + 'data.nii.gz') data[np.isnan(data) == 1] = 0 mask, affine = load_nifti(path + 'nodif_brain_mask.nii.gz') mask[np.isnan(mask) == 1] = 0 mask[:, :, 2:] = 0 gtab = gradient_table(path + 'bvals', path + 'bvecs') if os.path.exists(path + 'grad_dev.nii.gz'): gd, affine_g = load_nifti(path + 'grad_dev.nii.gz') else: gd = None csa_model = CsaOdfModel(gtab, smooth=1, sh_order=12) peaks = peaks_from_model(csa_model, data, default_sphere, relative_peak_threshold=0.99, min_separation_angle=25, mask=mask) seedss = copy.deepcopy(mask) seeds = utils.seeds_from_mask(seedss, affine, [2, 2, 2]) stopping_criterion = ThresholdStoppingCriterion(mask, 0) tracked = tracking(peaks, stopping_criterion, seeds, affine, graddev=gd, sphere=default_sphere) tracked.localTracking() return tracked
def calculate_model(self, response): csa_model = CsaOdfModel(self.gtab, sh_order=self.sh_order) csd_model = ConstrainedSphericalDeconvModel(self.gtab, response, sh_order=self.sh_order) csd_fit = csd_model.fit(self.data, mask=self.white_mask) return csd_fit, csa_model
def basic_tracking(name=None, data_path=None, output_path='.', Threshold=.20, data_list=None): time0 = time.time() print("begin loading data, time:", time.time() - time0) if data_list == None: data, affine, img, labels, gtab, head_mask = get_data(name, data_path) else: data = data_list['DWI'] affine = data_list['affine'] img = data_list['img'] labels = data_list['labels'] gtab = data_list['gtab'] head_mask = data_list['head_mask'] seed_mask = (labels == 2) * (head_mask == 1) white_matter = (labels == 2) * (head_mask == 1) seeds = utils.seeds_from_mask(seed_mask, affine, density=1) print('begin reconstruction, time:', time.time() - time0) from dipy.reconst.csdeconv import auto_response_ssst from dipy.reconst.shm import CsaOdfModel from dipy.data import default_sphere from dipy.direction import peaks_from_model response, ratio = auto_response_ssst(gtab, data, roi_radii=10, fa_thr=0.7) csa_model = CsaOdfModel(gtab, sh_order=6) csa_peaks = peaks_from_model(csa_model, data, default_sphere, relative_peak_threshold=.8, min_separation_angle=45, mask=white_matter) stopping_criterion = ThresholdStoppingCriterion(csa_peaks.gfa, Threshold) print("begin tracking, time:", time.time() - time0) # Initialization of LocalTracking. The computation happens in the next step. streamlines_generator = LocalTracking(csa_peaks, stopping_criterion, seeds, affine=affine, step_size=.5) # Generate streamlines object streamlines = Streamlines(streamlines_generator) print('begin saving, time:', time.time() - time0) from dipy.io.stateful_tractogram import Space, StatefulTractogram from dipy.io.streamline import save_trk sft = StatefulTractogram(streamlines, img, Space.RASMM) output = output_path + '/tractogram_EuDX_' + name + '.trk' save_trk(sft, output, streamlines)
def loc_track(path, default_sphere, coords=None, npath=None, UParams=None, ang_thr=None): data, affine = load_nifti(path + 'data.nii.gz') data[np.isnan(data) == 1] = 0 mask, affine = load_nifti(path + 'nodif_brain_mask.nii.gz') mask[np.isnan(mask) == 1] = 0 mask[:, :, 1:] = 0 stopper = copy.deepcopy(mask) #stopper[:, :, :] = 1 gtab = gradient_table(path + 'bvals', path + 'bvecs') csa_model = CsaOdfModel(gtab, smooth=1, sh_order=12) peaks = peaks_from_model(csa_model, data, default_sphere, relative_peak_threshold=0.99, min_separation_angle=25, mask=mask) if ang_thr is not None: peaks.ang_thr = ang_thr if os.path.exists(path + 'grad_dev.nii.gz'): gd, affine_g = load_nifti(path + 'grad_dev.nii.gz') nmask, naffine = load_nifti(npath + 'nodif_brain_mask.nii.gz') nmask[np.isnan(nmask) == 1] = 0 nmask[:, :, 1:] = 0 seedss = copy.deepcopy(nmask) seedss = utils.seeds_from_mask(seedss, naffine, [2, 2, 2]) useed = [] UParams = coords.Uparams for seed in seedss: us = coords.rFUa_xyz(seed[0], seed[1], seed[2]) vs = coords.rFVa_xyz(seed[0], seed[1], seed[2]) ws = coords.rFWa_xyz(seed[0], seed[1], seed[2]) condition = us >= UParams.min_a and us <= UParams.max_a and vs >= UParams.min_b and vs <= UParams.max_b \ and ws >= UParams.min_c and ws <= UParams.max_c if condition == True: useed.append([float(us), float(vs), float(ws)]) seeds = np.asarray(useed) else: gd = None seedss = copy.deepcopy(mask) seeds = utils.seeds_from_mask(seedss, affine, [2, 2, 2]) stopping_criterion = BinaryStoppingCriterion(stopper) tracked = tracking(peaks, stopping_criterion, seeds, affine, graddev=gd, sphere=default_sphere) tracked.localTracking() return tracked
def ClosestPeak(name=None, data_path=None, output_path='.', Threshold=.20): time0 = time.time() print("begin loading data, time:", time.time() - time0) data, affine, img, labels, gtab, head_mask = get_data(name, data_path) seed_mask = (labels == 2) * (head_mask == 1) white_matter = (labels == 2) * (head_mask == 1) seeds = utils.seeds_from_mask(seed_mask, affine, density=1) print("begin reconstruction, time:", time.time() - time0) response, ratio = auto_response_ssst(gtab, data, roi_radii=10, fa_thr=0.7) csd_model = ConstrainedSphericalDeconvModel(gtab, response, sh_order=6) #csd_fit = csd_model.fit(data, mask=white_matter) #pmf = csd_fit.odf(small_sphere).clip(min=0) peak_dg = BootDirectionGetter.from_data(data, csd_model, max_angle=30., sphere=small_sphere) csa_model = CsaOdfModel(gtab, sh_order=6) gfa = csa_model.fit(data, mask=white_matter).gfa stopping_criterion = ThresholdStoppingCriterion(gfa, Threshold) #from dipy.data import small_sphere print("begin tracking, time:", time.time() - time0) #detmax_dg = DeterministicMaximumDirectionGetter.from_shcoeff( # csd_fit.shm_coeff, max_angle=30., sphere=default_sphere) streamline_generator = LocalTracking(peak_dg, stopping_criterion, seeds, affine, step_size=.5) streamlines = Streamlines(streamline_generator) sft = StatefulTractogram(streamlines, img, Space.RASMM) print("begin saving, time:", time.time() - time0) output = output_path + '/tractogram_ClosestPeak_' + name + '.trk' save_trk(sft, output) print("finished, time:", time.time() - time0)
def fit_data(data, bvals, bvecs, model_type='3D-SHORE', calculate_peak_image=False): """ Fits the defined model to the input dMRI and returns an MITK compliant ODF image. """ # create dipy Sphere sphere = get_mitk_sphere() odf = None model = None gtab = gradient_table(bvals, bvecs) # fit selected model if model_type == '3D-SHORE': print('Fitting 3D-SHORE') radial_order = 6 zeta = 700 lambdaN = 1e-8 lambdaL = 1e-8 model = ShoreModel(gtab, radial_order=radial_order, zeta=zeta, lambdaN=lambdaN, lambdaL=lambdaL) asmfit = model.fit(data) odf = asmfit.odf(sphere) elif model_type == 'CSA-QBALL': print('Fitting CSA-QBALL') model = CsaOdfModel(gtab, 4) odf = model.fit(data).odf(sphere) odf = np.clip(odf, 0, np.max(odf, -1)[..., None]) elif model_type == 'SFM': print('Fitting SFM') response, ratio = auto_response(gtab, data, roi_radius=10, fa_thr=0.7) model = sfm.SparseFascicleModel(gtab, sphere=sphere, l1_ratio=0.5, alpha=0.001, response=response[0]) odf = model.fit(data).odf(sphere) elif model_type == 'CSD': print('Fitting CSD') response, ratio = auto_response(gtab, data, roi_radius=10, fa_thr=0.7) model = ConstrainedSphericalDeconvModel(gtab, response, sh_order=6) odf = model.fit(data).odf(sphere) else: raise ValueError('Model type not supported. Available models: 3D-SHORE, CSA-QBALL, SFM, CSD') print('Preparing ODF image') # swap axes to obtain MITK compliant format. # odf = odf.swapaxes(3, 2) # odf = odf.swapaxes(2, 1) # odf = odf.swapaxes(1, 0) odf_image = sitk.Image([data.shape[2], data.shape[1], data.shape[0]], sitk.sitkVectorFloat32, len(sphere.vertices)) for x in range(data.shape[2]): for y in range(data.shape[1]): for z in range(data.shape[0]): odf_image.SetPixel(x,y,z, odf[z,y,x,:]) # if not calculate_peak_image: return odf_image, None
def calculate_odf(gtab, data, sh_order=4): csamodel = CsaOdfModel(gtab, sh_order) data_small = data[30:65, 40:75, 39:40] csa_odf = csamodel.fit(data_small).odf(default_sphere) csa_odf = np.clip(csa_odf, 0, np.max(csa_odf, -1)[..., None]) odf_spheres = actor.odf_slicer(csa_odf, sphere=default_sphere, scale=0.9, norm=False, colormap='plasma') ren = window.Scene() ren.add(odf_spheres) print('Saving illustration as csa_odfs_{}.png'.format(data.shape[-1] - 1)) window.record(ren, out_path='results/csa_odfs_{}.png'.format(data.shape[-1] - 1), size=(600, 600)) return csa_odf
def csa_mod_est(gtab, data, B0_mask, sh_order=8): """ Estimate a Constant Solid Angle (CSA) model from dwi data. Parameters ---------- gtab : Obj DiPy object storing diffusion gradient information data : array 4D numpy array of diffusion image data. B0_mask : str File path to B0 brain mask. sh_order : int The order of the SH model. Default is 8. Returns ------- csa_mod : ndarray Coefficients of the csa reconstruction. model : obj Fitted csa model. References ---------- .. [1] Aganj, I., et al. 2009. ODF Reconstruction in Q-Ball Imaging with Solid Angle Consideration. """ from dipy.reconst.shm import CsaOdfModel print("Reconstructing using CSA...") model = CsaOdfModel(gtab, sh_order=sh_order) csa_mod = model.fit( data, np.nan_to_num(np.asarray( nib.load(B0_mask).dataobj)).astype("bool")).shm_coeff # Clip any negative values csa_mod = np.clip(csa_mod, 0, np.max(csa_mod, -1)[..., None]) return csa_mod.astype("float32"), model
def to_generate_tractography(path_dwi_input, path_binary_mask, path_out, path_bval, path_bvec): from dipy.reconst.shm import CsaOdfModel from dipy.data import default_sphere from dipy.direction import peaks_from_model from dipy.tracking.local import LocalTracking from dipy.tracking import utils from dipy.tracking.local import ThresholdTissueClassifier print(' - Starting reconstruction of Tractography...') if not os.path.exists(path_out + '_tractography_CsaOdf' + '.trk'): dwi_img = nib.load(path_dwi_input) dwi_data = dwi_img.get_data() dwi_affine = dwi_img.affine dwi_mask_data = nib.load(path_binary_mask).get_data() g_tab = gradient_table(path_bval, path_bvec) 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(path_out + '_tractography_CsaOdf' + '.trk', streamlines, dwi_affine, dwi_mask_data.shape) print(' - Ending reconstruction of Tractography...')
def main(): start = time.time() with open('config.json') as config_json: config = json.load(config_json) # Load the data dmri_image = nib.load(config['data_file']) dmri = dmri_image.get_data() print('Dmri' + str(dmri.shape)) #aparc_im = nib.load(config['freesurfer']) aparc_im = nib.load("volume.nii.gz") aparc = aparc_im.get_data() print('Aparc' + str(aparc.shape)) end = time.time() print('Loaded Files: ' + str((end - start))) # Create the white matter mask start = time.time() wm_regions = [ 2, 41, 16, 17, 28, 60, 51, 53, 12, 52, 12, 52, 13, 18, 54, 50, 11, 251, 252, 253, 254, 255, 10, 49, 46, 7 ] wm_mask = np.zeros(aparc.shape) for l in wm_regions: wm_mask[aparc == l] = 1 print('Created white matter mask: ' + str(time.time() - start)) # Create the gradient table from the bvals and bvecs start = time.time() bvals, bvecs = read_bvals_bvecs(config['data_bval'], config['data_bvec']) gtab = gradient_table(bvals, bvecs, b0_threshold=100) end = time.time() print('Created Gradient Table: ' + str((end - start))) # Create the csa model and calculate peaks start = time.time() csa_model = CsaOdfModel(gtab, sh_order=6) print('Created CSA Model: ' + str(time.time() - start)) csa_peaks = peaks_from_model(csa_model, dmri, default_sphere, relative_peak_threshold=.8, min_separation_angle=45, mask=wm_mask) print('Generated peaks: ' + str(time.time() - start)) save_peaks('peaks.pam5', csa_peaks)
def csa_mod_est(gtab, data, wm_in_dwi): ''' Estimate a Constant Solid Angle (CSA) model from dwi data. Parameters ---------- gtab : Obj DiPy object storing diffusion gradient information data : array 4D numpy array of diffusion image data. wm_in_dwi : str File path to white-matter tissue segmentation Nifti1Image. Returns ------- csa_mod : obj Spherical harmonics coefficients of the CSA-estimated reconstruction model. ''' from dipy.reconst.shm import CsaOdfModel print('Fitting CSA model...') wm_in_dwi_mask = nib.load(wm_in_dwi).get_fdata().astype('bool') model = CsaOdfModel(gtab, sh_order=6) csa_mod = model.fit(data, wm_in_dwi_mask).shm_coeff return csa_mod
def init_odf(self, params={}, csd=False): baseparams = { 'assume_normed': self.normed, 'sh_order': 6, } baseparams.update(params) if csd: logging.info("Using CSD for ground truth reconstruction.") basemodel = ConstrainedSphericalDeconvModel( self.gtab, self.csd_response) else: basemodel = CsaOdfModel(self.gtab, **baseparams) S_data = self.raw[self.slice] S_data_orig = self.ground_truth[self.slice] f = basemodel.fit(S_data).odf(self.dipy_sph) self.odf = np.clip(f, 0, np.max(f, -1)[..., None]) f = basemodel.fit(S_data_orig).odf(self.dipy_sph) self.odf_ground_truth = np.clip(f, 0, np.max(f, -1)[..., None])
from dipy.reconst.shm import CsaOdfModel, QballModel, OpdtModel, sh_to_sf fetch_stanford_hardi() img, gtab = read_stanford_hardi() vizu = 1 data = img.get_data() affine = img.get_affine() print('data.shape (%d, %d, %d, %d)' % data.shape) #mrconvert dwi.nii -coord 3 0 - | threshold - - | median3D - - | median3D - mask.nii #mask = data[..., 0] > 50 order = 4 csamodel = CsaOdfModel(gtab, order, smooth=0.006) print 'Computing the CSA odf...' csafit = csamodel.fit(data) coeff = csafit._shm_coef # dipy-dev compatible #GFA = csafit.gfa #nib.save(nib.Nifti1Image(GFA.astype('float32'), affine), 'gfa_csa.nii.gz') nib.save(nib.Nifti1Image(coeff.astype('float32'), affine), 'csa_odf_sh.nii.gz') sphere = get_sphere('symmetric724') odfs = sh_to_sf(coeff[20:50,55:85, 38:39], sphere, order) if vizu : from dipy.viz import fvtk r = fvtk.ren()
affine = hardi_img.get_affine() seed_mask = labels == 2 white_matter = (labels == 1) | (labels == 2) seeds = utils.seeds_from_mask(seed_mask, density=1, affine=affine) csd_model = ConstrainedSphericalDeconvModel(gtab, None, sh_order=6) csd_fit = csd_model.fit(data, mask=white_matter) """ We use the GFA of the CSA model to build a tissue classifier. """ from dipy.reconst.shm import CsaOdfModel csa_model = CsaOdfModel(gtab, sh_order=6) gfa = csa_model.fit(data, mask=white_matter).gfa classifier = ThresholdTissueClassifier(gfa, .25) """ The fiber orientation distribution (FOD) of the CSD model estimates the distribution of small fiber bundles within each voxel. We can use this distribution for probabilistic fiber tracking. One way to do this is to represent the FOD using a discrete sphere. This discrete FOD can be used by the 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
def Analyze(img_d_path, img_s_path, gtab): # For fiber tracking, 3 things are needed # 1. Method for getting directions # 2. Method for identifying different tissue types # 3. seeds to begin tracking from print_info = False if print_info: print( "============================ Diffusion ============================" ) print(img_d) print( "============================ Structural =============================" ) print(img_s) print("Labels:", np.unique(img_s.get_data()).astype('int')) # Load images img_d = nib.load(img_d_path) img_s = nib.load(img_s_path) # Resize the label (img_s) # 0. create an empty array the shape of diffusion image, without # the 4th dimension # 1. Convert structural voxel coordinates into ref space (affine) # 2. Convert diffusion voxel coordinates into ref space (affine) # 3 For each diffusion ref coordinate, # find the closest structural ref coordinate # 4. find its corresponding label, then input it to the empty array print_info_2 = True if print_info_2: #print(img_d.get_data().shape[]) print(img_d.affine) print(img_s.affine) print(img_s._dataobj._shape) print(img_d._dataobj._shape) img_d_shape_3D = [j for i, j in enumerate(img_d.dataobj._shape) if i < 3] img_s_shape_3D = img_s.dataobj._shape #raise ValueError(" ") img_d_affine = img_d.affine img_s_affine = img_s.affine img_s_data = img_s.get_data() img_d_data = img_d.get_data() Vox_coord_s_i = np.arange(img_s_shape_3D[0]) Vox_coord_s_j = np.arange(img_s_shape_3D[1]) Vox_coord_s_k = np.arange(img_s_shape_3D[2]) Ref_coord_s_i = Vox_coord_s_i * img_s_affine[0, 0] + img_s_affine[0, 3] Ref_coord_s_j = Vox_coord_s_j * img_s_affine[1, 1] + img_s_affine[1, 3] Ref_coord_s_k = Vox_coord_s_k * img_s_affine[2, 2] + img_s_affine[2, 3] #print(Ref_coord_s_j) reduced_size_label = np.zeros(img_d_shape_3D) for i in range(img_d_shape_3D[0]): for j in range(img_d_shape_3D[1]): for k in range(img_d_shape_3D[2]): # convert to reference coordinate ref_coord_i = i * img_d_affine[0, 0] + img_d_affine[0, 3] ref_coord_j = j * img_d_affine[1, 1] + img_d_affine[1, 3] ref_coord_k = k * img_d_affine[2, 2] + img_d_affine[2, 3] min_i_ind = bisect.bisect_left(np.sort(Ref_coord_s_i), ref_coord_i) min_j_ind = bisect.bisect_left(Ref_coord_s_j, ref_coord_j) min_k_ind = bisect.bisect_left(Ref_coord_s_k, ref_coord_k) #print(min_i_ind,min_j_ind,min_k_ind) #print(img_s_data[260-1-min_i_ind][311-1-min_j_ind][260-1-min_k_ind]) #reduced_size_label[i][j][k]=img_s_data[260-1-min_i_ind][311-1-min_j_ind][260-1-min_k_ind] reduced_size_label[i][j][k] = img_s_data[260 - 1 - min_i_ind, min_j_ind, min_k_ind] print("Label image reduction successful") # Divide Brainstem #msk_Midbrain yy, xx, zz = np.meshgrid(np.arange(174), np.arange(145), np.arange(145)) pon_midbrain_msk = yy > (-115 / 78) * zz + 115 midbrain_msk = zz > 48 BS_msk = reduced_size_label == 16 reduced_size_label_BS_seg = np.copy(reduced_size_label) reduced_size_label_BS_seg[BS_msk * pon_midbrain_msk] = 90 reduced_size_label_BS_seg[BS_msk * midbrain_msk] = 120 plt.figure(figsize=[11, 8.5]) msk = reduced_size_label > 200 temp_reduced_size_label = np.copy(reduced_size_label_BS_seg) temp_reduced_size_label[msk] = 0 plt.imshow(temp_reduced_size_label[72, :, :], origin='lower') msk = reduced_size_label == 16 temp_reduced_size_label = np.copy(reduced_size_label) temp_reduced_size_label[~msk] = 0 plt.figure(figsize=[11, 8.5]) plt.imshow(temp_reduced_size_label[72, :, :], origin='lower') #print("image display complete") #input1=raw_input("stopping") T1_path = "C:\\Users\\gham\\Desktop\\Human Brain\\Data\\102109\\102109_3T_Diffusion_preproc\\102109\\T1w\\" T1_file = "T1w_acpc_dc_restore_1.25.nii.gz" T1 = nib.load(T1_path + T1_file) T1_data = T1.get_data() plt.figure(figsize=[11, 8.5]) plt.imshow(T1_data[72, :, :], origin='lower') plt.show() # implement the modified label reduced_size_label = reduced_size_label_BS_seg #raise ValueError("========== Stop =============") #White matter mask left_cerebral_wm = reduced_size_label == 2 right_cerebral_wm = reduced_size_label == 41 cerebral_wm = left_cerebral_wm + right_cerebral_wm left_cerebellum_wm = reduced_size_label == 7 right_cerebellum_wm = reduced_size_label == 46 cerebellum_wm = left_cerebellum_wm + right_cerebellum_wm CC = np.zeros(reduced_size_label.shape) for i in [251, 252, 253, 254, 255]: CC += reduced_size_label == i left_cortex = np.zeros(reduced_size_label.shape) for i in np.arange(1000, 1036): left_cortex += reduced_size_label == i right_cortex = np.zeros(reduced_size_label.shape) for i in np.arange(2000, 2036): right_cortex += reduced_size_label == i extra = np.zeros(reduced_size_label.shape) for i in [ 4, 5, 8, 10, 11, 12, 13, 14, 15, 16, 90, 120, 17, 18, 24, 26, 28, 30, 31, 43, 44, 46, 47, 49, 50, 51, 52, 53, 54, 58, 60, 62, 63, 77, 80, 85 ]: extra += reduced_size_label == i #for i in np.arange(1001,1035): # extra+=reduced_size_label==i wm = cerebral_wm + cerebellum_wm + CC + extra + left_cortex + right_cortex #seed_mask1=np.zeros(reduced_size_label.shape) #for i in [16]: # seed_mask1+=reduced_size_label==i #seed_mask2=np.zeros(reduced_size_label.shape) #seed_mask=seed_mask1+seed_mask2 #seed_mask=(reduced_size_label==16)+(reduced_size_label==2)+(reduced_size_label==41) #seeds = utils.seeds_from_mask(seed_mask, density=1, affine=img_d_affine) seeds = utils.seeds_from_mask(wm, density=1, affine=img_d_affine) # Constrained Spherical Deconvolution #reference: https://www.imagilys.com/constrained-spherical-deconvolution-CSD-tractography/ csd_model = ConstrainedSphericalDeconvModel(gtab, None, sh_order=6) csd_fit = csd_model.fit(img_d_data, mask=wm) print("CSD model complete") # reconstruction from dipy.reconst.shm import CsaOdfModel csa_model = CsaOdfModel(gtab, sh_order=6) gfa = csa_model.fit(img_d_data, mask=wm).gfa classifier = ThresholdTissueClassifier(gfa, .25) # ============================================================================= # import dipy.reconst.dti as dti # from dipy.reconst.dti import fractional_anisotropy # tensor_model = dti.TensorModel(gtab) # tenfit=tensor_model.fit(img_d_data,mask=wm) #COMPUTATIONALL INTENSE # FA=fractional_anisotropy(tenfit.evals) # classifier=ThresholdTissueClassifier(FA,.1) # 0.2 enough? # ============================================================================= print("Classifier complete") # Probabilistic direction getter from dipy.direction import ProbabilisticDirectionGetter from dipy.data import small_sphere from dipy.io.streamline import save_trk fod = csd_fit.odf(small_sphere) pmf = fod.clip(min=0) prob_dg = ProbabilisticDirectionGetter.from_pmf(pmf, max_angle=75., sphere=small_sphere) streamlines_generator = LocalTracking(prob_dg, classifier, seeds, img_d_affine, step_size=.5) save_trk("probabilistic_small_sphere.trk", streamlines_generator, img_d_affine, reduced_size_label.shape) astreamlines = np.array(list(streamlines_generator)) endpoints = np.array( [st[0::len(st) - 1] for st in astreamlines if len(st) > 1]) print(endpoints) with open('endpoints-shorder=6-maxangle=75-gfa=0.25-BSdiv-v3.pkl', 'wb') as f: pickle.dump(endpoints, f) with open("reduced_label-shorder=6-maxangle=75-gfa=0.25-BSdiv-v3.pkl", "wb") as g: pickle.dump(reduced_size_label, g)
fetch_stanford_hardi() img, gtab = read_stanford_hardi() 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)
from dipy.tracking.streamline import Streamlines from dipy.viz import actor, window, colormap as cmap """ First, we need to generate some streamlines. For a more complete description of these steps, please refer to the CSA Probabilistic Tracking Tutorial. """ hardi_img, gtab, labels_img = read_stanford_labels() data = hardi_img.get_data() labels = labels_img.get_data() affine = hardi_img.affine white_matter = (labels == 1) | (labels == 2) csa_model = CsaOdfModel(gtab, sh_order=6) csa_peaks = peaks_from_model(csa_model, data, default_sphere, relative_peak_threshold=.8, min_separation_angle=45, mask=white_matter) stopping_criterion = ThresholdStoppingCriterion(csa_peaks.gfa, .25) seed_mask = labels == 2 seeds = utils.seeds_from_mask(seed_mask, affine, density=[1, 1, 1]) # Initialization of LocalTracking. The computation happens in the next step. streamlines = LocalTracking(csa_peaks, stopping_criterion,
def test_contour_from_roi(): # Render volume renderer = window.renderer() data = np.zeros((50, 50, 50)) data[20:30, 25, 25] = 1. data[25, 20:30, 25] = 1. affine = np.eye(4) surface = actor.contour_from_roi(data, affine, color=np.array([1, 0, 1]), opacity=.5) renderer.add(surface) renderer.reset_camera() renderer.reset_clipping_range() # window.show(renderer) # Test binarization renderer2 = window.renderer() data2 = np.zeros((50, 50, 50)) data2[20:30, 25, 25] = 1. data2[35:40, 25, 25] = 1. affine = np.eye(4) surface2 = actor.contour_from_roi(data2, affine, color=np.array([0, 1, 1]), opacity=.5) renderer2.add(surface2) renderer2.reset_camera() renderer2.reset_clipping_range() # window.show(renderer2) arr = window.snapshot(renderer, 'test_surface.png', offscreen=True) arr2 = window.snapshot(renderer2, 'test_surface2.png', offscreen=True) report = window.analyze_snapshot(arr, find_objects=True) report2 = window.analyze_snapshot(arr2, find_objects=True) npt.assert_equal(report.objects, 1) npt.assert_equal(report2.objects, 2) # test on real streamlines using tracking example from dipy.data import read_stanford_labels from dipy.reconst.shm import CsaOdfModel from dipy.data import default_sphere from dipy.direction import peaks_from_model from dipy.tracking.local import ThresholdTissueClassifier from dipy.tracking import utils from dipy.tracking.local import LocalTracking from fury.colormap import line_colors hardi_img, gtab, labels_img = read_stanford_labels() data = hardi_img.get_data() labels = labels_img.get_data() affine = hardi_img.affine white_matter = (labels == 1) | (labels == 2) csa_model = CsaOdfModel(gtab, sh_order=6) csa_peaks = peaks_from_model(csa_model, data, default_sphere, relative_peak_threshold=.8, min_separation_angle=45, mask=white_matter) classifier = ThresholdTissueClassifier(csa_peaks.gfa, .25) seed_mask = labels == 2 seeds = utils.seeds_from_mask(seed_mask, density=[1, 1, 1], affine=affine) # Initialization of LocalTracking. # The computation happens in the next step. streamlines = LocalTracking(csa_peaks, classifier, seeds, affine, step_size=2) # Compute streamlines and store as a list. streamlines = list(streamlines) # Prepare the display objects. streamlines_actor = actor.line(streamlines, line_colors(streamlines)) seedroi_actor = actor.contour_from_roi(seed_mask, affine, [0, 1, 1], 0.5) # Create the 3d display. r = window.Renderer() r2 = window.Renderer() r.add(streamlines_actor) arr3 = window.snapshot(r, 'test_surface3.png', offscreen=True) report3 = window.analyze_snapshot(arr3, find_objects=True) r2.add(streamlines_actor) r2.add(seedroi_actor) arr4 = window.snapshot(r2, 'test_surface4.png', offscreen=True) report4 = window.analyze_snapshot(arr4, find_objects=True) # assert that the seed ROI rendering is not far # away from the streamlines (affine error) npt.assert_equal(report3.objects, report4.objects)
from dipy.data import fetch_stanford_hardi, read_stanford_hardi, get_sphere from dipy.reconst.shm import CsaOdfModel, QballModel, OpdtModel, normalize_data from dipy.reconst.odf import gfa, odf_remove_negative_values, minmax_normalize fetch_stanford_hardi() img, gtab = read_stanford_hardi() data = img.get_data() affine = img.get_affine() print('data.shape (%d, %d, %d, %d)' % data.shape) #mrconvert dwi.nii -coord 3 0 - | threshold - - | median3D - - | median3D - mask.nii #mask = data[..., 0] > 50 csamodel = CsaOdfModel(gtab, 4, smooth=0.006) print 'Computing the CSA odf...' coeff = csamodel._get_shm_coef(data) print coeff.shape print 'Computing GFA...' print np.min(coeff[:,:,:,0]),np.max(coeff[:,:,:,0]) gfa_sh = np.sqrt(1.0 - (coeff[:,:,:,0] ** 2 / ( np.sum(np.square(coeff), axis=3) ) ) ) gfa_sh[np.isnan(gfa_sh)] = 0 print 'Saving nifti...' nib.save(nib.Nifti1Image(gfa_sh.astype('float32'), affine), 'gfa_full_brain.nii.gz') nib.save(nib.Nifti1Image(coeff.astype('float32'), affine), 'csa_odf_sh.nii.gz') qballmodel = QballModel(gtab, 4, smooth=0.006)
data.shape ``(81, 106, 76, 160)`` Remove most of the background using dipy's mask module. """ from dipy.segment.mask import median_otsu maskdata, mask = median_otsu(data, 3, 1, True, vol_idx=range(10, 50), dilate=2) """ We instantiate our CSA model with spherical harmonic order of 4 """ csamodel = CsaOdfModel(gtab, 4) """ `Peaks_from_model` is used to calculate properties of the ODFs (Orientation Distribution Function) and return for example the peaks and their indices, or GFA which is similar to FA but for ODF based models. This function mainly needs a reconstruction model, the data and a sphere as input. The sphere is an object that represents the spherical discrete grid where the ODF values will be evaluated. """ sphere = get_sphere('symmetric724') csapeaks = peaks_from_model(model=csamodel, data=maskdata, sphere=sphere,
def run(self, input_files, bvalues_files, bvectors_files, mask_files, sh_order=6, odf_to_sh_order=8, b0_threshold=50.0, bvecs_tol=0.01, extract_pam_values=False, parallel=False, nbr_processes=None, out_dir='', out_pam='peaks.pam5', out_shm='shm.nii.gz', out_peaks_dir='peaks_dirs.nii.gz', out_peaks_values='peaks_values.nii.gz', out_peaks_indices='peaks_indices.nii.gz', out_gfa='gfa.nii.gz'): """ Constant Solid Angle. Parameters ---------- input_files : string Path to the input volumes. This path may contain wildcards to process multiple inputs at once. bvalues_files : string Path to the bvalues files. This path may contain wildcards to use multiple bvalues files at once. bvectors_files : string Path to the bvectors files. This path may contain wildcards to use multiple bvectors files at once. mask_files : string Path to the input masks. This path may contain wildcards to use multiple masks at once. (default: No mask used) sh_order : int, optional Spherical harmonics order used in the CSA fit. odf_to_sh_order : int, optional Spherical harmonics order used for peak_from_model to compress the ODF to spherical harmonics coefficients. b0_threshold : float, optional Threshold used to find b0 volumes. bvecs_tol : float, optional Threshold used so that norm(bvec)=1. extract_pam_values : bool, optional Whether or not to save pam volumes as single nifti files. parallel : bool, optional Whether to use parallelization in peak-finding during the calibration procedure. nbr_processes : int, optional If `parallel` is True, the number of subprocesses to use (default multiprocessing.cpu_count()). out_dir : string, optional Output directory. (default current directory) out_pam : string, optional Name of the peaks volume to be saved. out_shm : string, optional Name of the spherical harmonics volume to be saved. out_peaks_dir : string, optional Name of the peaks directions volume to be saved. out_peaks_values : string, optional Name of the peaks values volume to be saved. out_peaks_indices : string, optional Name of the peaks indices volume to be saved. out_gfa : string, optional Name of the generalized FA volume to be saved. References ---------- .. [1] Aganj, I., et al. 2009. ODF Reconstruction in Q-Ball Imaging with Solid Angle Consideration. """ io_it = self.get_io_iterator() for (dwi, bval, bvec, maskfile, opam, oshm, opeaks_dir, opeaks_values, opeaks_indices, ogfa) in io_it: logging.info('Loading {0}'.format(dwi)) data, affine = load_nifti(dwi) bvals, bvecs = read_bvals_bvecs(bval, bvec) if b0_threshold < bvals.min(): warn( "b0_threshold (value: {0}) is too low, increase your " "b0_threshold. It should be higher than the first b0 value " "({1}).".format(b0_threshold, bvals.min())) gtab = gradient_table(bvals, bvecs, b0_threshold=b0_threshold, atol=bvecs_tol) mask_vol = load_nifti_data(maskfile).astype(bool) peaks_sphere = default_sphere logging.info('Starting CSA computations {0}'.format(dwi)) csa_model = CsaOdfModel(gtab, sh_order) peaks_csa = peaks_from_model(model=csa_model, data=data, sphere=peaks_sphere, relative_peak_threshold=.5, min_separation_angle=25, mask=mask_vol, return_sh=True, sh_order=odf_to_sh_order, normalize_peaks=True, parallel=parallel, nbr_processes=nbr_processes) peaks_csa.affine = affine save_peaks(opam, peaks_csa) logging.info('Finished CSA {0}'.format(dwi)) if extract_pam_values: peaks_to_niftis(peaks_csa, oshm, opeaks_dir, opeaks_values, opeaks_indices, ogfa, reshape_dirs=True) dname_ = os.path.dirname(opam) if dname_ == '': logging.info('Pam5 file saved in current directory') else: logging.info('Pam5 file saved in {0}'.format(dname_)) return io_it
print("radial_order: ", radial_order) print("zeta: ", zeta) print("lambdaN: ", lambdaN) print("lambdaL: ", lambdaL) model = ShoreModel(gtab, radial_order=radial_order, zeta=zeta, lambdaN=lambdaN, lambdaL=lambdaL) asmfit = model.fit(data) odf = asmfit.odf(sphere) elif model_type == 'CSA-QBALL': print('Fitting CSA-QBALL') print("sh_order: ", sh_order) print("smooth: ", smooth) model = CsaOdfModel(gtab=gtab, sh_order=sh_order, smooth=smooth) sh_coeffs = model.fit(data, mask=mask).shm_coeff elif model_type == 'SFM': print('Fitting SFM') print("fa_thr: ", fa_thr) response, ratio = auto_response(gtab, data, roi_radius=10, fa_thr=fa_thr) model = sfm.SparseFascicleModel(gtab, sphere=sphere, l1_ratio=0.5, alpha=0.001, response=response[0]) odf = model.fit(data, mask=mask).odf(sphere) elif model_type == 'CSD':
def odf_mod_est(self): print("Fitting CSA ODF model...") self.mod = CsaOdfModel(self.gtab, sh_order=6) return self.mod
data = img.get_data() affine = img.get_affine() header = img.get_header() voxel_size = header.get_zooms()[:3] mask, S0_mask = median_otsu(data[:, :, :, 0]) fbval = "original.bval" fbvec = "original.bvec" bvals, bvecs = read_bvals_bvecs(fbval, fbvec) gtab = gradient_table(bvals, bvecs) ten_model = TensorModel(gtab) ten_fit = ten_model.fit(data, mask) fa = fractional_anisotropy(ten_fit.evals) cfa = color_fa(fa, ten_fit.evecs) csamodel = CsaOdfModel(gtab, 6) sphere = get_sphere('symmetric724') pmd = peaks_from_model(model=csamodel, data=data, sphere=sphere, relative_peak_threshold=.5, min_separation_angle=25, mask=mask, return_odf=False) #Deterministic tractography eu = EuDX(a=fa, ind=pmd.peak_indices[..., 0], seeds=2000000, odf_vertices=sphere.vertices, a_low=0.2)
gtab = gradient_table(bvals, bvecs) seed_mask = (labels == 2) white_matter = (labels == 1) | (labels == 2) seeds = utils.seeds_from_mask(seed_mask, affine, density=1) 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) """ We use the GFA of the CSA model to build a stopping criterion. """ from dipy.reconst.shm import CsaOdfModel csa_model = CsaOdfModel(gtab, sh_order=6) gfa = csa_model.fit(data, mask=white_matter).gfa stopping_criterion = ThresholdStoppingCriterion(gfa, .25) """ The Fiber Orientation Distribution (FOD) of the CSD model estimates the distribution of small fiber bundles within each voxel. We can use this distribution for probabilistic fiber tracking. One way to do this is to represent the FOD using a discrete sphere. This discrete FOD can be used by the ``ProbabilisticDirectionGetter`` 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
data = img.get_data() print('data.shape (%d, %d, %d, %d)' % data.shape) """ data.shape ``(81, 106, 76, 160)`` Remove most of the background in the following simple way. """ mask = data[..., 0] > 50 """ We instantiate our CSA model with sperical harmonic order of 4 """ csamodel = CsaOdfModel(gtab, 4) """ `Peaks_from_model` is used to calculate properties of the ODFs (Orientation Distribution Function) and return for example the peaks and their indices, or GFA which is similar to FA but for ODF based models. This function mainly needs a reconstruction model, the data and a sphere as input. The sphere is an object that represents the spherical discrete grid where the ODF values will be evaluated. """ sphere = get_sphere('symmetric724') csapeaks = peaks_from_model(model=csamodel, data=data, sphere=sphere,