Score one cluster's expression signature against the atlas.
cluster_zscores is {gene_symbol: cluster_vs_rest_zscore} —
one cluster's differential-expression z-score against all other
cells. The recommended client recipe is scanpy's
rank_genes_groups(adata, groupby='leiden', method='wilcoxon'),
keeping only HVGs (~2k-5k genes, ~50 KB JSON). z > 0 = the gene
is upregulated in this cluster vs rest; z < 0 = downregulated.
Do NOT use "cluster mean of globally z-scored X" — that collapses
to ≈ 0 for clusters that dominate the cohort (the cluster's cells
ARE the population mean it's z-scored against). Cluster-vs-rest
is the right baseline.
The server scores each candidate as the L2-normalised inner
product of the cluster's z-vector against a signed marker
template (+spec for positive markers, -spec for negative markers,
spec scoped to tissue + species + optional disease). The full
atlas never leaves the server.