Skip to content

Connecting Cells

connect(pre, post, synapse_type)

Connect two compartments with a chemical synapse.

The pre- and postsynaptic compartments must be different compartments of the same network.

Parameters:

Name Type Description Default
pre CompartmentView

View of the presynaptic compartment.

required
post CompartmentView

View of the postsynaptic compartment.

required
synapse_type Synapse

The synapse to append

required
Source code in jaxley/connect.py
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
def connect(
    pre: "CompartmentView",
    post: "CompartmentView",
    synapse_type: "Synapse",
):
    """Connect two compartments with a chemical synapse.

    The pre- and postsynaptic compartments must be different compartments of the
    same network.

    Args:
        pre: View of the presynaptic compartment.
        post: View of the postsynaptic compartment.
        synapse_type: The synapse to append
    """
    assert is_same_network(
        pre, post
    ), "Pre and post compartments must be part of the same network."
    assert np.all(
        pre_comp_not_equal_post_comp(pre, post)
    ), "Pre and post compartments must be different."

    pre._append_multiple_synapses(pre.view, post.view, synapse_type)

connectivity_matrix_connect(pre_cell_view, post_cell_view, synapse_type, connectivity_matrix)

Appends multiple connections which build a custom connected network.

Connects pre- and postsynaptic cells according to a custom connectivity matrix. Entries > 0 in the matrix indicate a connection between the corresponding cells. Connections are from branch 0 location 0 to a randomly chosen branch and loc.

Parameters:

Name Type Description Default
pre_cell_view CellView

View of the presynaptic cell.

required
post_cell_view CellView

View of the postsynaptic cell.

required
synapse_type Synapse

The synapse to append.

required
connectivity_matrix ndarray[bool]

A boolean matrix indicating the connections between cells.

required
Source code in jaxley/connect.py
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
def connectivity_matrix_connect(
    pre_cell_view: "CellView",
    post_cell_view: "CellView",
    synapse_type: "Synapse",
    connectivity_matrix: np.ndarray[bool],
):
    """Appends multiple connections which build a custom connected network.

    Connects pre- and postsynaptic cells according to a custom connectivity matrix.
    Entries > 0 in the matrix indicate a connection between the corresponding cells.
    Connections are from branch 0 location 0 to a randomly chosen branch and loc.

    Args:
        pre_cell_view: View of the presynaptic cell.
        post_cell_view: View of the postsynaptic cell.
        synapse_type: The synapse to append.
        connectivity_matrix: A boolean matrix indicating the connections between cells.
    """
    # Get pre- and postsynaptic cell indices.
    pre_cell_inds, post_cell_inds = get_pre_post_inds(pre_cell_view, post_cell_view)

    assert connectivity_matrix.shape == (
        pre_cell_view.shape[0],
        post_cell_view.shape[0],
    ), "Connectivity matrix must have shape (num_pre, num_post)."
    assert connectivity_matrix.dtype == bool, "Connectivity matrix must be boolean."

    # get connection pairs from connectivity matrix
    from_idx, to_idx = np.where(connectivity_matrix)
    pre_cell_inds = pre_cell_inds[from_idx]
    post_cell_inds = post_cell_inds[to_idx]

    # Sample random postsynaptic compartments (global comp indices).
    global_post_indices = [
        sample_comp(post_cell_view, cell_idx).index[0] for cell_idx in post_cell_inds
    ]
    post_rows = post_cell_view.view.loc[global_post_indices]

    idcs_to_zero = np.zeros_like(from_idx)
    get_global_idx = post_cell_view.pointer._local_inds_to_global
    global_pre_indices = get_global_idx(pre_cell_inds, idcs_to_zero, idcs_to_zero)
    pre_rows = pre_cell_view.view.loc[global_pre_indices]

    pre_cell_view._append_multiple_synapses(pre_rows, post_rows, synapse_type)

fully_connect(pre_cell_view, post_cell_view, synapse_type)

Appends multiple connections which build a fully connected layer.

Connections are from branch 0 location 0 to a randomly chosen branch and loc.

Parameters:

Name Type Description Default
pre_cell_view CellView

View of the presynaptic cell.

required
post_cell_view CellView

View of the postsynaptic cell.

required
synapse_type Synapse

The synapse to append.

required
Source code in jaxley/connect.py
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
def fully_connect(
    pre_cell_view: "CellView",
    post_cell_view: "CellView",
    synapse_type: "Synapse",
):
    """Appends multiple connections which build a fully connected layer.

    Connections are from branch 0 location 0 to a randomly chosen branch and loc.

    Args:
        pre_cell_view: View of the presynaptic cell.
        post_cell_view: View of the postsynaptic cell.
        synapse_type: The synapse to append.
    """
    # Get pre- and postsynaptic cell indices.
    pre_cell_inds, post_cell_inds = get_pre_post_inds(pre_cell_view, post_cell_view)
    num_pre, num_post = len(pre_cell_inds), len(post_cell_inds)

    # Infer indices of (random) postsynaptic compartments.
    global_post_indices = (
        post_cell_view.view.groupby("cell_index")
        .sample(num_pre, replace=True)
        .index.to_numpy()
    )
    global_post_indices = global_post_indices.reshape((-1, num_pre), order="F").ravel()
    post_rows = post_cell_view.view.loc[global_post_indices]

    # Pre-synapse is at the zero-eth branch and zero-eth compartment.
    pre_rows = pre_cell_view[0, 0].view
    # Repeat rows `num_post` times. See SO 50788508.
    pre_rows = pre_rows.loc[pre_rows.index.repeat(num_post)].reset_index(drop=True)

    pre_cell_view._append_multiple_synapses(pre_rows, post_rows, synapse_type)

