{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Intrinsic currents spiking\n\nThis example illustrates a neuron receiving spiking input through\nseveral different receptors (AMPA, NMDA, GABA_A, GABA_B), provoking\nspike output. The model, ``ht_neuron``, also has intrinsic currents\n(``I_NaP``, ``I_KNa``, ``I_T``, and ``I_h``). It is a slightly simplified implementation of\nneuron model proposed in [1]_.\n\nThe neuron is bombarded with spike trains from four Poisson generators,\nwhich are connected to the AMPA, NMDA, GABA_A, and GABA_B receptors,\nrespectively.\n\n## References\n\n.. [1] Hill and Tononi (2005) Modeling sleep and wakefulness in the\n       thalamocortical system. J Neurophysiol 93:1671\n       http://dx.doi.org/10.1152/jn.00915.2004.\n\n## See Also\n\n:doc:`intrinsic_currents_subthreshold`\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We imported all necessary modules for simulation, analysis and plotting.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import nest\nimport matplotlib.pyplot as plt"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Additionally, we set the verbosity using ``set_verbosity`` to suppress info\nmessages. We also reset the kernel to be sure to start with a clean NEST.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "nest.set_verbosity(\"M_WARNING\")\nnest.ResetKernel()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We define the simulation parameters:\n\n- The rate of the input spike trains\n- The weights of the different receptors (names must match receptor types)\n- The time to simulate\n\nNote that all parameter values should be doubles, since NEST expects doubles.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "rate_in = 100.\nw_recep = {'AMPA': 30., 'NMDA': 30., 'GABA_A': 5., 'GABA_B': 10.}\nt_sim = 250.\n\nnum_recep = len(w_recep)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We create\n\n- one neuron instance\n- one Poisson generator instance for each synapse type\n- one multimeter to record from the neuron:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "#   - membrane potential\n#   - threshold potential\n#   - synaptic conductances\n#   - intrinsic currents\n#\n# See :doc:`intrinsic_currents_subthreshold` for more details on ``multimeter``\n# configuration.\n\nnrn = nest.Create('ht_neuron')\np_gens = nest.Create('poisson_generator', 4, params={'rate': rate_in})\nmm = nest.Create('multimeter',\n                 params={'interval': 0.1,\n                         'record_from': ['V_m', 'theta',\n                                         'g_AMPA', 'g_NMDA',\n                                         'g_GABA_A', 'g_GABA_B',\n                                         'I_NaP', 'I_KNa', 'I_T', 'I_h']})"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We now connect each Poisson generator with the neuron through a different\nreceptor type.\n\nFirst, we need to obtain the numerical codes for the receptor types from\nthe model. The ``receptor_types`` entry of the default dictionary for the\n``ht_neuron`` model is a dictionary mapping receptor names to codes.\n\nIn the loop, we use Python's tuple unpacking mechanism to unpack\ndictionary entries from our `w_recep` dictionary.\n\nNote that we need to pack the `pg` variable into a list before\npassing it to ``Connect``, because iterating over the `p_gens` list\nmakes `pg` a \"naked\" node ID.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "receptors = nest.GetDefaults('ht_neuron')['receptor_types']\nfor index, (rec_name, rec_wgt) in enumerate(w_recep.items()):\n    nest.Connect(p_gens[index], nrn, syn_spec={'receptor_type': receptors[rec_name], 'weight': rec_wgt})"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We then connect the ``multimeter``. Note that the multimeter is connected to\nthe neuron, not the other way around.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "nest.Connect(mm, nrn)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We are now ready to simulate.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "nest.Simulate(t_sim)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We now fetch the data recorded by the multimeter. The data are returned as\na dictionary with entry ``times`` containing timestamps for all\nrecorded data, plus one entry per recorded quantity.\nAll data is contained in the ``events`` entry of the status dictionary\nreturned by the multimeter.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "data = mm.events\nt = data['times']"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The following function turns a name such as ``I_NaP`` into proper TeX code\n$I_{\\mathrm{NaP}}$ for a pretty label.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "def texify_name(name):\n    return r'${}_{{\\mathrm{{{}}}}}$'.format(*name.split('_'))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The next step is to plot the results. We create a new figure, and add one\nsubplot each for membrane and threshold potential, synaptic conductances,\nand intrinsic currents.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "fig = plt.figure()\n\nVax = fig.add_subplot(311)\nVax.plot(t, data['V_m'], 'b', lw=2, label=r'$V_m$')\nVax.plot(t, data['theta'], 'g', lw=2, label=r'$\\Theta$')\nVax.set_ylabel('Potential [mV]')\n\ntry:\n    Vax.legend(fontsize='small')\nexcept TypeError:\n    Vax.legend()  # work-around for older Matplotlib versions\nVax.set_title('ht_neuron driven by Poisson processes')\n\nGax = fig.add_subplot(312)\nfor gname in ('g_AMPA', 'g_NMDA', 'g_GABA_A', 'g_GABA_B'):\n    Gax.plot(t, data[gname], lw=2, label=texify_name(gname))\n\ntry:\n    Gax.legend(fontsize='small')\nexcept TypeError:\n    Gax.legend()  # work-around for older Matplotlib versions\nGax.set_ylabel('Conductance [nS]')\n\nIax = fig.add_subplot(313)\nfor iname, color in (('I_h', 'maroon'), ('I_T', 'orange'),\n                     ('I_NaP', 'crimson'), ('I_KNa', 'aqua')):\n    Iax.plot(t, data[iname], color=color, lw=2, label=texify_name(iname))\n\ntry:\n    Iax.legend(fontsize='small')\nexcept TypeError:\n    Iax.legend()  # work-around for older Matplotlib versions\nIax.set_ylabel('Current [pA]')\nIax.set_xlabel('Time [ms]')"
      ]
    }
  ],
  "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.8.6"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}