Skip to main content

RetroCast: A Unified Format for Multistep Retrosynthesis

isChemist Protocol v1.0.0 Ruff ty coverage arXiv

RetroCast is a comprehensive toolkit for standardizing, scoring, and analyzing multistep retrosynthesis models. It decouples prediction from evaluation, allowing rigorous, apples-to-apples comparison of disparate algorithms on a unified playing field.

The Crisis of Evaluation

The field of retrosynthesis is fragmented.

  1. Incompatible Outputs: AiZynthFinder outputs bipartite graphs; Retro* outputs precursor maps; DirectMultiStep outputs recursive dictionaries. Comparing them requires writing bespoke parsers for every paper.
  2. Ad-Hoc Metrics: "Solvability" is often calculated differently across publications, with varying definitions of commercial stock (e.g., using made-to-order libraries vs. actual off-the-shelf compounds).
  3. Flawed Benchmarks: The standard PaRoutes n5 dataset is heavily skewed (74% of routes are length 3-4), masking performance failures on complex targets. Furthermore, the standard stock definition for PaRoutes creates synthetic "ground truths" that are often physically unobtainable.

RetroCast solves this. It provides a canonical schema, adapters for 10+ models, and rigorous statistical evaluation to turn retrosynthesis from a qualitative art into a quantitative science.


Key Features

  • Universal Adapters: "Air-gapped" translation layers for AiZynthFinder, *Retro**, DirectMultiStep, SynPlanner, Syntheseus, ASKCOS, RetroChimera, DreamRetro, MultiStepTTL, SynLlama, and *PaRoutes*.
  • Canonical Schema: All routes are cast into a strict schema-2 Molecule / Reaction tree.
  • Rust Core: Every built-in planner adapter, ingest, scoring, and analysis runs in Rust, with canonical SMILES, InChIKeys, and molecular descriptors calculated through RDKit C++.
  • Curated Benchmarks: Includes the Reference Series (for algorithm comparison) and Market Series (for practical utility), stratified by route length and topology to eliminate statistical noise.
  • Rigorous Statistics: Built-in bootstrapping (95% CI), pairwise tournaments, and probabilistic ranking. No more "Model A is 0.1% better than Model B" without significance testing.
  • Reproducibility: Every artifact is tracked via cryptographic manifests (SHA256).

Installation

The Python package includes the native engine and its RDKit C++ libraries; it does not install Python RDKit. Install it when you want import retrocast:

uv add retrocast

The standalone Rust executable provides the retrocast CLI and is published separately on the GitHub Releases page. Download the archive for linux-x86_64, macos-arm64, macos-x86_64, or windows-x86_64; each archive contains retrocast and the RDKit libraries it was built and smoke-tested with. It does not require Python, Conda, Rust, or a separately installed RDKit.

Markdown docs are formatted with oxfmt and kept unwrapped (proseWrap: "never"). Use pnpm docs:fmt to normalize docs formatting or pnpm docs:fmt:check to verify it in review/CI.

Get Data

Latest Data (Updated Regularly)

For the most up-to-date benchmarks and stocks, use the RetroCast CLI:

# Download a specific benchmark (includes definition + required stock)
retrocast get-data mkt-cnv-160

Publication Data (Frozen)

The complete data/ folder as used in the preprint is available at files.ischemist.com/retrocast/publication-data:

# Show available folders and their sizes
curl -fsSL https://files.ischemist.com/retrocast/get-pub-data.sh | bash -s

# Download all benchmark definitions
curl -fsSL https://files.ischemist.com/retrocast/get-pub-data.sh | bash -s -- definitions

you can verify the integrity of downloaded files against the manifests by running

retrocast verify --all

that command might warn you about missing files---that is expected. Manifests for, say 4-scored, contain hashes of input files from 3-results, and if you downloaded only 4-scored, you will get warnings about missing 3-results files.

a dump of the sqlite db with the stocks, routes, and results loaded into SynthArena can be found in ischemist/syntharena repo.


Quick Start

1. The Ad-Hoc Workflow

Have a raw output file from a model? Score it immediately.

# Convert raw AiZynthFinder JSON to RetroCast format
retrocast adapt \
    --input raw_predictions.json.gz \
    --adapter aizynthfinder \
    --output candidates.json.gz

# Align predictions to benchmark-keyed candidates
retrocast collect \
    --input candidates.json.gz \
    --benchmark data/retrocast/1-benchmarks/definitions/ref-lin-600.json.gz \
    --output collected-candidates.json.gz

# Score against a stock file
retrocast score-file \
    --benchmark data/retrocast/1-benchmarks/definitions/ref-lin-600.json.gz \
    --candidates collected-candidates.json.gz \
    --stock data/retrocast/1-benchmarks/stocks/n5-stock.csv.gz \
    --output scores.json.gz \
    --model-name "My-Experimental-Model"

2. The Project Workflow

For full-scale benchmarking, RetroCast enforces a structured data lifecycle: Ingest $\to$ Score $\to$ Analyze.

