Skip to main content

A multi-objective reaction optimization framework based on Bayesian optimization

Project description

SynBO: Synthetic Bayesian Optimization for Reaction Condition Screening

Python 3.10+ License: MIT

SynBO (Synthetic Bayesian Optimization) is an intelligent reaction optimization framework that uses Bayesian Optimization to find optimal reaction conditions with minimal experimental effort.


๐Ÿšฉ Getting Started with SynBO & AutoClaw

  1. Download AutoClaw Download and set up AutoClaw from the official release page: https://autoglm.z.ai/autoclaw/

  2. Install SynBO Skills Install the SynBO skill package via SkillHub: https://skillhub.cn/skills/synbo When initiating the installation, provide the following input context to ensure proper setup:

    Please check if the SkillHub store is already installed. If not, follow the guide at https://skillhub.cn/install/skillhub.md to install only the SkillHub CLI, then install the SynBO skill. If it is already installed, proceed directly to install the SynBO skill.
    
  3. Optimize Reaction Conditions Launch AutoClaw and prompt it to optimize your reaction conditions using the integrated SynBO skills. Example usage:

    Please optimize the reaction condition for [insert your reaction name].
    

    AutoClaw will then guide you through the SynBO optimization process, providing recommendations and insights to improve your reaction outcomes.


๐Ÿ“ Example Project: Cobalt-Catalyzed Asymmetric Reaction

The examples/ directory contains a complete, runnable example of a cobalt-catalyzed reaction optimization with 5 reagent types and 2 objectives (yield + ee):

examples/
โ”œโ”€โ”€ optimization_settings.json          # Optimization goals & settings
โ”œโ”€โ”€ rxn_space/                          # Reaction space definitions
โ”‚   โ”œโ”€โ”€ alkali.csv                      #   9 alkali/additive options
โ”‚   โ”œโ”€โ”€ cobalt_catalyst.csv             #   8 Co-catalyst candidates
โ”‚   โ”œโ”€โ”€ organo_catalyst.csv             #   9 organocatalyst candidates
โ”‚   โ”œโ”€โ”€ oxidant.csv                     #   9 oxidant options
โ”‚   โ””โ”€โ”€ solvent.csv                     # 10 solvent options
โ”œโ”€โ”€ descriptors/                        # RDKit molecular descriptors
โ”‚   โ”œโ”€โ”€ alkali_RDKit.csv
โ”‚   โ”œโ”€โ”€ cobalt_catalyst_RDKit.csv
โ”‚   โ”œโ”€โ”€ organo_catalyst_RDKit.csv
โ”‚   โ”œโ”€โ”€ oxidant_RDKit.csv
โ”‚   โ””โ”€โ”€ solvent_RDKit.csv
โ””โ”€โ”€ results/                            # Example optimization outputs
    โ”œโ”€โ”€ batch-0_20260420.csv            # Initial sampling results
    โ”œโ”€โ”€ batch-0_20260420.xlsx
    โ”œโ”€โ”€ batch-1_20260420.csv            # 1st optimization round results
    โ””โ”€โ”€ batch-1_20260420.xlsx

Reaction space size: 9 ร— 8 ร— 9 ร— 9 ร— 10 = 58,320 possible combinations

Step-by-Step Workflow

1. Define Your Reaction Space

Create CSV files for each reagent/condition type under rxn_space/. Each file must contain SMILES and name columns:

# rxn_space/solvent.csv
SMILES,name
ClCCl,DCM
CC#N,CH3CN
C1CCOC1,THF
...

2. Generate Molecular Descriptors

python scripts/get_desc.py --input rxn_space/solvent.csv --smiles-col 'SMILES' --name-col 'name'

Repeat for each reagent type. Outputs go to descriptors/{reagent}_RDKit.csv.

3. Define Optimization Goals

Create optimization_settings.json:

