def csd_mod_est(self): print("Fitting CSD model...") try: print("Attempting to use spherical harmonic basis first...") self.mod = ConstrainedSphericalDeconvModel(self.gtab, None, sh_order=6) except: print("Falling back to estimating recursive response...") self.response = recursive_response( self.gtab, self.data, mask=self.wm_in_dwi_data, sh_order=6, peak_thr=0.01, init_fa=0.08, init_trace=0.0021, iter=8, convergence=0.001, parallel=False, ) print("CSD Reponse: " + str(self.response)) self.mod = ConstrainedSphericalDeconvModel(self.gtab, self.response, sh_order=6) return self.mod
def csd_mod_est(gtab, data, B0_mask, sh_order=8): ''' Estimate a Constrained Spherical Deconvolution (CSD) 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 ------- csd_mod : ndarray Coefficients of the csd reconstruction. model : obj Fitted csd model. References ---------- .. [1] Tournier, J.D., et al. NeuroImage 2007. Robust determination of the fibre orientation distribution in diffusion MRI: Non-negativity constrained super-resolved spherical deconvolution .. [2] Descoteaux, M., et al. IEEE TMI 2009. Deterministic and Probabilistic Tractography Based on Complex Fibre Orientation Distributions .. [3] Côté, M-A., et al. Medical Image Analysis 2013. Tractometer: Towards validation of tractography pipelines .. [4] Tournier, J.D, et al. Imaging Systems and Technology 2012. MRtrix: Diffusion Tractography in Crossing Fiber Regions ''' from dipy.reconst.csdeconv import ConstrainedSphericalDeconvModel, recursive_response print('Fitting CSD model...') B0_mask_data = np.asarray(nib.load(B0_mask).dataobj).astype('bool') print('Reconstructing...') response = recursive_response(gtab, data, mask=B0_mask_data, sh_order=sh_order, peak_thr=0.01, init_fa=0.08, init_trace=0.0021, iter=8, convergence=0.001, parallel=False) print('CSD Reponse: ' + str(response)) model = ConstrainedSphericalDeconvModel(gtab, response, sh_order=sh_order) csd_mod = model.fit(data, B0_mask_data).shm_coeff del response, B0_mask_data return csd_mod, model
def csd_mod_est(gtab, data, wm_in_dwi): from dipy.reconst.csdeconv import ConstrainedSphericalDeconvModel, recursive_response print('Fitting CSD model...') wm_in_dwi_mask = nib.load(wm_in_dwi).get_fdata().astype('bool') try: print('Attempting to use spherical harmonic...') model = ConstrainedSphericalDeconvModel(gtab, None, sh_order=6) except: print('Falling back to recursive response...') response = recursive_response(gtab, data, mask=wm_in_dwi_mask, sh_order=8, peak_thr=0.01, init_fa=0.08, init_trace=0.0021, iter=8, convergence=0.001, parallel=False) print('CSD Reponse: ' + str(response)) model = ConstrainedSphericalDeconvModel(gtab, response) mod = model.fit(data, wm_in_dwi_mask) return mod.shm_coeff
def csd_mod_est(dwi, gtab, wm_mask): print("Fitting CSD model...") print("Estimating recursive response...") response = recursive_response( gtab, dwi, mask=wm_mask, sh_order=6, peak_thr=0.01, init_fa=0.08, init_trace=0.0021, iter=8, convergence=0.001, parallel=False, ) mod = ConstrainedSphericalDeconvModel(gtab, response, sh_order=6) return mod
def csd_response(gtab, data): """ Estimate response function for given HARDI data. Unfortunately, does not work for 2d (synthetic) data (why?). """ tenmodel = dti.TensorModel(gtab) tenfit = tenmodel.fit(data, mask=data[..., 0] > 200) FA = fractional_anisotropy(tenfit.evals) MD = dti.mean_diffusivity(tenfit.evals) wm_mask = (np.logical_or(FA >= 0.4, (np.logical_and(FA >= 0.15, MD >= 0.0011)))) response = recursive_response(gtab, data, mask=wm_mask, sh_order=8, peak_thr=0.01, init_fa=0.08, init_trace=0.0021, iter=8, convergence=0.001, parallel=True) return response
def csd_mod_est(gtab, data, wm_in_dwi): ''' Estimate a Constrained Spherical Deconvolution (CSD) 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 ------- csd_mod : obj Spherical harmonics coefficients of the CSD-estimated reconstruction model. ''' from dipy.reconst.csdeconv import ConstrainedSphericalDeconvModel, recursive_response print('Fitting CSD model...') wm_in_dwi_mask = nib.load(wm_in_dwi).get_fdata().astype('bool') try: print('Reconstructing...') model = ConstrainedSphericalDeconvModel(gtab, None, sh_order=6) except: print('Falling back to recursive response...') response = recursive_response(gtab, data, mask=wm_in_dwi_mask, sh_order=8, peak_thr=0.01, init_fa=0.08, init_trace=0.0021, iter=8, convergence=0.001, parallel=False) print('CSD Reponse: ' + str(response)) model = ConstrainedSphericalDeconvModel(gtab, response) csd_mod = model.fit(data, wm_in_dwi_mask).shm_coeff return csd_mod
def csd_mod_est(gtab, data, B0_mask, sh_order=8): ''' Estimate a Constrained Spherical Deconvolution (CSD) 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 ------- csd_mod : obj Spherical harmonics coefficients of the CSD-estimated reconstruction model. ''' from dipy.reconst.csdeconv import ConstrainedSphericalDeconvModel, recursive_response print('Fitting CSD model...') B0_mask_data = np.asarray(nib.load(B0_mask).dataobj).astype('bool') print('Reconstructing...') response = recursive_response(gtab, data, mask=B0_mask_data, sh_order=sh_order, peak_thr=0.01, init_fa=0.08, init_trace=0.0021, iter=8, convergence=0.001, parallel=False) print('CSD Reponse: ' + str(response)) model = ConstrainedSphericalDeconvModel(gtab, response, sh_order=sh_order) csd_mod = model.fit(data, B0_mask_data).shm_coeff del model, response, B0_mask_data return csd_mod
def test_recursive_response_calibration(): """ Test the recursive response calibration method. """ SNR = 100 S0 = 1 sh_order = 8 _, fbvals, fbvecs = get_data('small_64D') bvals = np.load(fbvals) bvecs = np.load(fbvecs) sphere = get_sphere('symmetric724') gtab = gradient_table(bvals, bvecs) evals = np.array([0.0015, 0.0003, 0.0003]) evecs = np.array([[0, 1, 0], [0, 0, 1], [1, 0, 0]]).T mevals = np.array(([0.0015, 0.0003, 0.0003], [0.0015, 0.0003, 0.0003])) angles = [(0, 0), (90, 0)] where_dwi = lazy_index(~gtab.b0s_mask) S_cross, sticks_cross = multi_tensor(gtab, mevals, S0, angles=angles, fractions=[50, 50], snr=SNR) S_single = single_tensor(gtab, S0, evals, evecs, snr=SNR) data = np.concatenate((np.tile(S_cross, (8, 1)), np.tile(S_single, (2, 1))), axis=0) odf_gt_cross = multi_tensor_odf(sphere.vertices, mevals, angles, [50, 50]) odf_gt_single = single_tensor_odf(sphere.vertices, evals, evecs) response = recursive_response(gtab, data, mask=None, sh_order=8, peak_thr=0.01, init_fa=0.05, init_trace=0.0021, iter=8, convergence=0.001, parallel=False) csd = ConstrainedSphericalDeconvModel(gtab, response) csd_fit = csd.fit(data) assert_equal(np.all(csd_fit.shm_coeff[:, 0] >= 0), True) fodf = csd_fit.odf(sphere) directions_gt_single, _, _ = peak_directions(odf_gt_single, sphere) directions_gt_cross, _, _ = peak_directions(odf_gt_cross, sphere) directions_single, _, _ = peak_directions(fodf[8, :], sphere) directions_cross, _, _ = peak_directions(fodf[0, :], sphere) ang_sim = angular_similarity(directions_cross, directions_gt_cross) assert_equal(ang_sim > 1.9, True) assert_equal(directions_cross.shape[0], 2) assert_equal(directions_gt_cross.shape[0], 2) ang_sim = angular_similarity(directions_single, directions_gt_single) assert_equal(ang_sim > 0.9, True) assert_equal(directions_single.shape[0], 1) assert_equal(directions_gt_single.shape[0], 1) sphere = Sphere(xyz=gtab.gradients[where_dwi]) sf = response.on_sphere(sphere) S = np.concatenate(([response.S0], sf)) tenmodel = dti.TensorModel(gtab, min_signal=0.001) tenfit = tenmodel.fit(S) FA = fractional_anisotropy(tenfit.evals) FA_gt = fractional_anisotropy(evals) assert_almost_equal(FA, FA_gt, 1)
def _run_interface(self, runtime): from dipy.core.gradients import GradientTable from dipy.reconst.dti import fractional_anisotropy, mean_diffusivity from dipy.reconst.csdeconv import recursive_response, auto_response img = nb.load(self.inputs.in_file) imref = nb.four_to_three(img)[0] affine = img.affine if isdefined(self.inputs.in_mask): msk = nb.load(self.inputs.in_mask).get_data() msk[msk > 0] = 1 msk[msk < 0] = 0 else: msk = np.ones(imref.shape) data = img.get_data().astype(np.float32) gtab = self._get_gradient_table() evals = np.nan_to_num(nb.load(self.inputs.in_evals).get_data()) FA = np.nan_to_num(fractional_anisotropy(evals)) * msk indices = np.where(FA > self.inputs.fa_thresh) S0s = data[indices][:, np.nonzero(gtab.b0s_mask)[0]] S0 = np.mean(S0s) if self.inputs.auto: response, ratio = auto_response(gtab, data, roi_radius=self.inputs.roi_radius, fa_thr=self.inputs.fa_thresh) response = response[0].tolist() + [S0] elif self.inputs.recursive: MD = np.nan_to_num(mean_diffusivity(evals)) * msk indices = np.logical_or(FA >= 0.4, (np.logical_and(FA >= 0.15, MD >= 0.0011))) data = nb.load(self.inputs.in_file).get_data() response = recursive_response(gtab, data, mask=indices, sh_order=8, peak_thr=0.01, init_fa=0.08, init_trace=0.0021, iter=8, convergence=0.001, parallel=True) ratio = abs(response[1] / response[0]) else: lambdas = evals[indices] l01 = np.sort(np.mean(lambdas, axis=0)) response = np.array([l01[-1], l01[-2], l01[-2], S0]) ratio = abs(response[1] / response[0]) if ratio > 0.25: IFLOGGER.warn( 'Estimated response is not prolate enough. ' 'Ratio=%0.3f.', ratio) elif ratio < 1.e-5 or np.any(np.isnan(response)): response = np.array([1.8e-3, 3.6e-4, 3.6e-4, S0]) IFLOGGER.warn( 'Estimated response is not valid, using a default one') else: IFLOGGER.info('Estimated response: %s', str(response[:3])) np.savetxt(op.abspath(self.inputs.response), response) wm_mask = np.zeros_like(FA) wm_mask[indices] = 1 nb.Nifti1Image(wm_mask.astype(np.uint8), affine, None).to_filename(op.abspath(self.inputs.out_mask)) return runtime
def dodata(f_name,data_path): dipy_home = pjoin(os.path.expanduser('~'), 'dipy_data') folder = pjoin(dipy_home, data_path) fraw = pjoin(folder, f_name+'.nii.gz') fbval = pjoin(folder, f_name+'.bval') fbvec = pjoin(folder, f_name+'.bvec') flabels = pjoin(folder, f_name+'.nii-label.nii.gz') bvals, bvecs = read_bvals_bvecs(fbval, fbvec) gtab = gradient_table(bvals, bvecs) img = nib.load(fraw) data = img.get_data() affine = img.get_affine() label_img = nib.load(flabels) labels=label_img.get_data() lap=through_label_sl.label_position(labels, labelValue=1) dataslice = data[40:80, 20:80, lap[2][2] / 2] #print lap[2][2]/2 #get_csd_gfa(f_name,data,gtab,dataslice) maskdata, mask = median_otsu(data, 2, 1, False, vol_idx=range(10, 50), dilate=2) #不去背景 """ get fa and tensor evecs and ODF""" from dipy.reconst.dti import TensorModel,mean_diffusivity tenmodel = TensorModel(gtab) tenfit = tenmodel.fit(data, mask) sphere = get_sphere('symmetric724') FA = fractional_anisotropy(tenfit.evals) FA[np.isnan(FA)] = 0 np.save(os.getcwd()+'\zhibiao'+f_name+'_FA.npy',FA) fa_img = nib.Nifti1Image(FA.astype(np.float32), affine) nib.save(fa_img,os.getcwd()+'\zhibiao'+f_name+'_FA.nii.gz') print('Saving "DTI_tensor_fa.nii.gz" sucessful.') evecs_img = nib.Nifti1Image(tenfit.evecs.astype(np.float32), affine) nib.save(evecs_img, os.getcwd()+'\zhibiao'+f_name+'_DTI_tensor_evecs.nii.gz') print('Saving "DTI_tensor_evecs.nii.gz" sucessful.') MD1 = mean_diffusivity(tenfit.evals) nib.save(nib.Nifti1Image(MD1.astype(np.float32), img.get_affine()), os.getcwd()+'\zhibiao'+f_name+'_MD.nii.gz') #tensor_odfs = tenmodel.fit(data[20:50, 55:85, 38:39]).odf(sphere) #from dipy.reconst.odf import gfa #dti_gfa=gfa(tensor_odfs) wm_mask = (np.logical_or(FA >= 0.4, (np.logical_and(FA >= 0.15, MD >= 0.0011)))) response = recursive_response(gtab, data, mask=wm_mask, sh_order=8, peak_thr=0.01, init_fa=0.08, init_trace=0.0021, iter=8, convergence=0.001, parallel=False) from dipy.reconst.csdeconv import ConstrainedSphericalDeconvModel csd_model = ConstrainedSphericalDeconvModel(gtab, response) #csd_fit = csd_model.fit(data) from dipy.direction import peaks_from_model csd_peaks = peaks_from_model(model=csd_model, data=data, sphere=sphere, relative_peak_threshold=.5, min_separation_angle=25, parallel=False) GFA = csd_peaks.gfa nib.save(GFA, os.getcwd()+'\zhibiao'+f_name+'_MSD.nii.gz') print('Saving "GFA.nii.gz" sucessful.') from dipy.reconst.shore import ShoreModel asm = ShoreModel(gtab) print('Calculating...SHORE msd') asmfit = asm.fit(data,mask) msd = asmfit.msd() msd[np.isnan(msd)] = 0 #print GFA[:,:,slice].T print('Saving msd_img.png') nib.save(msd, os.getcwd()+'\zhibiao'+f_name+'_GFA.nii.gz')
def dwi_dipy_run(dwi_dir, node_size, dir_path, conn_model, parc, atlas_select, network, wm_mask=None): from dipy.reconst.dti import TensorModel, quantize_evecs from dipy.reconst.csdeconv import ConstrainedSphericalDeconvModel, recursive_response from dipy.tracking.local import LocalTracking, ActTissueClassifier from dipy.tracking import utils from dipy.direction import peaks_from_model from dipy.tracking.eudx import EuDX from dipy.data import get_sphere, default_sphere from dipy.core.gradients import gradient_table from dipy.io import read_bvals_bvecs from dipy.tracking.streamline import Streamlines from dipy.direction import ProbabilisticDirectionGetter, ClosestPeakDirectionGetter, BootDirectionGetter from nibabel.streamlines import save as save_trk from nibabel.streamlines import Tractogram ## dwi_dir = '/Users/PSYC-dap3463/Downloads/bedpostx_s002' img_pve_csf = nib.load( '/Users/PSYC-dap3463/Downloads/002_all/tmp/reg_a/t1w_vent_csf_diff_dwi.nii.gz' ) img_pve_wm = nib.load( '/Users/PSYC-dap3463/Downloads/002_all/tmp/reg_a/t1w_wm_in_dwi_bin.nii.gz' ) img_pve_gm = nib.load( '/Users/PSYC-dap3463/Downloads/002_all/tmp/reg_a/t1w_gm_mask_dwi.nii.gz' ) labels_img = nib.load( '/Users/PSYC-dap3463/Downloads/002_all/tmp/reg_a/dwi_aligned_atlas.nii.gz' ) num_total_samples = 10000 tracking_method = 'boot' # Options are 'boot', 'prob', 'peaks', 'closest' procmem = [2, 4] ## if parc is True: node_size = 'parc' dwi_img = "%s%s" % (dwi_dir, '/dwi.nii.gz') nodif_brain_mask_path = "%s%s" % (dwi_dir, '/nodif_brain_mask.nii.gz') bvals = "%s%s" % (dwi_dir, '/bval') bvecs = "%s%s" % (dwi_dir, '/bvec') dwi_img = nib.load(dwi_img) data = dwi_img.get_data() [bvals, bvecs] = read_bvals_bvecs(bvals, bvecs) gtab = gradient_table(bvals, bvecs) gtab.b0_threshold = min(bvals) sphere = get_sphere('symmetric724') # Loads mask and ensures it's a true binary mask mask_img = nib.load(nodif_brain_mask_path) mask = mask_img.get_data() mask = mask > 0 # Fit a basic tensor model first model = TensorModel(gtab) ten = model.fit(data, mask) fa = ten.fa # Tractography if conn_model == 'csd': print('Tracking with csd model...') elif conn_model == 'tensor': print('Tracking with tensor model...') else: raise RuntimeError("%s%s" % (conn_model, ' is not a valid model.')) # Combine seed counts from voxel with seed counts total wm_mask_data = img_pve_wm.get_data() wm_mask_data[0, :, :] = False wm_mask_data[:, 0, :] = False wm_mask_data[:, :, 0] = False seeds = utils.seeds_from_mask(wm_mask_data, density=1, affine=dwi_img.get_affine()) seeds_rnd = utils.random_seeds_from_mask(ten.fa > 0.02, seeds_count=num_total_samples, seed_count_per_voxel=True) seeds_all = np.vstack([seeds, seeds_rnd]) # Load tissue maps and prepare tissue classifier (Anatomically-Constrained Tractography (ACT)) background = np.ones(img_pve_gm.shape) background[(img_pve_gm.get_data() + img_pve_wm.get_data() + img_pve_csf.get_data()) > 0] = 0 include_map = img_pve_gm.get_data() include_map[background > 0] = 1 exclude_map = img_pve_csf.get_data() act_classifier = ActTissueClassifier(include_map, exclude_map) if conn_model == 'tensor': ind = quantize_evecs(ten.evecs, sphere.vertices) streamline_generator = EuDX(a=fa, ind=ind, seeds=seeds_all, odf_vertices=sphere.vertices, a_low=0.05, step_sz=.5) elif conn_model == 'csd': print('Tracking with CSD model...') response = recursive_response( gtab, data, mask=img_pve_wm.get_data().astype('bool'), sh_order=8, peak_thr=0.01, init_fa=0.05, init_trace=0.0021, iter=8, convergence=0.001, parallel=True) csd_model = ConstrainedSphericalDeconvModel(gtab, response) if tracking_method == 'boot': dg = BootDirectionGetter.from_data(data, csd_model, max_angle=30., sphere=default_sphere) elif tracking_method == 'prob': try: print( 'First attempting to build the direction getter directly from the spherical harmonic representation of the FOD...' ) csd_fit = csd_model.fit( data, mask=img_pve_wm.get_data().astype('bool')) dg = ProbabilisticDirectionGetter.from_shcoeff( csd_fit.shm_coeff, max_angle=30., sphere=default_sphere) except: print( 'Sphereical harmonic not available for this model. Using peaks_from_model to represent the ODF of the model on a spherical harmonic basis instead...' ) peaks = peaks_from_model( csd_model, data, default_sphere, .5, 25, mask=img_pve_wm.get_data().astype('bool'), return_sh=True, parallel=True, nbr_processes=procmem[0]) dg = ProbabilisticDirectionGetter.from_shcoeff( peaks.shm_coeff, max_angle=30., sphere=default_sphere) elif tracking_method == 'peaks': dg = peaks_from_model(model=csd_model, data=data, sphere=default_sphere, relative_peak_threshold=.5, min_separation_angle=25, mask=img_pve_wm.get_data().astype('bool'), parallel=True, nbr_processes=procmem[0]) elif tracking_method == 'closest': csd_fit = csd_model.fit(data, mask=img_pve_wm.get_data().astype('bool')) pmf = csd_fit.odf(default_sphere).clip(min=0) dg = ClosestPeakDirectionGetter.from_pmf(pmf, max_angle=30., sphere=default_sphere) streamline_generator = LocalTracking(dg, act_classifier, seeds_all, affine=dwi_img.affine, step_size=0.5) del dg try: del csd_fit except: pass try: del response except: pass try: del csd_model except: pass streamlines = Streamlines(streamline_generator, buffer_size=512) save_trk(Tractogram(streamlines, affine_to_rasmm=dwi_img.affine), 'prob_streamlines.trk') tracks = [sl for sl in streamlines if len(sl) > 1] labels_data = labels_img.get_data().astype('int') labels_affine = labels_img.affine conn_matrix, grouping = utils.connectivity_matrix( tracks, labels_data, affine=labels_affine, return_mapping=True, mapping_as_streamlines=True, symmetric=True) conn_matrix[:3, :] = 0 conn_matrix[:, :3] = 0 return conn_matrix
def csd_mod_est(gtab, data, B0_mask, sh_order=8): """ Estimate a Constrained Spherical Deconvolution (CSD) 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 ------- csd_mod : ndarray Coefficients of the csd reconstruction. model : obj Fitted csd model. References ---------- .. [1] Tournier, J.D., et al. NeuroImage 2007. Robust determination of the fibre orientation distribution in diffusion MRI: Non-negativity constrained super-resolved spherical deconvolution .. [2] Descoteaux, M., et al. IEEE TMI 2009. Deterministic and Probabilistic Tractography Based on Complex Fibre Orientation Distributions .. [3] Côté, M-A., et al. Medical Image Analysis 2013. Tractometer: Towards validation of tractography pipelines .. [4] Tournier, J.D, et al. Imaging Systems and Technology 2012. MRtrix: Diffusion Tractography in Crossing Fiber Regions """ from dipy.reconst.csdeconv import ( ConstrainedSphericalDeconvModel, recursive_response, ) import pkg_resources import yaml with open(pkg_resources.resource_filename("pynets", "runconfig.yaml"), "r") as stream: hardcoded_params = yaml.load(stream) nthreads = hardcoded_params["nthreads"][0] stream.close() print("Fitting CSD model...") B0_mask_data = np.nan_to_num(np.asarray( nib.load(B0_mask).dataobj)).astype("bool") print("Reconstructing...") response = recursive_response(gtab, data, mask=B0_mask_data, sh_order=sh_order, peak_thr=0.01, init_fa=0.08, init_trace=0.0021, iter=8, convergence=0.001, parallel=False, nbr_processes=nthreads) print("CSD Reponse: " + str(response)) model = ConstrainedSphericalDeconvModel(gtab, response, sh_order=sh_order) csd_mod = model.fit(data, B0_mask_data).shm_coeff del response, B0_mask_data return csd_mod, model
def dwi_dipy_run(dwi_dir, node_size, dir_path, conn_model, parc, atlas_select, network, wm_mask=None): import os import glob import re import nipype.interfaces.fsl as fsl from dipy.reconst.dti import TensorModel, quantize_evecs from dipy.reconst.csdeconv import ConstrainedSphericalDeconvModel, recursive_response from dipy.tracking.local import LocalTracking, ThresholdTissueClassifier from dipy.tracking import utils from dipy.direction import peaks_from_model from dipy.tracking.eudx import EuDX from dipy.data import get_sphere from dipy.core.gradients import gradient_table from dipy.io import read_bvals_bvecs def atoi(text): return int(text) if text.isdigit() else text def natural_keys(text): return [atoi(c) for c in re.split('(\d+)', text)] dwi_img = "%s%s" % (dwi_dir, '/dwi.nii.gz') nodif_brain_mask_path = "%s%s" % (dwi_dir, '/nodif_brain_mask.nii.gz') bvals = "%s%s" % (dwi_dir, '/bval') bvecs = "%s%s" % (dwi_dir, '/bvec') img = nib.load(dwi_img) data = img.get_data() # Loads mask and ensures it's a true binary mask img = nib.load(nodif_brain_mask_path) mask = img.get_data() mask = mask > 0 [bvals, bvecs] = read_bvals_bvecs(bvals, bvecs) gtab = gradient_table(bvals, bvecs) # Estimates some tensors model = TensorModel(gtab) ten = model.fit(data, mask) sphere = get_sphere('symmetric724') ind = quantize_evecs(ten.evecs, sphere.vertices) # Tractography if conn_model == 'csd': trac_mod = 'csd' else: conn_model = 'tensor' trac_mod = ten.fa affine = img.affine print('Tracking with tensor model...') if wm_mask is None: mask = nib.load(mask).get_data() mask[0, :, :] = False mask[:, 0, :] = False mask[:, :, 0] = False seeds = utils.seeds_from_mask(mask, density=2) else: wm_mask_data = nib.load(wm_mask).get_data() wm_mask_data[0, :, :] = False wm_mask_data[:, 0, :] = False wm_mask_data[:, :, 0] = False seeds = utils.seeds_from_mask(wm_mask_data, density=2) #seeds = random_seeds_from_mask(ten.fa > 0.3, seeds_count=num_total_samples) if conn_model == 'tensor': eu = EuDX(a=trac_mod, ind=ind, seeds=seeds, odf_vertices=sphere.vertices, a_low=0.05, step_sz=.5) tracks = [e for e in eu] elif conn_model == 'csd': print('Tracking with CSD model...') if wm_mask is None: response = recursive_response(gtab, data, mask=mask.astype('bool'), sh_order=8, peak_thr=0.01, init_fa=0.08, init_trace=0.0021, iter=8, convergence=0.001, parallel=True) else: response = recursive_response(gtab, data, mask=wm_mask_data.astype('bool'), sh_order=8, peak_thr=0.01, init_fa=0.08, init_trace=0.0021, iter=8, convergence=0.001, parallel=True) csd_model = ConstrainedSphericalDeconvModel(gtab, response) csd_peaks = peaks_from_model(model=csd_model, data=data, sphere=sphere, relative_peak_threshold=.5, min_separation_angle=25, parallel=True) tissue_classifier = ThresholdTissueClassifier(ten.fa, 0.1) streamline_generator = LocalTracking(csd_peaks, tissue_classifier, seeds, affine=affine, step_size=0.5) tracks = [e for e in streamline_generator] if parc is True: node_size = 'parc' if network: seeds_dir = "%s%s%s%s%s%s%s" % (dir_path, '/seeds_', network, '_', atlas_select, '_', str(node_size)) else: seeds_dir = "%s%s%s%s%s" % (dir_path, '/seeds_', atlas_select, '_', str(node_size)) seed_files = glob.glob("%s%s" % (seeds_dir, '/*diff.nii.gz')) seed_files.sort(key=natural_keys) # Binarize ROIs print('\nBinarizing seed masks...') j = 1 for i in seed_files: args = ' -bin ' out_file = "%s%s" % (i.split('.nii.gz')[0], '_bin.nii.gz') maths = fsl.ImageMaths(in_file=i, op_string=args, out_file=out_file) os.system(maths.cmdline) args = ' -mul ' + str(j) maths = fsl.ImageMaths(in_file=out_file, op_string=args, out_file=out_file) os.system(maths.cmdline) j = j + 1 # Create atlas from ROIs seed_files = glob.glob("%s%s" % (seeds_dir, '/*diff_bin.nii.gz')) seed_files.sort(key=natural_keys) print('\nMerging seed masks into single labels image...') label_sum = "%s%s" % (seeds_dir, '/all_rois.nii.gz') args = ' -add ' + i maths = fsl.ImageMaths(in_file=seed_files[0], op_string=args, out_file=label_sum) os.system(maths.cmdline) for i in seed_files: args = ' -add ' + i maths = fsl.ImageMaths(in_file=label_sum, op_string=args, out_file=label_sum) os.system(maths.cmdline) labels_im = nib.load(label_sum) labels_data = labels_im.get_data().astype('int') conn_matrix, grouping = utils.connectivity_matrix( tracks, labels_data, affine=affine, return_mapping=True, mapping_as_streamlines=True) conn_matrix[:3, :] = 0 conn_matrix[:, :3] = 0 return conn_matrix
import dipy.reconst.dti as dti tenmodel = dti.TensorModel(gtab) tenfit = tenmodel.fit(data, mask=data[..., 0] > 200) from dipy.reconst.dti import fractional_anisotropy FA = fractional_anisotropy(tenfit.evals) MD = dti.mean_diffusivity(tenfit.evals) wm_mask = (np.logical_or(FA >= 0.4, (np.logical_and(FA >= 0.15, MD >= 0.0011)))) response = recursive_response(gtab, data, mask=wm_mask, sh_order=8, peak_thr=0.01, init_fa=0.08, init_trace=0.0021, iter=8, convergence=0.001, parallel=True) """ We can check the shape of the signal of the response function, which should be like a pancake: """ response_signal = response.on_sphere(default_sphere) # transform our data from 1D to 4D response_signal = response_signal[None, None, None, :] response_actor = actor.odf_slicer(response_signal, sphere=default_sphere, colormap='plasma')
""" A WM mask can shorten computation time for the whole dataset. Here it is created based on the DTI fit. """ import dipy.reconst.dti as dti tenmodel = dti.TensorModel(gtab) tenfit = tenmodel.fit(data, mask=data[..., 0] > 200) from dipy.reconst.dti import fractional_anisotropy FA = fractional_anisotropy(tenfit.evals) MD = dti.mean_diffusivity(tenfit.evals) wm_mask = (np.logical_or(FA >= 0.4, (np.logical_and(FA >= 0.15, MD >= 0.0011)))) response = recursive_response(gtab, data, mask=wm_mask, sh_order=8, peak_thr=0.01, init_fa=0.08, init_trace=0.0021, iter=8, convergence=0.001, parallel=True) """ We can check the shape of the signal of the response function, which should be like a pancake: """ response_signal = response.on_sphere(sphere) response_actor = fvtk.sphere_funcs(response_signal, sphere) ren = fvtk.ren() fvtk.add(ren, response_actor) print('Saving illustration as csd_recursive_response.png')
def test_recursive_response_calibration(): """ Test the recursive response calibration method. """ SNR = 100 S0 = 1 _, fbvals, fbvecs = get_fnames('small_64D') bvals, bvecs = read_bvals_bvecs(fbvals, fbvecs) sphere = default_sphere gtab = gradient_table(bvals, bvecs) evals = np.array([0.0015, 0.0003, 0.0003]) evecs = np.array([[0, 1, 0], [0, 0, 1], [1, 0, 0]]).T mevals = np.array(([0.0015, 0.0003, 0.0003], [0.0015, 0.0003, 0.0003])) angles = [(0, 0), (90, 0)] where_dwi = lazy_index(~gtab.b0s_mask) S_cross, _ = multi_tensor(gtab, mevals, S0, angles=angles, fractions=[50, 50], snr=SNR) S_single = single_tensor(gtab, S0, evals, evecs, snr=SNR) data = np.concatenate((np.tile(S_cross, (8, 1)), np.tile(S_single, (2, 1))), axis=0) odf_gt_cross = multi_tensor_odf(sphere.vertices, mevals, angles, [50, 50]) odf_gt_single = single_tensor_odf(sphere.vertices, evals, evecs) with warnings.catch_warnings(): warnings.filterwarnings("ignore", message=descoteaux07_legacy_msg, category=PendingDeprecationWarning) response = recursive_response(gtab, data, mask=None, sh_order=8, peak_thr=0.01, init_fa=0.05, init_trace=0.0021, iter=8, convergence=0.001, parallel=False) with warnings.catch_warnings(): warnings.filterwarnings("ignore", message=descoteaux07_legacy_msg, category=PendingDeprecationWarning) csd = ConstrainedSphericalDeconvModel(gtab, response) csd_fit = csd.fit(data) assert_equal(np.all(csd_fit.shm_coeff[:, 0] >= 0), True) with warnings.catch_warnings(): warnings.filterwarnings("ignore", message=descoteaux07_legacy_msg, category=PendingDeprecationWarning) fodf = csd_fit.odf(sphere) directions_gt_single, _, _ = peak_directions(odf_gt_single, sphere) directions_gt_cross, _, _ = peak_directions(odf_gt_cross, sphere) directions_single, _, _ = peak_directions(fodf[8, :], sphere) directions_cross, _, _ = peak_directions(fodf[0, :], sphere) ang_sim = angular_similarity(directions_cross, directions_gt_cross) assert_equal(ang_sim > 1.9, True) assert_equal(directions_cross.shape[0], 2) assert_equal(directions_gt_cross.shape[0], 2) ang_sim = angular_similarity(directions_single, directions_gt_single) assert_equal(ang_sim > 0.9, True) assert_equal(directions_single.shape[0], 1) assert_equal(directions_gt_single.shape[0], 1) with warnings.catch_warnings(record=True) as w: sphere = Sphere(xyz=gtab.gradients[where_dwi]) npt.assert_equal(len(w), 1) npt.assert_(issubclass(w[0].category, UserWarning)) npt.assert_("Vertices are not on the unit sphere" in str(w[0].message)) with warnings.catch_warnings(): warnings.filterwarnings("ignore", message=descoteaux07_legacy_msg, category=PendingDeprecationWarning) sf = response.on_sphere(sphere) S = np.concatenate(([response.S0], sf)) tenmodel = TensorModel(gtab, min_signal=0.001) tenfit = tenmodel.fit(S) FA = fractional_anisotropy(tenfit.evals) FA_gt = fractional_anisotropy(evals) assert_almost_equal(FA, FA_gt, 1)
def _run_interface(self, runtime): from dipy.core.gradients import GradientTable from dipy.reconst.dti import fractional_anisotropy, mean_diffusivity from dipy.reconst.csdeconv import recursive_response, auto_response img = nb.load(self.inputs.in_file) affine = img.get_affine() if isdefined(self.inputs.in_mask): msk = nb.load(self.inputs.in_mask).get_data() msk[msk > 0] = 1 msk[msk < 0] = 0 else: msk = np.ones(imref.get_shape()) data = img.get_data().astype(np.float32) gtab = self._get_gradient_table() evals = np.nan_to_num(nb.load(self.inputs.in_evals).get_data()) FA = np.nan_to_num(fractional_anisotropy(evals)) * msk indices = np.where(FA > self.inputs.fa_thresh) S0s = data[indices][:, np.nonzero(gtab.b0s_mask)[0]] S0 = np.mean(S0s) if self.inputs.auto: response, ratio = auto_response(gtab, data, roi_radius=self.inputs.roi_radius, fa_thr=self.inputs.fa_thresh) response = response[0].tolist() + [S0] elif self.inputs.recursive: MD = np.nan_to_num(mean_diffusivity(evals)) * msk indices = np.logical_or( FA >= 0.4, (np.logical_and(FA >= 0.15, MD >= 0.0011))) data = nb.load(self.inputs.in_file).get_data() response = recursive_response(gtab, data, mask=indices, sh_order=8, peak_thr=0.01, init_fa=0.08, init_trace=0.0021, iter=8, convergence=0.001, parallel=True) ratio = abs(response[1] / response[0]) else: lambdas = evals[indices] l01 = np.sort(np.mean(lambdas, axis=0)) response = np.array([l01[-1], l01[-2], l01[-2], S0]) ratio = abs(response[1] / response[0]) if ratio > 0.25: IFLOGGER.warn(('Estimated response is not prolate enough. ' 'Ratio=%0.3f.') % ratio) elif ratio < 1.e-5 or np.any(np.isnan(response)): response = np.array([1.8e-3, 3.6e-4, 3.6e-4, S0]) IFLOGGER.warn( ('Estimated response is not valid, using a default one')) else: IFLOGGER.info(('Estimated response: %s') % str(response[:3])) np.savetxt(op.abspath(self.inputs.response), response) wm_mask = np.zeros_like(FA) wm_mask[indices] = 1 nb.Nifti1Image( wm_mask.astype(np.uint8), affine, None).to_filename(op.abspath(self.inputs.out_mask)) return runtime
def dodata(f_name, data_path): dipy_home = pjoin(os.path.expanduser('~'), 'dipy_data') folder = pjoin(dipy_home, data_path) fraw = pjoin(folder, f_name + '.nii.gz') fbval = pjoin(folder, f_name + '.bval') fbvec = pjoin(folder, f_name + '.bvec') flabels = pjoin(folder, f_name + '.nii-label.nii.gz') bvals, bvecs = read_bvals_bvecs(fbval, fbvec) gtab = gradient_table(bvals, bvecs) img = nib.load(fraw) data = img.get_data() affine = img.get_affine() label_img = nib.load(flabels) labels = label_img.get_data() lap = through_label_sl.label_position(labels, labelValue=1) dataslice = data[40:80, 20:80, lap[2][2] / 2] #print lap[2][2]/2 #get_csd_gfa(f_name,data,gtab,dataslice) maskdata, mask = median_otsu(data, 2, 1, False, vol_idx=range(10, 50), dilate=2) #不去背景 """ get fa and tensor evecs and ODF""" from dipy.reconst.dti import TensorModel, mean_diffusivity tenmodel = TensorModel(gtab) tenfit = tenmodel.fit(data, mask) sphere = get_sphere('symmetric724') FA = fractional_anisotropy(tenfit.evals) FA[np.isnan(FA)] = 0 np.save(os.getcwd() + '\zhibiao' + f_name + '_FA.npy', FA) fa_img = nib.Nifti1Image(FA.astype(np.float32), affine) nib.save(fa_img, os.getcwd() + '\zhibiao' + f_name + '_FA.nii.gz') print('Saving "DTI_tensor_fa.nii.gz" sucessful.') evecs_img = nib.Nifti1Image(tenfit.evecs.astype(np.float32), affine) nib.save(evecs_img, os.getcwd() + '\zhibiao' + f_name + '_DTI_tensor_evecs.nii.gz') print('Saving "DTI_tensor_evecs.nii.gz" sucessful.') MD1 = mean_diffusivity(tenfit.evals) nib.save(nib.Nifti1Image(MD1.astype(np.float32), img.get_affine()), os.getcwd() + '\zhibiao' + f_name + '_MD.nii.gz') #tensor_odfs = tenmodel.fit(data[20:50, 55:85, 38:39]).odf(sphere) #from dipy.reconst.odf import gfa #dti_gfa=gfa(tensor_odfs) wm_mask = (np.logical_or(FA >= 0.4, (np.logical_and(FA >= 0.15, MD >= 0.0011)))) response = recursive_response(gtab, data, mask=wm_mask, sh_order=8, peak_thr=0.01, init_fa=0.08, init_trace=0.0021, iter=8, convergence=0.001, parallel=False) from dipy.reconst.csdeconv import ConstrainedSphericalDeconvModel csd_model = ConstrainedSphericalDeconvModel(gtab, response) #csd_fit = csd_model.fit(data) from dipy.direction import peaks_from_model csd_peaks = peaks_from_model(model=csd_model, data=data, sphere=sphere, relative_peak_threshold=.5, min_separation_angle=25, parallel=False) GFA = csd_peaks.gfa nib.save(GFA, os.getcwd() + '\zhibiao' + f_name + '_MSD.nii.gz') print('Saving "GFA.nii.gz" sucessful.') from dipy.reconst.shore import ShoreModel asm = ShoreModel(gtab) print('Calculating...SHORE msd') asmfit = asm.fit(data, mask) msd = asmfit.msd() msd[np.isnan(msd)] = 0 #print GFA[:,:,slice].T print('Saving msd_img.png') nib.save(msd, os.getcwd() + '\zhibiao' + f_name + '_GFA.nii.gz')