3. Connectivity¶
Everything lives under ds.connectivity.
Edges¶
fw.connectivity.edges("DA1_lPN") # both directions -> (40581, 3)
fw.connectivity.edges("DA1_lPN", upstream=False) # outputs only
fw.connectivity.edges("DA1_lPN", downstream=False) # inputs only
fw.connectivity.edges("DA1_lPN", min_weight=10) # >= 10 synapses
weight is a synapse count. Always int32, always the same column name.
Edges between two of your query neurons appear once, not twice — connecto de-duplicates across the up- and downstream fetches for you.
Adjacency¶
When you want a matrix rather than a list:
post 720575940603231916 720575940604407468 720575940605102694 ...
pre
720575940603231916 0 0 2
720575940604407468 0 0 0
720575940605102694 10 0 0
720575940613345442 4 0 6
...
Rows are sources, columns are targets, int32, zeros filled in. Different sets on the
two axes if you want them:
The row and column order is exactly the order of the IDs you passed, so it lines up with anything else you built from the same selection.
Synapse counts¶
id pre post
0 720575940603231916 4571 887
1 720575940604407468 4719 852
2 720575940605102694 5252 1155
3 720575940613345442 4381 852
4 720575940614309535 4308 876
pre = outgoing synapses, post = incoming. Add by_roi=True to split by neuropil.
Individual synapses¶
id pre post pre_x pre_y pre_z score roi
0 191366973 720575940621185050 720575940622964735 350712.0 152184.0 147120.0 176.0 LH_L
1 1200702 720575940621185050 720575940626999114 431108.0 146448.0 198600.0 71.0 MB_CA_L
2 1201179 720575940630066007 720575940588344515 615904.0 146364.0 199560.0 133.0 MB_CA_R
Positions are in nanometres. Not voxels, not "whatever the backend used". CAVE hands connecto nanometres; neuPrint hands it voxels and connecto multiplies by the dataset's voxel size. You never have to remember which.
Filtering synapses¶
fw.connectivity.synapses("DA1_lPN", min_score=50) # cleft score
fw.connectivity.synapses("DA1_lPN", rois=["LH_L"]) # by neuropil
fw.connectivity.synapses("DA1_lPN", pre=True, post=False) # outgoing only
min_score is the interesting one:
CapabilityError: MICrONS (minnie65) public does not support `min_score`
(no synapse_scores). Drop the argument, or use a dataset that has it.
MICrONS has no per-synapse cleft score. It would be easy for connecto to accept the argument and ignore it — and you would then believe you had filtered when you had not. That is the single most dangerous thing a normalisation layer can do, so it does not do it. See Capabilities.
Per-ROI connectivity¶
On datasets with neuropil annotations, split the edges by region:
pre post weight roi
0 722817260 296199149 1 LH(R)
1 722817260 297520036 1 LH(R)
2 722817260 297869179 2 LH(R)
3 722817260 329206392 1 LH(R)
4 722817260 329906396 7 LH(R)
Same three columns, plus roi. What ROIs are there?
roi primary
0 AB(L) True
1 AB(R) True
2 AL(L) True
3 AL(R) True
4 AL-D(L) False
...
[231 rows x 2 columns]
primary=True marks the non-overlapping set — the one to use if you want the parts to
sum to the whole. neuPrint's ROIs nest (AL-DA1(R) is inside AL(R)), and summing
across all 231 would double-count. There is a containment tree if you need it:
Transmitters¶
FlyWire has per-synapse neurotransmitter predictions — through the CAVE door. The
neuPrint mirror's Synapse nodes do not carry them, so ask the door that has them:
id nt confidence
0 720575940603231916 acetylcholine 0.972872
1 720575940604407468 acetylcholine 0.960161
2 720575940605102694 acetylcholine 0.942879
3 720575940613345442 acetylcholine 0.958457
4 720575940614309535 acetylcholine 0.964485
The vote is taken over that neuron's presynapses, and confidence is the winning
fraction — so you can see how convincing the call was, rather than just being handed a
label. Cholinergic, and confidently so, which is what an olfactory PN should be.
hemibrain has no per-synapse predictions, so:
CapabilityError: hemibrain (neuprint) does not support nt_per_synapse.
Available: annotations, connectivity, meshes, roi_connectivity, rois, segmentation,
skeletons, somas, synapse_scores, synapses.
Ask the neuPrint-backed FlyWire and you get the same refusal — but with a way out, because that dataset does have transmitters, just not through that door:
CapabilityError: FlyWire (FAFB) public release (neuprint) does not support
nt_per_synapse. ... The cave backend does: cn.get_dataset("flywire", backend="cave").
Caching¶
Edge fetches can be slow. cache=True writes the raw response to disk and reuses it:
The cache key includes the dataset, the version and the query — so a cached result can never be served for a different materialization. See Caching.
Next: morphology.