NMR (Nuclear Magnetic Resonance) chemistry analysis platform. Provides tools for reaction product prediction, NMR reference lookup, and mixture quantification.
Requires Python 3.10+. Uses uv for dependency management.
uv syncuv run python -m app.gradio_llm_app
# Launches at localhost:7667uv run python -m app.mcp_serverExposes chemistry tools via Model Context Protocol:
lookup_nmr_reference(smiles)- Find NMR reference by SMILESresolve_chemical_name(name)- Convert name to SMILESpredict_products(reactants, reagents)- Predict reaction productsdeconvolve_mixture(ppm, intensity, refs)- Quantify mixture componentsload_references_for_smiles(smiles_list)- Batch reference lookup
| Module | Description |
|---|---|
tools_nmrbank.py |
NMRBank reference lookup. Lazy-loads CSV into LUT keyed by canonical SMILES. |
tools_reactiont5.py |
Product prediction using ReactionT5 model. Local model preferred, falls back to HuggingFace API. |
tools_deconvolve.py |
Wrapper for Masserstein+Gurobi deconvolution. |
tools_magnetstein.py |
Alternative quantification using magnetstein's optimal transport. |
tools_asics.py |
R-based ASICS quantification. |
Autonomous agent that chains tools via OpenAI-compatible tool calling:
- Resolve reactant names → SMILES
- Predict products
- Find reference spectra
- Optionally quantify mixture
Web interface with:
- Agent Chat - Autonomous LLM agent with tool calling
- Manual Deconvolution - Step-by-step analysis control
- magnetstein/ - Masserstein optimal transport library
- NMRBank/ - Reference NMR spectra database (~156k compounds)
| Variable | Purpose |
|---|---|
HF_TOKEN |
HuggingFace API token (required for reaction prediction via API) |
GRB_LICENSE_FILE |
Gurobi license file path |
NMRBANK_CSV |
Override NMRBank CSV location |
NMRBANK_SKIP_LOAD_FOR_TESTS |
Set to 1 to skip CSV load in tests |
NMR Spectra CSV: Two columns (ppm, intensity), no header. TSV also supported.
Reference Library: List of dicts: {name, ppm: [...], intensity: [...], smiles}
Script: app/tool_deconvolve_nmr.py
Goal: Deconvolve a 1D NMR mixture spectrum into contributions from known component spectra using Masserstein optimal transport and the Gurobi linear programming solver.
Required:
- Mixture spectrum (
mixture): CSV/TSV with columns (ppm, intensity) - Component spectra (
components): One or more CSV/TSV files with the same format
Optional:
--protons: Number of protons per component (for intensity normalization)--names: Custom names for components (for output table and JSON)--mnova: If files are Mnova TSV exports
| Flag | Description | Default |
|---|---|---|
--threads |
Number of BLAS / solver threads | 8 |
--time-limit |
Gurobi solver time limit (seconds) | 300 |
--method |
LP solve method: auto, primal, dual, barrier |
dual |
--presolve |
Gurobi presolve level (0–2) | 2 |
--numeric-focus |
NumericFocus (0–3, higher = more numerical stability) | 1 |
--skip-crossover |
Skip crossover when using barrier method | off |
--license-file |
Path to gurobi.lic license file |
env |
--json |
Print output also in JSON | off |
--quiet |
Reduce solver verbosity | off |
uv run python app/tool_deconvolve_nmr.py \
mixture.csv comp1.csv comp2.csv \
--protons 16 12 \
--names "Component 1" "Component 2" \
--json- Python 3.10+
- rdkit, transformers, torch (for ReactionT5)
- mcp (for MCP server)
- gradio (for web UI)
- IsoSpecPy, masserstein (for deconvolution)
- Gurobi optimizer (optional, for full LP-based deconvolution)
See pyproject.toml for the full pinned dependency list.
# Run all tests
uv run pytest tests/ -v
# Skip NMRBank CSV loading (faster)
NMRBANK_SKIP_LOAD_FOR_TESTS=1 uv run pytest tests/ -v