{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Example of multimeter recording to file\n\nThis file demonstrates recording from an ``iaf_cond_alpha`` neuron using a\nmultimeter and writing data to file.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "First, we import the necessary modules to simulate and plot this example.\nThe simulation kernel is put back to its initial state using ``ResetKernel``.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import nest\nimport numpy\nimport matplotlib.pyplot as plt\n\nnest.ResetKernel()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Global properties of the simulation kernel can be set via attributes\nof the nest module. The following properties are related to writing to file:\n\n* ``overwrite_files`` can be set True to permit overwriting of existing files.\n* ``data_path`` is the path to which all data is written. It is given relative\n  to  the current working directory.\n* ``data_prefix`` allows to specify a common prefix for all data files.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "nest.overwrite_files = True\nnest.data_path = \"\"\nnest.data_prefix = \"\""
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "For illustration, the recordables of the ``iaf_cond_alpha`` neuron model are\ndisplayed. This model is an implementation of a spiking neuron using\nintegrate-and-fire dynamics with conductance-based synapses. Incoming spike\nevents induce a postsynaptic change of conductance modeled by an alpha\nfunction.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "print(\"iaf_cond_alpha recordables: {0}\".format(\n      nest.GetDefaults(\"iaf_cond_alpha\")[\"recordables\"]))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "A neuron, a multimeter as recording device, and two spike generators for\nexcitatory and inhibitory stimulation are instantiated. The command ``Create``\nexpects a model type and, optionally, the desired number of nodes and a\ndictionary of parameters to overwrite the default values of the model.\n\n * For the neuron, the rise time of the excitatory synaptic alpha function\n   (`tau_syn_ex`, in ms) and the reset potential of the membrane\n   (`V_reset`, in mV) are specified.\n * For the ``multimeter``, the time interval for recording (`interval`, in\n   ms) and the measures to record (membrane potential `V_m` in mV and\n   excitatory and inhibitory synaptic conductances `g_ex` and`g_in` in nS)\n   are set.\n\n In addition, more parameters can be modified for writing to file:\n\n - `record_to` indicates where to put recorded data. All possible values are\n   available by inspecting the keys of the dictionary obtained from the\n   kernel attribute ``recording_backends``.\n - `label` specifies an arbitrary label for the device. If writing to files,\n   it used in the file name instead of the model name.\n\n * For the spike generators, the spike times in ms (`spike_times`) are given\n   explicitly.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "n = nest.Create(\"iaf_cond_alpha\",\n                params={\"tau_syn_ex\": 1.0, \"V_reset\": -70.0})\n\nm = nest.Create(\"multimeter\",\n                params={\"interval\": 0.1,\n                        \"record_from\": [\"V_m\", \"g_ex\", \"g_in\"],\n                        \"record_to\": \"ascii\",\n                        \"label\": \"my_multimeter\"})\n\ns_ex = nest.Create(\"spike_generator\",\n                   params={\"spike_times\": numpy.array([10.0, 20.0, 50.0])})\ns_in = nest.Create(\"spike_generator\",\n                   params={\"spike_times\": numpy.array([15.0, 25.0, 55.0])})"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Next, we connect the spike generators to the neuron with ``Connect``. Synapse\nspecifications can be provided in a dictionary. In this example of a\nconductance-based neuron, the synaptic weight ``weight`` is given in nS.\nNote that the values are  positive for excitatory stimulation and negative\nfor inhibitor connections.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "nest.Connect(s_ex, n, syn_spec={\"weight\": 40.0})\nnest.Connect(s_in, n, syn_spec={\"weight\": -20.0})\nnest.Connect(m, n)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "A network simulation with a duration of 100 ms is started with ``Simulate``.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "nest.Simulate(100.)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "After the simulation, the recordings are obtained from the file the\nmultimeter wrote to, accessed with the `filenames` property of the\nmultimeter. After three header rows, the data is formatted in columns. The\nfirst column is the ID of the sender node. The second column is the time\nof the recording, in ms. Subsequent rows are values of properties specified\nin the `record_from` property of the multimeter.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "data = numpy.loadtxt(m.filenames[0], skiprows=3)\nsender, t, v_m, g_ex, g_in = data.T"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Finally, the time courses of the membrane voltage and the synaptic\nconductance are displayed.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "plt.clf()\n\nplt.subplot(211)\nplt.plot(t, v_m)\nplt.axis([0, 100, -75, -53])\nplt.ylabel(\"membrane potential (mV)\")\n\nplt.subplot(212)\nplt.plot(t, g_ex, t, g_in)\nplt.axis([0, 100, 0, 45])\nplt.xlabel(\"time (ms)\")\nplt.ylabel(\"synaptic conductance (nS)\")\nplt.legend((\"g_exc\", \"g_inh\"))\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
}