///|
fn format_doubles(values : Array[Double]) -> String {
let mut result = "["
let mut index = 0
while index < values.length() {
if index > 0 {
result = result + ", "
}
result = result + values[index].to_string()
index = index + 1
}
result + "]"
}
///|
fn main {
println("=== Bioconductor decontX Demo ===")
let (counts, genes, cells, clusters, background) = @src.decontx_example_data()
println("\n1. Infer cluster-aware ambient RNA contamination")
let result = @src.decontx(counts, genes, cells, clusters) catch {
_ => abort("failed to run cluster-aware decontX")
}
println(" " + result.summary())
println(" per-cell contamination: " + format_doubles(result.contamination))
println("\n2. Inspect cross-population marker correction")
println(
" B marker in T1: observed=" +
counts[2][0].to_string() +
", native=" +
result.corrected_counts[2][0].to_string() +
", contaminant=" +
result.contamination_counts[2][0].to_string(),
)
println(
" T marker in B1: observed=" +
counts[0][4].to_string() +
", native=" +
result.corrected_counts[0][4].to_string() +
", contaminant=" +
result.contamination_counts[0][4].to_string(),
)
println("\n3. Summarize contamination by cluster")
for estimate in result.cluster_estimates() {
println(
" " +
estimate.cluster +
": cells=" +
estimate.n_cells.to_string() +
", mean contamination=" +
estimate.mean_contamination.to_string() +
", contaminant counts=" +
estimate.contaminant_counts.to_string(),
)
}
let most_contaminated = result.most_contaminated_cells(2)
for estimate in most_contaminated {
println(
" high-contamination cell " +
estimate.cell_name +
": " +
estimate.contamination.to_string(),
)
}
println("\n4. Use empty droplets as an explicit ambient profile")
let background_result = @src.decontx(
counts,
genes,
cells,
clusters,
background~,
) catch {
_ => abort("failed to run background-aware decontX")
}
println(" " + background_result.summary())
println(
" shared ambient profile: " +
format_doubles(background_result.contaminant_profiles[0]),
)
println("\n5. Add corrected counts and diagnostics to an SCE copy")
let sce = @src.SingleCellExperiment::new(counts, genes, cells)
sce.col_data["cluster"] = clusters
let output = @src.decontx_sce(sce, background~) catch {
_ => abort("failed to integrate decontX with SingleCellExperiment")
}
println(
" corrected assay dimensions: " +
@src.sce_get_assay(output.experiment, "decontXcounts").length().to_string() +
" genes x " +
output.result.n_cells().to_string() +
" cells",
)
println(
" contamination metadata entries: " +
@src.sce_get_col_data(output.experiment, "decontX_contamination")
.length()
.to_string(),
)
println(
" source object unchanged: " +
(@src.sce_get_assay(sce, "decontXcounts").length() == 0).to_string(),
)
println("\n=== Demo Complete ===")
}