""" ============================================================== Crossing invariant fiber response function with FORECAST model ============================================================== We show how to obtain a voxel specific response function in the form of axially symmetric tensor and the fODF using the FORECAST model from [Anderson2005]_ , [Kaden2016]_ and [Zucchelli2017]_. First import the necessary modules: """ import numpy as np import matplotlib.pyplot as plt from dipy.reconst.forecast import ForecastModel from dipy.viz import actor, window from dipy.data import fetch_hbn, get_sphere import nibabel as nib import os.path as op from dipy.core.gradients import gradient_table ############################################################################### # Download and read the data for this tutorial. Our implementation of FORECAST # requires multi-shell `data.fetch_hbn()` provides data that was acquired using # b-values of 1000 and 2000 as part of the Healthy Brain Network study # [Alexander2017]_ and was preprocessed and quality controlled in the HBN-POD2 # dataset [RichieHalford2022]_. data_path = fetch_hbn(["NDARAA948VFH"])[1] dwi_path = op.join( data_path, "derivatives", "qsiprep", "sub-NDARAA948VFH", "ses-HBNsiteRU", "dwi") img = nib.load(op.join( dwi_path, "sub-NDARAA948VFH_ses-HBNsiteRU_acq-64dir_space-T1w_desc-preproc_dwi.nii.gz")) gtab = gradient_table( op.join(dwi_path, "sub-NDARAA948VFH_ses-HBNsiteRU_acq-64dir_space-T1w_desc-preproc_dwi.bval"), op.join(dwi_path, "sub-NDARAA948VFH_ses-HBNsiteRU_acq-64dir_space-T1w_desc-preproc_dwi.bvec")) data = np.asarray(img.dataobj) mask_img = nib.load( op.join(dwi_path, "sub-NDARAA948VFH_ses-HBNsiteRU_acq-64dir_space-T1w_desc-brain_mask.nii.gz")) brain_mask = mask_img.get_fdata() ############################################################################### # Let us consider only a single slice for the FORECAST fitting data_small = data[:, :, 50:51] mask_small = brain_mask[:, :, 50:51] ############################################################################### # Instantiate the FORECAST Model. # # "sh_order" is the spherical harmonics order used for the fODF. # # dec_alg is the spherical deconvolution algorithm used for the FORECAST basis # fitting, in this case we used the Constrained Spherical Deconvolution (CSD) # algorithm. fm = ForecastModel(gtab, sh_order=6, dec_alg='CSD') ############################################################################### # Fit the FORECAST to the data f_fit = fm.fit(data_small, mask_small) ############################################################################### # Calculate the crossing invariant tensor indices [Kaden2016]_ : the parallel # diffusivity, the perpendicular diffusivity, the fractional anisotropy and the # mean diffusivity. d_par = f_fit.dpar d_perp = f_fit.dperp fa = f_fit.fractional_anisotropy() md = f_fit.mean_diffusivity() ############################################################################### # Show the indices and save them in FORECAST_indices.png. fig = plt.figure(figsize=(6, 6)) ax1 = fig.add_subplot(2, 2, 1, title='parallel diffusivity') ax1.set_axis_off() ind = ax1.imshow(d_par[:, :, 0].T, interpolation='nearest', origin='lower', cmap=plt.cm.gray) plt.colorbar(ind, shrink=0.6) ax2 = fig.add_subplot(2, 2, 2, title='perpendicular diffusivity') ax2.set_axis_off() ind = ax2.imshow(d_perp[:, :, 0].T, interpolation='nearest', origin='lower', cmap=plt.cm.gray) plt.colorbar(ind, shrink=0.6) ax3 = fig.add_subplot(2, 2, 3, title='fractional anisotropy') ax3.set_axis_off() ind = ax3.imshow(fa[:, :, 0].T, interpolation='nearest', origin='lower', cmap=plt.cm.gray) plt.colorbar(ind, shrink=0.6) ax4 = fig.add_subplot(2, 2, 4, title='mean diffusivity') ax4.set_axis_off() ind = ax4.imshow(md[:, :, 0].T, interpolation='nearest', origin='lower', cmap=plt.cm.gray) plt.colorbar(ind, shrink=0.6) plt.savefig('FORECAST_indices.png', dpi=300, bbox_inches='tight') ############################################################################### # .. figure:: FORECAST_indices.png # :align: center # # **FORECAST scalar indices**. # ############################################################################### # Load an ODF reconstruction sphere sphere = get_sphere('repulsion724') ############################################################################### # Compute the fODFs. odf = f_fit.odf(sphere) print('fODF.shape (%d, %d, %d, %d)' % odf.shape) ############################################################################### # Display a part of the fODFs odf_actor = actor.odf_slicer(odf[30:60, 30:60, :], sphere=sphere, colormap='plasma', scale=0.6) scene = window.Scene() scene.add(odf_actor) window.record(scene, out_path='fODFs.png', size=(600, 600), magnification=4) ############################################################################### # .. figure:: fODFs.png # :align: center # # **Fiber Orientation Distribution Functions, in a small ROI of the brain**. # # References # ---------- # # .. [Anderson2005] Anderson A. W., "Measurement of Fiber Orientation # Distributions Using High Angular Resolution Diffusion Imaging", Magnetic # Resonance in Medicine, 2005. # # .. [Kaden2016] Kaden E. et al., "Quantitative Mapping of the Per-Axon Diffusion # Coefficients in Brain White Matter", Magnetic Resonance in Medicine, # 2016. # # .. [Zucchelli2017] Zucchelli E. et al., "A generalized SMT-based framework for # Diffusion MRI microstructural model estimation", MICCAI Workshop on # Computational DIFFUSION MRI (CDMRI), 2017. # # .. [Alexander2017] Alexander LM, Escalera J, Ai L, et al. An open resource for # transdiagnostic research in pediatric mental health and learning # disorders. Sci Data. 2017;4:170181. # # .. [RichieHalford2022] Richie-Halford A, Cieslak M, Ai L, et al. An # analysis-ready and quality controlled resource for pediatric brain # white-matter research. Scientific Data. 2022;9(1):1-27. # # # .. include:: ../links_names.inc #