neurodata/ndmg

View on GitHub
examples/inside_run_ndmg.ipynb

Summary

Maintainability
Test Coverage
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Under the hood of run_ndmg()\n",
    "\n",
    "Let's take a closer look at how the `run_ndmg()` method operates under the hood. `run_ndmg()`",
    " is our suggested one-click pipeline for reliable connectome estimation from diffusion and structural MRI data.",
    " This pipeline makes use of internally exposed modules, and they can be strung together differently if the",
    " user wishes to vary their processing technique while performing exploratory analysis. Let's dive in!\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We start with importing the things we're going to need:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from argparse import ArgumentParser\n",
    "from datetime import datetime\n",
    "from subprocess import Popen, PIPE\n",
    "import os.path as op\n",
    "import ndmg.utils as mgu\n",
    "import ndmg.register as mgr\n",
    "import ndmg.track as mgt\n",
    "import ndmg.graph as mgg\n",
    "import numpy as np\n",
    "import nibabel as nb\n",
    "\n",
    "from dipy.reconst.dti import TensorModel, fractional_anisotropy, quantize_evecs\n",
    "from dipy.reconst.csdeconv import (ConstrainedSphericalDeconvModel,\n",
    "                                   auto_response)\n",
    "from dipy.direction import peaks_from_model\n",
    "from dipy.tracking.eudx import EuDX\n",
    "from dipy.data import get_sphere, get_data\n",
    "from dipy.core.gradients import gradient_table"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As you know, the `run_ndmg` function is called as follows:\n",
    "\n",
    "    run_ndmg(dwi, bvals, bvecs, mprage, atlas, mask, labels, outdir)\n",
    "    \n",
    "Therefore, we should define some input parameters in our workspace.\n",
    "Let's pretend the files are the same as in the first example."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "dwi = './KKI2009_113_1_DTI.nii'\n",
    "bvals = './KKI2009_113_1_DTI.bval'\n",
    "bvecs = './KKI2009_113_1_DTI.bvec'\n",
    "mprage = './KKI2009_113_1_MPRAGE.nii'\n",
    "atlas = './MNI152_T1_1mm.nii.gz'\n",
    "mask = './MNI152_T1_1mm_brain_mask.nii.gz'\n",
    "labels = ['./desikan.nii.gz']\n",
    "outdir = '.'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, instead of calling the function we're going to go through it step by step...\n",
    "\n",
    "... Up first, preparing output filenames!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "This pipeline will produce the following derivatives...\n",
      "DTI volume resitered to atlas: ./reg_dwi/KKI2009_113_1_DTI_aligned.nii.gz\n",
      "Diffusion tensors in atlas space: ./tensors/KKI2009_113_1_DTI_tensors.npz\n",
      "Fiber streamlines in atlas space: ./fibers/KKI2009_113_1_DTI_fibers.npz\n",
      "Graphs of streamlines downsampled to given labels: ./graphs/desikan/KKI2009_113_1_DTI_desikan.graphml\n"
     ]
    }
   ],
   "source": [
    "# Create derivative output directories\n",
    "dwi_name = op.splitext(op.splitext(op.basename(dwi))[0])[0]\n",
    "cmd = \"mkdir -p \" + outdir + \"/reg_dwi \" + outdir + \"/tensors \" +\\\n",
    "       outdir + \"/fibers \" + outdir + \"/graphs\"\n",
    "p = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True)\n",
    "p.communicate()\n",
    "\n",
    "# Graphs are different because of potential for multiple parcellations\n",
    "label_name = [op.splitext(op.splitext(op.basename(x))[0])[0]\n",
    "              for x in labels]\n",
    "for label in label_name:\n",
    "    p = Popen(\"mkdir -p \" + outdir + \"/graphs/\" + label,\n",
    "              stdout=PIPE, stderr=PIPE, shell=True)\n",
    "\n",
    "# Create derivative output file names\n",
    "aligned_dwi = outdir + \"/reg_dwi/\" + dwi_name + \"_aligned.nii.gz\"\n",
    "tensors = outdir + \"/tensors/\" + dwi_name + \"_tensors.npz\"\n",
    "fibers = outdir + \"/fibers/\" + dwi_name + \"_fibers.npz\"\n",
    "print \"This pipeline will produce the following derivatives...\"\n",
    "print \"DTI volume resitered to atlas: \" + aligned_dwi\n",
    "print \"Diffusion tensors in atlas space: \" + tensors\n",
    "print \"Fiber streamlines in atlas space: \" + fibers\n",
    "\n",
    "# Again, graphs are different\n",
    "graphs = [outdir + \"/graphs/\" + x + '/' + dwi_name + \"_\" + x + \".graphml\"\n",
    "          for x in label_name]\n",
    "print \"Graphs of streamlines downsampled to given labels: \" +\\\n",
    "      (\", \".join([x for x in graphs]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Great. Now we have some input files defined and stored, and we know where we'll dump outputs.\n",
    "I'd say we're about ready to start the real stuff!\n",
    "\n",
    "Let's start by making a gradient table. The gradient table combines the b-values and b-vectors, \n",
    "and is used when computing tensors on the diffusion data - a necessary step before making our\n",
    "connectome.\n",
    "\n",
    "Also, some DTI volumes contain an \"extra\" scan at the end so here we toss that out."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Generating gradient table...\n",
      "B-values shape (33,)\n",
      "         min 0.000000 \n",
      "         max 700.000000 \n",
      "B-vectors shape (33, 3)\n",
      "         min -0.996763 \n",
      "         max 1.000000 \n",
      "None\n"
     ]
    }
   ],
   "source": [
    "print \"Generating gradient table...\"\n",
    "dwi1 = outdir + \"/\" + dwi_name + \"_t1.nii.gz\"\n",
    "gtab = mgu.load_bval_bvec(bvals, bvecs, dwi, dwi1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Great! Now we need to align our data. There's no point in doing analysis if you can't compare your\n",
    "results to anything. How we solve this, is by aligning all of our images to a defined and commonly\n",
    "used atlas, the MNI152 template, and perform all of our analysis in these coordinates.\n",
    "\n",
    "Before that alignment we'll do some basic denoising of our dwi image stack. If you don't know, DTI\n",
    "images are collections of 3D volumes, so essentially this step is aligning many (> 30, or even\n",
    "\\> 100 on high quality data sets) 3D images together. For this reason, this is by far the longest\n",
    "step in the pipeline and takes often around 20-30 minutes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Executing: eddy_correct ./KKI2009_113_1_DTI_t1.nii.gz ./KKI2009_113_1_DTI_t2.nii.gz [32]\n"
     ]
    }
   ],
   "source": [
    "# We create some temp files we'll need to use along this process\n",
    "dwi_name = op.splitext(op.splitext(op.basename(dwi))[0])[0]\n",
    "mprage_name = op.splitext(op.splitext(op.basename(mprage))[0])[0]\n",
    "atlas_name = op.splitext(op.splitext(op.basename(atlas))[0])[0]\n",
    "\n",
    "dwi2 = outdir + \"/\" + dwi_name + \"_t2.nii.gz\"\n",
    "b0 = outdir + \"/\" + dwi_name + \"_b0.nii.gz\"\n",
    "xfm1 = outdir + \"/\" + dwi_name + \"_\" + mprage_name + \"_xfm.mat\"\n",
    "xfm2 = outdir + \"/\" + mprage_name + \"_\" + atlas_name + \"_xfm.mat\"\n",
    "xfm3 = outdir + \"/\" + dwi_name + \"_\" + atlas_name + \"_xfm.mat\"\n",
    "\n",
    "# Align DTI volumes to each other\n",
    "mgr().align_slices(dwi1, dwi2, np.where(gtab.b0s_mask)[0])\n",
    "\n",
    "# Loads DTI image in as data and extracts B0 volume\n",
    "dwi_im = nb.load(dwi2)\n",
    "b0_im = mgu.get_b0(gtab, dwi_im.get_data())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "That took a while, but looks like it went off without a hitch!\n",
    "\n",
    "Now let's take the most-structural-looking scan from out DTI volume (termed B0) and align it to our\n",
    "structural data, and eventually our atlas. We're getting there!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Executing: flirt -in ./KKI2009_113_1_DTI_b0.nii.gz -ref ./KKI2009_113_1_MPRAGE.nii -omat ./KKI2009_113_1_DTI_KKI2009_113_1_MPRAGE_xfm.mat -cost mutualinfo -bins 256 -dof 12 -searchrx -180 180 -searchry -180 180 -searchrz -180 180\n",
      "Executing: flirt -in ./KKI2009_113_1_MPRAGE.nii -ref ./MNI152_T1_1mm.nii.gz -omat ./KKI2009_113_1_MPRAGE_MNI152_T1_1mm_xfm.mat -cost mutualinfo -bins 256 -dof 12 -searchrx -180 180 -searchry -180 180 -searchrz -180 180\n"
     ]
    }
   ],
   "source": [
    "# Wraps B0 volume in new nifti image\n",
    "b0_head = dwi_im.get_header()\n",
    "b0_head.set_data_shape(b0_head.get_data_shape()[0:3])\n",
    "b0_out = nb.Nifti1Image(b0_im, affine=dwi_im.get_affine(),\n",
    "                        header=b0_head)\n",
    "b0_out.update_header()\n",
    "nb.save(b0_out, b0)\n",
    "\n",
    "# Algins B0 volume to MPRAGE, and MPRAGE to Atlas\n",
    "mgr().align(b0, mprage, xfm1)\n",
    "mgr().align(mprage, atlas, xfm2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now that wasn't nearly as painful. Even got two print statements to keep us company! So we have aligned\n",
    "the B0 volume to our structural scan, and the structural scan to our atlas... But our image still isn't\n",
    "in atlas space, right?\n",
    "\n",
    "Right! We will combine those transforms in sequence, and then apply the registration to our DTI images."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Executing: flirt -in ./KKI2009_113_1_DTI_t2.nii.gz -ref ./MNI152_T1_1mm.nii.gz -out ./reg_dwi/KKI2009_113_1_DTI_aligned.nii.gz -init ./KKI2009_113_1_DTI_MNI152_T1_1mm_xfm.mat -interp trilinear -applyxfm\n"
     ]
    }
   ],
   "source": [
    "# Combines transforms from previous registrations in proper order\n",
    "cmd = \"convert_xfm -omat \" + xfm3 + \" -concat \" + xfm2 + \" \" + xfm1\n",
    "p = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True)\n",
    "p.communicate()\n",
    "\n",
    "# Applies combined transform to dwi image volume\n",
    "mgr().applyxfm(dwi2, atlas, xfm3, aligned_dwi)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally, we're getting somewhere! We have our DTI volume in the atlas space now, so \n",
    "let the fun diffusion processing begin.\n",
    "\n",
    "So, let's not waste any time and generate some tensors! Once we've got them let's use\n",
    "DiPy's EuDX algorithm to form fiber streamlines.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saving tensors and fibers...\n"
     ]
    }
   ],
   "source": [
    "# Loads image data\n",
    "img = nb.load(aligned_dwi)\n",
    "data = img.get_data()\n",
    "\n",
    "# Loads mask and ensures it's a true binary mask\n",
    "img = nb.load(mask)\n",
    "mask = img.get_data()\n",
    "mask = mask > 0\n",
    "\n",
    "# Estimates some tensors\n",
    "model = TensorModel(gtab)\n",
    "ten = model.fit(data, mask)\n",
    "sphere = get_sphere('symmetric724')\n",
    "ind = quantize_evecs(ten.evecs, sphere.vertices)\n",
    "\n",
    "# Peforms tractography on the tensors\n",
    "eu = EuDX(a=ten.fa, ind=ind, seeds=1000000,\n",
    "          odf_vertices=sphere.vertices, a_low=0.1)\n",
    "tracks = [e for e in eu]\n",
    "\n",
    "print \"Saving tensors and fibers...\"\n",
    "np.savez(tensors, ten)\n",
    "np.savez(fibers, tracks)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Super cool, we have fibers now! We're just about finished, so let's hurry up and finish this\n",
    "so we can get out of here early.\n",
    "\n",
    "All that's left do is generate our graphs for each of our parcellations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Generating graph for desikan parcellation...\n",
      "# of Streamlines: 188956\n",
      "0\n",
      "25000\n",
      "50000\n",
      "75000\n",
      "100000\n",
      "125000\n",
      "150000\n",
      "175000\n",
      "Graph attributes: None\n",
      "Number of nodes: 70\n",
      "Node attributes: ids\n",
      "Number of edges: 1184\n",
      "Edge attributes: weight\n"
     ]
    }
   ],
   "source": [
    "# Generate graphs from streamlines for each parcellation\n",
    "for idx, label in enumerate(label_name):\n",
    "    print \"Generating graph for \" + label + \" parcellation...\"\n",
    "    labels_im = nb.load(labels[idx])\n",
    "    g = mgg(len(np.unique(labels_im.get_data()))-1, labels[idx])\n",
    "    g.make_graph(tracks)\n",
    "    g.summary()\n",
    "    g.save_graph(graphs[idx])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And voila! We're done! Congratulations, you've just successfully mapped a brain. Want to see\n",
    "the produced graph? I suppose we can let you do that..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python2.7/site-packages/matplotlib/font_manager.py:273: UserWarning: Matplotlib is building the font cache using fc-list. This may take a moment.\n",
      "  warnings.warn('Matplotlib is building the font cache using fc-list. This may take a moment.')\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10bcc0a10>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib.pylab as plt\n",
    "\n",
    "fig = plt.figure()\n",
    "ax = fig.add_subplot(1,1,1)\n",
    "ax.set_aspect('equal')\n",
    "g1 = g.get_graph()\n",
    "G1 = g1.get_adjacency(attribute='weight')\n",
    "G1 = np.asarray(G1.data)\n",
    "\n",
    "plt.imshow(G1, interpolation='nearest', cmap=plt.cm.ocean)\n",
    "plt.colorbar()\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}