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 reconstruct_shore_fodf(bval_path, bvec_path, data_path, data_var, zeta_val=700.0): bval_path = os.path.normpath(bval_path) bvec_path = os.path.normpath(bvec_path) data_path = os.path.normpath(data_path) bvals, bvecs = read_bvals_bvecs(bval_path, bvec_path) gtab = gradient_table(bvals, bvecs) data = loadmat(data_path) data = data[data_var] shore_model = ShoreModel(gtab, radial_order=6, zeta=zeta_val) shore_peaks = peaks_from_model(shore_model, data, default_sphere, relative_peak_threshold=.1, min_separation_angle=45) print('Debug Here') return shore_peaks.shm_coeff
def anisotropic_power_map(data, mask, gtab, power=2, nbr_processes=None, verbose=False): # compute response if verbose: print(' - computing response') response, _ = auto_response(gtab, data, roi_radius=10, fa_thr=0.7) # compute spherical harmonics from spherical deconvoluten if verbose: print(' - preparing spherical deconvolution model') csd_model = ConstrainedSphericalDeconvModel(gtab, response) sphere = get_sphere('symmetric724') if verbose: print(' - computing spherical harmonics from spherical deconvolution') csd_peaks = peaks_from_model(model=csd_model, data=data, mask=mask, sphere=sphere, relative_peak_threshold=.5, min_separation_angle=25, parallel=True, nbr_processes=nbr_processes) # compute anisotropic power map if verbose: print(' - computing anisotropic power map') return anisotropic_power(csd_peaks.shm_coeff, norm_factor=1e-05, power=power, non_negative=True)
def reconst_gqi_fodf_return_sh_coeffs(bval_path,bvec_path,data_path,data_var): bval_path = os.path.normpath(bval_path) bvec_path = os.path.normpath(bvec_path) data_path = os.path.normpath(data_path) bvals, bvecs = read_bvals_bvecs(bval_path, bvec_path) gtab = gradient_table(bvals, bvecs) data = loadmat(data_path) data = data[data_var] gqmodel = GeneralizedQSamplingModel(gtab, sampling_length=1.2) #gqfit = gqmodel.fit(dataslice, mask=mask) sphere = get_sphere('symmetric724') #ODF = gqfit.odf(sphere) #odf = gqmodel.fit(data).odf(sphere) gqpeaks = peaks_from_model(model=gqmodel, data=data, sphere=sphere, relative_peak_threshold=.5, min_separation_angle=25, return_odf=True, normalize_peaks=True) print('Debug here') fodfs_shm = gqpeaks.shm_coeff return fodfs_shm
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 get_csd_peaks(DWI_image_noisy, sch_mat_b0, num_fasc): '''Get peak orientations using constrained spherical deconvolution (CSD) ''' S0mean = np.mean(DW_image_noisy[bvals == 0]) # mean on dictionary is array([0.00215257, 0.00022733, 0.00022463]) # median is array([0.00213064, 0.00017771, 0.00017323]) sing_fasc_response = (np.array([0.0020, 0.00024, 0.00024]), S0mean) csd_mod = ConstrainedSphericalDeconvModel(gtab, sing_fasc_response, sh_order=sh_max_order) # we cheat a bit by using groundtruth information on the angle to set the # minimum separation angle: min_sep_angle = 0.9 * crossangle_min * 180 / np.pi # in degrees ! peaks = peaks_from_model(model=csd_mod, data=DW_image_noisy, sphere=odf_sphere, relative_peak_threshold=0.9 * nu_min / nu_max, min_separation_angle=min_sep_angle, sh_order=sh_max_order, npeaks=num_fasc) # direction of peaks, shape (npeaks, 3). pdirs[0] is main peak, # peak_dirs[1] secondary peak. peak_dirs[1] could be [0, 0, 0] if no peak # was detected. return peaks.peak_dirs
def track(self): SeedBasedTracker.track(self) if self.streamlines is not None: return roi_r = Config.get_config().getint("CSDTracking", "autoResponseRoiRadius", fallback="10") fa_thr = Config.get_config().getfloat("CSDTracking", "autoResponseFaThreshold", fallback="0.7") response, _ = auto_response_ssst(self.data.gtab, self.data.dwi, roi_radii=roi_r, fa_thr=fa_thr) csd_model = ConstrainedSphericalDeconvModel(self.data.gtab, response) relative_peak_thr = Config.get_config().getfloat("CSDTracking", "relativePeakTreshold", fallback="0.5") min_separation_angle = Config.get_config().getfloat("CSDTracking", "minimumSeparationAngle", fallback="25") direction_getter = peaks_from_model(model=csd_model, data=self.data.dwi, sphere=get_sphere('symmetric724'), mask=self.data.binarymask, relative_peak_threshold=relative_peak_thr, min_separation_angle=min_separation_angle, parallel=False) dti_fit = dti.TensorModel(self.data.gtab, fit_method='LS') dti_fit = dti_fit.fit(self.data.dwi, mask=self.data.binarymask) self._track(ThresholdStoppingCriterion(dti_fit.fa, self.options.fa_threshold), direction_getter) Cache.get_cache().set(self.id, self.streamlines)
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 generate_peaks(self): csa_peaks = peaks_from_model( self.csa_model, self.data, default_sphere, relative_peak_threshold=self.relative_peak_threshold, min_separation_angle=self.min_angle, mask=self.white_matter, ) return csa_peaks
def tractography(img, gtab, mask, dwi_dir, do_viz=True): data = img.get_data() # dirty imputation data[np.isnan(data)] = 0 # Diffusion model csd_model = ConstrainedSphericalDeconvModel(gtab, response=None) sphere = get_sphere('symmetric724') csd_peaks = peaks_from_model(model=csd_model, data=data, sphere=sphere, mask=mask, relative_peak_threshold=.5, min_separation_angle=25, parallel=False) # FA values to stop the tractography tensor_model = TensorModel(gtab, fit_method='WLS') tensor_fit = tensor_model.fit(data, mask) fa = fractional_anisotropy(tensor_fit.evals) stopping_values = np.zeros(csd_peaks.peak_values.shape) stopping_values[:] = fa[..., None] # tractography streamline_generator = EuDX(stopping_values, csd_peaks.peak_indices, seeds=10**6, odf_vertices=sphere.vertices, a_low=0.1) streamlines = [streamline for streamline in streamline_generator] streamlines = filter_according_to_length(streamlines) np.savez(os.path.join(dwi_dir, 'streamlines.npz'), streamlines) # write the result as images hdr = nib.trackvis.empty_header() hdr['voxel_size'] = img.header.get_zooms()[:3] hdr['voxel_order'] = 'LAS' hdr['dim'] = fa.shape[:3] csd_streamlines_trk = ((sl, None, None) for sl in streamlines) csd_sl_fname = os.path.join(dwi_dir, 'csd_streamline.trk') nib.trackvis.write(csd_sl_fname, csd_streamlines_trk, hdr, points_space='voxel') fa_image = os.path.join(dwi_dir, 'fa_map.nii.gz') nib.save(nib.Nifti1Image(fa, img.affine), fa_image) if 1: visualization(os.path.join(dwi_dir, 'streamlines.npz')) return streamlines
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 _init_shm_coefficient(self, sh_basis_type=None): print("Initialising spherical harmonics") self.dti_model = dti.TensorModel(self.dataset.gtab, fit_method='LS') peaks = peaks_from_model(model=self.dti_model, data=self.dataset.dwi, sphere=self.sphere, relative_peak_threshold=.2, min_separation_angle=25, mask=self.dataset.binary_mask, npeaks=2) self.sh_coefficient = peaks.shm_coeff sh_order = order_from_ncoef(self.sh_coefficient.shape[-1]) try: basis = sph_harm_lookup[sh_basis_type] except KeyError: raise ValueError("%s is not a known basis type." % sh_basis_type) self._B, m, n = basis(sh_order, self.sphere.theta, self.sphere.phi)
model = GeneralizedQSamplingModel(gtab, sampling_length=1.2) if rec_model == 'SFM': # Ariel please add here your best SFM calls and parameters pass if rec_model == 'MAPL': # Brent look at Aman's PR and call here pass if rec_model == 'CSD': # Elef add CSD version and add MTMSCSD when is ready. pass pam = peaks_from_model(model, data, sphere, relative_peak_threshold=.8, min_separation_angle=45, mask=mask, parallel=parallel) ten_model = TensorModel(gtab) fa = ten_model.fit(data, mask).fa save_nifti(ffa, fa, affine) save_peaks(fpam5, pam, affine) show_odfs_and_fa(fa, pam, mask, None, sphere, ftmp='odf.mmap', basis_type=None)
logic = np.logical_or(logic1, logic2) logic_ = np.logical_or(labels_==150, labels_==316) wm = np.where(logic, True, np.where(logic_, True, False)) mask = wm radius = 15 response, ratio, nvl = auto_response(gtab, data, roi_radius=radius, return_number_of_voxels=True) print 'We use the roi_radius={},\nand the response is {},\nthe ratio is {},\nusing {} of voxels'.format(radius, response, ratio, nvl) print 'fitting CSD model' st2 = time.time() sphere = get_sphere('symmetric724') csd_model = ConstrainedSphericalDeconvModel(gtab, response, sh_order=8) csd_peaks = peaks_from_model(csd_model, data, sphere = sphere, relative_peak_threshold=0.1, min_separation_angle=25,mask=mask, return_sh=True, parallel=True, normalize_peaks=True) et2 = time.time() - st2 print 'fitting CSD model finished, running time is {}'.format(et2) print 'seeding begins, using np.random.seed(123)' st3 = time.time() np.random.seed(123) seeds = utils.random_seeds_from_mask(mask, 4) for i in range(len(seeds)): if seeds[i][0]>199.: seeds[i][0]=398-seeds[i][0] if seeds[i][1]>399.: seeds[i][1]=798-seeds[i][1] if seeds[i][2]>199.: seeds[i][2]=398-seeds[i][2]
def eudx_advanced(self, dti_file, mask_file, gtab, seed_num=100000, stop_val=0.1): """ Tracking with more complex tensors - experimental Initializes the graph with nodes corresponding to the number of ROIs **Positional Arguments:** dti_file: - File (registered) to use for tensor/fiber tracking mask_file: - Brain mask to keep tensors inside the brain gtab: - dipy formatted bval/bvec Structure **Optional Arguments:** seed_num: - Number of seeds to use for fiber tracking stop_val: - Value to cutoff fiber track """ img = nb.load(dti_file) data = img.get_data() img = nb.load(mask_file) mask = img.get_data() mask = mask > 0 # to ensure binary mask """ For the constrained spherical deconvolution we need to estimate the response function (see :ref:`example_reconst_csd`) and create a model. """ response, ratio = auto_response(gtab, data, roi_radius=10, fa_thr=0.7) csd_model = ConstrainedSphericalDeconvModel(gtab, response) """ Next, we use ``peaks_from_model`` to fit the data and calculated the fiber directions in all voxels. """ sphere = get_sphere('symmetric724') csd_peaks = peaks_from_model(model=csd_model, data=data, sphere=sphere, mask=mask, relative_peak_threshold=.5, min_separation_angle=25, parallel=True) """ For the tracking part, we will use ``csd_model`` fiber directions but stop tracking where fractional anisotropy (FA) is low (< 0.1). To derive the FA, used as a stopping criterion, we need to fit a tensor model first. Here, we use weighted least squares (WLS). """ print 'tensors...' tensor_model = TensorModel(gtab, fit_method='WLS') tensor_fit = tensor_model.fit(data, mask) FA = fractional_anisotropy(tensor_fit.evals) """ In order for the stopping values to be used with our tracking algorithm we need to have the same dimensions as the ``csd_peaks.peak_values``. For this reason, we can assign the same FA value to every peak direction in the same voxel in the following way. """ stopping_values = np.zeros(csd_peaks.peak_values.shape) stopping_values[:] = FA[..., None] streamline_generator = EuDX(stopping_values, csd_peaks.peak_indices, seeds=seed_num, odf_vertices=sphere.vertices, a_low=stop_val) streamlines = [streamline for streamline in streamline_generator] return streamlines
# Compute odfs in Brain Mask t2 = time() radius = 20 response, ratio, nvl = auto_response(gtab, data, roi_radius=radius, return_number_of_voxels=True) print( 'We use the roi_radius={},\nand the response is {},\nthe ratio is {},\nusing {} of voxels' .format(radius, response, ratio, nvl)) csd_model = ConstrainedSphericalDeconvModel(gtab, response, sh_order=6) csd_peaks = peaks_from_model(csd_model, data, sphere=peaks.default_sphere, relative_peak_threshold=0.5, min_separation_angle=60, mask=mask, return_odf=True, return_sh=False, parallel=True, nbr_processes=multiprocessing.cpu_count()) duration2 = time() - t2 print(runno + ' CSD duration %.3f' % (duration2, )) #mask and classifier seeds = utils.seeds_from_mask(mask, density=1, affine=np.eye(4)) classifier = BinaryTissueClassifier(bm) #local tracking streamlines_generator = LocalTracking(csd_peaks, classifier, seeds, affine=np.eye(4),
""" ODF = gqfit.odf(sphere) print('ODF.shape (%d, %d, %d)' % ODF.shape) """ ODF.shape ``(96, 96, 724)`` Using ``peaks_from_model`` we can find the main peaks of the ODFs and other properties. """ gqpeaks = peaks_from_model(model=gqmodel, data=dataslice, sphere=sphere, relative_peak_threshold=.5, min_separation_angle=25, mask=mask, return_odf=False, normalize_peaks=True) gqpeak_values = gqpeaks.peak_values """ ``gqpeak_indices`` show which sphere points have the maximum values. """ gqpeak_indices = gqpeaks.peak_indices """ It is also possible to calculate GFA. """ GFA = gqpeaks.gfa
parallel. If ``num_processes`` is None it will figure out automatically the number of CPUs available in your system. Alternatively, you can set ``num_processes`` manually. Here, we show an example where we compare the duration of execution with or without parallelism. """ import time from dipy.direction import peaks_from_model start_time = time.time() csd_peaks_parallel = peaks_from_model(model=csd_model, data=data, sphere=default_sphere, relative_peak_threshold=.5, min_separation_angle=25, mask=mask, return_sh=True, return_odf=False, normalize_peaks=True, npeaks=5, parallel=True, num_processes=None) time_parallel = time.time() - start_time print("peaks_from_model using " + str(multiprocessing.cpu_count()) + " process ran in :" + str(time_parallel) + " seconds") """ ``peaks_from_model`` using 8 processes ran in 114.425682068 seconds """ start_time = time.time() csd_peaks = peaks_from_model(model=csd_model,
""" The data is first fitted to Constant Solid Angle (CDA) ODF Model. CSA is a good choice to estimate general fractional anisotropy (GFA), which the tissue classifier can use to restrict fiber tracking to those areas where the ODF shows significant restricted diffusion, thus creating a region-of-interest in which the computations are done. """ # Perform CSA 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=6) csa_peaks = peaks_from_model(csa_model, data, default_sphere, relative_peak_threshold=.6, min_separation_angle=45, mask=selectionmask) # Tissue classifier from dipy.tracking.local import ThresholdTissueClassifier classifier = ThresholdTissueClassifier(csa_peaks.gfa, 0.25) """ In order to perform probabilistic fiber tracking we first fit the data to the Constrained Spherical Deconvolution (CSD) model in DIPY. 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), used in the fiber tracking. """
response, ratio = auto_response(gtab, data, roi_radius=10, fa_thr=0.7) csd_model = ConstrainedSphericalDeconvModel(gtab, response) """ Next, we use ``peaks_from_model`` to fit the data and calculated the fiber directions in all voxels. """ sphere = get_sphere('symmetric724') csd_peaks = peaks_from_model(model=csd_model, data=data, sphere=sphere, mask=mask, relative_peak_threshold=.5, min_separation_angle=25, parallel=True) """ For the tracking part, we will use the fiber directions from the ``csd_model`` but stop tracking in areas where fractional anisotropy is low (< 0.1). To derive the FA, used here as a stopping criterion, we would need to fit a tensor model first. Here, we fit the tensor using weighted least squares (WLS). """ tensor_model = TensorModel(gtab, fit_method='WLS') tensor_fit = tensor_model.fit(data, mask) fa = tensor_fit.fa
ODF = gqfit.odf(sphere) print('ODF.shape (%d, %d, %d)' % ODF.shape) """ ODF.shape ``(96, 96, 724)`` Using peaks_from_model we can find the main peaks of the ODFs and other properties. """ gqpeaks = peaks_from_model(model=gqmodel, data=dataslice, sphere=sphere, relative_peak_threshold=.5, min_separation_angle=25, mask=mask, return_odf=False, normalize_peaks=True) gqpeak_values = gqpeaks.peak_values """ gqpeak_indices show which sphere points have the maximum values. """ gqpeak_indices = gqpeaks.peak_indices """ It is also possible to calculate GFA. """
fa = tensor_fit.fa duration1 = time() - t1 #wenlin make this change-adress name to each animal # print('DTI duration %.3f' % (duration1,)) print(runno + ' DTI duration %.3f' % (duration1, )) # Compute odfs in Brain Mask t2 = time() csa_model = CsaOdfModel(gtab, 6) csa_peaks = peaks_from_model( model=csa_model, data=data, sphere=peaks.default_sphere, # issue with complete sphere mask=mask, relative_peak_threshold=.5, min_separation_angle=25, parallel=True, nbr_processes=4) duration2 = time() - t2 print(duration2)\ #wenlin make this change-adress name to each animal # print('CSA duration %.3f' % (duration2,)) print(runno + ' CSA duration %.3f' % (duration2, )) t3 = time() # from dipy.tracking.local import ThresholdTissueClassifier
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 prob_dg = ProbabilisticDirectionGetter.from_shcoeff(csd_fit.shm_coeff, max_angle=30., sphere=default_sphere) streamlines = LocalTracking(prob_dg, classifier, seeds, affine, step_size=.5) save_trk("probabilistic_shm_coeff.trk", streamlines, affine, labels.shape) """ Not all model fits have the ``shm_coeff`` attribute because not all models use this basis to represent the data internally. However we can fit the ODF of any model to the spherical harmonic basis using the ``peaks_from_model`` function. """ from dipy.direction import peaks_from_model peaks = peaks_from_model(csd_model, data, default_sphere, .5, 25, mask=white_matter, return_sh=True, parallel=True) fod_coeff = peaks.shm_coeff prob_dg = ProbabilisticDirectionGetter.from_shcoeff(fod_coeff, max_angle=30., sphere=default_sphere) streamlines = LocalTracking(prob_dg, classifier, seeds, affine, step_size=.5) save_trk("probabilistic_peaks_from_model.trk", streamlines, affine, labels.shape)
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() affine = dmri_image.affine #aparc_im = nib.load(config['freesurfer']) aparc_im = nib.load('volume.nii.gz') aparc = aparc_im.get_data() end = time.time() print('Loaded Files: ' + str((end - start))) print(dmri.shape) print(aparc.shape) # Create the white matter and callosal masks 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 #np.save('wm_mask',wm_mask) #p = os.getcwd()+'wm.json' #json.dump(wm_mask, codecs.open(p, 'w', encoding='utf-8'), separators=(',', ':'), sort_keys=True, indent=4) #with open('wm_mask.txt', 'wb') as wm: #np.savetxt('wm.txt', wm_mask, fmt='%5s') #print(wm_mask) # Create the gradient table from the bvals and bvecs 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))) ##The probabilistic model## """ # Use the Constant Solid Angle (CSA) to find the Orientation Dist. Function # Helps orient the wm tracts start = time.time() csa_model = CsaOdfModel(gtab, sh_order=6) csa_peaks = peaks_from_model(csa_model, dmri, default_sphere, relative_peak_threshold=.8, min_separation_angle=45, mask=wm_mask) print('Creating CSA Model: ' + str(time.time() - start)) """ # Use the SHORE model to find Orientation Dist. Function start = time.time() shore_model = ShoreModel(gtab) shore_peaks = peaks_from_model(shore_model, dmri, default_sphere, relative_peak_threshold=.8, min_separation_angle=45, mask=wm_mask) print('Creating Shore Model: ' + str(time.time() - start)) # Begins the seed in the wm tracts seeds = utils.seeds_from_mask(wm_mask, density=[1, 1, 1], affine=affine) print('Created White Matter seeds: ' + str(time.time() - start)) # Create a CSD model to measure Fiber Orientation Dist print('Begin the probabilistic model') response, ratio = auto_response(gtab, dmri, roi_radius=10, fa_thr=0.7) csd_model = ConstrainedSphericalDeconvModel(gtab, response, sh_order=6) csd_fit = csd_model.fit(data=dmri, mask=wm_mask) print('Created the CSD model: ' + str(time.time() - start)) # Set the Direction Getter to randomly choose directions prob_dg = ProbabilisticDirectionGetter.from_shcoeff(csd_fit.shm_coeff, max_angle=30., sphere=default_sphere) print('Created the Direction Getter: ' + str(time.time() - start)) # Restrict the white matter tracking classifier = ThresholdTissueClassifier(shore_peaks.gfa, .25) print('Created the Tissue Classifier: ' + str(time.time() - start)) # Create the probabilistic model streamlines = LocalTracking(prob_dg, tissue_classifier=classifier, seeds=seeds, step_size=.5, max_cross=1, affine=affine) print('Created the probabilistic model: ' + str(time.time() - start)) # Compute streamlines and store as a list. streamlines = list(streamlines) print('Computed streamlines: ' + str(time.time() - start)) #from dipy.tracking.streamline import transform_streamlines #streamlines = transform_streamlines(streamlines, np.linalg.inv(affine)) # Create a tractogram from the streamlines and save it tractogram = Tractogram(streamlines, affine_to_rasmm=affine) save(tractogram, 'track.tck') end = time.time() print("Created the tck file: " + str((end - start)))
1. The first thing we need to begin fiber tracking is a way of getting directions from this diffusion data set. In order to do that, we can fit the data to a Constant Solid Angle ODF Model. This model will estimate the Orientation Distribution Function (ODF) at each voxel. The ODF is the distribution of water diffusion as a function of direction. The peaks of an ODF are good estimates for the orientation of tract segments at a point in the image. """ 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=6) csa_peaks = peaks_from_model(csa_model, data, default_sphere, relative_peak_threshold=.8, min_separation_angle=45, mask=white_matter) """ 2. Next we need some way of restricting the fiber tracking to areas with good directionality information. We've already created the white matter mask, but we can go a step further and restrict fiber tracking to those areas where the ODF shows significant restricted diffusion by thresholding on the general fractional anisotropy (GFA). """ from dipy.tracking.local import ThresholdTissueClassifier classifier = ThresholdTissueClassifier(csa_peaks.gfa, .25) """
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
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 dipy.viz.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.get_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.ren() r2 = window.ren() 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)
""" `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, relative_peak_threshold=.5, min_separation_angle=25, mask=mask, return_odf=False, normalize_peaks=True) GFA = csapeaks.gfa print('GFA.shape (%d, %d, %d)' % GFA.shape) """ GFA.shape ``(81, 106, 76)`` Apart from GFA, csapeaks also has the attributes peak_values, peak_indices and ODF. peak_values shows the maxima values of the ODF and peak_indices gives us their position on the discrete sphere that was used to do the reconstruction of the ODF. In order to obtain the full ODF, return_odf should be True. Before
parallel. If ``nbr_processes`` is None it will figure out automatically the number of CPUs available in your system. Alternatively, you can set ``nbr_processes`` manually. Here, we show an example where we compare the duration of execution with or without parallelism. """ import time from dipy.direction import peaks_from_model start_time = time.time() csd_peaks_parallel = peaks_from_model(model=csd_model, data=data, sphere=sphere, relative_peak_threshold=.5, min_separation_angle=25, mask=mask, return_sh=True, return_odf=False, normalize_peaks=True, npeaks=5, parallel=True, nbr_processes=None) time_parallel = time.time() - start_time print("peaks_from_model using " + str(multiprocessing.cpu_count()) + " process ran in :" + str(time_parallel) + " seconds") """ ``peaks_from_model`` using 8 processes ran in 114.425682068 seconds """ start_time = time.time()
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)
def run_to_generate_tractography(path_input, path_output, file_inMask="", fbval="", fbvec=""): print(' - Starting reconstruction of Tractography...') folder = os.path.dirname(path_input) if fbval == "" or fbvec == "": folder_sujeto = path_output for l in os.listdir(folder_sujeto): if "TENSOR" in l and "bval" in l: fbval = os.path.join(folder_sujeto, l) if "TENSOR" in l and "bvec" in l: fbvec = os.path.join(folder_sujeto, l) if file_inMask == "": for i in os.listdir(folder): if "masked_mask" in i: file_inMask = os.path.join(folder, i) if not os.path.exists( os.path.join(path_output, '_tractography_CsaOdf' + '.trk')): dwi_img = nib.load(path_input) dwi_data = dwi_img.get_data() dwi_affine = dwi_img.affine dwi_mask_data = nib.load(file_inMask).get_data() g_tab = gradient_table(fbval, fbvec) 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...') return path_input
window.show(scene) """ .. figure:: csd_odfs.png :align: center CSD ODFs. In DIPY we also provide tools for finding the peak directions (maxima) of the ODFs. For this purpose we recommend using ``peaks_from_model``. """ from dipy.direction import peaks_from_model csd_peaks = peaks_from_model(model=csd_model, data=data_small, sphere=default_sphere, relative_peak_threshold=.5, min_separation_angle=25, parallel=True) scene.clear() fodf_peaks = actor.peak_slicer(csd_peaks.peak_dirs, csd_peaks.peak_values) scene.add(fodf_peaks) print('Saving illustration as csd_peaks.png') window.record(scene, out_path='csd_peaks.png', size=(600, 600)) if interactive: window.show(scene) """ .. figure:: csd_peaks.png :align: center
def QCSA_tractmake(data, affine, vox_size, gtab, mask, masktype, header, step_size, peak_processes, outpathtrk, subject='NA', ratio=1, overwrite=False, get_params=False, doprune=False, figspath=None, verbose=None): # Compute odfs in Brain Mask t2 = time() if os.path.isfile(outpathtrk) and not overwrite: txt = "Subject already saved at "+outpathtrk print(txt) streamlines_generator = None params = None return outpathtrk, streamlines_generator, params csa_model = CsaOdfModel(gtab, 6) if peak_processes == 1: parallel = False else: parallel = True if verbose: send_mail("Starting calculation of Constant solid angle model for subject " + subject,subject="CSA model start") wholemask = np.where(mask == 0, False, True) print(f"There are {peak_processes} and {parallel} here") csa_peaks = peaks_from_model(model=csa_model, data=data, sphere=peaks.default_sphere, # issue with complete sphere mask=wholemask, relative_peak_threshold=.5, min_separation_angle=25, parallel=parallel, nbr_processes=peak_processes) duration = time() - t2 if verbose: print(subject + ' CSA duration %.3f' % (duration,)) t3 = time() if verbose: send_mail('Computing classifier for local tracking for subject ' + subject + ',it has been ' + str(round(duration)) + 'seconds since the start of tractmaker',subject="Seed computation" ) print('Computing classifier for local tracking for subject ' + subject) if masktype == "FA": #tensor_model = dti.TensorModel(gtab) #tenfit = tensor_model.fit(data, mask=labels > 0) #FA = fractional_anisotropy(tenfit.evals) FA_threshold = 0.05 classifier = ThresholdStoppingCriterion(mask, FA_threshold) if figspath is not None: fig = plt.figure() mask_fa = mask.copy() mask_fa[mask_fa < FA_threshold] = 0 plt.xticks([]) plt.yticks([]) plt.imshow(mask_fa[:, :, data.shape[2] // 2].T, cmap='gray', origin='lower', interpolation='nearest') fig.tight_layout() fig.savefig(figspath + 'threshold_fa.png') else: classifier = BinaryStoppingCriterion(wholemask) # generates about 2 seeds per voxel # seeds = utils.random_seeds_from_mask(fa > .2, seeds_count=2, # affine=np.eye(4)) # generates about 2 million streamlines # seeds = utils.seeds_from_mask(fa > .2, density=1, # affine=np.eye(4)) if verbose: print('Computing seeds') seeds = utils.seeds_from_mask(wholemask, density=1, affine=np.eye(4)) #streamlines_generator = local_tracking.local_tracker(csa_peaks,classifier,seeds,affine=np.eye(4),step_size=step_size) if verbose: print('Computing the local tracking') duration = time() - t2 send_mail('Start of the local tracking ' + ',it has been ' + str(round(duration)) + 'seconds since the start of tractmaker', subject="Seed computation") #stepsize = 2 #(by default) stringstep = str(step_size) stringstep = stringstep.replace(".", "_") if verbose: print("stringstep is "+stringstep) streamlines_generator = LocalTracking(csa_peaks, classifier, seeds, affine=np.eye(4), step_size=step_size) if verbose: duration = time() - t2 txt = 'About to save streamlines at ' + outpathtrk + ',it has been ' + str(round(duration)) + \ 'seconds since the start of tractmaker', send_mail(txt,subject="Tract saving" ) cutoff = 2 if doprune: streamlines_generator = prune_streamlines(list(streamlines_generator), data[:, :, :, 0], cutoff=cutoff, verbose=verbose) myheader = create_tractogram_header(outpathtrk, *header) sg = lambda: (s for i, s in enumerate(streamlines_generator) if i % ratio == 0) save_trk_heavy_duty(outpathtrk, streamlines=sg, affine=affine, header=myheader, shape=mask.shape, vox_size=vox_size) else: sg = lambda: (s for i, s in enumerate(streamlines_generator) if i % ratio == 0) myheader = create_tractogram_header(outpathtrk, *header) save_trk_heavy_duty(outpathtrk, streamlines=sg, affine=affine, header=myheader, shape=mask.shape, vox_size=vox_size) if verbose: duration = time() - t2 txt = "Tract files were saved at "+outpathtrk + ',it has been ' + str(round(duration)) + \ 'seconds since the start of tractmaker' print(txt) send_mail(txt,subject="Tract saving" ) # save everything - will generate a 20+ GBytes of data - hard to manipulate # possibly add parameter in csv file or other to decide whether to save large tractogram file # outpathfile=outpath+subject+"bmCSA_detr"+stringstep+".trk" # myheader=create_tractogram_header(outpathfile,*get_reference_info(fdwi)) duration3 = time() - t2 if verbose: print(duration3) print(subject + ' Tracking duration %.3f' % (duration3,)) send_mail("Finished file save at "+outpathtrk+" with tracking duration of " + str(duration3) + "seconds", subject="file save update" ) if get_params: numtracts, minlength, maxlength, meanlength, stdlength = get_trk_params(streamlines_generator, verbose) params = [numtracts, minlength, maxlength, meanlength, stdlength] if verbose: print("For subject " + str(subject) + " the number of tracts is " + str(numtracts) + ", the minimum length is " + str(minlength) + ", the maximum length is " + str(maxlength) + ", the mean length is " + str(meanlength) + ", the std is " + str(stdlength)) else: params = None return outpathtrk, streamlines_generator, params
""" .. figure:: csd_odfs.png :align: center **CSD ODFs**. In Dipy we also provide tools for finding the peak directions (maxima) of the ODFs. For this purpose we recommend using ``peaks_from_model``. """ from dipy.direction import peaks_from_model csd_peaks = peaks_from_model(model=csd_model, data=data_small, sphere=sphere, relative_peak_threshold=.5, min_separation_angle=25, parallel=True) fvtk.clear(ren) fodf_peaks = fvtk.peaks(csd_peaks.peak_dirs, csd_peaks.peak_values, scale=1.3) fvtk.add(ren, fodf_peaks) print('Saving illustration as csd_peaks.png') fvtk.record(ren, out_path='csd_peaks.png', size=(600, 600)) """ .. figure:: csd_peaks.png :align: center **CSD Peaks**.
def particle_tracking(self): self.sphere = get_sphere("repulsion724") if self.mod_type == "det": maxcrossing = 1 print("Obtaining peaks from model...") self.mod_peaks = peaks_from_model( self.mod, self.data, self.sphere, relative_peak_threshold=0.5, min_separation_angle=25, mask=self.wm_in_dwi_data, npeaks=5, normalize_peaks=True, ) qa_tensor.create_qa_figure(self.mod_peaks.peak_dirs, self.mod_peaks.peak_values, self.qa_tensor_out, self.mod_func) self.streamline_generator = ParticleFilteringTracking( self.mod_peaks, self.tiss_classifier, self.seeds, self.stream_affine, max_cross=maxcrossing, step_size=0.5, maxlen=1000, pft_back_tracking_dist=2, pft_front_tracking_dist=1, particle_count=15, return_all=True, ) elif self.mod_type == "prob": maxcrossing = 2 print("Preparing probabilistic tracking...") print("Fitting model to data...") self.mod_fit = self.mod.fit(self.data, self.wm_in_dwi_data) print("Building direction-getter...") self.mod_peaks = peaks_from_model( self.mod, self.data, self.sphere, relative_peak_threshold=0.5, min_separation_angle=25, mask=self.wm_in_dwi_data, npeaks=5, normalize_peaks=True, ) qa_tensor.create_qa_figure(self.mod_peaks.peak_dirs, self.mod_peaks.peak_values, self.qa_tensor_out, self.mod_func) try: print( "Proceeding using spherical harmonic coefficient from model estimation..." ) self.pdg = ProbabilisticDirectionGetter.from_shcoeff( self.mod_fit.shm_coeff, max_angle=60.0, sphere=self.sphere) except: print("Proceeding using FOD PMF from model estimation...") self.fod = self.mod_fit.odf(self.sphere) self.pmf = self.fod.clip(min=0) self.pdg = ProbabilisticDirectionGetter.from_pmf( self.pmf, max_angle=60.0, sphere=self.sphere) self.streamline_generator = ParticleFilteringTracking( self.pdg, self.tiss_classifier, self.seeds, self.stream_affine, max_cross=maxcrossing, step_size=0.5, maxlen=1000, pft_back_tracking_dist=2, pft_front_tracking_dist=1, particle_count=15, return_all=True, ) print("Reconstructing tractogram streamlines...") self.streamlines = Streamlines(self.streamline_generator) return self.streamlines
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, seeds, affine, step_size=2)
""" 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. """ csapeaks = peaks_from_model(model=csamodel, data=maskdata, sphere=default_sphere, relative_peak_threshold=.5, min_separation_angle=25, mask=mask, return_odf=False, normalize_peaks=True) GFA = csapeaks.gfa print('GFA.shape (%d, %d, %d)' % GFA.shape) """ GFA.shape ``(81, 106, 76)`` Apart from GFA, csapeaks also has the attributes peak_values, peak_indices and ODF. peak_values shows the maxima values of the ODF and peak_indices gives us their position on the discrete sphere that was used to do the reconstruction of the ODF. In order to obtain the full ODF, return_odf should be True. Before enabling this option, make sure that you have enough memory.
:align: center **Corpus Callosum using probabilistic direction getter from SH** """ """ Not all model fits have the ``shm_coeff`` attribute because not all models use this basis to represent the data internally. However we can fit the ODF of any model to the spherical harmonic basis using the ``peaks_from_model`` function. """ from dipy.direction import peaks_from_model peaks = peaks_from_model(csd_model, data, default_sphere, .5, 25, mask=white_matter, return_sh=True, parallel=True) fod_coeff = peaks.shm_coeff prob_dg = ProbabilisticDirectionGetter.from_shcoeff(fod_coeff, max_angle=30., sphere=default_sphere) streamline_generator = LocalTracking(prob_dg, stopping_criterion, seeds, affine, step_size=.5) streamlines = Streamlines(streamline_generator) sft = StatefulTractogram(streamlines, hardi_img, Space.RASMM)
def compute_tensors(self, dti_vol, atlas_file, gtab): # WGR:TODO figure out how to organize tensor options and formats # WGR:TODO figure out how to deal with files on disk vs. in workspace """ Takes registered DTI image and produces tensors **Positional Arguments:** dti_vol: - Registered DTI volume, from workspace. atlas_file: - File containing an atlas (or brain mask). gtab: - Structure containing dipy formatted bval/bvec information """ labeldata = nib.load(atlas_file) label = labeldata.get_data() """ Create a brain mask. Here we just threshold labels. """ mask = (label > 0) gtab.info print data.shape """ For the constrained spherical deconvolution we need to estimate the response function (see :ref:`example_reconst_csd`) and create a model. """ response, ratio = auto_response(gtab, dti_vol, roi_radius=10, fa_thr=0.7) csd_model = ConstrainedSphericalDeconvModel(gtab, response) """ Next, we use ``peaks_from_model`` to fit the data and calculated the fiber directions in all voxels. """ sphere = get_sphere('symmetric724') csd_peaks = peaks_from_model(model=csd_model, data=data, sphere=sphere, mask=mask, relative_peak_threshold=.5, min_separation_angle=25, parallel=True) """ For the tracking part, we will use ``csd_model`` fiber directions but stop tracking where fractional anisotropy (FA) is low (< 0.1). To derive the FA, used as a stopping criterion, we need to fit a tensor model first. Here, we use weighted least squares (WLS). """ print 'tensors...' tensor_model = TensorModel(gtab, fit_method='WLS') tensor_fit = tensor_model.fit(data, mask) FA = fractional_anisotropy(tensor_fit.evals) """ In order for the stopping values to be used with our tracking algorithm we need to have the same dimensions as the ``csd_peaks.peak_values``. For this reason, we can assign the same FA value to every peak direction in the same voxel in the following way. """ stopping_values = np.zeros(csd_peaks.peak_values.shape) stopping_values[:] = FA[..., None] print datetime.now() - startTime pass