code wiki / (root) / nx_chem_report_csv_test.nx

nx_chem_report_csv_test.nx source

↩ module page · 172 lines · 8642 B

1// nx_chem_report_csv_test.nx -- C6.1 KAT. 2// 3// expect_exit: 0 4// license_tier: ORIGINAL 5 6import "nx_chem.nx" 7import "nx_chem_molecule.nx" 8import "nx_chem_smiles.nx" 9import "nx_chem_periodic.nx" 10import "nx_chem_valence.nx" 11import "nx_chem_mass.nx" 12import "nx_chem_isotope_pattern.nx" 13import "nx_chem_adulterant_db.nx" 14import "nx_chem_peak_list.nx" 15import "nx_chem_report_json.nx" 16import "nx_chem_report_csv.nx" 17 18// ================================================================= 19// A -- emit_csv_field: bare ASCII (no commas/quotes) -> no quoting 20// ================================================================= 21func a_csv_field_bare() -> nx_int { 22 let buf: *u8 = sys_mmap(64) 23 let n: nx_int = nx_chem_emit_csv_field(buf, 0, "sibutramine" as *u8) 24 if n != 11 { return 11 } 25 if buf[0] as nx_int != 0x73 { return 12 } // 's' 26 if buf[10] as nx_int != 0x65 { return 13 } // 'e' 27 return 0 28} 29 30// ================================================================= 31// B -- emit_csv_field: with comma -> wrap in quotes 32// "DMAA (1,3-dimethylamylamine)" -> "DMAA (1,3-dimethylamylamine)" 33// (12 + 2 quotes = 14? No, original is 28 chars + 2 quotes = 30) 34// ================================================================= 35func b_csv_field_with_comma() -> nx_int { 36 let buf: *u8 = sys_mmap(128) 37 let n: nx_int = nx_chem_emit_csv_field(buf, 0, "DMAA (1,3-dimethylamylamine)" as *u8) 38 if n != 30 { return 21 } 39 if buf[0] as nx_int != 0x22 { return 22 } // opening " 40 if buf[n - 1] as nx_int != 0x22 { return 23 } // closing " 41 return 0 42} 43 44// ================================================================= 45// C -- emit_csv_field: with quote -> double the quote inside 46// 'say "hi"' -> '"say ""hi"""' 47// ================================================================= 48func c_csv_field_with_quote() -> nx_int { 49 let buf: *u8 = sys_mmap(128) 50 let src: *u8 = sys_mmap(32) 51 src[0] = 0x73; src[1] = 0x61; src[2] = 0x79; src[3] = 0x20 52 src[4] = 0x22 // " 53 src[5] = 0x68; src[6] = 0x69 54 src[7] = 0x22 // " 55 src[8] = 0 56 let n: nx_int = nx_chem_emit_csv_field(buf, 0, src) 57 // Expected: "say ""hi""" = " s a y SP " " h i " " " = 12 bytes 58 if n != 12 { return 31 } 59 if buf[0] as nx_int != 0x22 { return 32 } // opening " 60 if buf[4] as nx_int != 0x20 { return 33 } // space 61 if buf[5] as nx_int != 0x22 { return 34 } // first " of "" 62 if buf[6] as nx_int != 0x22 { return 35 } // second " of "" 63 return 0 64} 65 66// ================================================================= 67// D -- emit_csv_header has all expected column names 68// ================================================================= 69func d_csv_header() -> nx_int { 70 let buf: *u8 = sys_mmap(256) 71 let n: nx_int = nx_chem_emit_csv_header(buf, 0) 72 if buf[n - 1] as nx_int != 0x0A { return 41 } // ends with newline 73 if nx_chem_buf_find(buf, n, "sample_id" as *u8) < 0 { return 42 } 74 if nx_chem_buf_find(buf, n, "peak_mz" as *u8) < 0 { return 43 } 75 if nx_chem_buf_find(buf, n, "regulatory" as *u8) < 0 { return 44 } 76 if nx_chem_buf_find(buf, n, "citation" as *u8) < 0 { return 45 } 77 return 0 78} 79 80// ================================================================= 81// E -- emit_report_csv full report: header + 2 matches 82// ================================================================= 83func e_full_report() -> nx_int { 84 let db: *AdulterantDB = nx_chem_adulterant_db_seed() 85 let e_sib: *AdulterantEntry = ((db.entries as nx_int) + (4 * NX_ADULTERANT_ENTRY_BYTES)) as *AdulterantEntry 86 let e_caf: *AdulterantEntry = ((db.entries as nx_int) + (5 * NX_ADULTERANT_ENTRY_BYTES)) as *AdulterantEntry 87 let pl: *PeakList = nx_chem_peak_list_new(8) 88 let _a1: nx_int = nx_chem_peak_list_add(pl, e_sib.mh_plus_q4, 1000000000, 742000) 89 let _a2: nx_int = nx_chem_peak_list_add(pl, e_caf.mh_plus_q4, 1500000000, 234000) 90 let buf: *u8 = sys_mmap(4096) 91 let n: nx_int = nx_chem_emit_report_csv(buf, pl, db, "TEST-001" as *u8, 5) 92 // Verify content 93 if nx_chem_buf_find(buf, n, "sample_id" as *u8) < 0 { return 51 } // header 94 if nx_chem_buf_find(buf, n, "TEST-001" as *u8) < 0 { return 52 } 95 if nx_chem_buf_find(buf, n, "sibutramine" as *u8) < 0 { return 53 } 96 if nx_chem_buf_find(buf, n, "BANNED" as *u8) < 0 { return 54 } 97 if nx_chem_buf_find(buf, n, "caffeine" as *u8) < 0 { return 55 } 98 if nx_chem_buf_find(buf, n, "APPROVED" as *u8) < 0 { return 56 } 99 // FDA citation has a colon but no comma -- should NOT be quoted 100 // 21 CFR citation has no special chars -- should NOT be quoted 101 if nx_chem_buf_find(buf, n, "21 CFR" as *u8) < 0 { return 57 } 102 return 0 103} 104 105// ================================================================= 106// END-TO-END DEMO: emit a CSV report to stdout 107// ================================================================= 108func run_csv_demo() -> nx_int { 109 println("" as *u8) 110 println("==================================================================" as *u8) 111 println(" CSV REPORT (Excel-ready output for lab analysts)" as *u8) 112 println("==================================================================" as *u8) 113 let db: *AdulterantDB = nx_chem_adulterant_db_seed() 114 let pl: *PeakList = nx_chem_peak_list_new(8) 115 let e_sib: *AdulterantEntry = ((db.entries as nx_int) + (4 * NX_ADULTERANT_ENTRY_BYTES)) as *AdulterantEntry 116 let e_dmaa: *AdulterantEntry = ((db.entries as nx_int) + (1 * NX_ADULTERANT_ENTRY_BYTES)) as *AdulterantEntry 117 let e_caf: *AdulterantEntry = ((db.entries as nx_int) + (5 * NX_ADULTERANT_ENTRY_BYTES)) as *AdulterantEntry 118 let e_eph: *AdulterantEntry = ((db.entries as nx_int) + (0 * NX_ADULTERANT_ENTRY_BYTES)) as *AdulterantEntry 119 let _a1: nx_int = nx_chem_peak_list_add(pl, e_sib.mh_plus_q4, 995230000, 742300) 120 let _a2: nx_int = nx_chem_peak_list_add(pl, e_dmaa.mh_plus_q4, 874310000, 45200) 121 let _a3: nx_int = nx_chem_peak_list_add(pl, e_caf.mh_plus_q4, 1500000000, 234100) 122 let _a4: nx_int = nx_chem_peak_list_add(pl, e_eph.mh_plus_q4, 321000000, 89500) 123 let buf: *u8 = sys_mmap(8192) 124 let n: nx_int = nx_chem_emit_report_csv(buf, pl, db, "SUSPECT-2026-001" as *u8, 5) 125 let _w: i64 = sys_write(1, buf, n as i64) 126 println("==================================================================" as *u8) 127 let _l1: i64 = print(" CSV size: " as *u8) 128 let _l2: i64 = print_i64(n as i64) 129 let _l3: i64 = println(" bytes (header + 4 rows)" as *u8) 130 println(" Open in Excel/Calc: comma-separated, RFC 4180 escaping," as *u8) 131 println(" citation field quoted only if it contains a comma" as *u8) 132 println("==================================================================" as *u8) 133 return 0 134} 135 136func main() -> nx_exit { 137 println("=== nx_chem_report_csv -- C6.1 KAT: CSV output ===" as *u8) 138 139 let ra: nx_int = a_csv_field_bare() 140 if ra != 0 { println("A csv_field_bare FAIL" as *u8); return ra } 141 println("A csv_field_bare PASS bare ASCII not quoted" as *u8) 142 143 let rb: nx_int = b_csv_field_with_comma() 144 if rb != 0 { println("B csv_field_with_comma FAIL" as *u8); return rb } 145 println("B csv_field_comma PASS comma triggers RFC 4180 quoting" as *u8) 146 147 let rc: nx_int = c_csv_field_with_quote() 148 if rc != 0 { println("C csv_field_quote FAIL" as *u8); return rc } 149 println("C csv_field_quote PASS internal \" doubled (RFC 4180)" as *u8) 150 151 let rd: nx_int = d_csv_header() 152 if rd != 0 { println("D csv_header FAIL" as *u8); return rd } 153 println("D csv_header PASS header has all 9 expected columns" as *u8) 154 155 let re: nx_int = e_full_report() 156 if re != 0 { println("E full_report FAIL" as *u8); return re } 157 println("E full_report PASS header + 2 matches with names + citations" as *u8) 158 159 let _demo: nx_int = run_csv_demo() 160 161 println("" as *u8) 162 println("=== C6.1 substrate milestone PASS ===" as *u8) 163 println(" emit_csv_field: RFC 4180 escaping (comma/quote/newline)" as *u8) 164 println(" emit_csv_header: 9-column header line" as *u8) 165 println(" emit_csv_row: per-match row with sample/peak/match/citation" as *u8) 166 println(" emit_report_csv: full report (header + N rows)" as *u8) 167 println(" emit_report_csv_rows_only: append rows without header" as *u8) 168 println(" (used in batch mode -- 1 header total)" as *u8) 169 println(" Excel-ready: lab analysts open CSV directly, sort/filter by" as *u8) 170 println(" regulatory column, hand to QA reviewer." as *u8) 171 return 0 172}