Skip to main content

Retrosynthesis toolkit: single-step prediction, multi-step route planning, synthesizability scoring

Project description

synomega

PyPI Python License: MIT

A retrosynthesis toolkit that turns a target molecule into synthesis routes and a continuous synthesizability score. Three decoupled layers:

synthesizability   is this target reachable from purchasable material, in N steps?
     ↑
search             Retro* / MCTS / best-first over an AND-OR graph
     ↑
single-step        product SMILES -> ranked reactant candidates

The layers meet at a deliberately narrow interface — a single-step backend only implements predict(smiles, top_k) -> [Prediction] — so the planner and the scorer do not care whether predictions come from a graph neural network, a transformer, or plain template matching.

Installation

pip install synomega           # core: rdkit + numpy
pip install "synomega[gnn]"    # + the D-MPNN neural single-step backend (torch)

The neural backend is an optional extra on purpose: the template-rule backend runs anywhere, with no GPU and no PyTorch. Requires Python ≥ 3.10.

Quick start

from synomega import Planner, SynthesizabilityScorer
from synomega.singlestep import TemplateGNN
from synomega.stock import InMemoryStock

model   = TemplateGNN.from_pretrained("path/to/model_run")   # a trained checkpoint
stock   = InMemoryStock.from_keys_file("building_blocks.keys.gz")
planner = Planner(model, stock, algorithm="retrostar")

result = planner.plan("CC(=O)Nc1ccccc1", max_depth=5, time_limit=60)
print(result.solved)
print(result.best_route.describe())
target: CC(=O)Nc1ccccc1
solved: True  steps: 2  depth: 2  bb_coverage: 1.00
  [1] CC(=O)O.Nc1ccccc1>>CC(=O)Nc1ccccc1  (score=0.4348)
  [2] O=[N+]([O-])c1ccccc1>>Nc1ccccc1     (score=0.2174)

Synthesizability scoring

scorer = SynthesizabilityScorer(planner)

r = scorer.score("CC(=O)Nc1ccccc1", max_steps=5)
r.solved            # True — a complete route to purchasable material exists
r.bb_coverage       # 1.0 — fraction of the best route's leaves that are buyable
r.min_steps         # 2  — reactions in the shortest solved route
r.min_route_depth   # 2  — longest linear sequence of that route

report = scorer.score_batch(targets, max_steps=5)
report.solve_rate         # fraction of targets solved
report.mean_bb_coverage
report.to_dataframe()

Two synthesizability metrics

These are conflated in the literature; synomega keeps them apart because they answer different questions.

Metric Meaning Use it for
solved@N / solve_rate Binary — does a route of depth ≤ N exist whose leaves are all purchasable? Comparing against published numbers
bb_coverage@N Continuous — fraction of the best route's leaves that are purchasable Ranking molecules by how close they are

bb_coverage matters because most targets are unsolved at realistic step limits. A 5-step route with 4 of 5 leaves buyable scores 0.8, not 0 — so a near-miss is distinguishable from a total failure, and a set of molecules can be ranked rather than merely split into solved/unsolved.

Search algorithms

Algorithm Character When to use
retrostar Expands the frontier molecule with the lowest estimated total route cost (Chen et al. 2020) Default
mcts UCT with greedy rollouts; tolerant of an unreliable top-1 Weak single-step model
bfs Best-first on g + h Baseline / debugging

All three share the AND-OR graph, the budget, and the route extractor, so their results are directly comparable.

Command line

# one-time: precompute building-block InChIKeys so later loads take seconds
synomega build-stock --catalogue catalogue.smi.gz --out building_blocks.keys.gz

synomega plan  --target "CC(=O)Nc1ccccc1" --model path/to/model_run \
               --stock building_blocks.keys.gz --stock-is-keys --max-steps 5

synomega score --targets targets.smi --model path/to/model_run \
               --stock building_blocks.keys.gz --stock-is-keys \
               --max-steps 5 --out report.json

Bring your own single-step model

Any object implementing the SingleStepModel interface plugs into the planner:

from synomega.singlestep import SingleStepModel, Prediction

class MyModel(SingleStepModel):
    name = "my-model"
    def predict(self, smiles: str, top_k: int = 50) -> list[Prediction]:
        # return candidate disconnections, best first
        return [Prediction(reactants=("CCO", "CC(=O)O"), score=0.9)]

planner = Planner(MyModel(), stock, algorithm="retrostar")

Built-in backends: TemplateGNN (D-MPNN template classifier, needs [gnn]) and TemplateRuleModel (pure template matching, no PyTorch).

Design notes

  • AND-OR graph, not a tree. A molecule is solved if it is in stock or any of its reactions is solved; a reaction is solved if all its reactants are. Molecules are interned by InChIKey, so an intermediate reached down two branches is one node, expanded once. Cycles are rejected at edge creation.
  • Batched expansion. The search pulls a batch of frontier molecules and issues one predict_batch, so a GPU-backed model is not left idle.
  • Caching. Planner(cache=True) (default) memoizes expansions; cache_path= persists them to SQLite across runs.
  • Stock membership is by InChIKey, matching a vendor catalogue written by a different toolkit. There is deliberately no Bloom-filter backend — false positives would inflate solve-rate and break comparability with published numbers.

Development

git clone https://github.com/zbc0315/synomega
cd synomega
pip install -e ".[gnn,dev]"
pytest

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

synomega-0.1.1.tar.gz (44.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

synomega-0.1.1-py3-none-any.whl (51.9 kB view details)

Uploaded Python 3

File details

Details for the file synomega-0.1.1.tar.gz.

File metadata

  • Download URL: synomega-0.1.1.tar.gz
  • Upload date:
  • Size: 44.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for synomega-0.1.1.tar.gz
Algorithm Hash digest
SHA256 e68a3af33a04a458fceb9aff7550e03f749bda4309e88b87cdd923619f1463d9
MD5 b7d7b64a1821534c73d83fb28b0fc49f
BLAKE2b-256 087d0e14bbe589bc59dcd8507f2e770e7689f0d3aea82454f645e34d9b88f0a1

See more details on using hashes here.

File details

Details for the file synomega-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: synomega-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 51.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for synomega-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f3bd83180150167d4c1a0e3162706bc2cd8c12932db248561a5673838a2169b3
MD5 3add21ca505b5f161efbd812d231c197
BLAKE2b-256 f0ba7dd9b90cabd281272873c09721481320cad7bad85f79d529aad210e7f593

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page