{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\nExample script to show some of the possibilities of the SynapseCollection class. We\nconnect neurons, and get the SynapseCollection with a GetConnections call. To get\na better understanding of the connections, we plot the weights between the\nsource and targets.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import nest\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n\ndef makeMatrix(sources, targets, weights):\n    \"\"\"\n    Returns a matrix with the weights between the source and target node_ids.\n    \"\"\"\n    aa = np.zeros((max(sources)+1, max(targets)+1))\n\n    for src, trg, wght in zip(sources, targets, weights):\n        aa[src, trg] += wght\n\n    return aa\n\n\ndef plotMatrix(srcs, tgts, weights, title, pos):\n    \"\"\"\n    Plots weight matrix.\n    \"\"\"\n    plt.subplot(pos)\n    plt.matshow(makeMatrix(srcs, tgts, weights), fignum=False)\n    plt.xlim([min(tgts)-0.5, max(tgts)+0.5])\n    plt.xlabel('target')\n    plt.ylim([max(srcs)+0.5, min(srcs)-0.5])\n    plt.ylabel('source')\n    plt.title(title)\n    plt.colorbar(fraction=0.046, pad=0.04)\n\n\n\"\"\"\nStart with a simple, one_to_one example.\nWe create the neurons, connect them, and get the connections. From this we can\nget the connected sources, targets, and weights. The corresponding matrix will\nbe the identity matrix, as we have a one_to_one connection.\n\"\"\"\nnest.ResetKernel()\n\nnrns = nest.Create('iaf_psc_alpha', 10)\n\nnest.Connect(nrns, nrns, 'one_to_one')\nconns = nest.GetConnections(nrns, nrns)  # This returns a SynapseCollection\n# We can get desired information of the SynapseCollection with simple get() call.\ng = conns.get(['source', 'target', 'weight'])\nsrcs = g['source']\ntgts = g['target']\nweights = g['weight']\n\n# Plot the matrix consisting of the weights between the sources and targets\nplt.figure(figsize=(12, 10))\nplotMatrix(srcs, tgts, weights, 'Uniform weight', 121)\n\n\"\"\"\nAdd some weights to the connections, and plot the updated weight matrix.\n\"\"\"\n# We can set data of the connections with a simple set() call.\nw = [{'weight': x*1.0} for x in range(1, 11)]\nconns.set(w)\nweights = conns.weight\n\nplotMatrix(srcs, tgts, weights, 'Set weight', 122)\n\n\"\"\"\nWe can also plot an all_to_all connection, with uniformly distributed weights,\nand different number of sources and targets.\n\"\"\"\nnest.ResetKernel()\n\npre = nest.Create('iaf_psc_alpha', 10)\npost = nest.Create('iaf_psc_delta', 5)\nnest.Connect(pre, post,\n             syn_spec={'weight':\n                       {'distribution': 'uniform', 'low': 0.5, 'high': 4.5}})\n\n# Get a SynapseCollection with all connections\nconns = nest.GetConnections()\nsrcs = conns.source\ntgts = conns.target\nweights = conns.weight\n\nplt.figure(figsize=(12, 10))\nplotMatrix(srcs, tgts, weights, 'All to all connection', 111)\n\n\"\"\"\nLastly, we'll do an exmple that is a bit more complex. We connect different\nneurons with different rules, synapse models and weight distributions, and get\ndifferent SynapseCollections by calling GetConnections with different inputs.\n\"\"\"\nnest.ResetKernel()\n\nnrns = nest.Create('iaf_psc_alpha', 15)\nnest.Connect(nrns[:5], nrns[:5],\n             'one_to_one',\n             {'synapse_model': 'stdp_synapse',\n              'weight': {'distribution': 'normal', 'mu': 5.0, 'sigma': 2.0}})\nnest.Connect(nrns[:10], nrns[5:12],\n             {'rule': 'pairwise_bernoulli', 'p': 0.4},\n             {'weight': 4.0})\nnest.Connect(nrns[5:10], nrns[:5],\n             {'rule': 'fixed_total_number', 'N': 5},\n             {'weight': 3.0})\nnest.Connect(nrns[10:], nrns[:12],\n             'all_to_all',\n             {'synapse_model': 'stdp_synapse',\n              'weight': {'distribution': 'uniform', 'low': 1., 'high': 5.}})\nnest.Connect(nrns, nrns[12:],\n             {'rule': 'fixed_indegree', 'indegree': 3})\n\n# First get a SynapseCollection consisting of all the connections\nconns = nest.GetConnections()\nsrcs = conns.source\ntgts = conns.target\nweights = conns.weight\n\nplt.figure(figsize=(14, 12))\nplotMatrix(list(srcs), list(tgts), weights, 'All connections', 221)\n\n# Get SynapseCollection consisting of a subset of connections\nconns = nest.GetConnections(nrns[:10], nrns[:10])\ng = conns.get(['source', 'target', 'weight'])\nsrcs = g['source']\ntgts = g['target']\nweights = g['weight']\n\nplotMatrix(srcs, tgts, weights, 'Connections of the first ten neurons', 222)\n\n# Get SynapseCollection consisting of just the stdp_synapses\nconns = nest.GetConnections(synapse_model='stdp_synapse')\ng = conns.get(['source', 'target', 'weight'])\nsrcs = g['source']\ntgts = g['target']\nweights = g['weight']\n\nplotMatrix(srcs, tgts, weights, 'Connections with stdp_synapse', 223)\n\n# Get SynapseCollection consisting of the fixed_total_number connections, but set\n# weight before plotting\nconns = nest.GetConnections(nrns[5:10], nrns[:5])\nw = [{'weight': x*1.0} for x in range(1, 6)]\nconns.set(w)\ng = conns.get(['source', 'target', 'weight'])\nsrcs = g['source']\ntgts = g['target']\nweights = g['weight']\n\nplotMatrix(srcs, tgts, weights, 'fixed_total_number, set weight', 224)\n\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
}