feat(thermo,chem): unified thermodynamics + cheminformatics facades (equilibrator, dGPredictor, molGPK/OPAM2)#47
Open
VibhavSetlur wants to merge 7 commits into
Conversation
jplfaria
pushed a commit
to jplfaria/KBUtilLib
that referenced
this pull request
Jul 21, 2026
…ry#42-cshenry#47) - Move kbu-literature-review/review/diagnose to .claude/agents/ as kbu-sub-* with type: agent frontmatter (AC cshenry#44, cshenry#45, cshenry#47) - Add data/, models/, genomes/ .gitkeep to template (AC cshenry#42) - Append [layout] shared_dirs block to kbu-project.toml.template (AC cshenry#43) - Add 9 root_gitignore_lines patterns to .gitignore template - Update bootstrap.py: _CLAUDE_AGENT_FILES list, agents dir creation loop, shared-dir .gitkeep scaffolding, [layout] in manifest, kbu-migrate.md in command list (skips silently when template absent - Option 1) - Update new_project.py: _TRACKED_DIRS includes .claude/agents, [layout] in manifest - Update tests: AC9 entry counts, _make_stub_template includes agents, new AC 42-47 tests Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add a PredictiveThermoUtils facade that estimates standard transformed Gibbs energies of formation (compounds) and reaction (delta_r G'^0) by dispatching across a priority-ordered set of pluggable backends, each of which degrades gracefully and never fabricates a value (unknown -> None plus a warning). Backends (src/kbutillib/thermo_predictors/): - equilibrator: live component-contribution via equilibrator-api (optional dep). Condition-aware (pH, ionic strength, T, p_Mg). - dgpredictor: Maranas/Tyo-lab group-contribution reaction predictor (Andrew Freiburger's fork). Runs out-of-process against a local clone to keep rdkit/openbabel and the ~150 MB model out of this process; KEGG stoichiometry in, kJ/mol transformed dG' out. Detects a missing/LFS-pointer model and reports unavailable. - modelseed_db: baked transformed dG from the expanded-eQuilibrator ModelSEED Database fork, read directly from compounds.tsv/reactions.tsv with the stdlib csv reader (kcal->kJ, fixed pH7/I0.25/298.15 K, EQU/EQC/EQP-preferred provenance gate). - modelseed: always-on fallback over the existing ThermoUtils lookups. - molgpk: stub for the Tyo-lab molGPK/OPAM2 predictor (unreleased); reports unavailable until configured. Dispatch order: equilibrator -> dgpredictor -> modelseed_db -> modelseed. Nothing in the subpackage imports a heavy/optional dependency at import time. Exposed as the lazy `predictive_thermo` property on KBUtilLib. Adds [project.optional-dependencies] equilibrator / thermo extras and a dependency-free test suite (tests/test_predictive_thermo.py) covering graceful degradation, the no-fabrication invariant, dispatch fall-through, and the kcal->kJ conversion against worked ATP / rxn00001 values.
…ules backends Add a pluggable in-silico reaction-prediction / metabolic-network-expansion layer mirroring the predictive-thermo facade pattern: - cheminformatics/base.py: ExpansionBackend protocol + PredictedCompound/ PredictedReaction/ExpansionResult dataclasses + BackendUnavailableError. Stdlib-only; importing it pulls no heavy dependency. - cheminformatics/pickaxe_backend.py: optional-dep wrapper over minedatabase (Pickaxe) SMARTS-operator expansion; robust rule-data-dir resolution (config -> env -> wheel -> source checkout) since the wheel ships no rule data; graceful degradation when absent. - cheminformatics/retrorules_backend.py: applies RetroRules SMARTS via RDKit (no-AddHs + partial-sanitize recipe), streaming the flat-rules TSV; filters by diameter/direction; graceful degradation when rdkit/TSV absent. - network_expansion_utils.py: NetworkExpansionUtils facade + Impl wrapper with backend dispatch (pickaxe -> retrorules), backend_status diagnostics, and never-fabricate semantics (empty result + warnings when nothing expands). - Wire NetworkExpansionUtils(Impl) into package __init__ and the toolkit (lazy 'network_expansion' property); add 'cheminformatics' optional-deps extra (rdkit). - tests/test_network_expansion.py: import/degradation invariants, injected-fake dispatch success path, and opt-in live integration tests gated on env vars. 16/16 tests pass (incl. live runs against real RetroRules + MINE-Database rule data); new modules ruff clean.
Replace the dead-endpoint molGPK stub with a working backend that wraps
Andrew Freiburger's OPAM2 (MolGpKa fine-tuned on the ModelSEED database).
- Subprocess-isolated so KBUtilLib never imports torch/torch-geometric;
the worker is bundled in-package (_molgpk_worker.py) and run with
OPAM2_SRC pointing at a cloned OPAM2 repo, so users only clone OPAM2
and set thermo.molgpk.repo_path/python (or MOLGPK_REPO/MOLGPK_PYTHON).
- compound_dgf -> pKa values + major microspecies; dgf left None (molGPK
feeds equilibrator, so ΔGf is never double-counted or fabricated).
- Probes worker + ModelSEED-tuned .pth checkpoints with a Git-LFS-pointer
size guard; degrades gracefully (per-compound miss != backend down).
- Batch path: worker accepts {compounds:[...]} and loads the model once;
compounds_dgf + facade.compounds_microspecies amortize the model load
across a whole compound set.
Tested: hermetic unavailable/degrade/LFS-pointer/hard-failure/misalign
cases plus env-gated live single + batch runs against a real OPAM2
checkout (acetate, glycine zwitterion, phosphate).
dGPredictor backend rewritten to Andrew Freiburger's ModelSEED fork API
(ModelSEEDdGPredictor.predict_reaction / predict_from_equation): addresses
reactions by rxnNNNNN accession or ModelSEED cpd stoichiometry, fixes the
model filename to model/modelseed_M12_model_BR.pkl, adds a batch path, and
ships the previously-missing subprocess worker (_dgpredictor_worker.py).
molGPK backend confirmed against the real OPAM2 API (predict_pka.predict /
protonate.Opam_protonate_mol + modelseed .pth weights).
Both validated end-to-end through the PredictiveThermoUtils facade with
config-driven repo paths (thermo.{dgpredictor,molgpk}.{repo_path,python}):
molgpk acetic acid pKa 2.01 -> CC(=O)[O-]; glycine -> [NH3+]CC(=O)[O-]
dgpredictor rxn00001 -15.76+/-3.63 kJ/mol; ATP hydrolysis -25.46 kJ/mol
Adds gated live integration tests (skip unless *_REPO/*_PYTHON set) and a
documented thermo: config block. 31 unit tests pass; 15 pass with repos
configured.
…-007 Andrew (relaying the Tyo lab) confirmed github.com/tyo-nu/MINE-Database as the pickaxe version to use. It IS the minedatabase package PickaxeBackend already wraps, with the bundled rule TSVs — so no separate tyo_pickaxe_backend.py is needed; point cheminformatics.pickaxe.data_dir at the clone's minedatabase/data. Validated end-to-end through the NetworkExpansionUtils (kbu.chem) facade: D-glucose, 1 generation, metacyc_generalized -> 901 new compounds / 1696 new reactions. Live integration test test_pickaxe_live_expansion passes. Resolves ADR-007 (wrap, don't reimplement). Documents the pickaxe/retrorules config block. Fixes test_backend_status_reports_all_backends to also clear the DGPREDICTOR_* env vars so it tests the not-configured contract deterministically. 45 unit tests pass; live thermo + pickaxe tests pass with repos configured.
Make the dGPredictor / molGPK / pickaxe backends self-contained the way the rest of KBUtilLib's external deps are: register the three research repos in dependencies.yaml (dGPredictor, OPAM2, MINE-Database) with path + git URL, and have each backend fall back to DependencyManager.get_dependency_path() when no explicit config key / env var is set. The pickaxe backend also puts a declared MINE-Database checkout on sys.path itself (no pip install, no .pth shim needed -- the Tyo repo pins python <3.10 which blocks pip install -e on 3.11). Net result: with zero env vars and zero config paths, all three backends resolve and compute purely from dependencies.yaml -- the same mechanism used for ModelSEEDpy / ModelSEEDDatabase / cobrakbase. Adds base.dependency_repo_path() helper, an INSTALL.md documenting the common footprint, and tightens the hermetic 'not configured' tests to also neutralize the DependencyManager so they stay deterministic. 45 unit tests pass; live thermo + pickaxe tests pass.
…eature Finalization pass to make the equilibrator + dGPredictor + molGPK/OPAM2 unified facade PR-ready. - docs/config: resolve API-name drift; document real attributes (kbu.predictive_thermo, kbu.network_expansion) and clarify legacy kbu.thermo; add kbu.chem alias on the toolkit facade - INSTALL.md: fix broken model-rebuild reference to dGPredictor's in-repo retrain_modelseed.py so the documented install path is real - thermo_predictors: add machine-readable `units` field (kJ/mol) to CompoundThermoEstimate/ReactionThermoEstimate and to_dict() - thermo_utils: fix stored-reaction deltaG bug (read reaction_obj.delta_g to match its guard instead of reaction_obj.deltag) - tests: rewrite stale test_ms_biochem_deltag.py against the relocated deltaG API in ThermoUtils; add gated molGPK predominant-ion pH-sweep test and units-field assertions - environment.yml: pinned conda env covering rdkit/openbabel/torch and backend runtime deps for a reproducible one-env install
VibhavSetlur
force-pushed
the
feature/thermo-cheminformatics-clean
branch
from
July 22, 2026 16:27
0434701 to
60d853b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a unified predictive-thermodynamics and cheminformatics network-expansion feature to KBUtilLib, exposing equilibrator, dGPredictor (Andrew's fork), and molGPK/OPAM2 (Andrew's MSDB fine-tuned fork) under one install and one API for KBase agent skills, as requested by Dr. Henry.
What's in this PR
New: Predictive Thermodynamics (
kbu.predictive_thermo)freiburgermsu/dGPredictormaster)freiburgermsu/OPAM2, fine-tuned on MSDB) — returns pKa + predominant ion at given pHunitsfield (kJ/mol) on all estimate dataclassesNew: Cheminformatics Network Expansion (
kbu.network_expansion)Install
pyproject.tomloptional[thermo]extradependencies.yamlsource-checkout resolver for dGPredictor / OPAM2 / MINE-Databaseenvironment.yml— pinned conda env (rdkit ≥ 2022.03, openbabel ≥ 3.1.1, pytorch ≥ 2.0, torch-geometric) for reproducible one-env setupconfig.yaml— runtime path config for backend reposAPI surface
Fixes included
thermo_utils.py: fix stored-reaction deltaG bug (guarded ondelta_gbut readdeltag)INSTALL.md: fix broken dGPredictor model-rebuild reference →retrain_modelseed.pyinside the dGPredictor repotest_ms_biochem_deltag.py: rewritten against relocatedThermoUtilsAPI (was testingMSBiochemUtilsmethods that moved)Tests
tests/test_predictive_thermo.py(39 tests — all backends, units field, molGPK pH sweep)tests/test_network_expansion.py(26 tests)tests/test_ms_biochem_deltag.py(rewritten, 17 tests — ThermoUtils deltaG API)Known deferred items (follow-up)