{
    "reagent_types": ["alkali", "cobalt_catalyst", "organo_catalyst", "oxidant", "solvent"],
    "opt_metrics": ["yield", "ee"],
    "opt_direct_info": [
        {"opt_direct": "max", "opt_range": [0, 100], "metric_weight": 1.0},
        {"opt_direct": "max", "opt_range": [0, 100], "metric_weight": 1.0}
    ]
}

4. Initialize โ€” Generate First Batch

CLI:

python scripts/initialize.py --project-dir examples --batch-size 8 --sampling-method lhs

Python API:

from synbo import ReactionOptimizer
from synbo.utils import load_desc_dict

desc_dict, condition_dict = load_desc_dict(
    reagent_types=["alkali", "cobalt_catalyst", "organo_catalyst", "oxidant", "solvent"],
    desc_dir="examples/descriptors",
    name_suffix="_RDKit",
    index_col="name",
    return_condition_dict=True,
)

optimizer = ReactionOptimizer(
    opt_metrics=["yield", "ee"],
    opt_type="init",
    random_seed=42,
    save_dir="examples/results",
)
optimizer.load_rxn_space(condition_dict)
optimizer.load_desc(desc_dict)
optimizer.initialize(batch_size=8, sampling_method="lhs")
optimizer.save_results(filetype="excel")

5. Run Experiments & Record Results

Run the recommended experiments in the lab. Fill in the yield and ee columns in the output file (replace [exp_data] with actual measurements).

6. Optimize โ€” Get the Next Batch

CLI:

python scripts/optimize.py --project-dir examples --batch-size 5

Python API:

from synbo.utils import get_prev_rxn

prev_data = get_prev_rxn("examples/results", "batch-*.csv")

optimizer = ReactionOptimizer(
    opt_metrics=["yield", "ee"],
    opt_type="auto",
    random_seed=42,
    save_dir="examples/results",
)
optimizer.load_rxn_space(condition_dict)
optimizer.load_desc(desc_dict)
optimizer.load_prev_rxn(prev_data)
optimizer.optimize(batch_size=5)
optimizer.save_results(filetype="excel")

7. Repeat Steps 5โ€“6 Until Satisfactory Results


๐Ÿ“Š Jupyter Notebook Demo

An interactive Jupyter notebook demonstrating the full optimization workflow with visualizations is available at examples/demo_optimization.ipynb. It covers:

  • Loading the example reaction space and descriptors
  • Running initialization and optimization rounds
  • Visualizing the Pareto front (yield vs ee trade-off)
  • Tracking optimization progress with Hypervolume metrics
  • Interpreting explore vs exploit recommendations

Run it: jupyter notebook examples/demo_optimization.ipynb


๐Ÿš€ Quick Start

Installation

conda create -n synbo python=3.13 # if there is a conda on your computer
pip install synbo

Minimal Python Example

from synbo import ReactionOptimizer

optimizer = ReactionOptimizer(
    opt_metrics=['yield', 'ee'],
    opt_type='auto',
    random_seed=42
)

# Load reaction space
optimizer.load_rxn_space({
    'catalyst': ['Pd(OAc)2', 'Pd(PPh3)4', 'Pd2(dba)3'],
    'solvent': ['THF', 'Dioxane', 'Toluene', 'DMF', 'MeCN'],
    'base': ['Cs2CO3', 'K2CO3', 'NaOEt', 'DBU'],
    'temperature': [25, 50, 80, 100]
})

# Use OneHot encoding (auto-generated when no descriptors provided)
optimizer.load_desc()

# Initial sampling
optimizer.run(batch_size=8)
optimizer.save_results(filetype='csv')

# After experiments, load results and optimize
# optimizer.load_prev_rxn(pd.read_csv('results.csv'))
# optimizer.run(batch_size=5)

๐Ÿงช Python API Reference

ReactionOptimizer

optimizer = ReactionOptimizer(
    opt_metrics=["yield", "ee"],
    opt_metric_settings=[
        {"opt_direct": "max", "opt_range": [0, 100], "metric_weight": 1.0},
        {"opt_direct": "max", "opt_range": [0, 100], "metric_weight": 1.0},
    ],
    opt_type="auto",    # "init" | "opt" | "auto"
    random_seed=42,
    save_dir="./results",
)

