///|
/// ESTIMATE module demo - tumor microenvironment scoring.
///
/// Run: moon run examples/estimate_score_demo
fn main {
println("=== ESTIMATE Module Demo ===")
println("Estimation of STromal and Immune cells in MAlignant Tumours")
println("Reference: Yoshihara K et al. (2013) Nature Communications 4:2612")
println("")
// ------------------------------------------------------------------
// 1. Display built-in gene signatures
// ------------------------------------------------------------------
println("=== 1. Built-in gene signatures ===")
let sig = @bio.est_default_signature()
println("Stromal signature genes: \{sig.stromal_genes().length()}")
println("Immune signature genes: \{sig.immune_genes().length()}")
let stromal_preview = sig.stromal_genes()
let immune_preview = sig.immune_genes()
// Show first 5 of each
let mut i = 0
let mut st_preview = ""
while i < 5 && i < stromal_preview.length() {
if i > 0 {
st_preview = st_preview + ", "
}
st_preview = st_preview + stromal_preview[i]
i = i + 1
}
i = 0
let mut im_preview = ""
while i < 5 && i < immune_preview.length() {
if i > 0 {
im_preview = im_preview + ", "
}
im_preview = im_preview + immune_preview[i]
i = i + 1
}
println("Stromal (first 5): \{st_preview}")
println("Immune (first 5): \{im_preview}")
println("")
// ------------------------------------------------------------------
// 2. Load sample expression data
// ------------------------------------------------------------------
println("=== 2. Load sample expression data ===")
let expr = @bio.est_sample_data()
println("Genes: \{expr.gene_names().length()}")
println("Samples: \{expr.sample_names().length()}")
println("Sample names: \{Repr(expr.sample_names())}")
println("")
// ------------------------------------------------------------------
// 3. Run ESTIMATE
// ------------------------------------------------------------------
println("=== 3. Run ESTIMATE scoring ===")
let result = @bio.est_run(expr)
println("Method: \{result.method_name()}")
println("")
// ------------------------------------------------------------------
// 4. Display per-sample scores
// ------------------------------------------------------------------
println("=== 4. Per-sample ESTIMATE scores ===")
for s in result.scores() {
println("--- Sample: \{s.sample_id()} ---")
println(" Stromal score: \{s.stromal_score()}")
println(" Immune score: \{s.immune_score()}")
println(" ESTIMATE score: \{s.estimate_score()}")
if s.tumor_purity().is_nan() {
println(" Tumor purity: NA (undefined)")
} else {
println(" Tumor purity: \{s.tumor_purity()}")
}
println("")
}
// ------------------------------------------------------------------
// 5. Compare infiltration profiles
// ------------------------------------------------------------------
println("=== 5. Infiltration profile comparison ===")
let high_stromal = result.get_score("HighStromal")
let high_immune = result.get_score("HighImmune")
let high_both = result.get_score("HighBoth")
let low_both = result.get_score("LowBoth")
println("Sample Stromal Immune ESTIMATE Purity")
println(
"HighStromal \{high_stromal.stromal_score()} \{high_stromal.immune_score()} \{high_stromal.estimate_score()} \{purity_str(high_stromal.tumor_purity())}",
)
println(
"HighImmune \{high_immune.stromal_score()} \{high_immune.immune_score()} \{high_immune.estimate_score()} \{purity_str(high_immune.tumor_purity())}",
)
println(
"HighBoth \{high_both.stromal_score()} \{high_both.immune_score()} \{high_both.estimate_score()} \{purity_str(high_both.tumor_purity())}",
)
println(
"LowBoth \{low_both.stromal_score()} \{low_both.immune_score()} \{low_both.estimate_score()} \{purity_str(low_both.tumor_purity())}",
)
println("")
// ------------------------------------------------------------------
// 6. Interpretation
// ------------------------------------------------------------------
println("=== 6. Interpretation ===")
if high_stromal.stromal_score() > low_both.stromal_score() {
println("-> HighStromal has higher stromal score than LowBoth (expected)")
}
if high_immune.immune_score() > low_both.immune_score() {
println("-> HighImmune has higher immune score than LowBoth (expected)")
}
if high_both.estimate_score() > low_both.estimate_score() {
println("-> HighBoth has higher ESTIMATE score than LowBoth (expected)")
}
if low_both.stromal_score() < 0.0 && low_both.immune_score() < 0.0 {
println("-> LowBoth has negative scores (low infiltration, tumor-dominant)")
}
if !low_both.tumor_purity().is_nan() &&
!high_both.tumor_purity().is_nan() &&
low_both.tumor_purity() >= high_both.tumor_purity() {
println("-> LowBoth has higher tumor purity (less infiltration)")
}
println("")
// ------------------------------------------------------------------
// 7. Custom signature example
// ------------------------------------------------------------------
println("=== 7. Custom gene signature example ===")
let custom_sig = @bio.EstSignature::new(["G1", "G2", "G3"], ["G3", "G4", "G5"])
let custom_expr = @bio.EstExpression::new(
["G1", "G2", "G3", "G4", "G5"],
["S1", "S2"],
[
[10.0, 1.0], // G1 - stromal, high in S1
[8.0, 1.0], // G2 - stromal, high in S1
[5.0, 5.0], // G3 - shared
[1.0, 9.0], // G4 - immune, high in S2
[1.0, 8.0], // G5 - immune, high in S2
],
)
let custom_result = @bio.est_run(custom_expr, signature=custom_sig)
println("Custom signature result:")
for s in custom_result.scores() {
println(
" \{s.sample_id()}: stromal=\{s.stromal_score()}, immune=\{s.immune_score()}, estimate=\{s.estimate_score()}",
)
}
println("")
// ------------------------------------------------------------------
// 8. Full result table
// ------------------------------------------------------------------
println("=== 8. Full result table ===")
println(result.to_string())
println("=== Demo Complete ===")
}
///|
/// Format tumor purity for display.
fn purity_str(p : Double) -> String {
if p.is_nan() {
"NA"
} else {
p.to_string()
}
}