Connectivity concepts

Autapse and multapse
Autapses and multapses
One to one
One-to-one
All to all
All-to-all
Pairwise Bernoulli
Pairwise Bernoulli
Fixed total number
Random, fixed total number
Fixed in-degree
Random, fixed in-degree
Fixed out-degree
Random, fixed out-degree

Basic connection rules commonly used in the computational neuroscience community. For more details, go to the section Connection rules or just click on one of the illustrations.

This documentation not only describes how to define network connectivity in NEST, but also provides details on connectivity concepts. The article “Connectivity concepts in neuronal network modeling” [1] serves as a permanent reference for a number of connection rules and we suggest to cite it if rules defined there are used. This documentation instead represents a living reference for these rules, and deviations from and extensions to what is described in the article will be highlighted.

The same article also introduces a graphical notation for neuronal network diagrams which is curated in the documentation of NEST Desktop.

Spatially-structured networks are described on a separate page.

We use the term connection to mean a single, atomic edge between network nodes (i.e., neurons or devices). A projection is a group of edges that connects groups of nodes with similar properties (i.e., populations). To specify network connectivity, each projection is specified by a triplet of source population, target population, and a connection rule which defines how to connect the individual nodes.

Projections are created in NEST with the Connect() function:

nest.Connect(pre, post)
nest.Connect(pre, post, conn_spec)
nest.Connect(pre, post, conn_spec, syn_spec)

In the simplest case, the function just takes the NodeCollections pre and post, defining the nodes of origin (sources) and termination (targets) for the connections to be established with the default rule all-to-all and the synapse model static_synapse.

Other connectivity patterns can be achieved by explicitly specifying the connection rule with the connectivity specification dictionary conn_spec which expects a rule alongside additional rule-specific parameters. Rules that do not require parameters can be directly provided as string instead of the dictionary; for example, nest.Connect(pre, post, 'one_to_one'). Examples of parameters might be in- and out-degrees, or the probability for establishing a connection. All available rules are described in the section Connection rules below.

Properties of individual connections (i.e., synapses) can be set via the synapse specification dictionary syn_spec. Parameters like the synaptic weight or delay can be either set values or drawn and combined flexibly from random distributions. For details on synapse models and their parameters refer to Synapse specification. Note that is also possible to define multiple projections with different synapse properties in the same Connect() call (see Collocated synapses).

By using the keyword variant nest.Connect(pre, post, syn_spec=syn_spec), the conn_spec can be omitted in the call to Connect() and will just take on the default value all-to-all.

After your connections are established, a quick sanity check is to look up the number of connections in the network, which can be easily done using the corresponding kernel attribute:

print(nest.num_connections)

Have a look at the section Working with connections to get more tips on how to examine the connections in greater detail.

Connection rules

Here we elaborate on the connectivity concepts with details on Autapses and multapses, Deterministic connection rules, Probabilistic connection rules, and the Connection generator interface (a method to create connections via CSA, the Connection Set Algebra [2]). Finally, we introduce the rule Tripartite Bernoulli with pool for third-party connections in addition to primary connections between pre and post. Each primary rule is described with an illustration, a NEST code example, and mathematical details. The mathematical details are extracted from the study on connectivity concepts [1] and contain a symbol which we recommend to use for describing this type of connectivity, the corresponding expression from CSA, and a formal definition with an algorithmic construction rule and the resulting connectivity distribution.

Mathematical details: General notations and definitions
Let \(\mathcal{S}=\{s_1,\ldots, s_{N_s}\}\) be the ordered set of sources of cardinality \(N_s\) and \(\mathcal{T}=\{t_1,\ldots, t_{N_t}\}\) the set of targets of cardinality \(N_t\). Then the set of all possible directed edges between members of \(\mathcal{S}\) and \(\mathcal{T}\) is given by the Cartesian product \(\mathcal{E}_{ST}=\mathcal{S \times T}\) of cardinality \(N_s\cdot N_t\).

If the source and target populations are identical (\(\mathcal{S=T}\)) a source can be its own target. We call such a self-connection an autapse. If autapses are not allowed, the target set for any node \(i \in \mathcal{S}\) is \(\mathcal{T=S} \setminus i\), with cardinality \(N_t=N_s-1\). If there is more than one edge between a source and target (or from a node to itself), we call this a multapse.

The degree distribution \(P(k)\) is the distribution across nodes of the number of edges per node. In a directed network, the distribution of the number of edges going out of (into) a node is called the out-degree (in-degree) distribution. The distributions given below describe the effect of applying a connection rule once to a given \(\mathcal{S}-\mathcal{T}\) pair.

