{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Using CSA with spatial populations\n\nThis example shows a brute-force way of specifying connections between\nNEST populations with spatial data using Connection Set Algebra instead of\nthe built-in connection routines.\n\nUsing the CSA requires NEST to be compiled with support for\nlibneurosim [1]_.\n\n## See Also\n\n:doc:`csa_example`\n\n## References\n\n.. [1] Djurfeldt M, Davison AP and Eppler JM (2014). Efficient generation of connectivity in neuronal networks\n       from simulator-independent descriptions. Front. Neuroinform.\n       http://dx.doi.org/10.3389/fninf.2014.00043\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "First, we import all necessary modules.\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": [
        "Next, we check for the availability of the CSA Python module. If it does\nnot import, we exit with an error message.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "try:\n    import csa\n    haveCSA = True\nexcept ImportError:\n    print(\"This example requires CSA to be installed in order to run.\\n\" +\n          \"Please make sure you compiled NEST using\\n\" +\n          \"  -Dwith-libneurosim=[OFF|ON|</path/to/libneurosim>]\\n\" +\n          \"and CSA and libneurosim are available.\")\n    import sys\n    sys.exit(1)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We define a factory that returns a CSA-style geometry function for\nthe given layer. The function returned will return for each CSA-index\nthe position in space of the given neuron as a 2- or 3-element list.\n\nThis function stores a copy of the neuron positions internally, entailing\nmemory overhead.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "def geometryFunction(population):\n\n    positions = nest.GetPosition(population)\n\n    def geometry_function(idx):\n        return positions[idx]\n\n    return geometry_function\n\n\nnest.ResetKernel()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We create two spatial populations that have 20x20 neurons of type\n``iaf_psc_alpha``.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "pop1 = nest.Create('iaf_psc_alpha', positions=nest.spatial.grid([20, 20]))\npop2 = nest.Create('iaf_psc_alpha', positions=nest.spatial.grid([20, 20]))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "For each population, we create a CSA-style geometry function and a CSA metric\nbased on them.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "g1 = geometryFunction(pop1)\ng2 = geometryFunction(pop2)\nd = csa.euclidMetric2d(g1, g2)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The connection set `cs` describes a Gaussian connectivity profile with\n``sigma = 0.2`` and cutoff at 0.5, and two values (10000.0 and 1.0) used as\n``weight`` and ``delay``, respectively.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "cs = csa.cset(csa.random * (csa.gaussian(0.2, 0.5) * d), 10000.0, 1.0)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We can now connect the populations using the ``CGConnect`` function. It\ntakes the IDs of pre- and postsynaptic neurons (`pop` and `pop2`),\nthe connection set (`cs`) and a dictionary that map the parameters\nweight and delay to positions in the value set associated with the\nconnection set.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "nest.CGConnect(pop1, pop2, cs, {\"weight\": 0, \"delay\": 1})"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Finally, we use the ``PlotTargets`` function to show all targets in `pop2`\nstarting at the center neuron of `pop1`.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "cntr = nest.FindCenterElement(pop1)\nnest.PlotTargets(cntr, pop2)\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
}