get_pre_post_inds(pre_cell_view, post_cell_view)

Get the unique cell indices of the pre- and postsynaptic cells.

Source code in jaxley/connect.py
 9
10
11
12
13
14
15
def get_pre_post_inds(
    pre_cell_view: "CellView", post_cell_view: "CellView"
) -> Tuple[np.ndarray, np.ndarray]:
    """Get the unique cell indices of the pre- and postsynaptic cells."""
    pre_cell_inds = np.unique(pre_cell_view.view["cell_index"].to_numpy())
    post_cell_inds = np.unique(post_cell_view.view["cell_index"].to_numpy())
    return pre_cell_inds, post_cell_inds

is_same_network(pre, post)

Check if views are from the same network.

Source code in jaxley/connect.py
26
27
28
29
30
def is_same_network(pre: "View", post: "View") -> bool:
    """Check if views are from the same network."""
    is_in_net = "network" in pre.pointer.__class__.__name__.lower()
    is_in_same_net = pre.pointer is post.pointer
    return is_in_net and is_in_same_net

pre_comp_not_equal_post_comp(pre, post)

Check if pre and post compartments are different.

Source code in jaxley/connect.py
18
19
20
21
22
23
def pre_comp_not_equal_post_comp(
    pre: "CompartmentView", post: "CompartmentView"
) -> np.ndarray[bool]:
    """Check if pre and post compartments are different."""
    cols = ["cell_index", "branch_index", "comp_index"]
    return np.any(pre.view[cols].values != post.view[cols].values, axis=1)

sample_comp(cell_view, cell_idx, num=1, replace=True)

Sample a compartment from a cell.

Returns View with shape (num, num_cols).

Source code in jaxley/connect.py
33
34
35
36
37
38
39
40
def sample_comp(
    cell_view: "CellView", cell_idx: int, num: int = 1, replace=True
) -> "CompartmentView":
    """Sample a compartment from a cell.

    Returns View with shape (num, num_cols)."""
    cell_idx_view = lambda view, cell_idx: view[view["cell_index"] == cell_idx]
    return cell_idx_view(cell_view.view, cell_idx).sample(num, replace=replace)

sparse_connect(pre_cell_view, post_cell_view, synapse_type, p)

Appends multiple connections which build a sparse, randomly connected layer.

Connections are from branch 0 location 0 to a randomly chosen branch and loc.

Parameters:

Name Type Description Default
pre_cell_view CellView

View of the presynaptic cell.

required
post_cell_view CellView

View of the postsynaptic cell.

required
synapse_type Synapse

The synapse to append.

required
p float

Probability of connection.

required
Source code in jaxley/connect.py
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
def sparse_connect(
    pre_cell_view: "CellView",
    post_cell_view: "CellView",
    synapse_type: "Synapse",
    p: float,
):
    """Appends multiple connections which build a sparse, randomly connected layer.

    Connections are from branch 0 location 0 to a randomly chosen branch and loc.

    Args:
        pre_cell_view: View of the presynaptic cell.
        post_cell_view: View of the postsynaptic cell.
        synapse_type: The synapse to append.
        p: Probability of connection.
    """
    # Get pre- and postsynaptic cell indices.
    pre_cell_inds, post_cell_inds = get_pre_post_inds(pre_cell_view, post_cell_view)
    num_pre, num_post = len(pre_cell_inds), len(post_cell_inds)

    num_connections = np.random.binomial(num_pre * num_post, p)
    pre_syn_neurons = np.random.choice(pre_cell_inds, size=num_connections)
    post_syn_neurons = np.random.choice(post_cell_inds, size=num_connections)

    # Sort the synapses only for convenience of inspecting `.edges`.
    sorting = np.argsort(pre_syn_neurons)
    pre_syn_neurons = pre_syn_neurons[sorting]
    post_syn_neurons = post_syn_neurons[sorting]

    # Post-synapse is a randomly chosen branch and compartment.
    global_post_indices = [
        sample_comp(post_cell_view, cell_idx).index[0] for cell_idx in post_syn_neurons
    ]
    post_rows = post_cell_view.view.loc[global_post_indices]

    # Pre-synapse is at the zero-eth branch and zero-eth compartment.
    idcs_to_zero = np.zeros_like(num_pre)
    get_global_idx = pre_cell_view.pointer._local_inds_to_global
    global_pre_indices = get_global_idx(pre_syn_neurons, idcs_to_zero, idcs_to_zero)
    pre_rows = pre_cell_view.view.loc[global_pre_indices]

    pre_cell_view._append_multiple_synapses(pre_rows, post_rows, synapse_type)