Autapses and multapses

../_images/Autapse_multapse.png

Autapses are self-connections of a node and multapses are multiple connections betweeen the same pair of nodes.

In the connection specification dictionary conn_spec, the additional switches allow_autapses (default: True) and allow_multapses (default: True) can be set to allow or disallow autapses and multapses.

These switches are only effective during each single call to Connect(). Calling the function multiple times with the same set of neurons might still lead to violations of these constraints, even though the switches were set to False in each individual call.

Deterministic connection rules

Deterministic connection rules establish precisely defined sets of connections without any variability across network realizations.

One-to-one

../_images/One_to_one.png

The i-th node in S (source) is connected to the i-th node in T (target). The NodeCollections of S and T have to contain the same number of nodes.

n = 5
S = nest.Create('iaf_psc_alpha', n)
T = nest.Create('spike_recorder', n)
nest.Connect(S, T, 'one_to_one')
Mathematical details: One-to-one
Symbol: \(\delta\)
CSA: \(\delta\)
Definition: Each node in \(\mathcal{S}\) is uniquely connected to one node in \(\mathcal{T}\).
\(\mathcal{S}\) and \(\mathcal{T}\) must have identical cardinality \(N_s=N_t\). Both sources and targets can be permuted independently even if \(\mathcal{S}=\mathcal{T}\). The in- and out-degree distributions are given by \(P(K)=\delta_{K,1}\), with Kronecker delta \(\delta_{i,j}=1\) if \(i=j\), and zero otherwise.

All-to-all

../_images/All_to_all.png

Each node in S is connected to every node in T. Since all_to_all is the default, the rule doesn’t actually have to be specified.

n, m = 5, 5
S = nest.Create('iaf_psc_alpha', n)
T = nest.Create('iaf_psc_alpha', m)
nest.Connect(S, T, 'all_to_all')
nest.Connect(S, T)  # equivalent
Mathematical details: All-to-all
Symbol: \(\Omega\)
CSA: \(\Omega\)
Definition: Each node in \(\mathcal{S}\) is connected to all nodes in \(\mathcal{T}\).
The resulting edge set is the full edge set \(\mathcal{E}_\mathcal{ST}\). The in- and out-degree distributions are \(P_\text{in}(K)=\delta_{K,N_s}\) for \(\mathcal{T}\), and \(P_\text{out}(K)=\delta_{K,N_t}\) for \(\mathcal{S}\), respectively.

Explicit connections

Connections between explicit lists of source-target pairs can be realized in NEST by extracting the respective node ids from the NodeCollections and using the One-to-one rule.

n, m = 5, 5
S = nest.Create('iaf_psc_alpha', n) # node ids: 1..5
T = nest.Create('iaf_psc_alpha', m) # node ids: 6..10
# source-target pairs: (3,8), (4,1), (1,9)
nest.Connect([3,4,1], [8,6,9], 'one_to_one')
Mathematical details: Explicit connections
Symbol: X
CSA: Not applicable
Definition: Connections are established according to an explicit list of source-target pairs.
Connectivity is defined by an explicit list of sources and targets, also known as adjacency list, as for instance derived from anatomical measurements. It is, hence, not the result of any specific algorithm. An alternative way of representing a fixed connectivity is by means of the adjacency matrix \(A\), such that \(A_{ij}=1\) if \(j\) is connected to \(i\), and zero otherwise. We here adopt the common computational neuroscience practice to have the first index \(i\) denote the target and the second index \(j\) denote the source node.

Probabilistic connection rules

Probabilistic connection rules establish edges according to a probabilistic rule. Consequently, the exact connectivity varies with realizations. Still, such connectivity leads to specific expectation values of network characteristics, such as degree distributions or correlation structure.

Pairwise Bernoulli

../_images/Pairwise_bernoulli.png

For each possible pair of nodes from S and T, a connection is created with probability p. Note that multapses cannot be produced with this rule because each possible edge is visited only once, independent of how allow_multapses is set.

