AiZynthFinder

repository·master·Indexed 21 days ago

https://github.com/molecularai/aizynthfinder

A retrosynthetic planning tool that uses neural network guided Monte-Carlo tree search to break down molecules into purchasable precursors. Version 4.4.1 provides a Python API via the AiZynthFinder and AiZynthExpander classes, a command-line interface (aizynthcli), and a Jupyter Notebook GUI (aizynthapp). It supports customizable expansion strategies, including Chemformer and ModelZoo, and allows for parallel execution across multiple processes.

Tokens
17.1K
Snippets
58
Records
68
Agent score
74%

What's inside aizynthfinder

  1. Available scoring functions in AiZynthFinder

    master

    AiZynthFinder can score reaction routes using MctsNode objects (during search) or ReactionTree objects (during post-processing).

    Built-in Scorers: When an aizynthfinder object is created, the following four scorers are loaded automatically:

    • State score: A function of the number of precursors in stock and the length of the route. Note: This score guides the tree search during the update phase and is not configurable.
    • Number of reactions: The number of steps in the route.
    • Number of pre-cursors: The number of precursors in the route.
    • Number of pre-cursors in stock: The number of precursors that are purchaseable.

    Other available scorers include:

    • Average template occurrence: The average occurrence of the templates used in the route.
    • Sum of prices: The plain sum of the price of all precursors.
    • Route cost score: The cost of synthesizing the route (based on Badowski et al. Chem Sci. 2019, 10, 4640).

    In the Jupyter notebook GUI, you can choose to score routes with any of the loaded scorers.

  2. How the Monte Carlo tree search (MCTS) works in AiZynthFinder

    master

    AiZynthFinder uses a Monte Carlo tree search to navigate reaction pathways. The search process is executed via the one_iteration() method of the MctsSearchTree class and consists of four distinct phases:

    1. Selection: The algorithm picks the most promising leaf node using select_leaf(). It traverses from the root by repeatedly calling promising_child() on MctsNode objects until it reaches a node that is either not expanded or is solved.
    2. Expansion: The selected leaf is expanded using expand(). This method uses an expansion policy to extract RetroReaction objects and their probabilities. It sets the initial visitation count for new child nodes to 1.
    3. Rollout: The algorithm enters an inner loop to expand the tree further until a terminal state is reached (where the is_terminal flag is set). It repeatedly retrieves and expands the most promising child.
    4. Backpropagation: The algorithm updates the values of all nodes on the path from the current leaf back to the root by calling backpropagate() on the MctsTreeSearch and its constituent nodes.
  3. How AiZynthFinder works

    master

    AiZynthFinder is a retrosynthetic planning tool. Its default algorithm uses a Monte Carlo tree search that recursively breaks down a molecule into purchasable precursors.

    The search is guided by a policy that suggests possible precursors using a neural network trained on known reaction templates. The tool is highly customizable, supporting various search algorithms and expansion policies.

  4. Understand the difference between single and batch SMILES input

    master

    The behavior of aizynthcli changes based on whether you provide one or multiple SMILES:

    Single SMILES:

    • Statistics are printed directly to the terminal.
    • Top-ranked routes are saved to a JSON file (default: trees.json).
    • The stock_info and trees columns are NOT included in the terminal output.

    Multiple SMILES (Batch):

    • Results are saved to a JSON or HDF5 file (default: output.json.gz).
    • The output file contains all columns defined in the batch output schema (including stock_info and trees).
  5. How `promising_child()` selects nodes

    master

    The promising_child() method of the MctsNode class is responsible for navigating the tree based on the Upper Confidence Bound (UCB) score.

    • Selection Logic: It sorts children by their UCB score and selects the highest-scoring child for instantiation.
    • Instantiation: When a child is selected, its associated RetroReaction is applied to create new precursors, which form the state of the new MctsNode.
    • Failure Handling: If a reaction fails to produce precursors, or if a filter policy rejects the reaction, the child's value is set to a large negative value to prevent future selection.
    • Recursion: The method calls itself recursively until a valid child can be instantiated. If no children can be instantiated, the is_expanded and is_expandable flags are updated, and the method returns None.
  6. Download public data for AiZynthFinder

    master

    To run retrosynthesis experiments, you need a trained policy model and a stock collection. You can download publicly available data (a USPTO-based model and a ZINC database stock collection) to your current directory using the provided utility command.

    This data allows you to use the config.yml file immediately with the package interfaces.

    download_public_data
  7. Launch the AiZynthFinder GUI via Jupyter Notebook

    master

    You can perform tree searches on single compounds using a graphical user interface within a Jupyter notebook.

    To start, launch Jupyter:

    jupyter notebook

    In a new or existing notebook, instantiate the AiZynthApp class by providing the path to your configuration file. Executing this cell will launch the GUI.

    Steps to run a search:

    1. Execute the initialization cell (press Ctrl+Enter).
    2. Enter the target SMILES string.
    3. Select your desired stocks and policy model.
    4. Click Run Search to begin the tree search.
    5. Click Show Reactions to view the top-ranked routes.
    6. You can optionally select and sort top-ranked routes using alternative scoring functions.
    from aizynthfinder.interfaces import AiZynthApp
    app = AiZynthApp("/path/to/configfile.yaml")
  8. Create a simple AiZynthFinder configuration file

    master

    To perform a basic tree search, create a config.yml file that maps your expansion models and stock files to specific keys.

    For a simple setup, you need:

    1. Expansion: A list containing a Keras expansion model (ONNX format) and a template file (CSV.GZ or HDF5).
    2. Stock: A path to an HDF5 stock file.

    Example config.yml for a basic setup:

    expansion:
      full:
        - uspto_expansion.onnx
        - uspto_templates.csv.gz
    stock:
      zinc: zinc_stock.hdf5
  9. Install AiZynthFinder for end-users

    master

    To install AiZynthFinder, use Conda to create a Python 3.10-3.12 environment and then install the package via pip. You can choose between a full installation with all functionalities or a smaller package.

    Full installation (recommended):

    conda create "python>=3.10,<3.13" -n aizynth-env
    conda activate aizynth-env
    python -m pip install aizynthfinder[all]

    Minimal installation:

    conda create "python>=3.10,<3.13" -n aizynth-env
    conda activate aizynth-env
    python -m pip install aizynthfinder
    conda create "python>=3.10,<3.13" -n aizynth-env
    conda activate aizynth-env
    python -m pip install aizynthfinder[all]
  10. Use the Chemformer expansion model

    master

    The Chemformer expansion model uses a REST API to perform expansions.

    Prerequisites:

    1. Install the chemformer package.
    2. Launch the chemformer REST API service.

    Configuration: Add the following to your configuration file. Ensure the url points to the correct host and port where your REST service is running (defaulting to http://localhost:8000/chemformer-api/predict).

    It is recommended to set a time_limit (e.g., 300 seconds) to allow the more computationally expensive expansion model enough time to complete sufficient retrosynthesis iterations.

    expansion:
        chemformer:
            type: expansion_strategies.ChemformerBasedExpansionStrategy
            url: http://localhost:8000/chemformer-api/predict
    search:
        algorithm_config:
            immediate_instantiation: [chemformer]
        time_limit: 300
  11. Use a custom stock with aizynthcli

    master

    To use a custom stock with the aizynthcli tool:

    1. Save your custom class in a module (e.g., custom_stock.py).
    2. Ensure the module is in a directory known to the Python interpreter.
    3. Define an instance of your class named stock within that module.

    Example custom_stock.py:

    from rdkit.Chem import Lipinski
    from aizynthfinder.context.stock.queries import StockQueryMixin
    
    class CriteriaStock(StockQueryMixin):
        def __contains__(self, mol):
            return Lipinski.HeavyAtomCount(mol.rd_mol) < 10
    
    stock = CriteriaStock()
    stock = CriteriaStock()
  12. Use the AiZynthExpander to break down molecules

    master

    The AiZynthExpander interface allows you to use expansion policies to break a molecule down into its reactants without performing a full tree search.

    Usage Details:

    • You must select an expansion policy and an optional filter policy using .select("key").
    • The filter policy, if used, adds feasibility checks to the reactions rather than filtering them out entirely.
    • The .do_expansion(smiles) method returns a nested list of FixedRetroReaction objects.

    Extracting Data:

    • To get reactant SMILES: Iterate through the reactions and access reaction_tuple[0].reactants[0].
    • To get metadata: Iterate through the reactions and collect the .metadata attribute from each reaction object, which can then be loaded into a pandas DataFrame.
    from aizynthfinder.aizynthfinder import AiZynthExpander
    
    # Initialize expander
    filename = "config.yml"
    expander = AiZynthExpander(configfile=filename)
    expander.expansion_policy.select("uspto")
    expander.filter_policy.select("uspto")
    
    # Perform expansion
    target = "Cc1cccc(c1N(CC(=O)Nc2ccc(cc2)c3ncon3)C(=O)C4CCS(=O)(=O)CC4)C"
    reactions = expander.do_expansion(target)
    
    # Example: Extracting reactant SMILES
    reactants_smiles = []
    for reaction_tuple in reactions:
        reactants_smiles.append([mol.smiles for mol in reaction_tuple[0].reactants[0]])
    
    # Example: Extracting metadata to pandas
    import pandas as pd
    metadata = []
    for reaction_tuple in reactions:
        for reaction in reaction_tuple:
            metadata.append(reaction.metadata)
    df = pd.DataFrame(metadata)