///|
fn bluster_demo_ints(values : Array[Int32]) -> String {
values.map(fn(value) { value.to_string() }).join(", ")
}
///|
fn bluster_demo_doubles(values : Array[Double]) -> String {
values.map(fn(value) { value.to_string() }).join(", ")
}
///|
fn bluster_demo_optional(value : Double?) -> String {
match value {
Some(actual) => actual.to_string()
None => "NA"
}
}
///|
fn main {
println("=== Bioconductor bluster 1.23.0 Demo ===")
let coordinates = [
[0.0, 0.0],
[0.1, 0.0],
[0.2, 0.1],
[0.3, 0.1],
[10.0, 10.0],
[10.1, 10.0],
[10.2, 10.1],
[10.3, 10.1],
]
let kmeans_config = @bio.BlusterKmeansConfig::create(2, starts=8, seed=101) catch {
_ => abort("failed to create the k-means configuration")
}
let kmeans = @bio.bluster_cluster_rows_kmeans(coordinates, kmeans_config) catch {
_ => abort("k-means clustering failed")
}
println("\n1. Deterministic multi-start K-means")
println(" clusters: " + bluster_demo_ints(kmeans.clusters))
println(
" total within sum of squares: " +
kmeans.total_within_sum_squares.to_string(),
)
let graph = @bio.bluster_make_snn_graph(
coordinates,
k=2,
weighting=@bio.bluster_rank_weight(),
) catch {
_ => abort("SNN graph construction failed")
}
let graph_config = @bio.BlusterGraphConfig::create(
k=2,
resolution=0.5,
seed=103,
) catch {
_ => abort("failed to create the graph configuration")
}
let graph_clusters = @bio.bluster_cluster_rows_graph(
coordinates, graph_config,
) catch {
_ => abort("graph clustering failed")
}
println("\n2. Exact SNN graph and Louvain-style optimization")
println(" graph edges: " + graph.edge_count().to_string())
println(" clusters: " + bluster_demo_ints(graph_clusters.clusters))
println(" modularity: " + graph_clusters.modularity.to_string())
let two_step_config = @bio.BlusterTwoStepConfig::create(
first_centers=4,
first_starts=5,
second_k=1,
resolution=0.5,
seed=107,
) catch {
_ => abort("failed to create the two-step configuration")
}
let two_step = @bio.bluster_cluster_rows_two_step(
coordinates, two_step_config,
) catch {
_ => abort("two-step clustering failed")
}
println("\n3. Two-step vector quantization")
println(" centroids: " + two_step.centroids.length().to_string())
println(" clusters: " + bluster_demo_ints(two_step.clusters))
let rand = @bio.bluster_pairwise_rand(
kmeans.clusters,
graph_clusters.clusters,
) catch {
_ => abort("Rand comparison failed")
}
let silhouette = @bio.bluster_approx_silhouette(
coordinates,
graph_clusters.clusters,
) catch {
_ => abort("silhouette approximation failed")
}
let purity = @bio.bluster_neighbor_purity(
coordinates,
graph_clusters.clusters,
k=2,
) catch {
_ => abort("neighbor purity failed")
}
let rmsd = @bio.bluster_cluster_rmsd(coordinates, graph_clusters.clusters) catch {
_ => abort("cluster RMSD failed")
}
println("\n4. Cluster diagnostics")
println(" adjusted Rand index: " + bluster_demo_optional(rand.index))
println(" silhouette widths: " + bluster_demo_doubles(silhouette.widths))
println(" neighbor purities: " + bluster_demo_doubles(purity.purity))
println(" first cluster RMSD: " + bluster_demo_optional(rmsd.values[0]))
let stability = @bio.bluster_bootstrap_kmeans_stability(
coordinates,
kmeans_config,
iterations=8,
seed=109,
) catch {
_ => abort("bootstrap stability failed")
}
println("\n5. Bootstrap stability")
println(
" first cluster coherence: " +
bluster_demo_optional(stability.ratios[0][0]),
)
println(
" cluster separation: " + bluster_demo_optional(stability.ratios[0][1]),
)
let experiment = @bio.SingleCellExperiment::new(
[
[8.0, 7.0, 9.0, 8.0, 1.0, 2.0, 1.0, 2.0],
[1.0, 2.0, 1.0, 2.0, 8.0, 7.0, 9.0, 8.0],
],
["MarkerA", "MarkerB"],
["C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8"],
)
experiment.reduced_dims["PCA"] = coordinates
experiment.metadata["source"] = "bluster_demo"
let clustered = @bio.bluster_cluster_sce(
experiment,
graph_config,
output_column="community",
) catch {
_ => abort("SCE clustering failed")
}
println("\n6. Immutable SingleCellExperiment integration")
println(
" written labels: " + clustered.experiment.col_data["community"].join(", "),
)
println(
" original unchanged: " +
(!experiment.col_data.contains("community")).to_string(),
)
println("\nbluster demo completed.")
}