Overview
P-Mix (POKY Mixture Design Engine) is a Tkinter-native port of NMRmix into a single POKY plugin. It designs mixtures of small molecules for 1D 1H NMR ligand-affinity screening (line-broadening screens, STD-NMR, WaterLOGSY) by grouping compounds so that as few NMR peaks as possible overlap between compounds sharing the same sample, using the same simulated-annealing approach as the original tool.
NMRmix was originally a PyQt5 desktop application (Stark, Eghbalnia, Lee, Westler & Markley, J. Proteome Res. 2016, 15(4):1360-1368; annealing approach based on Arroyo, Goldflam, Feliz, Belda & Giralt, PLoS ONE 2013, 8(3):e58571), licensed GPL-3.0 because of its PyQt5 dependency. P-Mix drops PyQt5 entirely in favor of Tkinter and POKY's own session API, carrying no GPL obligation forward, and consolidates NMRmix's original chain of eight sequential dialog windows (splash β title β library β peak import β peak stats β mixtures β optimize β compound info) into two tabs of a single window.
Library Tab
Compounds are managed as a library CSV (Active, Identifier, Compound Name, BMRB ID, HMDB ID, local peak-list file, Peaklist Format, Group/Solvent, PubChem CID, KEGG ID, SMILES). Two ways to populate it:
- Download BMRB Library β fetches a ready-made library of reference compounds from MetaLib and caches it locally under the project's directory (see MetaLib for the shared download/cache convention this follows, also used by A-SIMA and LigLib).
- Add Compound... β manually add a compound, either by BMRB ID
(peak list auto-downloaded and cached as an NMR-STAR file from the same MetaLib
mirror) or as a local USER CSV
(
ppm, intensity[, width]per row).
"Import Peak Lists for Active Compounds" downloads/parses every active compound's
peak list in a background thread with a progress log, so the UI stays responsive
even for large libraries. Solvent/buffer peaks can be excluded from scoring via a
comma-separated ppm-range field (e.g. 4.7-4.9, 3.3-3.4); a "Reapply
Ignore Regions" button re-filters already-downloaded peak lists without needing to
re-fetch them.
The library table itself shows Active/Identifier/Name/Group/Format/BMRB ID/Peaks-imported columns at a glance. Double-clicking a row (or selecting one and clicking "View Compound Info...") opens a Compound Info window: editable metadata (name, group, active state, format, BMRB ID, local peak-list path, PubChem CID, KEGG ID, SMILES, with a Save button), one-click "Open PubChem"/"Open KEGG"/"Search HMDB" links (HMDB opens a by-name search rather than a specific entry, since BMRB metabolomics entries don't reliably cross-reference an HMDB accession number - see the note below), the full peak list table with an "Import/Refresh Peak List Now" button (for a compound that hasn't been imported yet, or to re-pull just that one compound), and a single-compound simulated spectrum.
Mixtures & Optimize Tab
Scoring, mixture-design, and annealing parameters are grouped into three panels:
| Panel | Key parameters |
|---|---|
| Scoring | Overlap range (ppm tolerance window per peak), score scale, whether to weight overlaps by peak intensity |
| Optimizing | Starting mixture number, mixture size, extra (buffer) mixtures, cooling schedule (linear/exponential), start/final temperature, max steps, mix rate, iterations (best-of-N), restrict mixing to same-group compounds, randomize initial assignment |
| Refining | An optional second, usually milder, annealing pass over the already-optimized result, with its own temperature/step/mix-rate settings |
"Generate Initial Mixtures" randomly deals active compounds into mixtures of the target size (optionally never mixing across groups/solvents); "Optimize Mixtures" runs the annealer in a background thread with a live progress bar and step/score readout, cancellable via "Stop". Rows can be locked (double-click, or the Lock/Unlock button) to exclude specific mixtures from further optimization - useful for mixtures you've already validated experimentally. "View Simulated Spectrum" opens an embedded, Lorentzian-line simulated overlay of every compound in a mixture, with a checkbutton per compound to toggle it on/off - a modernized, single-window redesign of NMRmix's original per-compound colored-button spectrum viewer.
Scoring & Annealing Algorithm
Ported faithfully from NMRmix's core scoring engine. Each peak of a compound counts as overlapped at most once, no matter how many peaks from other mixture members it overlaps with:
- SC = k Β· (Noverlapped / Ntotal) - unweighted, or
- SC* = k Β· (Ioverlapped / Itotal) - intensity-weighted
where k is the score scale. Mixture and total scores are memoized by the sorted tuple of member compound IDs, so re-scoring an unchanged combination during annealing is O(1). The annealing "move" picks a few mixtures at random, removes one compound from each, and cyclically reinserts them into the next mixture in the sampled order; candidates are always accepted if they improve (or perfectly zero out) the total score, and otherwise accepted with probability
- P = exp( β(|ΞStotal| / (mix_rateΒ·score_scale)) Β· 25000 / T )
following the cooling schedule (linear or exponential) down from the start temperature to the final temperature over the configured number of steps - this matches the formula NMRmix's GUI actually used (with its hard-coded temperature- scaling constant of 25,000), rather than the simpler, unused variant that also existed in NMRmix's non-GUI code path.
Export
Mixtures, regions of interest (ROIs), scores, and full peak lists all export as plain CSV/TXT, matching NMRmix's original output files:
- Mixtures CSV/TXT - mixture number, score, group, member compounds
- ROIs CSV - per-compound ppm ranges not overlapped in their assigned mixture (optionally including overlapped ranges too) - the actual deliverable for automating post-screen spectrum integration
- Scores CSV - per-compound score/overlap-count breakdown
- Peaks CSV - full per-compound peak list as assigned to mixtures
An additional one-sheet Excel summary export is available when
openpyxl is installed, for a quick shareable overview.
Scope Compared to NMRmix
This is a single-file, from-scratch reimplementation, not a line-for-line translation of all ~8,800 lines of the original. Deliberately out of scope for this port:
- ACD/MNOVA/TopSpin/VnmrJ peak-list import formats, and HMDB-scraped peak lists (only BMRB_ID and USER are supported)
- RDKit 2D chemical structure rendering in the compound info view
- Per-group parallel annealing threads (groups are annealed sequentially in one background thread instead - simpler, and still fully cancellable, just not literally parallelized)
- Library-wide peak-count/aromaticity/histogram statistics popups