n, m, p = 5, 5, 0.5
S = nest.Create('iaf_psc_alpha', n)
T = nest.Create('iaf_psc_alpha', m)
conn_spec = {'rule': 'pairwise_bernoulli', 'p': p}
nest.Connect(S, T, conn_spec)
Mathematical details: Pairwise Bernoulli
Symbol: \(p\)
CSA: \(\rho(p)\)
Definition: Each pair of nodes, with source in \(\mathcal{S}\) and target in \(\mathcal{T}\), is connected with probability \(p\).
In its standard form this rule cannot produce multapses since each possible edge is visited only once. If \(\mathcal{S=T}\), this concept is similar to Erdős-Rényi-graphs of the constant probability p-ensemble \(G(N,p)\)—also called binomial ensemble [3]; the only difference being that we here consider directed graphs, whereas the Erdős-Rényi model is undirected. The distribution of both in- and out-degrees is binomial,
\[\begin{split}P(K_\text{in}=K)=\mathcal{B}(K|N_s,p):=\begin{pmatrix}N_s\\K\end{pmatrix}p^{K}(1-p)^{N_s-K}\end{split}\]

and

\[P(K_\text{out}=K)=\mathcal{B}(K|N_t,p)\,,\]

respectively. The expected total number of edges equals \(\text{E}[N_\text{syn}]=pN_tN_s\).

Symmetric pairwise Bernoulli

For each possible pair of nodes from S and T, a connection is created with probability p from S to T, as well as a connection from T to S (two connections in total). To use this rule, allow_autapses must be False, and make_symmetric must be True.

n, m, p = 10, 12, 0.2
S = nest.Create('iaf_psc_alpha', n)
T = nest.Create('iaf_psc_alpha', m)
conn_spec = {'rule': 'symmetric_pairwise_bernoulli', 'p': p,
             'allow_autapses': False, 'make_symmetric': True}
nest.Connect(S, T, conn_spec)

Pairwise Poisson

For each possible pair of nodes from S and T, a number of connections is created following a Poisson distribution with mean pairwise_avg_num_conns. This means that even for a small average number of connections between single neurons in S and T multiple connections are possible. Thus, for this rule allow_multapses cannot be False. The pairwise_avg_num_conns can be greater than one.

n, m, p_avg_num_conns = 10, 12, 0.2
S = nest.Create('iaf_psc_alpha', n)
T = nest.Create('iaf_psc_alpha', m)
conn_spec = {'rule': 'pairwise_poisson',
             'pairwise_avg_num_conns': p_avg_num_conns}
nest.Connect(S, T, conn_spec)

Random, fixed total number

../_images/Fixed_total_number.png

The nodes in S are randomly connected with the nodes in T such that the total number of connections equals N.

As multapses are per default allowed and possible with this rule, you can disallow them by adding 'allow_multapses': False to the conn_dict.

n, m, N = 5, 5, 10
S = nest.Create('iaf_psc_alpha', n)
T = nest.Create('iaf_psc_alpha', m)
conn_spec = {'rule': 'fixed_total_number', 'N': N}
nest.Connect(S, T, conn_spec)
Mathematical details: Random, fixed total number with multapses
Symbol: \(\mathbf{\rho_N}(N_\text{syn})\mathbf{M}(\mathbb{N}_S \times \mathbb{N}_T)\)
CSA: \(\mathbf{\rho_N}(N_\text{syn})\mathbf{M}(\mathbb{N}_S \times \mathbb{N}_T)\)
Definition: \(N_\text{syn}\in\{0,\ldots,N_sN_t\}\) edges are randomly drawn from the edge set \(\mathcal{E}_\mathcal{ST}\) with replacement.
If multapses are allowed, there are \(\begin{pmatrix}N_sN_t+N_\text{syn}-1\\N_\text{syn}\end{pmatrix}\) possible networks for any given number \(N_\text{syn}\leq N_sN_t\).
Because exactly \(N_\text{syn}\) connections are distributed across \(N_t\) targets with replacement, the joint in-degree distribution is multinomial,
\[\begin{split}\begin{equation}\label{eq:randfixKm} \begin{split} &P(K_{\text{in},1}=K_1,\ldots,K_{\text{in},N_t}=K_{N_t})\\ & \quad \quad \quad=\begin{cases} \frac{N_\text{syn}!}{K_1!...K_{N_t}!} \,p^{N_\text{syn}} & \text{if}\,\,\sum_{j=1}^{N_t} K_j = N_\text{syn}\\ \quad\quad 0 & \text{otherwise}\end{cases}\, \end{split} \end{equation}\end{split}\]

with \(p=1/N_t\).

