{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Example for the quantal_stp_synapse\n\nThe ``quantal_stp_synapse`` is a stochastic version of the Tsodys-Markram model\nfor synaptic short term plasticity (STP).\nThis script compares the two variants of the Tsodyks/Markram synapse in NEST.\n\nThis synapse model implements synaptic short-term depression and short-term\nfacilitation according to the quantal release model described by Fuhrmann et\nal. [1]_ and Loebel et al. [2]_.\n\nEach presynaptic spike will stochastically activate a fraction of the\navailable release sites.  This fraction is binomialy distributed and the\nrelease probability per site is governed by the Fuhrmann et al. (2002) model.\nThe solution of the differential equations is taken from Maass and Markram\n2002 [3]_.\n\nThe connection weight is interpreted as the maximal weight that can be\nobtained if all n release sites are activated.\n\n## Parameters\n\nThe following parameters can be set in the status dictionary:\n\n* U         - Maximal fraction of available resources [0,1], default=0.5\n* u         - available fraction of resources [0,1], default=0.5\n* p         - probability that a vesicle is available, default = 1.0\n* n         - total number of release sites, default = 1\n* a         - number of available release sites, default = n\n* tau_rec   - time constant for depression in ms, default=800 ms\n* tau_rec   - time constant for facilitation in ms, default=0 (off)\n\n\n## References\n\n.. [1] Fuhrmann G, Segev I, Markram H, and Tsodyks MV. (2002). Coding of\n       temporal information by activity-dependent synapses. Journal of\n       Neurophysiology, 8. https://doi.org/10.1152/jn.00258.2001\n.. [2] Loebel, A., Silberberg, G., Helbig, D., Markram, H., Tsodyks,\n       M. V, & Richardson, M. J. E. (2009). Multiquantal release underlies\n       the distribution of synaptic efficacies in the neocortex. Frontiers\n       in Computational Neuroscience, 3:27. doi:10.3389/neuro.10.027.\n.. [3] Maass W, and Markram H. (2002). Synapses as dynamic memory buffers.\n       Neural Networks, 15(2), 155-161.\n       http://dx.doi.org/10.1016/S0893-6080(01)00144-7\n\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import nest\nimport nest.voltage_trace\nimport numpy\nimport matplotlib.pyplot as plt\n\nnest.ResetKernel()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "On average, the ``quantal_stp_synapse`` converges to the ``tsodyks2_synapse``,\nso we can compare the two by running multiple trials.\n\nFirst we define the number of trials as well as the number of release sites.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "n_syn = 10.0  # number of synapses in a connection\nn_trials = 100  # number of measurement trials"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Next, we define parameter sets for facilitation\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "fac_params = {\"U\": 0.02, \"u\": 0.02, \"tau_fac\": 500.,\n              \"tau_rec\": 200., \"weight\": 1.}"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Then, we assign the parameter set to the synapse models\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "t1_params = fac_params  # for tsodyks2_synapse\nt2_params = t1_params.copy()  # for quantal_stp_synapse\n\nt1_params['x'] = t1_params['U']\nt2_params['n'] = n_syn"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "To make the responses comparable, we have to scale the weight by the\nnumber of synapses.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "t2_params['weight'] = 1. / n_syn"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Next, we chage the defaults of the various models to our parameters.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "nest.SetDefaults(\"tsodyks2_synapse\", t1_params)\nnest.SetDefaults(\"quantal_stp_synapse\", t2_params)\nnest.SetDefaults(\"iaf_psc_exp\", {\"tau_syn_ex\": 3.})"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We create three different neurons.\nNeuron one is the sender, the two other neurons receive the synapses.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "neuron = nest.Create(\"iaf_psc_exp\", 3)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The connection from neuron 1 to neuron 2 is a deterministic synapse.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "nest.Connect(neuron[0], neuron[1], syn_spec=\"tsodyks2_synapse\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The connection from neuron 1 to neuron 3 has a stochastic\n``quantal_stp_synapse``.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "nest.Connect(neuron[0], neuron[2], syn_spec=\"quantal_stp_synapse\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The voltmeter will show us the synaptic responses in neurons 2 and 3.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "voltmeter = nest.Create(\"voltmeter\", 2)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "One dry run to bring all synapses into their rest state.\nThe default initialization does not achieve this. In large network\nsimulations this problem does not show, but in small simulations like\nthis, we would see it.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "neuron[0].I_e = 376.0\n\nnest.Simulate(500.0)\nneuron[0].I_e = 0.0\nnest.Simulate(1000.0)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Only now do we connect the ``voltmeter`` to the neurons.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "nest.Connect(voltmeter[0], neuron[1])\nnest.Connect(voltmeter[1], neuron[2])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "This loop runs over the `n_trials` trials and performs a standard protocol\nof a high-rate response, followed by a pause and then a recovery response.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "for t in range(n_trials):\n    neuron[0].I_e = 376.0\n    nest.Simulate(500.0)\n    neuron[0].I_e = 0.0\n    nest.Simulate(1000.0)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Flush the last voltmeter events from the queue by simulating one time-step.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "nest.Simulate(.1)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Extract the reference trace.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "vm = numpy.array(voltmeter[1].get('events', 'V_m'))\nvm_reference = numpy.array(voltmeter[0].get('events', 'V_m'))\n\nvm.shape = (n_trials, 1500)\nvm_reference.shape = (n_trials, 1500)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Now compute the mean of all trials and plot against trials and references.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "vm_mean = numpy.array([numpy.mean(vm[:, i]) for (i, j) in enumerate(vm[0, :])])\nvm_ref_mean = numpy.array([numpy.mean(vm_reference[:, i])\n                           for (i, j) in enumerate(vm_reference[0, :])])\nplt.plot(vm_mean)\nplt.plot(vm_ref_mean)\nplt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Finally, print the mean-suqared error between the trial-average and the\nreference trace. The value should be `< 10^-9`.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "print(numpy.mean((vm_ref_mean - vm_mean) ** 2))"
      ]
    }
  ],
  "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
}