code wiki / (root) / nx_supplement_csv.nx

nx_supplement_csv.nx source

↩ module page · 86 lines · 3060 B

1// nx_supplement_csv.nx -- C6.1 CLI variant emitting CSV instead of JSON. 2// 3// For lab analysts who work in Excel rather than LIMS. 4// 5// USAGE: 6// nx_supplement_csv <cal-file-or-dash> <peak1> [peak2] ... 7// 8// OUTPUT: 9// One CSV header line, then one row per match across all samples. 10// Pipe directly to file -> open in Excel. 11// 12// EXIT CODE: 13// Total banned detections across all samples. 14 15import "nx_chem.nx" 16import "nx_chem_molecule.nx" 17import "nx_chem_smiles.nx" 18import "nx_chem_periodic.nx" 19import "nx_chem_valence.nx" 20import "nx_chem_mass.nx" 21import "nx_chem_isotope_pattern.nx" 22import "nx_chem_adulterant_db.nx" 23import "nx_chem_peak_list.nx" 24import "nx_chem_report_json.nx" 25import "nx_chem_report_csv.nx" 26 27func process_one_csv(db: *AdulterantDB, peak_path: *u8) -> nx_int { 28 let pl: *PeakList = nx_chem_peak_list_read_file(peak_path) 29 if pl.n == 0 { return 0 } 30 let sample_id: *u8 = sys_mmap(256) 31 let _bn: nx_int = nx_chem_basename(peak_path, sample_id) 32 let buf: *u8 = sys_mmap(32768) 33 let n: nx_int = nx_chem_emit_report_csv_rows_only(buf, pl, db, sample_id, 5) 34 let _w: i64 = sys_write(1, buf, n as i64) 35 // Count banned 36 var n_banned: nx_int = 0 37 var pi: nx_int = 0 38 while pi < pl.n { 39 let p: *PeakObservation = ((pl.peaks as nx_int) + (pi * NX_PEAK_OBS_BYTES)) as *PeakObservation 40 let outs: *MatchResult = (sys_mmap((4 * NX_MATCH_RESULT_BYTES) as i64)) as *MatchResult 41 let nm: nx_int = nx_chem_adulterant_db_lookup_with_rt(db, p.mz_q4, p.rt_q3, 5, outs, 4) 42 var mi: nx_int = 0 43 while mi < nm { 44 let rr: *MatchResult = ((outs as nx_int) + (mi * NX_MATCH_RESULT_BYTES)) as *MatchResult 45 let ee: *AdulterantEntry = nx_chem_adulterant_entry_by_id(db, rr.entry_id) 46 if ee.regulatory == NX_REG_BANNED { n_banned = n_banned + 1 } 47 mi = mi + 1 48 } 49 pi = pi + 1 50 } 51 return n_banned 52} 53 54func main(argc: i64, argv: *i64) -> i64 { 55 if argc < 3 { 56 let msg: *u8 = "nx_supplement_csv: usage: <cal-file-or-dash> <peak1> [peak2] ...\n" as *u8 57 var n: i64 = 0 58 while msg[n] != 0 { n = n + 1 } 59 let _w: i64 = sys_write(2, msg, n) 60 return 1 61 } 62 let db: *AdulterantDB = nx_chem_adulterant_db_seed() 63 let cal_path: *u8 = argv[1] as *u8 64 let cal_first: nx_int = cal_path[0] as nx_int 65 if cal_first != 45 { 66 let _n: nx_int = nx_chem_load_rt_calibration(db, cal_path) 67 } 68 if cal_first == 45 { 69 if cal_path[1] as nx_int != 0 { 70 let _n: nx_int = nx_chem_load_rt_calibration(db, cal_path) 71 } 72 } 73 // Emit header once at the start 74 let hbuf: *u8 = sys_mmap(256) 75 let nh: nx_int = nx_chem_emit_csv_header(hbuf, 0) 76 let _wh: i64 = sys_write(1, hbuf, nh as i64) 77 var total_banned: i64 = 0 78 var i: i64 = 2 79 while i < argc { 80 let peak_path: *u8 = argv[i] as *u8 81 let b: nx_int = process_one_csv(db, peak_path) 82 total_banned = total_banned + (b as i64) 83 i = i + 1 84 } 85 return total_banned 86}