{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# IAF neuron example\n\nA DC current is injected into the neuron using a current generator\ndevice. The membrane potential as well as the spiking activity are\nrecorded by corresponding devices.\n\nIt can be observed how the current charges the membrane, a spike\nis emitted, the neuron becomes absolute refractory, and finally\nstarts to recover.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "First, we import all necessary modules for simulation 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": [
        "Second the function ``build_network`` is defined to build the network and\nreturn the handles of the ``spike_recorder`` and the ``voltmeter``. The\nfunction takes the simulation resolution as argument\n\nThe function first resets the simulation kernel and sets the number of\nthreads and the simulation resolution.  The ``iaf_psc_alpha`` neuron is\ncreated and the handle is stored in the variable `neuron`. The status of\nthe neuron is changed so it receives an external current. Next a\n``voltmeter`` and a ``spike_recorder`` are created and their handles stored\nin the variables `vm` and `sr` respectively.\n\nThe voltmeter and spike recorder are then connected to the neuron. ``Connect``\ntakes the device and neuron handles as input. The voltmeter is connected to the\nneuron and the neuron to the spike recorder because the neuron sends spikes\nto the recorder and the voltmeter 'observes' the neuron.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "def build_network(dt):\n\n    nest.ResetKernel()\n    nest.local_num_threads = 1\n    nest.resolution = dt\n\n    neuron = nest.Create('iaf_psc_alpha')\n    neuron.I_e = 376.0\n\n    vm = nest.Create('voltmeter')\n    sr = nest.Create('spike_recorder')\n\n    nest.Connect(vm, neuron)\n    nest.Connect(neuron, sr)\n\n    return vm, sr"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The neuron is simulated for three different resolutions and then the\nvoltage trace is plotted\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "for dt in [0.1, 0.5, 1.0]:\n    print(f\"Running simulation with dt={dt:.2f}\")\n    vm, sr = build_network(dt)\n\n    nest.Simulate(1000.0)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The network is simulated using ``Simulate``, which takes the desired\nsimulation time in milliseconds and advances the network state by this\namount of time. During simulation, the ``spike_recorder`` counts the\nspikes of the target neuron and the total number is read out at the\nend of the simulation period.\n\nThe values of the voltage recorded by the voltmeter are read out and\nthe values for the membrane potential are stored in potential and the\ncorresponding times in the times array\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "potentials = vm.get('events', 'V_m')\n    times = vm.get('events', 'times')"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Using the matplotlib library the voltage trace is plotted over time\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "plt.plot(times, potentials, label=f\"dt={dt:.2f}\")\n    print(f\"  Number of spikes: {sr.n_events}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Finally the axis are labelled and a legend is generated\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "plt.legend(loc=3)\n    plt.xlabel(\"time (ms)\")\n    plt.ylabel(\"V_m (mV)\")\n\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.8.6"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}