nx_peptide_ext_test.nx source
↩ module page · 211 lines · 10234 B
1// nx_peptide_ext_test.nx -- gate for nx_peptide_ext. Oxytocin and
2// vasopressin are checked against PUBLISHED monoisotopic masses, and the
3// no-amide / no-disulfide variants are run as NEGATIVE CONTROLS so the
4// match cannot be an accident of two errors cancelling.
5// expect_exit: 0 license_tier: ORIGINAL
6import "nx_syscalls.nx"
7import "nx_peptide.nx"
8import "nx_peptide_ext.nx"
9
10func t_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
11func t_putn(v: i64) -> i64 { let bb: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 - m; sys_write(1, "-" as *u8, 1) } let t: *u8 = sys_mmap(28); var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 } while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } sys_write(1, bb, k); return 0 }
12
13// Oxytocin: CYIQNCPLG, C-terminal amide, one 1-6 disulfide.
14func build_oxytocin() -> *NxPepBuild {
15 let b: *NxPepBuild = nx_pep_build_new()
16 pex_add_seq(b, "CYIQNCPLG" as *u8)
17 pex_set_amide(b)
18 pex_add_disulfide(b)
19 return b
20}
21
22// Arginine vasopressin: CYFQNCPRG, amide, one 1-6 disulfide.
23func build_vasopressin() -> *NxPepBuild {
24 let b: *NxPepBuild = nx_pep_build_new()
25 pex_add_seq(b, "CYFQNCPRG" as *u8)
26 pex_set_amide(b)
27 pex_add_disulfide(b)
28 return b
29}
30
31// Ipamorelin: Aib-His-D-2Nal-D-Phe-Lys-NH2.
32func build_ipamorelin() -> *NxPepBuild {
33 let b: *NxPepBuild = nx_pep_build_new()
34 pex_add_ext(b, PEX_AIB)
35 pex_add_seq(b, "H" as *u8)
36 pex_add_ext(b, PEX_2NAL)
37 pex_add_seq(b, "FK" as *u8)
38 pex_set_amide(b)
39 return b
40}
41
42// Melanotan II: Ac-Nle-cyclo[Asp-His-D-Phe-Arg-Trp-Lys]-NH2 (lactam bridge).
43func build_melanotan2() -> *NxPepBuild {
44 let b: *NxPepBuild = nx_pep_build_new()
45 pex_add_ext(b, PEX_NLE)
46 pex_add_seq(b, "DHFRWK" as *u8)
47 pex_set_acetyl(b)
48 pex_set_amide(b)
49 pex_add_lactam(b)
50 return b
51}
52
53func main() -> i64 {
54 var pass: i64 = 0
55 var total: i64 = 0
56
57 // --- T1 OXYTOCIN vs published 1006.4367 Da ---
58 total = total + 1
59 let oxy: *NxPepBuild = build_oxytocin()
60 let m_oxy: i64 = pex_mass_q4(oxy)
61 t_puts("T1 oxytocin Q4=" as *u8); t_putn(m_oxy); t_puts(" vs lit 10064367 tol 2: " as *u8)
62 if pep_mass_agrees(m_oxy, 10064367, 2) == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) }
63
64 // --- T2 NEGATIVE CONTROLS: drop each modification, must MISS ---
65 total = total + 1
66 let no_ss: *NxPepBuild = nx_pep_build_new()
67 pex_add_seq(no_ss, "CYIQNCPLG" as *u8)
68 pex_set_amide(no_ss)
69 let m_no_ss: i64 = pex_mass_q4(no_ss)
70 let no_am: *NxPepBuild = nx_pep_build_new()
71 pex_add_seq(no_am, "CYIQNCPLG" as *u8)
72 pex_add_disulfide(no_am)
73 let m_no_am: i64 = pex_mass_q4(no_am)
74 t_puts("T2 no-disulfide=" as *u8); t_putn(m_no_ss); t_puts(" (+2.0157) no-amide=" as *u8); t_putn(m_no_am); t_puts(" (+0.984), both must MISS lit: " as *u8)
75 var ok2: i64 = 1
76 if m_no_ss - m_oxy != 20157 { ok2 = 0 }
77 if m_no_am - m_oxy != 9840 { ok2 = 0 }
78 if pep_mass_agrees(m_no_ss, 10064367, 2) != 0 { ok2 = 0 }
79 if pep_mass_agrees(m_no_am, 10064367, 2) != 0 { ok2 = 0 }
80 if ok2 == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) }
81
82 // --- T3 VASOPRESSIN vs published 1083.4380 Da (independent anchor) ---
83 total = total + 1
84 let vas: *NxPepBuild = build_vasopressin()
85 let m_vas: i64 = pex_mass_q4(vas)
86 t_puts("T3 vasopressin Q4=" as *u8); t_putn(m_vas); t_puts(" vs lit 10834380 tol 2: " as *u8)
87 if pep_mass_agrees(m_vas, 10834380, 2) == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) }
88
89 // --- T4 IPAMORELIN: was REFUSED before this rung, now computable ---
90 total = total + 1
91 let ipa: *NxPepBuild = build_ipamorelin()
92 let m_ipa: i64 = pex_mass_q4(ipa)
93 t_puts("T4 ipamorelin Q4=" as *u8); t_putn(m_ipa); t_puts(" vs lit 7113900 tol 100: " as *u8)
94 if pep_mass_agrees(m_ipa, 7113900, 100) == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) }
95
96 // --- T5 MELANOTAN II: acetyl + amide + lactam all at once ---
97 total = total + 1
98 let mt2: *NxPepBuild = build_melanotan2()
99 let m_mt2: i64 = pex_mass_q4(mt2)
100 t_puts("T5 melanotan-II Q4=" as *u8); t_putn(m_mt2); t_puts(" vs lit 10235400 tol 100: " as *u8)
101 if pep_mass_agrees(m_mt2, 10235400, 100) == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) }
102
103 // --- T6 lactam is a REAL water loss, not a fudge ---
104 total = total + 1
105 let lin: *NxPepBuild = nx_pep_build_new()
106 pex_add_ext(lin, PEX_NLE)
107 pex_add_seq(lin, "DHFRWK" as *u8)
108 pex_set_acetyl(lin)
109 pex_set_amide(lin)
110 let m_lin: i64 = pex_mass_q4(lin)
111 let dlac: i64 = m_lin - m_mt2
112 t_puts("T6 linear-vs-cyclic delta=" as *u8); t_putn(dlac); t_puts(" want 180106 (one H2O): " as *u8)
113 if dlac == 180106 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) }
114
115 // --- T7 isomer residues are ISOBARIC (table self-consistency) ---
116 total = total + 1
117 let nle: i64 = pex_residue_mono_q4(PEX_NLE)
118 let leu: i64 = pep_residue_mono_q4(PEP_L)
119 let nva: i64 = pex_residue_mono_q4(PEX_NVA)
120 let val: i64 = pep_residue_mono_q4(PEP_V)
121 let sar: i64 = pex_residue_mono_q4(PEX_SAR)
122 let ala: i64 = pep_residue_mono_q4(PEP_A)
123 t_puts("T7 Nle==Leu, Nva==Val, Sar==Ala: " as *u8)
124 var ok7: i64 = 1
125 if nle != leu { ok7 = 0 }
126 if nva != val { ok7 = 0 }
127 if sar != ala { ok7 = 0 }
128 if ok7 == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) }
129
130 // --- T8 derived relationships hold: Aib=Ala+CH2, Hyp=Pro+O, Orn=Lys-CH2 ---
131 total = total + 1
132 let aib: i64 = pex_residue_mono_q4(PEX_AIB)
133 let hyp: i64 = pex_residue_mono_q4(PEX_HYP)
134 let pro: i64 = pep_residue_mono_q4(PEP_P)
135 let orn: i64 = pex_residue_mono_q4(PEX_ORN)
136 let lys: i64 = pep_residue_mono_q4(PEP_K)
137 let cit: i64 = pex_residue_mono_q4(PEX_CIT)
138 let arg: i64 = pep_residue_mono_q4(PEP_R)
139 t_puts("T8 Aib-Ala=" as *u8); t_putn(aib - ala); t_puts(" (CH2 140157) Hyp-Pro=" as *u8); t_putn(hyp - pro); t_puts(" (O 159949) Lys-Orn=" as *u8); t_putn(lys - orn); t_puts(" Cit-Arg=" as *u8); t_putn(cit - arg); t_puts(": " as *u8)
140 var ok8: i64 = 1
141 if aib - ala != 140157 { ok8 = 0 }
142 if hyp - pro != 159949 { ok8 = 0 }
143 if lys - orn != 140157 { ok8 = 0 }
144 if cit - arg != 9840 { ok8 = 0 }
145 if ok8 == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) }
146
147 // --- T9 the CH4/O near-isobar trap: Hyp vs Leu, Orn vs Asn ---
148 total = total + 1
149 let asn: i64 = pep_residue_mono_q4(PEP_N)
150 let d_hyp: i64 = leu - hyp
151 let d_orn: i64 = orn - asn
152 let iso1: i64 = pex_near_isobaric(leu, hyp)
153 let iso2: i64 = pex_near_isobaric(orn, asn)
154 let far: i64 = pex_near_isobaric(leu, arg)
155 t_puts("T9 Leu-Hyp=" as *u8); t_putn(d_hyp); t_puts(" Orn-Asn=" as *u8); t_putn(d_orn); t_puts(" near-isobaric=" as *u8); t_putn(iso1); t_puts("/" as *u8); t_putn(iso2); t_puts(" Leu-vs-Arg=" as *u8); t_putn(far); t_puts(": " as *u8)
156 var ok9: i64 = 1
157 if d_hyp != 364 { ok9 = 0 }
158 if d_orn != 364 { ok9 = 0 }
159 if iso1 != 1 { ok9 = 0 }
160 if iso2 != 1 { ok9 = 0 }
161 if far != 0 { ok9 = 0 }
162 if ok9 == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) }
163
164 // --- T10 resolving power needed to split the near-isobar ---
165 total = total + 1
166 let rp: i64 = pex_resolving_power_needed(leu, hyp)
167 let rp_same: i64 = pex_resolving_power_needed(leu, nle)
168 t_puts("T10 resolving power for Leu/Hyp=" as *u8); t_putn(rp); t_puts(" (>1000), for Leu/Nle=" as *u8); t_putn(rp_same); t_puts(" (0, identical): " as *u8)
169 if rp > 1000 { if rp_same == 0 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) } } else { t_puts("FAIL\n" as *u8) }
170
171 // --- T11 FAIL-CLOSED: bad sequence and unknown ext id both refuse ---
172 total = total + 1
173 let bad1: *NxPepBuild = nx_pep_build_new()
174 pex_add_seq(bad1, "CYIQNCPLZ" as *u8)
175 let m_bad1: i64 = pex_mass_q4(bad1)
176 let bad2: *NxPepBuild = nx_pep_build_new()
177 pex_add_seq(bad2, "GG" as *u8)
178 pex_add_ext(bad2, 99)
179 let m_bad2: i64 = pex_mass_q4(bad2)
180 let empty: *NxPepBuild = nx_pep_build_new()
181 let m_empty: i64 = pex_mass_q4(empty)
182 t_puts("T11 bad-letter=" as *u8); t_putn(m_bad1); t_puts(" bad-ext=" as *u8); t_putn(m_bad2); t_puts(" empty=" as *u8); t_putn(m_empty); t_puts(" (all -1): " as *u8)
183 var ok11: i64 = 1
184 if m_bad1 != PEP_INVALID { ok11 = 0 }
185 if m_bad2 != PEP_INVALID { ok11 = 0 }
186 if m_empty != PEP_INVALID { ok11 = 0 }
187 if ok11 == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) }
188
189 // --- T12 STRUCTURAL refusal: more bridges than cysteines allow ---
190 total = total + 1
191 let ok_br: i64 = pex_bridges_possible(oxy, 2)
192 let greedy: *NxPepBuild = nx_pep_build_new()
193 pex_add_seq(greedy, "CYIQNCPLG" as *u8)
194 pex_add_disulfide(greedy)
195 pex_add_disulfide(greedy)
196 let bad_br: i64 = pex_bridges_possible(greedy, 2)
197 t_puts("T12 oxytocin 1 bridge w/ 2 Cys=" as *u8); t_putn(ok_br); t_puts(" 2 bridges w/ 2 Cys=" as *u8); t_putn(bad_br); t_puts(" want 1/0: " as *u8)
198 if ok_br == 1 { if bad_br == 0 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) } } else { t_puts("FAIL\n" as *u8) }
199
200 // --- T13 built peptides feed the ion ladder unchanged ---
201 total = total + 1
202 let mz1: i64 = pex_mz_q4(oxy, 1)
203 let mz2: i64 = pex_mz_q4(oxy, 2)
204 let want1: i64 = m_oxy + 10073
205 t_puts("T13 oxytocin [M+H]+=" as *u8); t_putn(mz1); t_puts(" [M+2H]2+=" as *u8); t_putn(mz2); t_puts(": " as *u8)
206 if mz1 == want1 { if mz2 < mz1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) } } else { t_puts("FAIL\n" as *u8) }
207
208 t_puts("PEPTIDE-EXT-GATE passed " as *u8); t_putn(pass); t_puts("/" as *u8); t_putn(total)
209 if pass == total { t_puts(" verdict=GREEN\n" as *u8); sys_exit(0); return 0 }
210 t_puts(" verdict=RED\n" as *u8); sys_exit(1); return 1
211}