\documentclass{article} \usepackage{url} \title{Topology User Manual} \author{Kittel Austvoll} \date{This version of the manual applies to NEST 1.9.r8375 and later.} \begin{document} \maketitle \tableofcontents \section{Introduction} The topology module is used to create connections between layers of nodes. Creating a connection between two layers of nodes consists of two main processes: \begin{itemize} \item Creating your layers \item Connecting the layers \end{itemize} %Check executable \noindent The module can either be accessed through the NEST SLI executable or through the PyNEST interface. In this userguide we're using the PyNEST interface. Before using the module you need to import it in addition to the \verb#nest# module itself. We import \verb#nest.topology# here under the short name \verb#topo# and will use that throughout this manual. Thus, all commands from the Topology module need to be prefixed with \verb#topo.#, while commands from nest proper are prefixed with \verb#nest.#. \begin{verbatim} import nest import nest.topology as topo \end{verbatim} \noindent \emph{PS!} More information about how to use the different commands included in the module can be found at the NEST helpdesk. \newline \emph{PPS!} Please send bugs and other feedback to \url{nest_user@nest-initiative.org}! \section{Creating your layers} Layers are created with the command \emph{CreateLayer}. The \emph{CreateLayer} command adds a new node of the type \emph{layer} or the type \emph{layer\_unrestricted} to your simulation network. The difference between the two layer types is that the unrestricted layer can place its nodes freely in space while the regular layer is restricted to a fixed node grid. The layer (or unrestricted layer) model inherit from the subnet model, making the layer node both a subnet and a layer. Being a subnet all regular node and subnet commands can be used on the layer node. \emph{SetStatus}, \emph{GetStatus} and \emph{PrintNetwork} are some examples of subnet or node commands that can be usefull when working with layers. %The layer subnet nodes can be added in the same way as regular subnet nodes. In addition the layer node contain information about the spatial distribution of its nodes in its dictionary. The \emph{CreateLayer} command accepts a dictionary as its sole input argument. We'll first go through how to set up this dictionary to create a \emph{layer} node, then how to set up this dictionary to create a \emph{layer\_unrestricted} node. \subsection{Creating a fixed grid layer} The most basic fixed grid layer dictionary contains the parameters: \begin{itemize} \item \emph{rows} - number of nodes along the y-dimension of the layer \item \emph{columns} - number of nodes along the x-dimension of the layer \item \emph{elements} - node models used in the layer \item \emph{extent} - the spatial dimensions (width and height) of the layer \end{itemize} All these parameters should in most cases be included when creating a fixed grid layer. The \emph{extent} parameter takes on the default values [1.0, 1.0] if nothing else is specified. According to these input parameters the \emph{layer} subnodes are distributed on a fixed grid, where the rightmost node is placed on the rightmost edge, the leftmost node is placed on the leftmost edge and so on, and where the other nodes are distributed uniformly throught the rest of the space. \subsection{Setting up the \emph{elements} parameter} Each position in the layer corresponds to a node in the layer node vector. The nodes in the layer node vector can either be single nodes or subnets. A single node is created by passing the name of the node to the \emph{elements} parameter \begin{verbatim} "elements": "iaf_neuron" \end{verbatim} \noindent A subnet of nodes can be created by enclosing several neuron types in brackets. Each bracket indicates a subnet. \begin{verbatim} # Create a subnet of nodes consisting of a single iaf_psc_alpha # node and a wrapped subnet of two more iaf_neurons. "elements": [["iaf_neuron", 2], "iaf_psc_alpha"] \end{verbatim} \noindent The single node or the subnet of nodes created with the \emph{elements} parameter will never occupy more than one place in the layer node vector no matter how many subnets that are wrapped within one another. The \emph{elements} parameter adds a third dimension to the 2-dimensional layer. Each node in the \emph{elements} parameter is associated with a specific depth. The nodes within the topmost subnet in the \emph{elements} structure is given a depth equal to their local id within that subnet. If only a single neuron exists at the topmost \emph{elements} level it is given the depth 1. In the description of the \emph{ConnectLayer} command you'll see how this third dimension can be used to create connection patterns in a 3D layer structure. \paragraph{For SLI users:} \noindent A subnet of nodes can be created by passing a SLI procedure to the \emph{elements} parameter. The nodes created with the SLI procedure will automatically be placed inside a main element subnet. The \emph{elements} procedure should keep the size of the SLI stack unchanged! \begin{verbatim} /elements {/iaf_neuron 2 Create ;} \end{verbatim} \paragraph{Example: Creating a 3 by 4 layer of iaf-neurons} \begin{verbatim} layer = topo.CreateLayer({"rows": 3, "columns": 4, "extent": [1.0, 1.0], "elements": "iaf_neuron"}) \end{verbatim} \subsection{Studying the layer with the \emph{PrintNetwork} command} The \emph{PrintNetwork} command can help us to get a better understanding of the layer node hierarchy. Observe how the 2D layer uses a 1D node vector to store its nodes. The layer uses column wise folding to convert between the 1D node vector and the 2D space. \paragraph{Example: Viewing the layout of a 3 by 4 layer of iaf-neurons} \begin{verbatim} nest.PrintNetwork(1, layer) +-[1] layer dim=[12] | +-[1]...[12] iaf_neuron \end{verbatim} \subsection{Wrapping the layer edges} The layer can be wrapped or cut-off (truncated) at the edges. The edge is by default cut-off. By setting the dictionary parameter \emph{edge\_wrap} to true the edges will be wrapped instead. \begin{verbatim} nest.SetStatus(layer, {"edge_wrap": True}) \end{verbatim} \subsection{Changing the 2D position of the layer} The previously introduced \emph{extent} parameter together with the \emph{center} parameters decide the position of the layer in the 2D space. The edges of the layer can be found by taking the position of the center and adding or subtracting half of the extent distance. The layer center is by default set to (0.0, 0.0). The layer nodes are distributed uniformly throughout this space. \begin{verbatim} nest.SetStatus(layer, {"center": [0.0, 0.0]}) \end{verbatim} \subsection{A complete fixed grid layer dictionary} \begin{verbatim} topo.CreateLayer({"rows": 3, "columns": 4, "extent": [1.0, 1.0], "center": [0.5, -1.4], "elements": ["iaf_neuron", "iaf_psc_alpha"], "edge_wrap": True}) \end{verbatim} \subsection{The unrestricted layer} The unrestricted layer is very similar to the fixed grid layer. The only exception is that the unrestricted layer nodes can be placed freely in the space that the layer occupies. The nodes are placed with the \emph{positions} dictionary parameter. The \emph{positions} parameter is an array that contains information about the x- and y-coordinates of the layer nodes. Each element in the array corresponds to a node in the layer node vector. The node positions have to be within the area defined by the \emph{extent} and \emph{center} parameters! The layer nodes can either be single neurons or subnets of neurons. \paragraph{Example: Creating a layer consisting of three nodes at the positions (-0.5, 0.3), (0.0, 0.4) and (0.5, -0.2)} \begin{verbatim} topo.CreateLayer({"extent": [1.0, 1.0], "elements": "iaf_psc_alpha", "positions": [[-0.5, 0.3], [0.0, 0.4], [0.5, -0.2]]}) \end{verbatim} \paragraph{For advanced users:} The unrestricted layer uses a quadtree structure to organize its nodes. The quadtree structure divides the space occupied by the layer into different regions of nodes. The number of nodes allowed in each region is decided by a predefined constant variable. Advanced users or developers can manipulate this variable by adding the \emph{quadrant\_max\_nodes} variable to the layer dictionary. Most users don't need to change this variable! \paragraph{Example: Changing the layout of the quadtree structure} \begin{verbatim} nest.SetStatus(layer, {"quadrant_max_nodes": 100}) \end{verbatim} \subsection{When to use a fixed grid layer and when to use an unrestricted layer} In many situations the choice of layer type will be decided by the nature of the layer connection desired. However in some cases the same network could be connected with both a fixed grid and an unrestricted layer. In that case it is your choice which type of layer you want to use. In general a fixed grid layer is faster than an unrestricted layers for most connection regions. \section{Connecting your layers} Once we've created our layers we can create connections between them. In the topology module connections between layers are created with the \emph{ConnectLayer} command. Connections are always created between two layers at a time (or between a layer and itself). The connections are created by specifiying which kind of connection pattern we wish to create, and then iterate through one of the layers and create this connection pattern for each node in that layer. In most cases the iterating node will connect to a region directly below it in the 2D space. To find out which position this corresponds to in the connecting layer the \emph{extent} and \emph{center} layer parameters have to be taken into account. The \emph{ConnectLayer} command accepts the GIDs of two layers and a special connection dictionary describing the nature of the connection as input. \begin{verbatim} topo.ConnectLayer(source_gid, target_gid, dictionary) \end{verbatim} The first GID passed to the command is the source layer of the connection (the layer that emits the neural spikes). The second GID is a reference to the target layer. In the following sections we'll see how the connection dictionary is created. \subsection{The connection type} The connection type parameter can be specified as \emph{convergent} (previously receptive field) or \emph{divergent} (perviously projective field). A convergent connection is a connection between a group (or region) of source nodes and a single target node. A divergent connection is a connection between a single source node and a group (or region) of target nodes. \begin{verbatim} dict = {"connection_type": "divergent", # other parameters } \end{verbatim} \subsection{The synapse type} The synapse model used in the connections can be set with the \emph{synapse\_model} parameter. If no synapse model is set the \emph{/static\_synapse} model will be used. \begin{verbatim} dict = {"connection_type": "divergent", "synapse_model": "tsodyks_synapse", # other parameters } \end{verbatim} \subsection{Defining the region from which to pick connection nodes} The region (or group) which we will pick nodes from is defined by the \emph{mask} parameter. The \emph{mask} defines a region in a 2D space (where the layers reside) from which to pick nodes from. The region can be defined as a \emph{rectangular}, \emph{circular} or a \emph{doughnut} parameter. The \emph{rectangular}, the \emph{circular} and the \emph{doughnut} parameters are all dictionaries. The \emph{rectangular} dictionary contains information about the lower left and upper right corner of the mask region. The \emph{circular} dictionary contains information about the radius of the mask region. The \emph{doughnut} dictionary is a special circular region where an inner radius and an outer radius is defined. The position of the mask is given relative to the position of the calling node in the iterating layer. As an example we can look at a convergent connection between a target node at position (0.3, -0.1) connecting to a region in a corresponding source layer. The region is specified as rectangular with an lower left corner at (-0.1, -0.1) and a upper right corner at (0.1, 0.1). The modified region (relative to the target node) for the source layer will then be a square having an lower left corner at (0.2, -0.2) and a upper right corner at (0.4, 0.0). \paragraph{Example: Creating a rectangular mask region} \begin{verbatim} dict = {"connection_type": "divergent", "mask": {"rectangular": {"lower_left": [-0.3, -0.25], "upper_right": [0.3, 0.25]}}} \end{verbatim} \paragraph{Example: Creating a circular mask region} \begin{verbatim} dict = {"connection_type": "divergent", "mask": {"circular": {"radius": 0.3}}} \end{verbatim} \paragraph{Example: Creating a doughnut mask region} \begin{verbatim} dict = {"connection_type": "divergent", "mask": {"doughnut": {"inner_radius": 0.1, "outer_radius": 0.4}}} \end{verbatim} \noindent Both the \emph{connection\_type} and the \emph{mask} parameter are mandatory in a connection dictionary. \subsection{Setting the weights, delays and kernel of the mask region} Connections initialised from different positions within the mask region can be given different weights, delays and kernel values. The kernel parameter is a special parameter that decides the likelihood of creating a specific connection within the region. These parameters can either be given as constant values or they can be calculated based upon the distance between the different mask positions and the mask center. The following functions can be used to generate values for these parameters. %$c + p\_center * e^{-((x-mean\_x)^2/(sigma\_x^2) + (y-mean\_y)^2/(sigma\_y^2) - 2*(x-mean\_x)*(y-mean\_y)*rho/(sigma\_x*sigma\_y))/(2*(1-rho^2))}$ \begin{itemize} \item gaussian: $c + p\_center * e^{-(distance-mean)^2/(2*sigma^2)}$ \item gaussian2D: $c + p\_center * \newline e^{-(\frac{(x-mean\_x)^2}{sigma\_x^2} + \frac{(y-mean\_y)^2}{sigma\_y^2} - \frac{2*(x-mean\_x)*(y-mean\_y)*rho}{sigma\_x*sigma\_y})/(2*(1-rho^2))}$ \item linear: $a*distance + c$ \item exponential: $c + a*e^{-distance/tau}$ \item uniform: $[min, max]$ - random number \end{itemize} %\begin{tabular}{|c|c|} %\hline %gaussian & $c + p\_center * e^{-(distance-mean)^2/(2*sigma^2)}$ \\ %\hline %gaussian2D & $c + p\_center * e^{-\frac{1}{2*(1-rho^2)}*(\frac{(x-mean\_x)^2}{sigma\_x^2} + \frac{(y-mean\_y)^2}{sigma\_y^2} - \frac{2*(x-mean\_x)*(y-mean\_y)*rho}{sigma\_x*sigma\_y})}$ \\ %\hline %linear & $a*distance + c$ \\ %\hline %exponential & $c + a*e^{-distance/tau}$ \\ %\hline %\end{tabular} %\begin{itemize} %\item Linear: $a*distance + c$ %\item Exponential: $c + a*e^{-distance/tau}$ %\item Gaussian: $c + p\_center * e^{-(distance-mean)^2/sigma^2}$ %Gaussian %\end{itemize} In addition the following parameters can be added to any of the functions: \begin{itemize} \item \emph{min} - the minimum value that the function will return \item \emph{max} - the maximum value that the function will return \item \emph{cutoff} - the function will return 0 if it has a value less than the cutoff value \item \emph{cutoff\_distance} - the function will return 0 if the distance is more than the set \emph{cutoff\_distance} \item \emph{anchor} - array with new center of parameters region \end{itemize} \paragraph{Example: Three different ways to set up the weights, delays and probabilities parameters} \begin{verbatim} dict = {"connection_type": "divergent", "mask": {"circular": {"radius": 0.3}}, "delays": 1.3, "weights": {"gaussian": {"sigma": 1.5, "p_center": 2.0, "c": 1.0, "mean": 0.1}}, "kernel": {"linear": {"a": -0.5, "c": 1.0, "min": 0.4, "max": 0.9}}} \end{verbatim} \paragraph{Note for developers and advanced users} Other distribution functions can easily be added to the list of already existing functions. \subsubsection{Combining different parameter functions} Advanced users can combine the different parameter functions to create even more complex connection patterns. \paragraph{Example: Using a combination of different parameter objects} \begin{verbatim} dict = {"connection_type": "divergent", "mask": {"circular": {"radius": 0.3}}, "kernel": {"combination": [{"gaussian": {"sigma": 0.3, "anchor": [0.3, 0.3], "cutoff": 0.4}}, {"gaussian": {"sigma": 0.3, "anchor": [-0.3, -0.3], "cutoff_distance": 0.7}}]}} \end{verbatim} \subsection{Creating 3D connections with the topology module} With the help of the layer \emph{elements} parameter 3D connections can be created with the topology module. In contrast to the 2D connections which are spatially dependent, the 3D connections are dependent upon node depth and node type. The 3D connection pattern is set in the \emph{sources} and \emph{targets} parameter dictionaries. The \emph{sources} parameter applies to the source layer, the \emph{targets} parameter applies to the target layer. These dictionaries can contain the parameters \emph{model} and \emph{lid}. The \emph{model} parameter decides which model type that is used in the connection. The \emph{lid} decides which depth we should pick nodes from. Only one model type or one depth can be specified for each call to \emph{ConnectLayer}. If these parameters are omitted all model types and all depths are connected to. By wrapping subnets within subnets in the depth column many nodes can be placed at the same depth in the layer. By using the \emph{CopyModel} command to create our own model types we can create our own model labels used with this connection parameter. \paragraph{Note to developers:} If CopyModel is on its way out of NEST this command has to be replaced with the new command. \paragraph{Example: Only connecting to excitatory nodes at depth 2} \begin{verbatim} # Create two neuron types nest.CopyModel("iaf_neuron", "my_excitatory") nest.CopyModel("iaf_neuron", "my_inhibitory") # Create a single layer dict = {"rows": 3, "columns": 4, "extent": [1.0, 1.0], "elements": ["my_excitatory", ["my_inhibitory", "my_excitatory"]]} layer = topo.CreateLayer(dict) # Connect layer to itself dict = {"connection_type": "divergent", "mask": {"circular": {"radius": 0.1}}, "targets": {"lid": 2, "model": "my_excitatory"}} topo.ConnectLayer(layer, layer, dict) \end{verbatim} \subsection{Limiting the number of synapses per node}\label{numberofconnections} In the topology module the \emph{connection\_type} parameter is particularly important when used together with the \emph{number\_of\_connections} parameter. The \emph{number\_of\_connections} parameter limits the maximum number of connections that are allowed for each source (for convergent connection) or target (for divergent connection) node. If used correctly this parameter would create a source layer where all the nodes have the same number of synapses (for divergent connection), or a target layer where all the nodes receive the same number of input synapses (for convergent connection). Whether to allow autapses (connections to oneself) and multapses (many identical connections) can also be set together with this parameter. The \emph{allow\_autapses} and \emph{allow\_multapses} parameters are by default set to true. PS! The allow autapses parameter doesn't have an effect when used independently of the number of connections parameter. \paragraph{Example: Limiting the number of synapses per target node to 100 unique synapses} \begin{verbatim} dict = {"connection_type": "divergent", "mask": {"doughnut": {"inner_radius": 0.1, "outer_radius": 0.3}}, "number_of_connections": 100, "allow_multapses": False} \end{verbatim} \subsection{Creating a fixed grid connection dictionary} All the features of the unrestricted layer connection dictionary are valid for fixed grid connection dictionaries. In addition the fixed grid connection dictionary includes some extra optional parameters. The fixed grid layer includes an extra mask region parameter. Instead of defining the rectangular mask parameter in terms of continuous spatial distances the rectangular mask can be defined in terms of discrete row and column distances. The row and column distances are given with respect to the node resolution of the layer which the mask is attached to. Using such a mask region speeds up the connection process in most cases. \paragraph{Example: Creating a simple fixed grid mask region} \begin{verbatim} dict = {"connection_type": "convergent", "mask": {"grid": {"rows": 2, "columns": 3}}} \end{verbatim} \subsubsection{The \emph{anchor} parameter} The center of the mask grid region is by default set in the upper left node of the grid region. This center can be moved with the help of the \emph{anchor} parameter. The mask grid row and column values starts with [0, 0] in the upper left corner of the region, and increases downwards and to the right in the grid. The anchor is given as a dictionary containing a row and a column position. For fixed grid layers there also exists an \emph{anchor} parameter for the individual layers in the connection. The layer anchor helps in further re-positioning of the layer without altering the layer parameters. The layer anchors can be given in terms of row/column or x/y coordinates. In contrast to the row/column coordinates, which increase downwards and to the right in the space, the x/y coordinates increases as we move upwards and to the right in the coordinate system (like we're used to). If the layers are given row/column anchor points all other spatial information such as the \emph{extent} and the \emph{center} are ignored. In this case the layer is automatically given the \emph{extent} [1.0, 1.0] and the \emph{center} [0.0, 0.0]. \paragraph{Example: Adding the anchor parameter} \begin{verbatim} dict = {"connection_type": "divergent", "mask": {"grid": {"rows": 2, "columns": 3}}, "anchor": {"row": 2, "column": -1}, "sources": {"anchor": {"x": 0.3, "y": -0.5}}} \end{verbatim} \paragraph{Example: Creating a centered grid mask region} \begin{verbatim} dict = {"connection_type": "divergent", "mask": {"grid": {"rows": 9, "columns": 7}, "anchor": {"row": 5, "column": 4}}} \end{verbatim} \subsubsection{Other differences between the layer types} The fixed grid layer allows for an additional kind of initialisation of the \emph{weights}, \emph{delays} and \emph{kernel} parameters. For this layer type the parameters can also be initialised as an array of decimal numbers. Where each array element correspond to a position in the mask region. The array elements are given columnwise. This parameter type can only be used together with a \emph{grid} mask region. \paragraph{Example: Initialising the \emph{weights} parameter with an array of decimal values} \begin{verbatim} dict = {"connection_type": "convergent", "mask": {"grid": {"rows": 2, "columns": 3}}, "weights": [0.5, 0.6, 0.3, 0.2, 0.4, 0.2]} \end{verbatim} \section{Other commands} \subsection{\emph{GetElement}} The \emph{GetElement} command can be used to retrieve a node at a specified layer position in a fixed grid layer. The position is given on the format \verb|[column row]|. The command only accepts fixed grid layers. \begin{verbatim} layer = topo.CreateLayer({"rows": 5, "columns": 4, "extent": [1.0, 1.0], "elements": "iaf_neuron"}) # Retrieve node at column 2 and row 3 print nest.GetElement(layer, [2, 3]) \end{verbatim} \subsection{\emph{GetPosition}} The \emph{GetPosition} command retrieves the position of a specific node. The position is returned on the format \verb|[x, y]|. \begin{verbatim} layer = topo.CreateLayer({"rows": 5, "columns": 4, "extent": [1.0, 1.0], "elements": "iaf_neuron"}) print nest.GetPosition([nest.GetLeaves(layer)[0][2]]) \end{verbatim} \subsection{\emph{GetRelativeDistance}} This command returns the spatial distance between two nodes. The wrapped distance is returned if edge wrapping is used. \begin{verbatim} layer = topo.CreateLayer({"rows": 5, "columns": 4, "extent": [1.0, 1.0], "elements": "iaf_neuron"}) node_a = [nest.GetLeaves(layer)[0][2]] node_b = [nest.GetLeaves(layer)[0][3]] print topo.GetRelativeDistance(node_a, node_b) \end{verbatim} \subsection{\emph{LayerGidPositionMap}} The command prints a list of the layer nodes and their corresponding positions. \begin{verbatim} layer = topo.CreateLayer({"rows": 5, "columns": 4, "extent": [1.0, 1.0], "elements": "iaf_neuron"}) topo.LayerGidPositionMap(layer, 'out.txt') \end{verbatim} \subsection{\emph{PrintLayerConnections}} Prints a list of connections for a layer together with the connection weights, delays and the distances between the source and target nodes. \begin{verbatim} ##Create and connect layers here # ... # ... topo.PrintLayerConnections(layer, 'static_synapse', 'out.txt') \end{verbatim} \section{Using MPI with the topology module} The topology module can easily be used on MPI systems. The efficiency of the module on the MPI system various according to the connection specifications. If we're using the \emph{convergent} connection type the connection efficiency scales linearly with the increase in processor power. The \emph{divergent} connection type is not that well suited for use on MPI systems and offers little efficiency increase despite the increase in overall processing power. \paragraph{Note to developers} When using the \emph{convergent} option the target node can be identified early in the connection process and the process aborted if the node isn't local. For the \emph{divergent} option the target node is identified at the very end of the connection process and this approach thus leads to little or no efficiency increase. \section{Using the topology module from the NEST/SLI executable} The PyNEST topology functions are designed so as to map directly to the SLI NEST executable functions. There are however a few exceptions to this. \paragraph{The \emph{elements} parameter:} From SLI this parameter can only be initialised as either a single model name or as a procedure. Array of modelnames are not allowed. \paragraph{Passing filenames:} Topology functions that request a filename in PyNEST would in most cases ask for a filestream in SLI. \paragraph{Literals:} Modelnames used as dictionary parameters that are passed as strings in PyNEST are passed as literals in SLI. \section{Case studies} \subsection{A gaussian distributed network} In this case study we'll reconstruct the network described in the article \emph{Activity dynamics and propagation of synchronous spiking in locally connected random networks} by \emph{Mehring et al.} (\emph{Biological Cybernetics}, 88, 395-408, 2003). You probably have to scale down this network if you want to recreate it on your own personal computer. \subsubsection{Creating our layers} The network consists of a single layer of excitatory and inhibitory iaf-neurons connected to it self. Because of density differences in the distribution of the two neuron types we'll create a separate layer for the each neuron type. The excitatory layer consists of 90.000 iaf-neurons placed on a fixed square grid (300 by 300 nodes). The layer has a width of 2 mm and a height of 2 mm. We'll use \emph{mm} as the unit of choice in our layer. The layer is wrapped at the edges. \paragraph{Excitatory layer dictionary} \begin{verbatim} excitatory_dict = {"rows": 300, "columns": 300, "extent": [2.0, 2.0], "elements": "iaf_neuron", "edge_wrap": True} \end{verbatim} The inhibitory layer consists of 22500 iaf-neurons with the same layer dimensions. \paragraph{Inhibitory layer dictionary} \begin{verbatim} inhibitory_dict = {"rows": 150, "columns": 150, "extent": [2.0, 2.0], "center": [0.0, 0.0], "elements": "iaf_neuron", "edge_wrap": True} \end{verbatim} After creating the layer dictionaries the two layers can be created. \paragraph{Creating the layers} \begin{verbatim} exc = topo.CreateLayer(excitatory_dict) inh = topo.CreateLayer(inhibitory_dict) \end{verbatim} You might be interested in replacing the iaf-neuron model type with a model of your own. Or create a SLI script to go through and modify the iaf-neurons to the nature used in the article. In this case study we're only interested in the connection network so we'll skip this part. \subsubsection{Connecting the layers} Next we have to create the connection dictionaries. We'll create one dictionary for the excitatory neurons and one for the inhibitory neurons. We want to create a network were each neuron receives a fixed set of inputs (11250 (9000 excitatory, and 2250 inhibitory)). So we'll set the connection type to receptive field connect, and the maximum number of connections to 9000 for the excitatory dictionary and 2250 for the inhibitory dictionary. We'll allow multapses and autapses. The synaptic delay is set to 1.5 ms. The weight of the signals coming from inhibitory neurons should be four times larger than the signals coming from excitatory neuron. We'll set the excitatory mask weight to the arbitrary value 1.0 and the corresponding inhibitory mask weight to 4.0. The probability of connecting two nodes is dependent upon distance and is described by a gaussian function with a standard deviation of 0.3. The size of the mask region is not described in the article. So we'll set this to an arbitrary large number. The connection process will be much faster by decreasing this number. The connecting nodes are drawn at random from this mask region. After finding a pair of nodes that we want to connect a random number is drawn, if this random number is lower than the probability of connection then the connection is created, otherwise the process is repeated. \paragraph{The connection dictionaries} \begin{verbatim} exc_par = {"connection_type": "convergent", ## We'll use a circular mask with a ## radius of 1.8. ## The validity of this mask size ## has to be discussed. "mask": {"circular": {"radius": 1.8}}, "weights": 1.0, "delays": 1.5, "kernel": {"gaussian": {"sigma": 0.3, "p_center": 1.3}}, "allow_autapses": True, "allow_multapses": True, "number_of_connections": 9000} \end{verbatim} \begin{verbatim} inh_par = {"connection_type": "convergent", "mask": {"circular": {"radius": 1.8}}, "weights": 4.0, # the weight of inhibitory connections are # four times as high as excitatory. "delays": 1.5, "kernel": {"gaussian": {"sigma": 0.3, "p_center": 1.3}}, "allow_autapses": True, "allow_multapses": True, "number_of_connections": 2250} \end{verbatim} \paragraph{Connecting the layers} \begin{verbatim} topo.ConnectLayer(exc, exc, exc_par) topo.ConnectLayer(exc, inh, exc_par) topo.ConnectLayer(inh, inh, inh_par) topo.ConnectLayer(inh, exc, inh_par) \end{verbatim} \subsubsection{External input} The layer should also receive input from an external poisson generator. We'll connect this generator with regular connection functions. The generator needs to be initialised properly. \begin{verbatim} pois = nest.Create("poisson_generator") nest.DivergentConnect(pois, nest.GetNodes(exc)[0]) nest.DivergentConnect(pois, nest.GetNodes(inh)[0]) \end{verbatim} \subsection{Combining a circular and a doughnut region} In the article \emph{Statistical analysis of spatially embedded networks: From grid to random node positions} Voges et al. describes a node network where each node have both a set of close-by neighbour connections and a few selected long range connections. Such a network can be created by combining the circular and the doughnut mask region. The circular mask region will in this case be responsible for the close-by connections and the doughnut region will be responsible for the long range connections. \paragraph{The circular mask region} Below follows an arbitrary example of how to set up the regions. The probability of connection, weights, number of connections have to be set up to suit your need. \begin{verbatim} {"connection_type": "convergent", "mask": {"circular": {"radius": 1.0}}} \end{verbatim} \paragraph{The doughnut mask region} \begin{verbatim} {"connection_type": "convergent", "mask": {"doughnut": {"inner_radius": 1.5, "outer_radius": 2.0}}, "number_of_connections": 10} \end{verbatim} \subsection{Another arbitrary example} \begin{verbatim} import nest ## Initialising module nest.sli_run("topology using") ## Create layers layer_settings = {"rows": 9, "columns": 8, "extent": [4.0, 5.0], "center": [1.0, -1.0], "elements": "iaf_neuron", "edge_wrap": False} source = topo.CreateLayer(layer_settings) layer_settings["extent"] = [2.0, 2.0] target = topo.CreateLayer(layer_settings) ## Connect layers connection_settings = {"connection_type": "convergent", "mask": {"circular": {"radius": 2.0}}, "weights": 1.0, "synapse_model": "static_synapse"} topo.ConnectLayer(source, target, connection_settings) \end{verbatim} \section{List of commands} \paragraph{Topology module} \begin{verbatim} CreateLayer ConnectLayer GetElement GetPosition GetRelativeDistance LayerGidPositionMap PrintLayerConnections \end{verbatim} \paragraph{Other useful commands} \begin{verbatim} SetStatus GetStatus PrintNetwork \end{verbatim} \end{document}