{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Multi-compartment neuron example\n\nSimple example of how to use the three-compartment ``iaf_cond_alpha_mc``\nneuron model.\n\nThree stimulation paradigms are illustrated:\n\n - externally applied current, one compartment at a time\n - spikes impinging on each compartment, one at a time\n - rheobase current injected to soma causing output spikes\n\nVoltage and synaptic conductance traces are shown for all compartments.\n\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "First, we import all necessary modules to simulate, analyze and plot this\nexample.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import nest\nimport matplotlib.pyplot as plt\n\nnest.ResetKernel()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We then extract the receptor types and the list of recordable quantities\nfrom the neuron model. Receptor types and recordable quantities uniquely\ndefine the receptor type and the compartment while establishing synaptic\nconnections or assigning multimeters.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "syns = nest.GetDefaults('iaf_cond_alpha_mc')['receptor_types']\nprint(\"iaf_cond_alpha_mc receptor_types: {0}\".format(syns))\n\nrqs = nest.GetDefaults('iaf_cond_alpha_mc')['recordables']\nprint(\"iaf_cond_alpha_mc recordables   : {0}\".format(rqs))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The simulation parameters are assigned to variables.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "nest.SetDefaults('iaf_cond_alpha_mc',\n                 {'V_th': -60.0,  # threshold potential\n                  'V_reset': -65.0,  # reset potential\n                  't_ref': 10.0,  # refractory period\n                  'g_sp': 5.0,  # somato-proximal coupling conductance\n                  'soma': {'g_L': 12.0},  # somatic leak conductance\n                  # proximal excitatory and inhibitory synaptic time constants\n                  'proximal': {'tau_syn_ex': 1.0,\n                               'tau_syn_in': 5.0},\n                  'distal': {'C_m': 90.0}  # distal capacitance\n                  })"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The nodes are created using ``Create``. We store the returned handles\nin variables for later reference.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "n = nest.Create('iaf_cond_alpha_mc')"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "A ``multimeter`` is created and connected to the neurons. The parameters\nspecified for the multimeter include the list of quantities that should be\nrecorded and the time interval at which quantities are measured.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "mm = nest.Create('multimeter', params={'record_from': rqs, 'interval': 0.1})\nnest.Connect(mm, n)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We create one current generator per compartment and configure a stimulus\nregime that drives distal, proximal and soma dendrites, in that order.\nConfiguration of the current generator includes the definition of the start\nand stop times and the amplitude of the injected current.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "cgs = nest.Create('dc_generator', 3)\ncgs[0].set(start=250.0, stop=300.0, amplitude=50.0)  # soma\ncgs[1].set(start=150.0, stop=200.0, amplitude=-50.0)  # proxim.\ncgs[2].set(start=50.0, stop=100.0, amplitude=100.0)  # distal"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Generators are then connected to the correct compartments. Specification of\nthe ``receptor_type`` uniquely defines the target compartment and receptor.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "nest.Connect(cgs[0], n, syn_spec={'receptor_type': syns['soma_curr']})\nnest.Connect(cgs[1], n, syn_spec={'receptor_type': syns['proximal_curr']})\nnest.Connect(cgs[2], n, syn_spec={'receptor_type': syns['distal_curr']})"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We create one excitatory and one inhibitory spike generator per compartment\nand configure a regime that drives distal, proximal and soma dendrites, in\nthat order, alternating the excitatory and inhibitory spike generators.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "sgs = nest.Create('spike_generator', 6)\nsgs[0].spike_times = [600.0, 620.0]  # soma excitatory\nsgs[1].spike_times = [610.0, 630.0]  # soma inhibitory\nsgs[2].spike_times = [500.0, 520.0]  # proximal excitatory\nsgs[3].spike_times = [510.0, 530.0]  # proximal inhibitory\nsgs[4].spike_times = [400.0, 420.0]  # distal excitatory\nsgs[5].spike_times = [410.0, 430.0]  # distal inhibitory"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Connect generators to correct compartments in the same way as in case of\ncurrent generator\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "nest.Connect(sgs[0], n, syn_spec={'receptor_type': syns['soma_exc']})\nnest.Connect(sgs[1], n, syn_spec={'receptor_type': syns['soma_inh']})\nnest.Connect(sgs[2], n, syn_spec={'receptor_type': syns['proximal_exc']})\nnest.Connect(sgs[3], n, syn_spec={'receptor_type': syns['proximal_inh']})\nnest.Connect(sgs[4], n, syn_spec={'receptor_type': syns['distal_exc']})\nnest.Connect(sgs[5], n, syn_spec={'receptor_type': syns['distal_inh']})"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Run the simulation for 700 ms.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "nest.Simulate(700)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Now we set the intrinsic current of soma to 150 pA to make the neuron spike.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "n.set({'soma': {'I_e': 150.}})"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We simulate the network for another 300 ms and retrieve recorded data from\nthe multimeter\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "nest.Simulate(300)\nrec = mm.events"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We create an array with the time points when the quantities were actually\nrecorded\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "t = rec['times']"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We plot the time traces of the membrane potential and the state of each\nmembrane potential for soma, proximal, and distal dendrites (`V_m.s`, `V_m.p`\nand `V_m.d`).\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "plt.figure()\nplt.subplot(211)\nplt.plot(t, rec['V_m.s'], t, rec['V_m.p'], t, rec['V_m.d'])\nplt.legend(('Soma', 'Proximal dendrite', 'Distal dendrite'),\n           loc='lower right')\nplt.axis([0, 1000, -76, -59])\nplt.ylabel('Membrane potential [mV]')\nplt.title('Responses of iaf_cond_alpha_mc neuron')"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Finally, we plot the time traces of the synaptic conductance measured in\neach compartment.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "plt.subplot(212)\nplt.plot(t, rec['g_ex.s'], 'b-', t, rec['g_ex.p'], 'g-',\n         t, rec['g_ex.d'], 'r-')\nplt.plot(t, rec['g_in.s'], 'b--', t, rec['g_in.p'], 'g--',\n         t, rec['g_in.d'], 'r--')\nplt.legend(('g_ex.s', 'g_ex.p', 'g_in.d', 'g_in.s', 'g_in.p', 'g_in.d'))\nplt.axis([350, 700, 0, 1.15])\nplt.xlabel('Time [ms]')\nplt.ylabel('Synaptic conductance [nS]')\nplt.show()"
      ]
    }
  ],
  "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.6.12"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}