code wiki / (root) / nx_align_test.nx

nx_align_test.nx source

↩ module page · 156 lines · 6186 B

1// nx_align_test.nx -- KAT for Smith-Waterman local alignment. 2// 3// All vectors hand-verifiable from the SW recurrence stated in 4// nx_align.nx. Convention: scoring (match, mismatch, gap) declared 5// per-test; tie-break = first max found wins (row-major scan). 6// 7// expect_exit: 0 8// 9// license_tier: ORIGINAL 10 11import "nx_syscalls.nx" 12import "nx_align.nx" 13 14func write_str8(buf: *u8, s0: i64, s1: i64, s2: i64, s3: i64, 15 s4: i64, s5: i64, s6: i64, s7: i64) -> i64 { 16 buf[0] = s0 & 0xff 17 buf[1] = s1 & 0xff 18 buf[2] = s2 & 0xff 19 buf[3] = s3 & 0xff 20 buf[4] = s4 & 0xff 21 buf[5] = s5 & 0xff 22 buf[6] = s6 & 0xff 23 buf[7] = s7 & 0xff 24 return 0 25} 26 27func main() -> i64 { 28 29 let a: *u8 = sys_mmap(32) 30 let b: *u8 = sys_mmap(32) 31 let mi: *i64 = sys_mmap(16) as *i64 32 let mj: *i64 = sys_mmap(16) as *i64 33 34 // ============================================================ 35 // Section A -- identical "ACGT" vs "ACGT", m=+2 mis=-1 gap=-2 36 // Expected: score = 8, end (4, 4) 37 // ============================================================ 38 39 write_str8(a, 0x41, 0x43, 0x47, 0x54, 0, 0, 0, 0) 40 write_str8(b, 0x41, 0x43, 0x47, 0x54, 0, 0, 0, 0) 41 let s1: i64 = smith_waterman_linear(a, 4, b, 4, 2, -1, -2, mi, mj) 42 if s1 != 8 { return 1 } 43 if mi[0] != 4 { return 2 } 44 if mj[0] != 4 { return 3 } 45 46 // ============================================================ 47 // Section B -- embedded match: "ACGT" vs "TTACGTGG" 48 // Expected: score = 8, end (4, 6) (alignment at b[2..5]) 49 // ============================================================ 50 51 write_str8(a, 0x41, 0x43, 0x47, 0x54, 0, 0, 0, 0) 52 b[0]=0x54; b[1]=0x54; b[2]=0x41; b[3]=0x43; b[4]=0x47; b[5]=0x54; b[6]=0x47; b[7]=0x47 53 let s2: i64 = smith_waterman_linear(a, 4, b, 8, 2, -1, -2, mi, mj) 54 if s2 != 8 { return 10 } 55 if mi[0] != 4 { return 11 } 56 if mj[0] != 6 { return 12 } 57 58 // ============================================================ 59 // Section C -- all-mismatch "AAAA" vs "TTTT", m=+2 mis=-1 gap=-2 60 // Expected: score = 0, end (0, 0) 61 // ============================================================ 62 63 write_str8(a, 0x41, 0x41, 0x41, 0x41, 0, 0, 0, 0) 64 write_str8(b, 0x54, 0x54, 0x54, 0x54, 0, 0, 0, 0) 65 let s3: i64 = smith_waterman_linear(a, 4, b, 4, 2, -1, -2, mi, mj) 66 if s3 != 0 { return 20 } 67 if mi[0] != 0 { return 21 } 68 if mj[0] != 0 { return 22 } 69 70 // ============================================================ 71 // Section D -- degenerate empty inputs return 0, (0, 0). 72 // ============================================================ 73 74 write_str8(a, 0x41, 0x43, 0x47, 0x54, 0, 0, 0, 0) 75 let s4: i64 = smith_waterman_linear(a, 0, b, 4, 2, -1, -2, mi, mj) 76 if s4 != 0 { return 30 } 77 if mi[0] != 0 { return 31 } 78 79 let s5: i64 = smith_waterman_linear(a, 4, b, 0, 2, -1, -2, mi, mj) 80 if s5 != 0 { return 32 } 81 if mj[0] != 0 { return 33 } 82 83 // ============================================================ 84 // Section E -- single-char match. "A" vs "TAT", m=+2 mis=-1 gap=-2 85 // Expected: score = 2, end (1, 2) (A matches at b[1]) 86 // ============================================================ 87 88 a[0] = 0x41 89 b[0]=0x54; b[1]=0x41; b[2]=0x54 90 let s6: i64 = smith_waterman_linear(a, 1, b, 3, 2, -1, -2, mi, mj) 91 if s6 != 2 { return 40 } 92 if mi[0] != 1 { return 41 } 93 if mj[0] != 2 { return 42 } 94 95 // ============================================================ 96 // Section F -- substitution path: "ACAT" vs "ACGT", m=+2 mis=-1 gap=-2 97 // Expected: score = 5, end (4, 4) (3 matches + 1 mismatch = 6-1=5) 98 // ============================================================ 99 100 write_str8(a, 0x41, 0x43, 0x41, 0x54, 0, 0, 0, 0) 101 write_str8(b, 0x41, 0x43, 0x47, 0x54, 0, 0, 0, 0) 102 let s7: i64 = smith_waterman_linear(a, 4, b, 4, 2, -1, -2, mi, mj) 103 if s7 != 5 { return 50 } 104 if mi[0] != 4 { return 51 } 105 if mj[0] != 4 { return 52 } 106 107 // ============================================================ 108 // Section G -- gap-in-A path: "ACT" vs "AGCT", m=+2 mis=-1 gap=-2 109 // Expected: score = 4, end (3, 4) (3 matches + 1 gap = 6-2=4) 110 // ============================================================ 111 112 write_str8(a, 0x41, 0x43, 0x54, 0, 0, 0, 0, 0) 113 write_str8(b, 0x41, 0x47, 0x43, 0x54, 0, 0, 0, 0) 114 let s8: i64 = smith_waterman_linear(a, 3, b, 4, 2, -1, -2, mi, mj) 115 if s8 != 4 { return 60 } 116 if mi[0] != 3 { return 61 } 117 if mj[0] != 4 { return 62 } 118 119 // ============================================================ 120 // Section H -- gap-in-B path: "AGCT" vs "ACT" -- symmetric of G. 121 // Expected: score = 4, end (4, 3) 122 // ============================================================ 123 124 write_str8(a, 0x41, 0x47, 0x43, 0x54, 0, 0, 0, 0) 125 write_str8(b, 0x41, 0x43, 0x54, 0, 0, 0, 0, 0) 126 let s9: i64 = smith_waterman_linear(a, 4, b, 3, 2, -1, -2, mi, mj) 127 if s9 != 4 { return 70 } 128 if mi[0] != 4 { return 71 } 129 if mj[0] != 3 { return 72 } 130 131 // ============================================================ 132 // Section I -- BWA-MEM-style scoring (m=+5 mis=-3 gap=-4) 133 // "ACGT" vs "ACGT" -> 4 * 5 = 20. 134 // ============================================================ 135 136 write_str8(a, 0x41, 0x43, 0x47, 0x54, 0, 0, 0, 0) 137 write_str8(b, 0x41, 0x43, 0x47, 0x54, 0, 0, 0, 0) 138 let s10: i64 = smith_waterman_linear(a, 4, b, 4, 5, -3, -4, mi, mj) 139 if s10 != 20 { return 80 } 140 141 // ============================================================ 142 // Section J -- tie-break determinism. 143 // "AA" vs "AAA" with m=+2. Two valid alignments score 4: 144 // AA matching b[0..1] or b[1..2]. Strict-> tie-break picks FIRST 145 // max in row-major scan = (2, 2). 146 // ============================================================ 147 148 write_str8(a, 0x41, 0x41, 0, 0, 0, 0, 0, 0) 149 write_str8(b, 0x41, 0x41, 0x41, 0, 0, 0, 0, 0) 150 let s11: i64 = smith_waterman_linear(a, 2, b, 3, 2, -1, -2, mi, mj) 151 if s11 != 4 { return 90 } 152 if mi[0] != 2 { return 91 } 153 if mj[0] != 2 { return 92 } 154 155 return 0 156}