///|
/// 空间邻域富集与空间细胞通讯演示.
///
/// 1. 6x6 网格, 左半 A 类 / 右半 B 类 -> 邻域富集 z-score
/// 2. 2x2 布局 sender/receiver -> 空间配体-受体通讯
/// 3. 通讯结果按 source->target 聚合
///|
/// 构造 n x n 网格坐标.
fn demo_grid(n : Int32) -> Array[(Double, Double)] {
let out : Array[(Double, Double)] = Array(capacity=0)
let mut i = 0
while i < n {
let mut j = 0
while j < n {
out.push((i.to_double(), j.to_double()))
j = j + 1
}
i = i + 1
}
out
}
///|
/// 左半 A / 右半 B 标签.
fn demo_split_labels(
coords : Array[(Double, Double)],
cut : Double,
) -> Array[String] {
let out : Array[String] = Array(capacity=0)
for c in coords {
let (x, _) = c
if x < cut {
out.push("A")
} else {
out.push("B")
}
}
out
}
///|
/// 主函数.
fn main raise {
println("=== 空间邻域富集 ===")
let coords = demo_grid(6)
let labels = demo_split_labels(coords, 3.0)
println(
"spot 数: " +
coords.length().to_string() +
", 类别: A(左半) / B(右半)",
)
let enr = @src.nhood_enrichment(coords, labels, k=6, n_perms=50, seed=1)
println("类别顺序: " + repr(enr.labels()))
println("z-score 矩阵 (行=源类别, 列=邻域类别):")
for row in enr.zscore() {
println(" " + repr(row))
}
println("A 邻域内 A 富集 z = " + enr.zscore_of("A", "A").to_string())
println("A 邻域内 B 富集 z = " + enr.zscore_of("A", "B").to_string())
println("\n=== 空间细胞通讯 ===")
let comm_coords : Array[(Double, Double)] = [
(0.0, 0.0),
(1.0, 0.0),
(0.0, 1.0),
(1.0, 1.0),
]
let comm_labels : Array[String] = ["S", "S", "R", "R"]
let expr : Array[Array[Double]] = [
[5.0, 0.0],
[4.0, 0.0],
[0.0, 3.0],
[0.0, 2.0],
]
let genes : Array[String] = ["LIG", "REC"]
let pairs : Array[@src.LRPair] = [@src.lr_pair("LIG", "REC")]
let scores = @src.spatial_cellchat(
comm_coords,
comm_labels,
expr,
genes,
pairs,
k=2,
)
println("检出通讯条目数: " + scores.length().to_string())
for s in scores {
println(
" " +
s.source() +
" -> " +
s.target() +
" " +
s.ligand() +
"-" +
s.receptor() +
" pairs=" +
s.n_pairs().to_string() +
" score=" +
s.score().to_string(),
)
}
let agg = @src.spatial_cellchat_aggregate(scores)
println("按 source->target 聚合:")
for key in agg.keys() {
println(" " + key + " : " + agg[key].to_string())
}
println("\n演示完成")
}