.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "howto/howto_examples/plot_stages_of_tractometry.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_howto_howto_examples_plot_stages_of_tractometry.py: ================================================= Making videos the different stages of tractometry ================================================= Two-dimensional figures of anatomical data are somewhat limited, because of the complex three-dimensional configuration of the brain. Therefored, dynamic videos of anatomical data are useful for exploring the data, as well as for creating dynamic presentations of the results. This example visualizes various stages of tractometry, from preprocessed diffusion data to the final tract profiles. We will use the `Fury `_ software library to visualize individual frames of the results of each stage, and then create videos of each stage of the process using the Python Image Library (PIL, also known as pillow). .. GENERATED FROM PYTHON SOURCE LINES 19-22 Imports ------- .. GENERATED FROM PYTHON SOURCE LINES 22-46 .. code-block:: Python import os import os.path as op import nibabel as nib import numpy as np import tempfile from dipy.io.streamline import load_trk from dipy.tracking.streamline import (transform_streamlines, set_number_of_points) from dipy.core.gradients import gradient_table from dipy.align import resample from fury import actor, window from fury.actor import colormap_lookup_table from fury.colormap import create_colormap from matplotlib.cm import tab20 import AFQ.data.fetch as afd from AFQ.viz.utils import gen_color_dict from PIL import Image .. GENERATED FROM PYTHON SOURCE LINES 47-59 Define a function that makes videos ----------------------------------- The PIL library has a function that can be used to create animated GIFs from a series of images. We will use this function to create videos. .. note:: This function is not part of the AFQ library, but is included here for convenience. It is not necessary to understand this function in order to understand the rest of the example. If you are interested in learning more about this function, you can read the PIL documentation. The function is based on the `PIL.Image.save `_ function. .. GENERATED FROM PYTHON SOURCE LINES 59-91 .. code-block:: Python def make_video(frames, out): """ Make a video from a series of frames. Parameters ---------- frames : list of str A list of file names of the frames to be included in the video. out : str The name of the output file. Format is determined by the file extension. """ video = [] for nn in frames: frame = Image.open(nn) video.append(frame) # Save the frames as an animated GIF video[0].save( out, save_all=True, append_images=video[1:], duration=300, loop=1) tmp = tempfile.mkdtemp() n_frames = 72 .. GENERATED FROM PYTHON SOURCE LINES 92-95 Get data from HBN POD2 ---------------------------- We get the same data that is used in the visualization tutorials. .. GENERATED FROM PYTHON SOURCE LINES 95-99 .. code-block:: Python afd.fetch_hbn_preproc(["NDARAA948VFH"]) study_path = afd.fetch_hbn_afq(["NDARAA948VFH"])[1] .. rst-class:: sphx-glr-script-out .. code-block:: none 0%| | 0/377 [00:00 0 waypoint2_data = waypoint2_xform.get_fdata() > 0 surface_color = tab20.colors[0] waypoint1_actor = actor.contour_from_roi(waypoint1_data, color=surface_color, opacity=0.5) waypoint2_actor = actor.contour_from_roi(waypoint2_data, color=surface_color, opacity=0.5) scene.add(waypoint1_actor) scene.add(waypoint2_actor) window.record(scene, out_path=f'{tmp}/whole_brain_with_waypoints', size=(2400, 2400), n_frames=n_frames, path_numbering=True) make_video([f"{tmp}/whole_brain_with_waypoints{ii:06d}.png" for ii in range(n_frames)], "whole_brain_with_waypoints.gif") bundle_path = op.join(afq_path, 'bundles') .. GENERATED FROM PYTHON SOURCE LINES 324-328 Visualize the arcuate bundle ---------------------------- Now visualize only the arcuate bundle that is selected with these waypoints. .. GENERATED FROM PYTHON SOURCE LINES 328-378 .. code-block:: Python fa_img = nib.load(op.join(afq_path, 'sub-NDARAA948VFH_ses-HBNsiteRU_acq-64dir_space-T1w_desc-preproc_dwi_model-DKI_FA.nii.gz')) fa = fa_img.get_fdata() sft_arc = load_trk(op.join(bundle_path, 'sub-NDARAA948VFH_ses-HBNsiteRU_acq-64dir_space-T1w_desc-preproc_dwi_space-RASMM_model-CSD_desc-prob-afq-ARC_L_tractography.trk'), fa_img) sft_arc.to_rasmm() arc_t1w = transform_streamlines(sft_arc.streamlines, np.linalg.inv(t1w_img.affine)) bundles = [ "ARC_R", "ATR_R", "CST_R", "IFO_R", "ILF_R", "SLF_R", "UNC_R", "CGC_R", "Orbital", "AntFrontal", "SupFrontal", "Motor", "SupParietal", "PostParietal", "Temporal", "Occipital", "CGC_L", "UNC_L", "SLF_L", "ILF_L", "IFO_L", "CST_L", "ATR_L", "ARC_L", ] color_dict = gen_color_dict(bundles) arc_actor = lines_as_tubes(arc_t1w, 8, colors=color_dict['ARC_L']) scene.clear() scene.add(arc_actor) for slicer in slicers: scene.add(slicer) scene.add(waypoint1_actor) scene.add(waypoint2_actor) window.record(scene, out_path=f'{tmp}/arc1', size=(2400, 2400), n_frames=n_frames, path_numbering=True) make_video([f"{tmp}/arc1{ii:06d}.png" for ii in range(n_frames)], "arc1.gif") .. GENERATED FROM PYTHON SOURCE LINES 379-383 Clean bundle ------------ The next step in processing would be to clean the bundle by removing streamlines that are outliers. We will visualize the cleaned bundle. .. GENERATED FROM PYTHON SOURCE LINES 383-418 .. code-block:: Python scene.clear() scene.add(arc_actor) for slicer in slicers: scene.add(slicer) window.record(scene, out_path=f'{tmp}/arc2', size=(2400, 2400), n_frames=n_frames, path_numbering=True) make_video([f"{tmp}/arc2{ii:06d}.png" for ii in range(n_frames)], "arc2.gif") clean_bundles_path = op.join(afq_path, 'clean_bundles') sft_arc = load_trk(op.join(clean_bundles_path, 'sub-NDARAA948VFH_ses-HBNsiteRU_acq-64dir_space-T1w_desc-preproc_dwi_space-RASMM_model-CSD_desc-prob-afq-ARC_L_tractography.trk'), fa_img) sft_arc.to_rasmm() arc_t1w = transform_streamlines(sft_arc.streamlines, np.linalg.inv(t1w_img.affine)) arc_actor = lines_as_tubes(arc_t1w, 8, colors=tab20.colors[18]) scene.clear() scene.add(arc_actor) for slicer in slicers: scene.add(slicer) window.record(scene, out_path=f'{tmp}/arc3', size=(2400, 2400), n_frames=n_frames, path_numbering=True) make_video([f"{tmp}/arc3{ii:06d}.png" for ii in range(n_frames)], "arc3.gif") .. GENERATED FROM PYTHON SOURCE LINES 419-425 Show the values of tissue properties along the bundle ------------------------------------------------------ We can also visualize the values of tissue properties along the bundle. Here we will visualize the fractional anisotropy (FA) along the arcuate bundle. This is done by using a colormap to color the streamlines according to the values of the tissue property, with `fury.colormap.create_colormap`. .. GENERATED FROM PYTHON SOURCE LINES 425-445 .. code-block:: Python lut_args = dict(scale_range=(0, 1), hue_range=(1, 0), saturation_range=(0, 1), value_range=(0, 1)) arc_actor = lines_as_tubes(arc_t1w, 8, colors=resample(fa_img, t1w_img).get_fdata(), lookup_colormap=colormap_lookup_table(**lut_args)) scene.clear() scene.add(arc_actor) for slicer in slicers: scene.add(slicer) window.record(scene, out_path=f'{tmp}/arc4', size=(2400, 2400), n_frames=n_frames, path_numbering=True) make_video([f"{tmp}/arc4{ii:06d}.png" for ii in range(n_frames)], "arc4.gif") .. GENERATED FROM PYTHON SOURCE LINES 446-451 Core of the bundle and tract profile ------------------------------------- Finally, we can visualize the core of the bundle and the tract profile. The core of the bundle is the median of the streamlines, and the tract profile is the values of the tissue property along the core of the bundle. .. GENERATED FROM PYTHON SOURCE LINES 451-481 .. code-block:: Python core_arc = np.median(np.asarray(set_number_of_points(arc_t1w, 20)), axis=0) from dipy.stats.analysis import afq_profile sft_arc.to_vox() arc_profile = afq_profile(fa, sft_arc.streamlines, affine=np.eye(4), n_points=20) core_arc_actor = lines_as_tubes( [core_arc], 40, colors=create_colormap(arc_profile, 'viridis') ) arc_actor = lines_as_tubes(arc_t1w, 1, colors=resample(fa_img, t1w_img).get_fdata(), lookup_colormap=colormap_lookup_table(**lut_args)) scene.clear() for slicer in slicers: scene.add(slicer) scene.add(arc_actor) scene.add(core_arc_actor) window.record(scene, out_path=f'{tmp}/arc5', size=(2400, 2400), n_frames=n_frames, path_numbering=True) make_video([f"{tmp}/arc5{ii:06d}.png" for ii in range(n_frames)], "arc5.gif") .. GENERATED FROM PYTHON SOURCE LINES 482-485 Core of all bundles and their tract profiles -------------------------------------------- Same as before, but for all bundles. .. GENERATED FROM PYTHON SOURCE LINES 485-546 .. code-block:: Python scene.clear() for slicer in slicers: scene.add(slicer) for bundle in bundles: sft = load_trk(op.join(clean_bundles_path, f'sub-NDARAA948VFH_ses-HBNsiteRU_acq-64dir_space-T1w_desc-preproc_dwi_space-RASMM_model-CSD_desc-prob-afq-{bundle}_tractography.trk'), fa_img) sft.to_rasmm() bundle_t1w = transform_streamlines(sft.streamlines, np.linalg.inv(t1w_img.affine)) bundle_actor = lines_as_tubes(bundle_t1w, 8, colors=color_dict[bundle]) scene.add(bundle_actor) window.record(scene, out_path=f'{tmp}/all_bundles', size=(2400, 2400), n_frames=n_frames, path_numbering=True) make_video( [f"{tmp}/all_bundles{ii:06d}.png" for ii in range(n_frames)], "all_bundles.gif") scene.clear() for slicer in slicers: scene.add(slicer) tract_profiles = [] for bundle in bundles: sft = load_trk(op.join(clean_bundles_path, f'sub-NDARAA948VFH_ses-HBNsiteRU_acq-64dir_space-T1w_desc-preproc_dwi_space-RASMM_model-CSD_desc-prob-afq-{bundle}_tractography.trk'), fa_img) sft.to_rasmm() bundle_t1w = transform_streamlines(sft.streamlines, np.linalg.inv(t1w_img.affine)) core_bundle = np.median(np.asarray( set_number_of_points(bundle_t1w, 20)), axis=0) sft.to_vox() tract_profiles.append( afq_profile(fa, sft.streamlines, affine=np.eye(4), n_points=20)) core_actor = lines_as_tubes( [core_bundle], 40, colors=create_colormap(tract_profiles[-1], 'viridis') ) scene.add(core_actor) window.record(scene, out_path=f'{tmp}/all_tract_profiles', size=(2400, 2400), n_frames=n_frames, path_numbering=True) make_video([f"{tmp}/all_tract_profiles{ii:06d}.png" for ii in range(n_frames)], "all_tract_profiles.gif") .. GENERATED FROM PYTHON SOURCE LINES 547-554 Tract profiles as a table ------------------------- Finally, we can visualize the tract profiles as a table. This is done by plotting the tract profiles for each bundle as a line plot, with the x-axis representing the position along the bundle, and the y-axis representing the value of the tissue property. We will use the `matplotlib` library to create this plot. .. GENERATED FROM PYTHON SOURCE LINES 554-567 .. code-block:: Python import matplotlib.pyplot as plt fig, ax = plt.subplots() for ii, bundle in enumerate(bundles): ax.plot(np.arange(ii * 20, (ii + 1) * 20), tract_profiles[ii], color=color_dict[bundle], linewidth=3) ax.set_xticks(np.arange(0, 20 * len(bundles), 20)) ax.set_xticklabels(bundles, rotation=45, ha='right') fig.set_size_inches(10, 5) plt.subplots_adjust(bottom=0.2) fig.savefig('tract_profiles_as_table.png') .. image-sg:: /howto/howto_examples/images/sphx_glr_plot_stages_of_tractometry_001.png :alt: plot stages of tractometry :srcset: /howto/howto_examples/images/sphx_glr_plot_stages_of_tractometry_001.png :class: sphx-glr-single-img .. image-sg:: /howto/howto_examples/images/sphx_glr_plot_stages_of_tractometry_002.png :alt: plot stages of tractometry :srcset: /howto/howto_examples/images/sphx_glr_plot_stages_of_tractometry_002.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (24 minutes 53.043 seconds) **Estimated memory usage:** 4131 MB .. _sphx_glr_download_howto_howto_examples_plot_stages_of_tractometry.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_stages_of_tractometry.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_stages_of_tractometry.py ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_