///|
/// GRanges advanced operations demo.
///
/// Demonstrates GRangesLocal construction, gaps, reduce, disjoin,
/// set operations (setdiff, intersect, union), coverage computation,
/// and promoter region calculation.
///
/// Run: moon run examples/genomic_ranges_gaps_demo/main.mbt
fn main {
println("=== GRanges Advanced Operations Demo ===")
println("")
println("1. Creating GRangesLocal with sample ranges")
let seqnames = ["chr1", "chr1", "chr1", "chr2", "chr2"]
let starts = [1, 50, 150, 1, 100]
let ends = [10, 80, 200, 50, 150]
let strands = ["+", "+", "-", "+", "-"]
let gr = @bio.grg_granges(seqnames, starts, ends, strands~)
println(" Created \{@bio.grg_length(gr)} ranges")
let mut i = 0
while i < gr.seqnames.length() {
println(
" \{gr.seqnames[i]}:\{gr.starts[i]}-\{gr.ends[i]} (strand=\{gr.strands[i]})",
)
i = i + 1
}
println("")
println("2. Finding gaps between ranges")
let seqlengths : Map[String, Int32] = Map([], capacity=2)
seqlengths["chr1"] = 300
seqlengths["chr2"] = 200
let gaps = @bio.grg_gaps(gr, seqlengths)
println(" Gaps found: \{gaps.seqnames.length()}")
i = 0
while i < gaps.seqnames.length() {
println(
" \{gaps.seqnames[i]}:\{gaps.starts[i]}-\{gaps.ends[i]} (length=\{gaps.gap_lengths[i]})",
)
i = i + 1
}
println("")
println("3. Reduce - merge overlapping/adjacent ranges")
// Create ranges that overlap
let gr_overlap = @bio.grg_granges(["chr1", "chr1", "chr1"], [1, 5, 20], [
10, 15, 30,
])
println(" Input ranges:")
i = 0
while i < gr_overlap.seqnames.length() {
println(
" \{gr_overlap.seqnames[i]}:\{gr_overlap.starts[i]}-\{gr_overlap.ends[i]}",
)
i = i + 1
}
let reduced = @bio.grg_reduce(gr_overlap)
println(" After reduce:")
i = 0
while i < reduced.seqnames.length() {
println(
" \{reduced.seqnames[i]}:\{reduced.starts[i]}-\{reduced.ends[i]} (merged \{reduced.merged_count[i]} ranges)",
)
i = i + 1
}
println("")
println("4. Disjoin - split into non-overlapping segments")
let disjoined = @bio.grg_disjoin(gr_overlap)
println(" Disjoined into segments: \{disjoined.seqnames.length()}")
i = 0
while i < disjoined.seqnames.length() {
println(
" \{disjoined.seqnames[i]}:\{disjoined.starts[i]}-\{disjoined.ends[i]} (segment id=\{disjoined.segment_ids[i]})",
)
i = i + 1
}
println("")
println("5. Set operations")
let gr_a = @bio.grg_granges(["chr1", "chr1"], [1, 50], [30, 80], strands=[
"+", "+",
])
let gr_b = @bio.grg_granges(["chr1"], [10], [20], strands=["-"])
println(" Set difference (A \\ B):")
let setdiff_result = @bio.grg_setdiff(gr_a, gr_b)
i = 0
while i < setdiff_result.seqnames.length() {
println(
" \{setdiff_result.seqnames[i]}:\{setdiff_result.starts[i]}-\{setdiff_result.ends[i]}",
)
i = i + 1
}
println(" Intersection (A ∩ B):")
let intersect_result = @bio.grg_intersect(gr_a, gr_b)
i = 0
while i < intersect_result.seqnames.length() {
println(
" \{intersect_result.seqnames[i]}:\{intersect_result.starts[i]}-\{intersect_result.ends[i]}",
)
i = i + 1
}
println(" Union (A ∪ B):")
let union_result = @bio.grg_union(gr_a, gr_b)
i = 0
while i < union_result.seqnames.length() {
println(
" \{union_result.seqnames[i]}:\{union_result.starts[i]}-\{union_result.ends[i]}",
)
i = i + 1
}
println("")
println("6. Computing coverage")
let gr_cov = @bio.grg_granges(["chr1", "chr1", "chr1"], [1, 3, 8], [5, 8, 12])
let cov_sl : Map[String, Int32] = Map([], capacity=1)
cov_sl["chr1"] = 15
let coverage = @bio.grg_compute_coverage(gr_cov, cov_sl)
let cov_arr = coverage["chr1"]
println(" Coverage array for chr1 (length 15):")
println(" \{Repr(cov_arr)}")
println("")
println("7. Computing promoter regions")
let gr_genes = @bio.grg_granges(
["chr1", "chr1", "chr2"],
[100, 500, 200],
[200, 600, 300],
strands=["+", "-", "*"],
)
println(" Gene ranges:")
i = 0
while i < gr_genes.seqnames.length() {
println(
" \{gr_genes.seqnames[i]}:\{gr_genes.starts[i]}-\{gr_genes.ends[i]} (strand=\{gr_genes.strands[i]})",
)
i = i + 1
}
let promoters = @bio.grg_promoters(gr_genes, upstream=50, downstream=20)
println(" Promoter regions (upstream=50, downstream=20):")
i = 0
while i < promoters.seqnames.length() {
println(
" \{promoters.seqnames[i]}:\{promoters.starts[i]}-\{promoters.ends[i]} (strand=\{promoters.strands[i]})",
)
i = i + 1
}
println("")
println("8. Trimming ranges to chromosome bounds")
let gr_trim = @bio.grg_granges(["chr1", "chr1", "chr2"], [-5, 8, 1], [
10, 250, 300,
])
let trim_sl : Map[String, Int32] = Map([], capacity=2)
trim_sl["chr1"] = 100
trim_sl["chr2"] = 200
let trimmed = @bio.grg_trim(gr_trim, trim_sl)
println(" After trimming to chromosome bounds:")
i = 0
while i < trimmed.seqnames.length() {
println(
" \{trimmed.seqnames[i]}:\{trimmed.starts[i]}-\{trimmed.ends[i]}",
)
i = i + 1
}
println("")
println("=== Demo Complete ===")
}