What is a connection weight made of?¶
The weight of a connection is a count of synapses from one cell to
another.
CAVE's synapse view has one row per synapse,
and champalimaud.fetch counts the rows of each pair of cells
(the outputs of a cell by its presynaptic id,
its inputs by its postsynaptic id).
If that is all a weight is,
the rows of one cell should reproduce its stored weights exactly.
synapses holds the rows of one LC16 cell, fetched once as the
dataset example_synapses.
| cell | id | pre_pt_root_id | post_pt_root_id |
|---|---|---|---|
| i64 | i64 | i64 | i64 |
| 720575940606173630 | 159305691 | 720575940606173630 | 720575940615645034 |
| 720575940606173630 | 162802451 | 720575940606173630 | 720575940615645034 |
| 720575940606173630 | 159304826 | 720575940606173630 | 720575940615645034 |
| 720575940606173630 | 161891568 | 720575940606173630 | 720575940615645034 |
| 720575940606173630 | 162803628 | 720575940606173630 | 720575940445991679 |
| … | … | … | … |
| 720575940606173630 | 190197806 | 720575940616434260 | 720575940606173630 |
| 720575940606173630 | 190197390 | 720575940616434260 | 720575940606173630 |
| 720575940606173630 | 190196942 | 720575940622648703 | 720575940606173630 |
| 720575940606173630 | 190193625 | 720575940622664522 | 720575940606173630 |
| 720575940606173630 | 190198656 | 720575940609598475 | 720575940606173630 |
Rows per pair¶
pairs counts the rows between each pair of cells.
pairs = (
synapses.group_by("pre_pt_root_id", "post_pt_root_id")
.agg(rows=pl.len())
.sort("rows", descending=True)
)
pairs
| pre_pt_root_id | post_pt_root_id | rows |
|---|---|---|
| i64 | i64 | u32 |
| 720575940606173630 | 720575940613369586 | 25 |
| 720575940606173630 | 720575940606609696 | 24 |
| 720575940627497244 | 720575940606173630 | 17 |
| 720575940606173630 | 720575940615645034 | 16 |
| 720575940619690968 | 720575940606173630 | 14 |
| … | … | … |
| 720575940610984516 | 720575940606173630 | 1 |
| 720575940611329501 | 720575940606173630 | 1 |
| 720575940624090493 | 720575940606173630 | 1 |
| 720575940623775843 | 720575940606173630 | 1 |
| 720575940637630565 | 720575940606173630 | 1 |
Against the stored weights¶
stored is every connection in connections.parquet that starts
or ends at the cell.
The joined table has one row per pair,
with the number of rows and the stored weight side by side.
stored = pl.concat(
[
load_connections_of([cell]),
load_connections_of([cell], end="post"),
]
).unique()
compared = pairs.join(
stored, on=["pre_pt_root_id", "post_pt_root_id"], how="full"
)
compared.select(
pairs=pl.len(),
only_in_rows=pl.col("weight").is_null().sum(),
only_stored=pl.col("rows").is_null().sum(),
equal=(pl.col("rows") == pl.col("weight")).sum(),
)
| pairs | only_in_rows | only_stored | equal |
|---|---|---|---|
| u32 | u32 | u32 | u32 |
| 692 | 0 | 0 | 692 |
How the weight is spread¶
The number of pairs at each weight, and the synapses they hold. Most connections are one or two synapses, but the heavier ones hold a large share of all synapses.
pairs.group_by("rows").agg(pairs=pl.len()).with_columns(
synapses=pl.col("rows") * pl.col("pairs")
).sort("rows").rename({"rows": "weight"})
| weight | pairs | synapses |
|---|---|---|
| u32 | u32 | u32 |
| 1 | 486 | 486 |
| 2 | 101 | 202 |
| 3 | 36 | 108 |
| 4 | 25 | 100 |
| 5 | 11 | 55 |
| … | … | … |
| 14 | 2 | 28 |
| 16 | 1 | 16 |
| 17 | 1 | 17 |
| 24 | 1 | 24 |
| 25 | 1 | 25 |