{ "cells": [ { "cell_type": "markdown", "id": "warming-county", "metadata": {}, "source": [ "# Diffusion Encoding Gradients Example" ] }, { "cell_type": "code", "execution_count": 1, "id": "hearing-laundry", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Building GrOpt . . .\n" ] }, { "data": { "text/html": [ " \n", " " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import os\n", "\n", "os.chdir(\"./python/\")\n", "\n", "import build_gropt\n", "build_gropt.build_gropt()\n", "import gropt\n", "\n", "from helper_utils import *\n", "from interactive_plots import plot_waveform_interactive\n", "from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot\n", "from IPython.core.display import display, HTML\n", "init_notebook_mode(connected = True)\n", "config={'showLink': False, 'displayModeBar': False}\n", "from timeit import default_timer as timer\n", "\n", "%matplotlib inline" ] }, { "cell_type": "markdown", "id": "official-gallery", "metadata": {}, "source": [ "## Constraints on:\n", "- Maximum gradient amplitude: params['gmax']\n", "- Maximum slew rate: params['smax']\n", "- Zero gradient moment = 0 (mT*ms)/m\n", "- Add objective function to maximize b-value\n", "- Add constraint to turn gradients off during excitation RF (T_90), refocusing RF (T_180), and ADC readout (T_redout)" ] }, { "cell_type": "code", "execution_count": 2, "id": "democratic-brass", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Minimum TE = 69.06 ms\n" ] }, { "data": { "text/html": [ "\n", "\n", "\n", "
\n", "
\n", "\n", "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "params = {}\n", "params['mode'] = 'diff_bval' # Objective function that maximizes b-value\n", "params['gmax'] = 50 # Maximum gradient amplitude, mT/m\n", "params['smax'] = 100 # Maximum slew rate, mT/m/ms\n", "params['MMT'] = 0 # Nulling M0\n", "params['T_readout'] = 20 # Time from start to center of readout, ms\n", "params['T_90'] = 3 # Duration of excitation RF pulse, ms\n", "params['T_180'] = 5 # Duration of refocusing RF pulse, ms\n", "params['b'] = 1000 # Diffusion b-value, s/mm^2\n", "params['dt'] = 400e-6 # Raster time of the gradient waveform being optimized\n", "\n", "# Convex Optimized Diffusion Encoding (CODE)\n", "G_min, T_min = get_min_TE(params, bval=params['b'], min_TE = 40, max_TE = 120)\n", "print('Minimum TE =', round(T_min,2), 'ms')\n", "\n", "fig = plot_waveform_interactive(-1*G_min, params, width=585, height=430)\n", "plot(fig, filename = 'fig.html', config = config)\n", "display(HTML('fig.html'))" ] }, { "cell_type": "markdown", "id": "manual-dining", "metadata": {}, "source": [ "## M0 Nulled CODE\n", "\n", "Generate a waveform with $M_0 = 0$, other parameters as listed in the code.\n", "\n", "TE was manually selected (44.4 ms) to hit b-value = 600" ] }, { "cell_type": "code", "execution_count": 3, "id": "cooked-applicant", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "
\n", "
\n", "\n", "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "params = {}\n", "# Maximize b-value for diffusion waveforms\n", "params['mode'] = 'diff_bval'\n", "\n", "# Hardware constraints\n", "params['gmax'] = 50.0 # Max Gradient Amplitude [mT/m], you can use T/m here too\n", "params['smax'] = 50.0 # Max Slewrate [mT/m/ms]\n", "\n", "# Moment nulling\n", "params['MMT'] = 0\n", "\n", "# Sequence TE and dt of output [ms]\n", "params['TE'] = 60\n", "params['dt'] = 400e-6\n", "\n", "# Time from end of diffusion waveform to TE [ms]\n", "params['T_readout'] = 16.0\n", "# Time of excitation 90 [ms]\n", "params['T_90'] = 4.0\n", "# Time for 180 flip [ms]\n", "params['T_180'] = 6.0\n", "\n", "# Run optimization\n", "G, dd = gropt.gropt(params, verbose=1)\n", "fig = plot_waveform_interactive(G, params, width=585, height=430)\n", "plot(fig, filename = 'fig.html', config = config)\n", "display(HTML('fig.html')) " ] }, { "cell_type": "markdown", "id": "compact-reservoir", "metadata": {}, "source": [ "## M0+M1 Nulled CODE\n", "\n", "Generate a waveform with $M_0 = 0$ and $M_1 = 0$, other parameters as listed in the code.\n", "\n", "TE was manually selected (82 ms) to hit b-value = 600" ] }, { "cell_type": "code", "execution_count": 4, "id": "enhanced-proportion", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "
\n", "
\n", "\n", "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "params = {}\n", "params['mode'] = 'diff_bval'\n", "params['gmax'] = 0.05\n", "params['smax'] = 50.0\n", "params['MMT'] = 1\n", "params['TE'] = 82.0\n", "params['T_readout'] = 16.0\n", "params['T_90'] = 4.0\n", "params['T_180'] = 6.0\n", "params['dt'] = 200e-6\n", "\n", "G, dd = gropt.gropt(params, verbose=1)\n", "\n", "fig = plot_waveform_interactive(G, params, width=585, height=430)\n", "plot(fig, filename = 'fig.html', config = config)\n", "display(HTML('fig.html'))" ] }, { "cell_type": "markdown", "id": "frequent-paris", "metadata": {}, "source": [ "Constraining $M_0 = M_1 = 0$ for conventional and optimized diffusion encoding methods mitigate signal losses, due to constant moving tissue" ] }, { "cell_type": "markdown", "id": "occupied-ghost", "metadata": {}, "source": [ "## M0+M1+M2 Nulled CODE\n", "\n", "Generate a waveform with $M_0 = 0$, $M_1 = 0$ and $M_2 = 0$, other parameters as listed in the code.\n", "\n", "TE was manually selected (97 ms) to hit b-value = 600" ] }, { "cell_type": "code", "execution_count": 5, "id": "egyptian-edwards", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "
\n", "
\n", "\n", "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "params = {}\n", "params['mode'] = 'diff_bval'\n", "params['gmax'] = 0.05\n", "params['smax'] = 50.0\n", "params['MMT'] = 2\n", "params['TE'] = 97.0\n", "params['T_readout'] = 16.0\n", "params['T_90'] = 4.0\n", "params['T_180'] = 6.0\n", "params['dt'] = 200e-6\n", "\n", "G, dd = gropt.gropt(params, verbose=1)\n", "\n", "fig = plot_waveform_interactive(G, params, width=585, height=430)\n", "plot(fig, filename = 'fig.html', config = config)\n", "display(HTML('fig.html'))" ] }, { "cell_type": "markdown", "id": "convenient-paris", "metadata": {}, "source": [ "Constraining $M_0 = M_1 = M_2 = 0$ for conventional and optimized diffusion encoding methods mitigate signal losses, due to constant moving **and** accelerating tissue" ] }, { "cell_type": "markdown", "id": "novel-relative", "metadata": {}, "source": [ "#### We constrain to null for a specific eddy current time constants (lambda) to null diffusion incuded eddy current" ] }, { "cell_type": "code", "execution_count": 6, "id": "adapted-binary", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Minimum TE = 88.2 ms\n" ] }, { "data": { "text/html": [ "\n", "\n", "\n", "
\n", "
\n", "\n", "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "params = {}\n", "params['mode'] = 'diff_bval'\n", "params['MMT'] = 0\n", "params['gmax'] = 50\n", "params['smax'] = 100.0\n", "params['T_readout'] = 20.0\n", "params['T_90'] = 3\n", "params['T_180'] = 5\n", "params['dt']= 400e-6\n", "bval = 1000\n", "\n", "# ************\n", "# Null eddy current for lambda time constant = 60ms\n", "# ************\n", "params['eddy_params'] = [[60.0, 0.0, 1.0e-4, 0.0]]\n", "\n", "\n", "G_min, T_min = get_min_TE(params, bval, min_TE = 80, max_TE = 120)\n", "print('Minimum TE =', round(T_min,2), 'ms')\n", "\n", "fig = plot_waveform_interactive(G_min, params, width=585, height=430)\n", "plot(fig, filename = 'fig.html', config = config)\n", "display(HTML('fig.html'))" ] }, { "cell_type": "markdown", "id": "second-rachel", "metadata": {}, "source": [ "#### We can constrain to null more than one eddy current time constants (lambda) as well" ] }, { "cell_type": "code", "execution_count": 7, "id": "bibliographic-tender", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Minimum TE = 97.81 ms\n" ] }, { "data": { "text/html": [ "\n", "\n", "\n", "
\n", "
\n", "\n", "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "params = {}\n", "params['mode'] = 'diff_bval'\n", "params['MMT'] = 0\n", "params['gmax'] = 50\n", "params['smax'] = 100.0\n", "params['T_readout'] = 20.0\n", "params['T_90'] = 3\n", "params['T_180'] = 5\n", "params['dt'] = 400e-6\n", "bval = 1000\n", "\n", "# ************\n", "# Null eddy current for lambda time constants = 5, 50, and 100ms\n", "# ************\n", "params['eddy_params'] = [[5.0, 0.0, 1.0e-4, 0.0]]\n", "params['eddy_params'].append([50.0, 0.0, 1.0e-4, 0.0])\n", "params['eddy_params'].append([100.0, 0.0, 1.0e-4, 0.0])\n", "\n", "\n", "G_min, T_min = get_min_TE(params, bval, min_TE = 80, max_TE = 120)\n", "print('Minimum TE =', round(T_min,2), 'ms')\n", "\n", "fig = plot_waveform_interactive(G_min, params, width=585, height=430)\n", "plot(fig, filename = 'fig.html', config = config)\n", "display(HTML('fig.html'))" ] } ], "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.7.6" } }, "nbformat": 4, "nbformat_minor": 5 }