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()

Excluding the target from stock. A molecule that is itself a catalogue item is otherwise "solved" in zero steps. Pass exclude_target=True to force a real disconnection — the target is treated as not purchasable, while its intermediates still are. Available on both planning and scoring (default off):

planner.plan("CC(=O)Nc1ccccc1O", exclude_target=True)
scorer.score("CC(=O)Nc1ccccc1O", max_steps=5, exclude_target=True)

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.2.0.tar.gz (46.0 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.2.0-py3-none-any.whl (52.9 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for synomega-0.2.0.tar.gz
Algorithm Hash digest
SHA256 c8cfb400a838b5e25d9651acd19a40997404c0693b6d9362434b9301c5d56257
MD5 be73455f1e8b852d15750f687b62bff3
BLAKE2b-256 4f14deccc51b5da169368abfd544503032f12c749ddfebe9ddf2daa4ab444d07

See more details on using hashes here.

File details

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

File metadata

  • Download URL: synomega-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 52.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.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c8e6fe51e4dad1e1a110fb167b74f3f02d2b561b8b45e19f049d8e3aa42ac7c1
MD5 d7f6ee5a46c734e5a207a93e7b3f3d2e
BLAKE2b-256 109023dd01c34c64477fe9bea26e34535bfd69922fc44ba1e442d5308e5292b8

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