The out-degrees have an analogous multinomial distribution \(P(K_{\text{out},1}=K_1,\ldots,K_{\text{out},N_s}=K_{N_s})\), with \(p=1/N_s\) and sources and targets switched. The marginal distributions are binomial distributions \(P(K_{\text{in},j}=K)= \mathcal{B}(K|N_\text{syn},1/N_t)\) and \(P(K_{\text{out},j}=K)= \mathcal{B}(K|N_\text{syn},1/N_s)\), respectively.

The \(\mathbf{M}\)-operator of CSA should not be confused with the “\(M\)” indicating that multapses are allowed in our symbolic notation.

Mathematical details: Random, fixed total number without multapses
Symbol: \(N_\text{syn} \cancel{M}\)
CSA: \(\mathbf{\rho_{N}}(N_\text{syn})(\mathbb{N}_S \times \mathbb{N}_T)\)
Definition: \(N_\text{syn}\in\{0,\ldots,N_sN_t\}\) edges are randomly drawn from the edge set \(\mathcal{E}_\mathcal{ST}\) without replacement.
For \(\mathcal{S}=\mathcal{T}\) this is a directed graph generalization of Erdős-Rényi graphs of the constant number of edges \(N_\text{syn}\)-ensemble \(G(N,N_\text{syn})\) [4]. There are \(\begin{pmatrix}N_s N_t\\N_\text{syn}\end{pmatrix}\) possible networks for any given number \(N_\text{syn}\leq N_sN_t\), which all have the same probability. The resulting in- and out-degree distributions are multivariate hypergeometric distributions.
\[\begin{split}\begin{split} &P(K_{\text{in},1}=K_1,\ldots,K_{\text{in},N_t}=K_{N_t})\\ & \quad \quad \quad = \begin{cases} \prod_{j=1}^{N_t} \begin{pmatrix} N_s\\K_j\end{pmatrix}\Bigg/\begin{pmatrix} N_sN_t\\N_\text{syn}\end{pmatrix} & \text{if}\,\,\sum_{j=1}^{N_t} K_j = N_\text{syn}\\ \phantom{bl}0 & \text{otherwise}\end{cases}\,, \end{split}\end{split}\]

and analogously \(P(K_{\text{out},1}=K_1,\ldots,K_{\text{out},N_s}=K_{N_s})\) with \(K_\text{out}\) instead of \(K_\text{in}\) and source and target indices switched.

The marginal distributions, i.e., the probability distribution for any specific node \(j\) to have in-degree \(K_j\), are hypergeometric distributions

\[\begin{split}P(K_{\text{in},j}=K_j)= \begin{pmatrix} N_s\\K_j \end{pmatrix} \begin{pmatrix}N_sN_t-1 \\ N_\text{syn}-K_j \end{pmatrix}\Bigg/\begin{pmatrix}N_sN_t \\ N_\text{syn}\end{pmatrix} \,,\end{split}\]

with sources and targets switched for \(P(K_{\text{out},j}=K_j)\).

Random, fixed in-degree

../_images/Fixed_indegree.png

The nodes in S are randomly connected with the nodes in T such that each node in T has a fixed indegree of N.

As multapses are per default allowed and possible with this rule, you can disallow them by adding 'allow_multapses': False to the conn_dict.

n, m, N = 5, 5, 2
S = nest.Create('iaf_psc_alpha', n)
T = nest.Create('iaf_psc_alpha', m)
conn_spec = {'rule': 'fixed_indegree', 'indegree': N}
nest.Connect(S, T, conn_spec)
Mathematical details: Random, fixed in-degree with multapses
Symbol: \(K_\text{in}, M\)
CSA: \(\mathbf{\rho_1}(K)\mathbf{M}(\mathbb{N}_S \times \mathbb{N}_T)\)
Definition: Each target node in \(\mathcal{T}\) is connected to \(K_\text{in}\) nodes in \(\mathcal{S}\) randomly chosen with replacement.
\(N_s\) is the number of source nodes from which exactly \(K_\text{in}\) connections are drawn with equal probability \(p=1/N_s\) for each of the \(N_t\) target nodes \(t_i\in\mathcal{T}\). The in-degree distribution is by definition \(P(K)=\delta_{K,K_\text{in}}\). To obtain the out-degree distribution, we observe that because multapses are allowed, drawing \(N_t\) times \(K_{\text{in},i}=K_\text{in}\) from \(\mathcal{S}\) is equivalent to drawing \(N_t K_\text{in}\) times with replacement from \(\mathcal{S}\). This procedure yields a multinomial distribution of the out-degrees \(K_{\text{out},j}\) of source nodes \(s_j\in\mathcal{S}\) [5], i.e.,
\[\begin{split}\begin{equation}\label{eq:rfin} \begin{split} &P(K_{\text{out},1}=K_1,\ldots,K_{\text{out},N_s}=K_{N_s})\\ & \quad \quad \quad =\begin{cases} \frac{(N_tK_\text{in})!}{K_1!...K_{N_s}!} p^{N_tK_\text{in}} & \text{if}\,\,\sum_{j=1}^{N_s} K_j = N_tK_\text{in}\\ \quad\quad 0 & \text{otherwise}\end{cases} \end{split} \end{equation}\end{split}\]

