def test_sfm_stick(): fdata, fbvals, fbvecs = dpd.get_fnames() data = load_nifti_data(fdata) gtab = grad.gradient_table(fbvals, fbvecs) sfmodel = sfm.SparseFascicleModel(gtab, solver='NNLS', response=[0.001, 0, 0]) sffit1 = sfmodel.fit(data[0, 0, 0]) sphere = dpd.get_sphere() sffit1.odf(sphere) sffit1.predict(gtab) SNR = 1000 S0 = 100 mevals = np.array(([0.001, 0, 0], [0.001, 0, 0])) angles = [(0, 0), (60, 0)] S, sticks = sims.multi_tensor(gtab, mevals, S0, angles=angles, fractions=[50, 50], snr=SNR) sfmodel = sfm.SparseFascicleModel(gtab, solver='NNLS', response=[0.001, 0, 0]) sffit = sfmodel.fit(S) pred = sffit.predict() npt.assert_(xval.coeff_of_determination(pred, S) > 96)
def test_predict(): SNR = 1000 S0 = 100 _, fbvals, fbvecs = dpd.get_data('small_64D') bvals = np.load(fbvals) bvecs = np.load(fbvecs) gtab = grad.gradient_table(bvals, bvecs) mevals = np.array(([0.0015, 0.0003, 0.0003], [0.0015, 0.0003, 0.0003])) angles = [(0, 0), (60, 0)] S, sticks = sims.multi_tensor(gtab, mevals, S0, angles=angles, fractions=[10, 90], snr=SNR) sfmodel = sfm.SparseFascicleModel(gtab, response=[0.0015, 0.0003, 0.0003]) sffit = sfmodel.fit(S) pred = sffit.predict() npt.assert_(xval.coeff_of_determination(pred, S) > 97) # Should be possible to predict using a different gtab: new_gtab = grad.gradient_table(bvals[::2], bvecs[::2]) new_pred = sffit.predict(new_gtab) npt.assert_(xval.coeff_of_determination(new_pred, S[::2]) > 97)
def test_sfm(): fdata, fbvals, fbvecs = dpd.get_fnames() data = load_nifti_data(fdata) gtab = grad.gradient_table(fbvals, fbvecs) for iso in [sfm.ExponentialIsotropicModel, None]: sfmodel = sfm.SparseFascicleModel(gtab, isotropic=iso) sffit1 = sfmodel.fit(data[0, 0, 0]) sphere = dpd.get_sphere() odf1 = sffit1.odf(sphere) pred1 = sffit1.predict(gtab) mask = np.ones(data.shape[:-1]) sffit2 = sfmodel.fit(data, mask) pred2 = sffit2.predict(gtab) odf2 = sffit2.odf(sphere) sffit3 = sfmodel.fit(data) pred3 = sffit3.predict(gtab) odf3 = sffit3.odf(sphere) npt.assert_almost_equal(pred3, pred2, decimal=2) npt.assert_almost_equal(pred3[0, 0, 0], pred1, decimal=2) npt.assert_almost_equal(odf3[0, 0, 0], odf1, decimal=2) npt.assert_almost_equal(odf3[0, 0, 0], odf2[0, 0, 0], decimal=2) # Fit zeros and you will get back zeros npt.assert_almost_equal( sfmodel.fit(np.zeros(data[0, 0, 0].shape)).beta, np.zeros(sfmodel.design_matrix[0].shape[-1]))
def test_exponential_iso(): fdata, fbvals, fbvecs = dpd.get_fnames() data_dti = nib.load(fdata).get_data() gtab_dti = grad.gradient_table(fbvals, fbvecs) data_multi, gtab_multi = dpd.dsi_deconv_voxels() for data, gtab in zip([data_dti, data_multi], [gtab_dti, gtab_multi]): sfmodel = sfm.SparseFascicleModel( gtab, isotropic=sfm.ExponentialIsotropicModel) sffit1 = sfmodel.fit(data[0, 0, 0]) sphere = dpd.get_sphere() sffit1.odf(sphere) sffit1.predict(gtab) SNR = 1000 S0 = 100 mevals = np.array(([0.0015, 0.0005, 0.0005], [0.0015, 0.0005, 0.0005])) angles = [(0, 0), (60, 0)] S, sticks = sims.multi_tensor(gtab, mevals, S0, angles=angles, fractions=[50, 50], snr=SNR) sffit = sfmodel.fit(S) pred = sffit.predict() npt.assert_(xval.coeff_of_determination(pred, S) > 96)
def test_design_matrix(): data, gtab = dpd.dsi_voxels() sphere = dpd.get_sphere() # Make it with NNLS, so that it gets tested regardless of sklearn sparse_fascicle_model = sfm.SparseFascicleModel(gtab, sphere, solver='NNLS') npt.assert_equal(sparse_fascicle_model.design_matrix.shape, (np.sum(~gtab.b0s_mask), sphere.vertices.shape[0]))
def test_sfm_background(): fdata, fbvals, fbvecs = dpd.get_fnames() data = load_nifti_data(fdata) gtab = grad.gradient_table(fbvals, fbvecs) to_fit = data[0, 0, 0] to_fit[gtab.b0s_mask] = 0 sfmodel = sfm.SparseFascicleModel(gtab, solver='NNLS') sffit = sfmodel.fit(to_fit) npt.assert_equal(sffit.beta, np.zeros_like(sffit.beta))
def sfm_mod_est(gtab, data, B0_mask, BACKEND='loky'): """ Estimate a Sparse Fascicle Model (SFM) 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 ------- sf_mod : ndarray Coefficients of the sfm reconstruction. model : obj Fitted sf model. References ---------- .. [1] Ariel Rokem, Jason D. Yeatman, Franco Pestilli, Kendrick N. Kay, Aviv Mezer, Stefan van der Walt, Brian A. Wandell (2015). Evaluating the accuracy of diffusion MRI models in white matter. PLoS ONE 10(4): e0123272. doi:10.1371/journal.pone.0123272 .. [2] Ariel Rokem, Kimberly L. Chan, Jason D. Yeatman, Franco Pestilli, Brian A. Wandell (2014). Evaluating the accuracy of diffusion models at multiple b-values with cross-validation. ISMRM 2014. """ from dipy.data import get_sphere import dipy.reconst.sfm as sfm from pynets.core.utils import load_runconfig sphere = get_sphere("repulsion724") print("Reconstructing using SFM...") hardcoded_params = load_runconfig() nthreads = hardcoded_params["omp_threads"][0] model = sfm.SparseFascicleModel(gtab, sphere=sphere, l1_ratio=0.5, alpha=0.001) sf_mod = model.fit(data, mask=np.nan_to_num(np.asarray( nib.load(B0_mask).dataobj)).astype("bool"), num_processes=nthreads, parallel_backend=BACKEND) sf_odf = sf_mod.odf(sphere) sf_odf = np.clip(sf_odf, 0, np.max(sf_odf, -1)[..., None]) return sf_odf.astype("float32"), model
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 sfm_mod_est(gtab, data, B0_mask): """ Estimate a Sparse Fascicle Model (SFM) 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 ------- sf_mod : ndarray Coefficients of the sfm reconstruction. model : obj Fitted sf model. References ---------- .. [1] Ariel Rokem, Jason D. Yeatman, Franco Pestilli, Kendrick N. Kay, Aviv Mezer, Stefan van der Walt, Brian A. Wandell (2015). Evaluating the accuracy of diffusion MRI models in white matter. PLoS ONE 10(4): e0123272. doi:10.1371/journal.pone.0123272 .. [2] Ariel Rokem, Kimberly L. Chan, Jason D. Yeatman, Franco Pestilli, Brian A. Wandell (2014). Evaluating the accuracy of diffusion models at multiple b-values with cross-validation. ISMRM 2014. """ from dipy.data import get_sphere import dipy.reconst.sfm as sfm sphere = get_sphere("repulsion724") print("Fitting SF model...") B0_mask_data = np.nan_to_num(np.asarray( nib.load(B0_mask).dataobj)).astype("bool") print("Reconstructing...") model = sfm.SparseFascicleModel(gtab, sphere=sphere, l1_ratio=0.5, alpha=0.001) sf_mod = model.fit(data, mask=B0_mask_data) sf_odf = sf_mod.odf(sphere) del B0_mask_data return sf_odf, model
def test_exponential_iso(): fdata, fbvals, fbvecs = dpd.get_fnames() data_dti = load_nifti_data(fdata) gtab_dti = grad.gradient_table(fbvals, fbvecs) data_multi, gtab_multi = dpd.dsi_deconv_voxels() for data, gtab in zip([data_dti, data_multi], [gtab_dti, gtab_multi]): sfmodel = sfm.SparseFascicleModel( gtab, isotropic=sfm.ExponentialIsotropicModel) sffit1 = sfmodel.fit(data[0, 0, 0]) sphere = dpd.get_sphere() odf = sffit1.odf(sphere) pred = sffit1.predict(gtab) npt.assert_equal(pred.shape, data[0, 0, 0].shape) npt.assert_equal(odf.shape, data[0, 0, 0].shape[:-1] + (sphere.x.shape[0], )) sffit2 = sfmodel.fit(data) sphere = dpd.get_sphere() odf = sffit2.odf(sphere) pred = sffit2.predict(gtab) npt.assert_equal(pred.shape, data.shape) npt.assert_equal(odf.shape, data.shape[:-1] + (sphere.x.shape[0], )) mask = np.zeros(data.shape[:3]) mask[2:5, 2:5, :] = 1 sffit3 = sfmodel.fit(data, mask=mask) sphere = dpd.get_sphere() odf = sffit3.odf(sphere) pred = sffit3.predict(gtab) npt.assert_equal(pred.shape, data.shape) npt.assert_equal(odf.shape, data.shape[:-1] + (sphere.x.shape[0], )) SNR = 1000 S0 = 100 mevals = np.array(([0.0015, 0.0005, 0.0005], [0.0015, 0.0005, 0.0005])) angles = [(0, 0), (60, 0)] S, sticks = sims.multi_tensor(gtab, mevals, S0, angles=angles, fractions=[50, 50], snr=SNR) sffit = sfmodel.fit(S) pred = sffit.predict() npt.assert_(xval.coeff_of_determination(pred, S) > 96)
def test_sfm_sklearnlinearsolver(): class SillySolver(opt.SKLearnLinearSolver): def fit(self, X, y): self.coef_ = np.ones(X.shape[-1]) class EvenSillierSolver(object): def fit(self, X, y): self.coef_ = np.ones(X.shape[-1]) fdata, fbvals, fbvecs = dpd.get_fnames() gtab = grad.gradient_table(fbvals, fbvecs) sfmodel = sfm.SparseFascicleModel(gtab, solver=SillySolver()) npt.assert_(isinstance(sfmodel.solver, SillySolver)) npt.assert_raises(ValueError, sfm.SparseFascicleModel, gtab, solver=EvenSillierSolver())
from dipy.reconst.csdeconv import auto_response response, ratio = auto_response(gtab, data, roi_radius=10, fa_thr=0.7) """ We initialize an SFM model object, using this response function and using the default sphere (362 vertices, symmetrically distributed on the surface of the sphere): """ from dipy.data import get_sphere sphere = get_sphere() from dipy.reconst import sfm sf_model = sfm.SparseFascicleModel(gtab, sphere=sphere, l1_ratio=0.5, alpha=0.001, response=response[0]) """ We fit this model to the data in each voxel in the white-matter mask, so that we can use these directions in tracking: """ from dipy.direction.peaks import peaks_from_model pnm = peaks_from_model(sf_model, data, sphere, relative_peak_threshold=.5, min_separation_angle=25, mask=white_matter, parallel=True )
def test_predict(): SNR = 1000 S0 = 100 _, fbvals, fbvecs = dpd.get_fnames('small_64D') bvals, bvecs = read_bvals_bvecs(fbvals, fbvecs) gtab = grad.gradient_table(bvals, bvecs) mevals = np.array(([0.0015, 0.0003, 0.0003], [0.0015, 0.0003, 0.0003])) angles = [(0, 0), (60, 0)] S, sticks = sims.multi_tensor(gtab, mevals, S0, angles=angles, fractions=[10, 90], snr=SNR) sfmodel = sfm.SparseFascicleModel(gtab, response=[0.0015, 0.0003, 0.0003]) sffit = sfmodel.fit(S) pred = sffit.predict() npt.assert_(xval.coeff_of_determination(pred, S) > 97) # Should be possible to predict using a different gtab: new_gtab = grad.gradient_table(bvals[::2], bvecs[::2]) new_pred = sffit.predict(new_gtab) npt.assert_(xval.coeff_of_determination(new_pred, S[::2]) > 97) # Should be possible to predict for a single direction: with warnings.catch_warnings(): warnings.simplefilter("ignore", category=UserWarning) new_gtab = grad.gradient_table(bvals[1][None], bvecs[1][None, :]) new_pred = sffit.predict(new_gtab) # Fitting and predicting with a volume of data: fdata, fbval, fbvec = dpd.get_fnames('small_25') gtab = grad.gradient_table(fbval, fbvec) data = load_nifti_data(fdata) sfmodel = sfm.SparseFascicleModel(gtab, response=[0.0015, 0.0003, 0.0003]) sffit = sfmodel.fit(data) pred = sffit.predict() # Should be possible to predict using a different gtab: new_gtab = grad.gradient_table(bvals[::2], bvecs[::2]) new_pred = sffit.predict(new_gtab) npt.assert_equal( new_pred.shape, data.shape[:-1] + bvals[::2].shape, ) # Should be possible to predict for a single direction: with warnings.catch_warnings(): warnings.simplefilter("ignore", category=UserWarning) new_gtab = grad.gradient_table(bvals[1][None], bvecs[1][None, :]) new_pred = sffit.predict(new_gtab) npt.assert_equal(new_pred.shape, data.shape[:-1]) # Fitting and predicting with masked data: mask = np.zeros(data.shape[:3]) mask[2:5, 2:5, :] = 1 sffit = sfmodel.fit(data, mask=mask) pred = sffit.predict() npt.assert_equal(pred.shape, data.shape) # Should be possible to predict using a different gtab: new_gtab = grad.gradient_table(bvals[::2], bvecs[::2]) new_pred = sffit.predict(new_gtab) npt.assert_equal( new_pred.shape, data.shape[:-1] + bvals[::2].shape, ) npt.assert_equal(new_pred[0, 0, 0], 0) # Should be possible to predict for a single direction: with warnings.catch_warnings(): warnings.simplefilter("ignore", category=UserWarning) new_gtab = grad.gradient_table(bvals[1][None], bvecs[1][None, :]) new_pred = sffit.predict(new_gtab) npt.assert_equal(new_pred.shape, data.shape[:-1]) npt.assert_equal(new_pred[0, 0, 0], 0)
# Load the data: img = nib.load(op.join('/input', str(fdata))) gtab = grad.gradient_table(op.join('/input', str(fbval)), op.join('/input', str(fbvec))) data = img.get_data() affine = img.get_affine() # Get the optional mask param: fmask = metadata.get('fmask', None) if fmask is None: mask = None else: mask = nib.load(op.join('/input', fmask)).get_data().astype(bool) # Fit the model: sfmodel = sfm.SparseFascicleModel(gtab) sffit = sfmodel.fit(data, mask=mask) # The output will all have the same basic name as the data file-name: root = op.join("/output", op.splitext(op.splitext(op.split(fdata)[-1])[0])[0]) # Save to files: dpsave(nib.Nifti1Image(sffit.beta, affine), root + '_SFM_params.nii.gz') sf_fa = calc_fa(sffit.beta, sffit.iso) dpsave(nib.Nifti1Image(sf_fa, affine), root + '_SFM_FA.nii.gz') sphere = dpd.get_sphere() sf_di = calc_di(sffit.beta, sphere, mask=mask) dpsave(nib.Nifti1Image(sf_di, affine), root + '_SFM_DI.nii.gz')
f_acc = np.zeros((len(par_vec), 2)) Mose_CM_matrix = np.zeros((6, 6, len(par_vec))) img_mos_mf = np.zeros((sx, sy, sz)) img_mos_mf_matrix = np.zeros((sx, sy, sz, len(par_vec))) sphere = dpd.get_sphere() for i_par in tqdm(range(len(par_vec)), ascii=True): par = par_vec[i_par] sf_model = sfm.SparseFascicleModel(gtab_test, sphere=sphere, l1_ratio=0.5, alpha=par, response=response[0]) '''sf_fit = sf_model.fit( hardi_d_img_test_np, mask ) sf_odf = sf_fit.odf(sphere)''' sf_peaks = dpp.peaks_from_model(sf_model, hardi_d_img_test_np, sphere, relative_peak_threshold=0.5, min_separation_angle=30, return_sh=False) peak_vals = sf_peaks.peak_values peak_dirs = sf_peaks.peak_dirs
for k in range(pmf.shape[2]): if fodf_pred_sum[i, j, k] > 0: pmf[i, j, k, :] /= fodf_pred_sum[i, j, k] pmf_dipy = pmf.copy() print('Finished estimating FODF with DIPY, time elapsed (minutes): ' + str(int((time.time() - t1) / 60))) del fodf_dipy, pmf print('Estimating FODF with sfm') t1 = time.time() sf_model = sfm.SparseFascicleModel(gtab_0_1000, sphere=sphere_fod, l1_ratio=0.5, alpha=0.001, response=response_0_1000[0]) sf_fit = sf_model.fit(d_img_0_1000, mask=mask) # mask odf_sfm = sf_fit.odf(sphere_fod) if save_fodf: h5f = h5py.File(dav_dir + 'odf_sfm.h5', 'w') h5f['odf_sfm'] = odf_sfm h5f.close() ''' h5f = h5py.File( dav_dir + 'odf_sfm.h5', 'r') odf_sfm = h5f['odf_sfm'][:] h5f.close()
def sfm_tracking(name=None, data_path=None, output_path='.', Threshold=.20, data_list=None, return_streamlines=False, save_track=True, seed='.', minus_ROI_mask='.', one_node=False, two_node=False): 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'] 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) 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) sphere = get_sphere() sf_model = sfm.SparseFascicleModel(gtab, sphere=sphere, l1_ratio=0.5, alpha=0.001, response=response[0]) pnm = peaks_from_model(sf_model, data, sphere, relative_peak_threshold=.5, min_separation_angle=25, mask=white_matter, parallel=True) stopping_criterion = ThresholdStoppingCriterion(pnm.gfa, Threshold) #seeds = utils.seeds_from_mask(white_matter, affine, density=1) print('begin tracking, time:', time.time() - time0) streamline_generator = LocalTracking(pnm, stopping_criterion, seeds, affine, step_size=.5) streamlines = Streamlines(streamline_generator) print('begin saving, time:', time.time() - time0) from dipy.io.stateful_tractogram import Space, StatefulTractogram from dipy.io.streamline import save_trk if save_track: 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) if type(minus_ROI_mask) != str: streamlines = minus_ROI(streamlines=streamlines, ROI=minus_ROI_mask) sft = StatefulTractogram(streamlines, img, Space.VOX) sft._vox_to_rasmm() output = output_path + '/tractogram_sfm_' + name + '.trk' save_trk(sft, output, streamlines) if return_streamlines: return streamlines