model-specific prediction runners were extracted from this repo and now live in project-pandora. use RetroCast here for standardization, scoring, and analysis; use pandora when you need the upstream model-runner scripts.

Inspect project paths:

retrocast config

Project mode reads raw model outputs from data/retrocast/2-raw/<model>/<benchmark>/. Pass the adapter on the command line, or put a manifest.json next to the raw results file:

{
  "directives": {
    "adapter": "directmultistep",
    "raw_results_filename": "predictions.json"
  }
}

Evaluate planner output:

# 1. Ingest: Standardize raw outputs from data/retrocast/2-raw/
retrocast ingest --model dms-explorer --dataset ref-lin-600 --adapter directmultistep

# 2. Score: Evaluate against the benchmark's defined stock
retrocast score --model dms-explorer --dataset ref-lin-600

# 3. Analyze: Generate bootstrap statistics
retrocast analyze --model dms-explorer --dataset ref-lin-600

The all-in-one command evaluates each target and releases its route graphs after preparing their analysis contributions:

retrocast evaluate \
  --raw data/retrocast/2-raw/aizynthfinder-run/mkt-cnv-160 \
  --adapter aizynthfinder \
  --benchmark data/retrocast/1-benchmarks/definitions/mkt-cnv-160.json.gz \
  --stock data/retrocast/1-benchmarks/stocks/buyables-stock.csv.gz \
  --output-dir native-results \
  --workers 12

This writes candidates.json.gz, evaluation.json.gz, analysis.json.gz, evaluation-run.json, and a verifiable manifest.json.

Output: A schema-v2 analysis report in data/retrocast/5-results/.


The Benchmarks

RetroCast introduces two new benchmark series derived from PaRoutes, fixing the skew and stock issues of the original dataset. These subsets were selected via seed stability analysis to ensure they are statistically representative of the underlying difficulty distribution.

The Reference Series (ref-)

Target Audience: Algorithm Developers Designed to compare search algorithms (e.g., MCTS vs. Retro* vs. Transformers). Uses the internal PaRoutes stock to isolate search failures from stock availability issues.

Benchmark Targets Description
ref-lin-600 600 Linear routes stratified by length (100 each for lengths 2–7).
ref-cnv-400 400 Convergent routes stratified by length (100 each for lengths 2–5).
ref-lng-84 84 All available routes of extreme length (8–10 steps).

The Market Series (mkt-)

Target Audience: Computational Chemists Designed to assess practical utility. Targets are filtered to be solvable using Buyables, a curated catalog of 300k compounds available for <$100/g.

Benchmark Targets Description
mkt-lin-500 500 Linear routes solvable with commercial buyables (Stratified).
mkt-cnv-160 160 Convergent routes solvable with commercial buyables (Stratified).

Python API

RetroCast is also a library. You can use it to integrate standardization directly into your training or inference loops.

adapt, ingest, score, and analyze use the same Rust core as the standalone retrocast executable for every built-in adapter. There is no Python/Rust engine selector and no Python implementation inside the wheel.

External planner runners can also use the Rust-owned producer contracts directly:

import retrocast

task = retrocast.load_task("benchmark.json.gz")
stock_smiles = retrocast.load_stock("buyables-stock.csv.gz")
retrocast.write_json_gz(raw_results, "results.json.gz")
manifest = retrocast.create_planner_manifest(
    "planner-run",
    "aizynthfinder",
    "results.json.gz",
    ["benchmark.json.gz", "buyables-stock.csv.gz"],
    ".",
)

Structural task loading, explicit chemistry validation, stock parsing, artifact serialization, execution-stat validation, and manifest provenance stay in retrocast-core; the runner owns model-specific serialization, logging, and progress presentation.

import retrocast

# Your model's raw output (any supported format)
raw_output = {
    "smiles": "CC(=O)Oc1ccccc1C(=O)O",
    "children": [...]
}

# Cast to canonical schema dictionaries.
candidates = retrocast.adapt([raw_output], "directmultistep")
route = candidates[0].get("route")

if route is None:
    raise ValueError("Could not adapt route")

print(route["target"]["smiles"])

Visualization: SynthArena

RetroCast powers SynthArena, an open-source web platform for visualizing and comparing retrosynthetic routes.

  • Compare predictions from any two models side-by-side.
  • Visualize ground truth vs. predicted routes with diff overlays.
  • Inspect stratified performance metrics interactively.

Vision: Structural AI for Chemistry

We distinguish between two fundamental classes of problems in scientific machine learning: quantitative (predicting scalar targets like toxicity or binding affinity) and structural (generating complex objects governed by an underlying grammar). Quantitative problems, analogous to early NLP challenges like sentiment analysis, are often constrained by data scarcity. In contrast, the most transformative AI breakthroughs—from large language models to AlphaFold—have occurred in structural domains.

