///|
/// NanoString nCounter demo - Digital barcode counting analysis.
///
/// Demonstrates sample/container construction, positive/negative/housekeeping
/// and content normalization, QC (imaging, linearity, LOQ), differential
/// expression analysis with t-tests and BH-FDR, and textual summaries.
///
/// Reference: RTC (2018) NanoStringNCTools: NanoString nCounter Tools.
/// Bioconductor package.
/// Run: moon run examples/nanostring_demo
fn main {
println("=== NanoString nCounter Demo ===")
println("Digital molecular barcode counting analysis")
println("")
// ------------------------------------------------------------------
// 1. Load sample data
// ------------------------------------------------------------------
println("=== 1. Load sample data ===")
let data = @bio.ns_sample_data()
println("Samples: \{data.n_samples()}")
println("Endogenous genes: \{data.n_genes()}")
let samples = data.samples()
for s in samples {
println(
" " +
s.sample_id() +
": raw=" +
s.raw_counts().length().to_string() +
" pos_ctrl=" +
s.positive_controls().length().to_string() +
" neg_ctrl=" +
s.negative_controls().length().to_string() +
" hk=" +
s.housekeeping().length().to_string() +
" endo=" +
s.endogenous().length().to_string(),
)
}
println("")
// ------------------------------------------------------------------
// 2. Geometric mean and log2 utility demonstration
// ------------------------------------------------------------------
println("=== 2. Utility functions ===")
let gm = @bio.ns_geometric_mean([2.0, 8.0])
println("geometric_mean([2, 8]) = " + gm.to_string() + " (expected 4.0)")
let log2_vals = @bio.ns_log2_counts([0.0, 1.0, 7.5, 15.5])
println("log2_counts([0, 1, 7.5, 15.5]) = " + repr(log2_vals))
println("")
// ------------------------------------------------------------------
// 3. Positive control normalization
// ------------------------------------------------------------------
println("=== 3. Positive control normalization ===")
let pos_results = @bio.ns_positive_control_norm(data)
for r in pos_results {
println(
" " +
r.sample_id() +
": factor=" +
r.norm_factors()[0].to_string() +
" method=" +
r.method_() +
" first_count=" +
r.normalized_counts()[0].to_string(),
)
}
println("")
// ------------------------------------------------------------------
// 4. Negative control (background) normalization
// ------------------------------------------------------------------
println("=== 4. Negative control normalization ===")
let neg_results = @bio.ns_negative_control_norm(data)
for r in neg_results {
println(
" " +
r.sample_id() +
": factor=" +
r.norm_factors()[0].to_string() +
" method=" +
r.method_() +
" first_count=" +
r.normalized_counts()[0].to_string(),
)
}
println("")
// ------------------------------------------------------------------
// 5. Housekeeping gene normalization
// ------------------------------------------------------------------
println("=== 5. Housekeeping normalization ===")
let hk_results = @bio.ns_housekeeping_norm(data)
for r in hk_results {
println(
" " +
r.sample_id() +
": factor=" +
r.norm_factors()[0].to_string() +
" method=" +
r.method_() +
" first_count=" +
r.normalized_counts()[0].to_string(),
)
}
println("")
// ------------------------------------------------------------------
// 6. Content normalization (positive + housekeeping)
// ------------------------------------------------------------------
println("=== 6. Content normalization ===")
let content_results = @bio.ns_content_norm(data)
for r in content_results {
let n_factors = r.norm_factors().length()
let factors_str = if n_factors >= 2 {
"pos=" +
r.norm_factors()[0].to_string() +
", hk=" +
r.norm_factors()[1].to_string()
} else {
"factor=" + r.norm_factors()[0].to_string()
}
println(
" " +
r.sample_id() +
": " +
factors_str +
" method=" +
r.method_() +
" first_count=" +
r.normalized_counts()[0].to_string(),
)
}
println("")
// ------------------------------------------------------------------
// 7. Quality control
// ------------------------------------------------------------------
println("=== 7. Quality control ===")
let imaging = @bio.ns_imaging_qc(data, 100)
let (r_sq, slope) = @bio.ns_pos_linearity_qc(data)
let loq = @bio.ns_loq_qc(data, 50)
println("Imaging QC (threshold=100):")
for i in 0.. 0.0 {
n_up = n_up + 1
} else {
n_down = n_down + 1
}
}
}
println("Genes tested: \{de_results.length()}")
println("Significant (adj p < 0.05): \{n_sig}")
println(" Up-regulated: \{n_up}")
println(" Down-regulated: \{n_down}")
println("")
// Manual bubble sort by adjusted p-value (ascending) for display.
let sorted_de = de_results.copy()
let m = sorted_de.length()
let mut i = 0
while i < m - 1 {
let mut j = 0
while j < m - 1 - i {
if sorted_de[j].adj_p_value() > sorted_de[j + 1].adj_p_value() {
let tmp = sorted_de[j]
sorted_de[j] = sorted_de[j + 1]
sorted_de[j + 1] = tmp
}
j = j + 1
}
i = i + 1
}
println("Top 10 DE genes by adjusted p-value:")
let top_n = if m < 10 { m } else { 10 }
for k in 0..