Connectivities / KNN Graph#
Audience: computational users
Time: 10–20 minutes
Goal: export a cell–cell graph safely (without shape/order bugs).
connectivities is an optional (n_cells, n_cells) adjacency/connectivity matrix.
In the Cellucid ecosystem, this is typically a KNN/SNN graph derived from:
scRNA-seq neighbor graphs,
integrated embeddings,
or any graph you want to visualize/use for neighbor-based interactions.
Requirements#
shape must be
(n_cells, n_cells)rows/cols must correspond to the same cell ordering as embeddings/obs
input can be:
a base R
matrix, ora
Matrix::Matrixsparse matrix (recommended)
values must be real numeric or logical, finite, and non-negative
topology and weights must be exactly symmetric
every diagonal value must be exactly
0the
Matrixpackage must be installed when the input is sparsesparse matrices must not contain stored zero entries or duplicate coordinates
Note
If you do not need connectivity features, skip this entirely. Exports load fine without it.
Exact exported representation#
Cellucid validates the graph without changing it. It does not symmetrize,
binarize, discard weights, coalesce coordinates, remove self-edges, or
otherwise reinterpret scientific input. Asymmetric, directed, negative,
non-finite, nonzero-diagonal, sparse-stored-zero, and duplicate-coordinate
graphs fail before graph artifacts are written. Logical TRUE is the explicit
unit edge and is written as the exact Float64 weight 1.0.
For a valid graph, the exporter:
extracts each undirected edge once from the upper triangle (
src < dst);sorts the pairs lexicographically;
writes three aligned arrays:
edges.src.binedges.dst.binedges.weights.f64.bin
Indices are zero-based in the binary files.
Weights are exact little-endian Float64 values.
A valid graph with no edges remains present and reports n_edges: 0 and
max_neighbors: 0; all three payloads are zero length.
Output files#
connectivity_manifest.jsonconnectivity/edges.src.bin(or.gz)connectivity/edges.dst.bin(or.gz)connectivity/edges.weights.f64.bin(or.gz)
The manifest records:
n_cellsn_edgesmax_neighbors(maximum degree in the validated graph)index_dtype/index_bytes(uint16oruint32)weightsPath,weight_dtype: "float64", andweight_bytes: 8
Index dtype and dataset size limits#
Cell indices are stored using the smallest unsigned integer that fits:
|
dtype |
|---|---|
1–65,536 |
|
65,537–4,294,967,296 |
|
larger |
rejected; no current |
R matrices have lower practical dimension and memory limits than the format’s
mathematical uint32 ceiling. Prefer sparse matrices and use server-backed
loading when a graph exceeds the browser working-set limit.
Practical recipes (where to get a graph)#
Seurat#
Seurat often stores graphs in seu@graphs, for example:
seu@graphs$RNA_snn
You must ensure it matches the cell order you export:
cells <- colnames(seu)
conn <- seu@graphs$RNA_snn
conn <- conn[cells, cells]
Then pass connectivities = conn.
SingleCellExperiment#
Graph storage varies by workflow. Common patterns include:
adjacency matrices stored in
metadata(sce)KNN graphs stored as edge lists / igraph objects
If you can obtain an adjacency matrix conn with shape (n_cells, n_cells), you can export it.
Edge cases#
Directed or asymmetric graphs#
Rejected. Construct and review the intended symmetric weighted graph explicitly
before calling cellucid_prepare().
Weighted graphs#
Accepted when weights are finite, non-negative, exactly symmetric, and exactly representable as Float64. They are preserved in the aligned weight payload.
Self-edges, negative values, or non-finite values#
Rejected. The diagonal must be exactly zero and every value must be finite and non-negative.
Dense matrices#
A dense (n_cells, n_cells) matrix becomes huge quickly. Prefer sparse matrices.
Troubleshooting pointers#
“Matrix package is required to export connectivity matrices” → install
Matrix.“Connectivity matrix shape … does not match number of cells” → you have an ordering or subset mismatch.
Viewer is slow/crashes after adding connectivities → your graph is too dense (too many edges).