Mastery of structure is a prerequisite for solving downstream quantitative tasks. Foundation models trained on the structure of language, for instance, now excel at sentiment analysis with little to no task-specific fine-tuning. In organic chemistry, the paramount structural challenge is retrosynthesis: designing a valid synthetic pathway to a molecule of interest. This capability is the key to unlocking critical quantitative problems like predicting synthetic accessibility, a significant bottleneck in drug discovery. Current accessibility heuristics, however, bypass the core structural challenge, relying on learned patterns that correlate with accessibility without ever generating the pathway itself.

A model cannot judge the difficulty of a journey it cannot first articulate.

Achieving structural mastery in retrosynthesis is a long journey—one that requires moving beyond fragmented data formats, inconsistent evaluation methods, and unreliable metrics. Progress demands unified, rigorous infrastructure to standardize outputs, track provenance, and measure improvements with statistical rigor.

RetroCast is that infrastructure.

Citation

If you use RetroCast in your research, please cite:

@misc{retrocast,
  title         = {Procrustean Bed for AI-Driven Retrosynthesis: A Unified Framework for Reproducible Evaluation},
  author        = {Anton Morgunov and Victor S. Batista},
  year          = {2025},
  eprint        = {2512.07079},
  archiveprefix = {arXiv},
  primaryclass  = {cs.LG},
  url           = {https://arxiv.org/abs/2512.07079}
}

License

MIT License. See LICENSE for details.

Metadata

Release files for retrocast 0.8.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for retrocast 0.8.3
File Size Uploaded Provenance
retrocast-0.8.3.tar.gz 153.7 kB With provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for retrocast 0.8.3
File
retrocast-0.8.3-cp311-abi3-win_amd64.whl CPython 3.11 abi3 Windows x86-64 Details
retrocast-0.8.3-cp311-abi3-manylinux_2_28_x86_64.whl CPython 3.11 abi3 Linux glibc 2.28+ x86-64 Details
retrocast-0.8.3-cp311-abi3-macosx_11_0_x86_64.whl CPython 3.11 abi3 macOS 11.0+ x86-64 Details
retrocast-0.8.3-cp311-abi3-macosx_11_0_arm64.whl CPython 3.11 abi3 macOS 11.0+ ARM64 Details

Total release size: 30.6 MB

Release files / retrocast-0.8.3.tar.gz

Download URL retrocast-0.8.3.tar.gz
Size 153.7 kB
Tags Source
SHA-256 checksum
How to use checksums
40a2b18163fd5f4ec618c866d20c8cc523659be07edbb0cd0a3f58822f8e5cb8
BLAKE2b-256 checksum
How to use checksums
03c1b936def9fcf21c3c90a9818677015f2ded0b9d3b30cf4a153f1e11c386b6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 4, 2026.

Transparency log

Release files / retrocast-0.8.3-cp311-abi3-win_amd64.whl

Download URL retrocast-0.8.3-cp311-abi3-win_amd64.whl
Size 6.6 MB
Tags CPython 3.11 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
0ab7ba8b6aaa305292fe18528f00776504bdb88b1809b7ec8d370b584596d592
BLAKE2b-256 checksum
How to use checksums
388bc9c0212d1c37aaa6b30b300937a35d123f129c83e2f878ef7db4684303cb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 4, 2026.

Transparency log

Release files / retrocast-0.8.3-cp311-abi3-manylinux_2_28_x86_64.whl

Download URL retrocast-0.8.3-cp311-abi3-manylinux_2_28_x86_64.whl
Size 8.9 MB
Tags CPython 3.11 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
e2a0983e33592c85328cc3c7106593c510ca02beb4760b1a2b00823d78dd6702
BLAKE2b-256 checksum
How to use checksums
e9d6d60ca99eef11dc2f5813298591a5e1e16ad109ee23ef6d1c27ad6c111cc4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 4, 2026.

Transparency log

Release files / retrocast-0.8.3-cp311-abi3-macosx_11_0_x86_64.whl

Download URL retrocast-0.8.3-cp311-abi3-macosx_11_0_x86_64.whl
Size 7.8 MB
Tags CPython 3.11 abi3 macOS 11.0+ x86-64
SHA-256 checksum
How to use checksums
ccbf3aaf6515d6342f20f580244f480e0e62781abf7c517995e81d98b7de5424
BLAKE2b-256 checksum
How to use checksums
7ea7bf8a292ab63f1812078224ed2f5d3eaba8b182b8debbb8975a72dd02c5c4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 4, 2026.

Transparency log

Release files / retrocast-0.8.3-cp311-abi3-macosx_11_0_arm64.whl

Download URL retrocast-0.8.3-cp311-abi3-macosx_11_0_arm64.whl
Size 7.2 MB
Tags CPython 3.11 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
a6581248055ad1fae6567ae5b4e44c8b858fe0a2cb5d8a8f4a5e3874b215bfcb
BLAKE2b-256 checksum
How to use checksums
b0d9433539fa5e07e83b04ac2b1c9d874cfbe2ef77438481b431fc3244363ac7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 4, 2026.

Transparency log

Security for retrocast 0.8.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 5 files in this release have been uploaded with provenance metadata.

Select from 5 files

Attestation for retrocast-0.8.3.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 4, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page