{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Comparing precise and grid-based neuron models\n\nIn traditional time-driven simulations, spikes are constrained to the\ntime grid at a user-defined resolution. The precise spiking models\novercome this by handling spikes in continuous time [1]_ and [2]_.\n\nThe precise spiking neuron models in NEST include: ``iaf_psc_exp_ps``,\n``iaf_psc_alpha_ps`` and ``iaf_psc_delta_ps``.\nMore detailed information about the precise spiking models can be\nfound here:\nhttps://www.nest-simulator.org/simulations-with-precise-spike-times/\n\nThis example compares the conventional grid-constrained model and the\nprecise version for an integrate-and-fire neuron model with exponential\npost-synaptic currents [2]_.\n\n## References\n\n.. [1] Morrison A, Straube S, Plesser HE, Diesmann M. 2007. Exact subthreshold\n       integration with continuous spike times in discrete-time neural network\n       simulations. Neural Computation. 19(1):47-79.\n       https://doi.org/10.1162/neco.2007.19.1.47\n\n.. [2] Hanuschkin A, Kunkel S, Helias M, Morrison A and Diesmann M. 2010. A\n       general and efficient method for incorporating precise spike times in\n       globally time-driven simulations. Froniers in Neuroinformatics. 4:113.\n       https://doi.org/10.3389/fninf.2010.00113\n\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "First, we import all necessary modules for simulation, analysis, and\nplotting.\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, we assign the simulation parameters to variables.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "simtime = 100.0           # ms\nstim_current = 700.0           # pA\nresolutions = [0.1, 0.5, 1.0]  # ms"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Now, we simulate the two versions of the neuron models (i.e. discrete-time:\n``iaf_psc_exp``; precise: ``iaf_psc_exp_ps``) for each of the defined\nresolutions. The neurons use their default parameters and we stimulate them\nby injecting a current using a ``dc_generator`` device. The membrane\npotential is recorded by a ``voltmeter``, the spikes are recorded by\na ``spike_recorder``.  The data is stored in a dictionary for later\nuse.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "data = {}\n\nfor h in resolutions:\n    data[h] = {}\n    for model in [\"iaf_psc_exp\", \"iaf_psc_exp_ps\"]:\n        nest.ResetKernel()\n        nest.SetKernelStatus({'resolution': h})\n\n        neuron = nest.Create(model)\n        voltmeter = nest.Create(\"voltmeter\", params={\"interval\": h})\n        dc = nest.Create(\"dc_generator\", params={\"amplitude\": stim_current})\n        sr = nest.Create(\"spike_recorder\")\n\n        nest.Connect(voltmeter, neuron)\n        nest.Connect(dc, neuron)\n        nest.Connect(neuron, sr)\n\n        nest.Simulate(simtime)\n\n        vm_status = voltmeter.events\n        sr_status = sr.events\n        data[h][model] = {\"vm_times\": vm_status['times'],\n                          \"vm_values\": vm_status['V_m'],\n                          \"spikes\": sr_status['times'],\n                          \"V_th\": neuron.V_th}"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "After simulation, we plot the results from the simulation. The figure\nillustrates the membrane potential excursion of the two models due to\ninjected current simulated for 100 ms for a different timestep in each panel.\nThe blue line is the voltage trace of the discrete-time neuron, the red line\nis that of the precise spiking version of the same model.\n\nPlease note that the temporal differences between the traces in the different\npanels is caused by the different resolutions used.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "colors = [\"#3465a4\", \"#cc0000\"]\n\nfor v, h in enumerate(sorted(data)):\n    plot = plt.subplot(len(data), 1, v + 1)\n    plot.set_title(\"Resolution: {0} ms\".format(h))\n\n    for i, model in enumerate(data[h]):\n        times = data[h][model][\"vm_times\"]\n        potentials = data[h][model][\"vm_values\"]\n        spikes = data[h][model][\"spikes\"]\n        spikes_y = [data[h][model][\"V_th\"]] * len(spikes)\n\n        plot.plot(times, potentials, \"-\", c=colors[i], ms=5, lw=2, label=model)\n        plot.plot(spikes, spikes_y, \".\", c=colors[i], ms=5, lw=2)\n\n    if v == 2:\n        plot.legend(loc=4)\n    else:\n        plot.set_xticklabels('')\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.6.12"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}