{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n# Fast Streamline Search\n\nThis example explains how Fast Streamline Search [StOnge2022]_\ncan be used to find all similar streamlines.\n\nFirst import the necessary modules.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import numpy as np\n\nfrom dipy.data import (get_target_tractogram_hcp, get_two_hcp842_bundles,\n fetch_bundle_atlas_hcp842, fetch_target_tractogram_hcp)\nfrom dipy.io.streamline import load_trk\nfrom dipy.segment.fss import FastStreamlineSearch, nearest_from_matrix_row\nfrom dipy.viz import actor, window" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Download and read data for this tutorial\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "fetch_bundle_atlas_hcp842()\nfetch_target_tractogram_hcp()\n\nhcp_file = get_target_tractogram_hcp()\nstreamlines = load_trk(hcp_file, \"same\", bbox_valid_check=False).streamlines" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Visualize the atlas (ref) bundle and full brain tractogram\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "interactive = False\n\nscene = window.Scene()\nscene.SetBackground(1, 1, 1)\nscene.add(actor.line(streamlines))\nif interactive:\n window.show(scene)\nelse:\n window.record(scene, out_path='tractograms_initial.png', size=(600, 600))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ".. figure:: tractograms_initial.png\n :align: center\n\n Atlas bundle and source streamlines before registration.\n\n\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Read Arcuate Fasciculus Left and Corticospinal Tract Left bundles from already\nfetched atlas data to use them as model bundle. Let's visualize the\nArcuate Fasciculus Left model bundle.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "model_af_l_file, model_cst_l_file = get_two_hcp842_bundles()\nsft_af_l = load_trk(model_af_l_file, \"same\", bbox_valid_check=False)\nmodel_af_l = sft_af_l.streamlines\n\nscene = window.Scene()\nscene.SetBackground(1, 1, 1)\nscene.add(actor.line(model_af_l, colors=(0, 1, 0)))\nscene.set_camera(focal_point=(-18.17281532, -19.55606842, 6.92485857),\n position=(-360.11, -30.46, -40.44),\n view_up=(-0.03, 0.028, 0.89))\nif interactive:\n window.show(scene)\nelse:\n window.record(scene, out_path='AF_L_model_bundle.png',\n size=(600, 600))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ".. figure:: AF_L_model_bundle.png\n :align: center\n\n Model Arcuate Fasciculus Left bundle\n\n\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Search for all similar streamlines [StOnge2022]_\n\nFast Streamline Search can do a radius search\nto find all streamlines that are similar to from one tractogram to another.\nIt return the distance matrix mapping between both tractograms.\nThe same list of streamlines can be given to recover the self distance matrix.\n\n FastStreamlinesSearch Class\n - ref_streamlines : reference streamlines, that will be searched in (tree)\n - max_radius : is the maximum distance that can be used with radius search\n\n radius_search() function\n - radius : for each streamline search find all similar ones in the\n \"ref_streamlines\" that are within the given radius\n\n Be cautious, a large radius might result in a dense distance computation,\n requiring a large amount of time and memory.\n Recommended range of the radius is from 1 to 10 mm.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "radius = 7.0\nfs_tree_af = FastStreamlineSearch(ref_streamlines=model_af_l, max_radius=radius)\ncoo_mdist_mtx = fs_tree_af.radius_search(streamlines, radius=radius)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Extract indices of streamlines with an similar ones in the reference\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "ids_s = np.unique(coo_mdist_mtx.row)\nids_ref = np.unique(coo_mdist_mtx.col)\n\nrecognized_af_l = streamlines[ids_s]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "let's visualize streamlines similar to the Arcuate Fasciculus Left bundle\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "scene = window.Scene()\nscene.SetBackground(1, 1, 1)\nscene.add(actor.line(recognized_af_l, colors=(0, 0, 1)))\nscene.set_camera(focal_point=(-18.17281532, -19.55606842, 6.92485857),\n position=(-360.11, -30.46, -40.44),\n view_up=(-0.03, 0.028, 0.89))\nif interactive:\n window.show(scene)\nelse:\n window.record(scene, out_path='AF_L_recognized_bundle.png',\n size=(600, 600))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ".. figure:: AF_L_recognized_bundle.png\n :align: center\n\n Recognized Arcuate Fasciculus Left bundle\n\n\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Color the resulting AF by the nearest streamlines distance\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "nn_s, nn_ref, nn_dist = nearest_from_matrix_row(coo_mdist_mtx)\n\nscene = window.Scene()\nscene.SetBackground(1, 1, 1)\ncmap = actor.colormap_lookup_table(scale_range=(nn_dist.min(), nn_dist.max()))\nscene.add(actor.line(recognized_af_l, colors=nn_dist, lookup_colormap=cmap))\nscene.add(actor.scalar_bar(cmap, title=\"distance to atlas (mm)\"))\nscene.set_camera(focal_point=(-18.17281532, -19.55606842, 6.92485857),\n position=(-360.11, -30.46, -40.44),\n view_up=(-0.03, 0.028, 0.89))\nif interactive:\n window.show(scene)\nelse:\n window.record(scene, out_path='AF_L_recognized_bundle_dist.png',\n size=(600, 600))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ".. figure:: AF_L_recognized_bundle_dist.png\n :align: center\n\n Recognized Arcuate Fasciculus Left bundle colored by distance to ref\n\n\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Display the streamlines reference reached in green\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Default red color\nref_color = np.zeros((len(model_af_l), 3), dtype=float)\nref_color[:] = (1.0, 0.0, 0.0)\n\n# Reached in green color\nref_color[ids_ref] = (0.0, 1.0, 0.0)\n\nscene = window.Scene()\nscene.SetBackground(1, 1, 1)\nscene.add(actor.line(model_af_l, ref_color))\nscene.set_camera(focal_point=(-18.17281532, -19.55606842, 6.92485857),\n position=(-360.11, -30.46, -40.44),\n view_up=(-0.03, 0.028, 0.89))\n\nif interactive:\n window.show(scene)\nelse:\n window.record(scene, out_path='AF_L_model_bundle_reached.png',\n size=(600, 600))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ".. figure:: AF_L_model_bundle_reached.png\n :align: center\n\n Arcuate Fasciculus Left model reached (green) in radius\n\n\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## References\n\n.. [StOnge2022] St-Onge E. et al. Fast Streamline Search:\n An Exact Technique for Diffusion MRI Tractography.\n Neuroinformatics, 2022.\n\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.13" } }, "nbformat": 4, "nbformat_minor": 0 }