Key Methods

Method Description
load_rxn_space(condition_dict) Load reaction space (all possible reagent combinations)
load_desc(desc_dict=None) Load molecular descriptors (OneHot encoding used if None)
load_prev_rxn(df) Load previous experimental results for optimization
initialize(batch_size, sampling_method) Generate initial batch (LHS/Sobol/K-Means/Random)
optimize(batch_size, constraints) Run Bayesian optimization to recommend next batch
save_results(filetype) Save recommendations to CSV/Excel/JSON
calculate_current_hv() Calculate current Hypervolume (multi-objective progress)
calculate_hv_by_batch() Track Hypervolume across optimization rounds

๐Ÿ“ˆ Understanding Optimization Results

Predictions with Uncertainty

Output files include predicted values with uncertainties:

batch alkali cobalt_catalyst ... pred yield pred ee yield ee
1 DBU [Co]-5 ... 62.35ยฑ3.12 85.20ยฑ2.87 [exp_data] [exp_data]
  • pred yield / pred ee: Model prediction ยฑ uncertainty
  • [exp_data]: Placeholder for your experimental results

Explore vs Exploit

  • EXPLORE: Testing new areas of the reaction space
  • EXPLOIT: Refining near known good results

Hypervolume Tracking

hv = optimizer.calculate_current_hv()
print(f"Progress: {hv['hv_normalized']*100:.1f}%")
history = optimizer.calculate_hv_by_batch()

โš™๏ธ Advanced Features

Reaction Constraints

constraints = {"alkali": ["DBU"], "solvent": ["DMSO"]}
optimizer.optimize(batch_size=5, constraints=constraints)

Or use prohibited_reagent.json for automatic loading.

GPU Acceleration

SynBO auto-detects GPU. Force CPU: optimizer.optimize(batch_size=5, device="cpu")

Excel Output with Molecular Structures

optimizer.save_results(
    filetype="excel",
    figure_output=["cobalt_catalyst", "organo_catalyst"],
    figure_path="examples/figures",
)

๐Ÿ”ง CLI Quick Reference

synbo --version
synbo create-config -o my_config.json
synbo validate my_config.json
synbo init my_config.json -b 8 -m lhs -o results/
synbo optimize my_config.json results/batch-0.csv -b 5 -o results/

๐Ÿ“ฆ Dependencies

Core: numpy, pandas, scikit-learn, torch, botorch | Chemistry: rdkit, epam.indigo | CLI: typer, rich | Viz: matplotlib, seaborn

See pyproject.toml for the complete list.


๐Ÿ“ง Contact

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

synbo-0.6.3.tar.gz (53.7 kB view details)

Uploaded Source

Built Distribution

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

synbo-0.6.3-py3-none-any.whl (52.9 kB view details)

Uploaded Python 3

File details

Details for the file synbo-0.6.3.tar.gz.

File metadata

  • Download URL: synbo-0.6.3.tar.gz
  • Upload date:
  • Size: 53.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for synbo-0.6.3.tar.gz
Algorithm Hash digest
SHA256 d56e5abb05887e3063dff4dcb247485bf4c47d601365ea23711f55f349eaaa30
MD5 77cfdade7d0983d2573d876ccaa07d75
BLAKE2b-256 f2cd173fc842508a540ab9b42ac0469db1760ad49dcfd88b7589cad4b0ea568b

See more details on using hashes here.

File details

Details for the file synbo-0.6.3-py3-none-any.whl.

File metadata

  • Download URL: synbo-0.6.3-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.13.9

File hashes

Hashes for synbo-0.6.3-py3-none-any.whl
Algorithm Hash digest
SHA256 1abbdec41fbd54aaf5c79e6480465f55965b5ee6e8fbad3140e7bfdd8c0368ce
MD5 91f41d85b9d41d7e30cc27c415f5a648
BLAKE2b-256 7369706849b7c7e1353a96bf4c7199e43d7d285c97774c47c43ac235d44ffaa1

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