The marginal distributions are binomial distributions

\[\begin{equation}\label{eq:rfinmarg} P(K_{\text{out},j}=K)= \mathcal{B}(K|N_tK_\text{in},1/N_s)\,. \end{equation}\]
Mathematical details: Random, fixed in-degree without multapses
Symbol: \(K_\text{in}, \cancel{M}\)
CSA: \({\rho_1}(K)(\mathbb{N}_S \times \mathbb{N}_T)\)
Definition: Each target node in \(\mathcal{T}\) is connected to \(K_\text{in}\) nodes in \(\mathcal{S}\) randomly chosen without replacement.
The in-degree distribution is by definition \(P(K)=\delta_{K,K_\text{in}}\). To obtain the out-degree distribution, observe that after one target node has drawn its \(K_\text{out}\) sources the joint probability distribution of out-degrees \(K_{\text{out},j}\) is multivariate-hypergeometric such that
\[\begin{split}\begin{equation}\label{eq:hypmult} \begin{split} &P(K_{\text{out},1}=K_1, \ldots,K_{\text{out},N_s}=K_{N_s})\\ & \quad \quad \quad= \begin{cases} \prod_{j=1}^{N_s} \begin{pmatrix} 1\\K_j\end{pmatrix}\Bigg/\begin{pmatrix} N_s\\K_\text{in}\end{pmatrix} & \text{if}\,\,\sum_{j=1}^{N_s} K_j = K_\text{in}\\ \phantom{bl}0 & \text{otherwise}\end{cases}\,, \qquad (1) \end{split} \end{equation}\end{split}\]

where \(\forall_j\,K_j\in\{0,1\}\). The marginal distributions are hypergeometric distributions

\[\begin{split}\begin{eqnarray}\label{eq:hypmarg} P(K_{\text{out},j}=K)= \begin{pmatrix} 1\\K \end{pmatrix} \begin{pmatrix}N_s-1 \\ K_\text{in}-K \end{pmatrix}\Bigg/\begin{pmatrix}N_s \\ K_\text{in}\end{pmatrix} = \text{Ber}(K_\text{in}/N_s)\,, \qquad (2) \end{eqnarray}\end{split}\]

with \(\text{Ber}(p)\) denoting the Bernoulli distribution with parameter \(p\), because \(K\in\{0,1\}\). The full joint distribution is the sum of \(N_t\) independent instances of equation (1).

Random, fixed out-degree

../_images/Fixed_outdegree.png

The nodes in S are randomly connected with the nodes in T such that each node in S has a fixed outdegree of N.

As multapses are per default allowed and possible with this rule, you can disallow them by adding 'allow_multapses': False to the conn_dict.

n, m, N = 5, 5, 2
S = nest.Create('iaf_psc_alpha', n)
T = nest.Create('iaf_psc_alpha', m)
conn_spec = {'rule': 'fixed_outdegree', 'outdegree': N}
nest.Connect(S, T, conn_spec)
Mathematical details: Random, fixed out-degree with multapses
Symbol: \(K_\text{out}, M\)
CSA: \(\mathbf{\rho_0}(K)\mathbf{M}(\mathbb{N}_S \times \mathbb{N}_T)\)
Definition: Each source node in \(\mathcal{S}\) is connected to \(K_\text{out}\) nodes in \(\mathcal{T}\) randomly chosen with replacement.
By definition, the out-degree distribution is a \(P(K)=\delta_{K,K_\text{out}}\). The respective in-degree distribution and marginal distributions are obtained by switching source and target indices, and replacing \(K_\text{out}\) with \(K_\text{in}\) in equation from Random, fixed in-degree [5].
Mathematical details: Random, fixed out-degree without multapses
Symbol: \(K_\text{out},\cancel{M}\)
CSA: \(\mathbf{\rho_0}(K)(\mathbb{N}_S \times \mathbb{N}_T)\)
Definition: Each source node in \(S\) is connected to \(K_\text{out}\) nodes in \(\mathcal{T}\) randomly chosen without replacement.
The out-degree distribution is by definition \(P(K)=\delta_{K,K_\text{out}}\), while the in-degree distribution is obtained by switching source and target indices, and replacing \(K_\text{out}\) with \(K_\text{in}\) in equation (2) from Random, fixed in-degree.

