nx_chem_adulterant_db.nx
buildroot/runtime/nx_chem_adulterant_db.nx
about
nx_chem_adulterant_db.nx -- C4.0 milestone: first usable supplement-arc
adulterant detection database + mass-window lookup pipeline.
This is the smallest end-to-end demo:
1. Build seed DB of known supplement adulterants
2. Each entry parses real SMILES at DB-build time
3. Compute monoisotopic mass + [M+H]+ + halogen signature
via C2.8a + C2.8b primitives
4. Lookup: given observed LC-MS peak m/z + ppm tolerance, scan DB
and return matching entries
5. Report: human-readable lab-facing output with verdict
Composes: C2.0 MolGraph + C2.1 SMILES parser + C2.3a implicit-H +
C2.8a monoisotopic mass + ion m/z + C2.8b halogen sig.
Seed compounds (publicly known supplement adulterants;
FDA Tainted Supplements list + DSHEA + IOC banned list references):
id 0 ephedrine C10H15NO restricted (DSHEA-pre-2004)
id 1 DMAA C7H17N banned 2013 (FDA action)
id 2 DMBA C6H15N banned 2014 (FDA action)
id 3 DMHA C8H19N banned 2019 (FDA caution)
id 4 sibutramine C17H26ClN banned 2010 (Abbott withdrew)
id 5 caffeine C8H10N4O2 approved (baseline, not banned)
id 6 higenamine C16H17NO3 banned 2017 (WADA + FDA)
id 7 yohimbine C21H26N2O3 restricted (some markets)
Honest gaps (deferred):
- sildenafil (C22H30N6O4S; Viagra-active spiked in herbal ED):
SMILES contains aromatic+saturated mixed ring system parser
doesn't yet handle perfectly; C4.1.
- Tadalafil (Cialis), anabolic steroid analogs, polyhalogenated:
more complex parsing required; C4.1.
- Persistent storage (memory-only DB at present); C4.2.
- Multiple-adulterant interactions: not modeled; lab interpretation.
dependencies 9 imports · 10 importers
imports: nx_chem.nxnx_chem_molecule.nxnx_chem_smiles.nxnx_chem_periodic.nxnx_chem_valence.nxnx_chem_mass.nxnx_chem_isotope_pattern.nxnx_chem_peak_list.nxnx_syscalls.nx
imported by: nx_chem_adulterant_db_test.nxnx_chem_peak_list_test.nxnx_chem_report_csv.nxnx_chem_report_csv_test.nxnx_chem_report_json.nxnx_chem_report_json_test.nxnx_supplement.nxnx_supplement_batch.nxnx_supplement_check.nxnx_supplement_csv.nx
structs
| 60 | struct AdulterantEntry |
| 77 | struct AdulterantDB |
| 86 | struct MatchResult |
consts
| 46 | const NX_MAGIC_30000: i64 = 30000 |
| 47 | const NX_MAGIC_1000000: i64 = 1000000 |
| 48 | const NX_MAGIC_10000000: i64 = 10000000 |
| 49 | const NX_MAGIC_2018: i64 = 2018 |
| 50 | const NX_MAGIC_10000: i64 = 10000 |
| 51 | const NX_MAGIC_300000: i64 = 300000 |
| 54 | const NX_REG_UNKNOWN: nx_int = 0 |
| 55 | const NX_REG_APPROVED: nx_int = 1 |
| 56 | const NX_REG_RESTRICTED: nx_int = 2 |
| 57 | const NX_REG_BANNED: nx_int = 3 |
| 58 | const NX_REG_RX_ONLY: nx_int = 4 |
| 75 | const NX_ADULTERANT_ENTRY_BYTES: nx_int = 96 |
| 83 | const NX_ADULTERANT_DB_BYTES: nx_int = 32 |
| 92 | const NX_MATCH_RESULT_BYTES: nx_int = 32 |
functions
| 97 | func nx_chem_adulterant_db_new(cap: nx_int) -> *AdulterantDB |
| 110 | func nx_chem_adulterant_db_add(db: *AdulterantDB, id: nx_int, smiles: *u8, n_smi: nx_int, regulatory: nx_int, ad_table: *AtomicData) -> nx_int |
| 155 | func nx_chem_adulterant_db_add_with_strings(db: *AdulterantDB, id: nx_int, smiles: *u8, n_smi: nx_int, regulatory: nx_int, name: *u8, citation: *u8, ad_table: *AtomicData) -> nx_int |
| 195 | func nx_chem_adulterant_db_set_rt(db: *AdulterantDB, id: nx_int, ref_rt_q3: nx_int, rt_tol_q3: nx_int) -> nx_int |
| 223 | func nx_chem_adulterant_db_lookup_with_rt(db: *AdulterantDB, mz_q4: nx_int, rt_q3: nx_int, ppm_tol: nx_int, out_matches: *MatchResult, max_out: nx_int) -> nx_int |
| 280 | func nx_chem_adulterant_db_lookup_mh_plus(db: *AdulterantDB, mz_q4: nx_int, ppm_tol: nx_int, out_matches: *MatchResult, max_out: nx_int) -> nx_int |
| 312 | func nx_chem_adulterant_name(id: nx_int) -> *u8 |
| 354 | func nx_chem_adulterant_citation(id: nx_int) -> *u8 |
| 394 | func nx_chem_regulatory_str(reg: nx_int) -> *u8 |
| 409 | func nx_chem_adulterant_seed_smiles(id: nx_int, buf: *u8) -> nx_int called by 1: nx_chem_adulterant_db_seed |
| 857 | func nx_chem_adulterant_db_seed() -> *AdulterantDB |
| 932 | func nx_chem_load_rt_calibration(db: *AdulterantDB, path: *u8) -> nx_int |
| 1048 | func nx_chem_load_compounds_from_file(db: *AdulterantDB, path: *u8) -> nx_int |
| 1161 | func print_q4_mass(q: nx_int) -> i64 |
| 1188 | func nx_chem_adulterant_report_match(observed_mz_q4: nx_int, db: *AdulterantDB, r: *MatchResult) -> nx_int |
| 1215 | func nx_chem_adulterant_entry_by_id(db: *AdulterantDB, id: nx_int) -> *AdulterantEntry |