Tripartite Bernoulli with pool

For each possible pair of nodes from a source NodeCollection (e.g., a neuron population S) and a target NodeCollection (e.g., a neuron population T), a connection is created with probability p_primary, and these connections are called ‘primary’ connections. For each primary connection, a third-party connection pair involving a node from a third NodeCollection (e.g., an astrocyte population A) is created with the conditional probability p_third_if_primary. This connection pair includes a connection from the S node to the A node, and a connection from the A node to the T node. The A node to connect to is chosen at random from a pool, a subset of the nodes in A. By default, this pool is all of A.

Pool formation is controlled by parameters pool_type, which can be 'random' (default) or 'block', and pool_size, which must be between 1 and the size of A (default). For random pools, for each node from T, pool_size nodes from A are chosen randomly without replacement.

For block pools, two variants exist. Let N_T and N_A be the number of nodes in T and A, respectively. If pool_size == 1, the first N_T/N_A nodes in T are assigned the first node in A as their pool, the second N_T/N_A nodes in T the second node in A and so forth. In this case, N_T must be a multiple of N_A. If pool_size > 1, the first pool_size elements of A are the pool for the first node in T, the second pool_size elements of A are the pool for the second node in T and so forth. In this case, N_T * pool_size == N_A is required.

The following figure and code demonstrate three use case examples with pool_type being 'random' or 'block':

../_images/tripartite_pool_type.svg

(A) In the example of 'random' pool type, each node in T can be connected with up to two randomly selected nodes in A (given pool_size == 2).

N_S, N_T, N_A, p_primary, p_third_if_primary = 6, 6, 3, 0.2, 1.0
pool_type, pool_size = 'random', 2
S = nest.Create('aeif_cond_alpha_astro', N_S)
T = nest.Create('aeif_cond_alpha_astro', N_T)
A = nest.Create('astrocyte_lr_1994', N_A)
conn_spec = {'rule': 'tripartite_bernoulli_with_pool',
                  'p_primary': p_primary,
                  'p_third_if_primary': p_third_if_primary,
                  'pool_type': pool_type,
                  'pool_size': pool_size}
syn_specs = {'third_out': 'sic_connection'}
nest.TripartiteConnect(S, T, A, conn_spec, syn_specs)

(B) In the first example of 'block' pool type, let N_T/N_A = 2, then each node in T can be connected with one node in A (pool_size == 1 is required because N_A < N_T), and each node in A can be connected with up to two nodes in T.

N_S, N_T, N_A, p_primary, p_third_if_primary = 6, 6, 3, 0.2, 1.0
pool_type, pool_size = 'block', 1
S = nest.Create('aeif_cond_alpha_astro', N_S)
T = nest.Create('aeif_cond_alpha_astro', N_T)
A = nest.Create('astrocyte_lr_1994', N_A)
conn_spec = {'rule': 'tripartite_bernoulli_with_pool',
             'p_primary': p_primary,
             'p_third_if_primary': p_third_if_primary,
             'pool_type': pool_type,
             'pool_size': pool_size}
syn_specs = {'third_out': 'sic_connection'}
nest.TripartiteConnect(S, T, A, conn_spec, syn_specs)

(C) In the second example of 'block' pool type, let N_A/N_T = 2, then each node in T can be connected with up to two nodes in A (pool_size == 2 is required because N_A/N_T = 2), and each node in A can be connected to one node in T.

N_S, N_T, N_A, p_primary, p_third_if_primary = 6, 3, 6, 0.2, 1.0
pool_type, pool_size = 'block', 2
S = nest.Create('aeif_cond_alpha_astro', N_S)
T = nest.Create('aeif_cond_alpha_astro', N_T)
A = nest.Create('astrocyte_lr_1994', N_A)
conn_spec = {'rule': 'tripartite_bernoulli_with_pool',
             'p_primary': p_primary,
             'p_third_if_primary': p_third_if_primary,
             'pool_type': pool_type,
             'pool_size': pool_size}
syn_specs = {'third_out': 'sic_connection'}
nest.TripartiteConnect(S, T, A, conn_spec, syn_specs)

References