schrodinger.analysis.reaction module

A module to support chemical reactions, retrosynthetic analysis, and reaction enumeration.

Examples:

# run one reaction
rxn_smarts = "[C:8][N:7][C:2]([C:1])=[O:4]>>[C:1][C:2](O)=[O:4].[N:7][C:8]"
rxn = Reaction("Amide coupling", rxn_smarts)
amide = Chem.MolFromSmiles('CC(=O)NC')
for acid, amine in rxn.apply((amide,)):
    print Chem.MolToSmiles(acid)
    print Chem.MolToSmiles(amine)
reverse_rxn = rxn.inverse()

# retrosynthetic analysis
reactions = read_reactions_file('reactions.json')
retrosynthesis = retrosynthesize(amide, reactions)
print retrosynthesis.asString()
for route in retrosynthesis.getRoutes():
    print route.asString()
    print "Starting materials:"
    for sm in route.getStartingNodes():
        print "-", sm
    route.write('route.json')

# combinatorial enumeration from a route file
route = read_route('route.json')
synthesizer = Synthesizer(route)
for product in synthesizer.synthesizeCombinations([acids, amines]):
    print Chem.MolToSmiles(product)
class schrodinger.analysis.reaction.Node(mol=None, reagent_class=None)

Bases: future.types.newobject.newobject

Base class for a node in a synthetic route or a retrosynthetic tree. A node is associated with a molecule and with a reagent class (both of which may be None). It is also associated with zero or more reaction instances, but the base class does not implement an API to add reaction instances because each subclass has a different policy concerning the number of reaction instances allowed.

treeAsString(products=True, starting_materials=True, indexes=True)

Return a recursive string representation of the tree (unlike __str__, which is a short representation of the current node). The reaction names are always shown; starting materials and products are optional.

Parameters:
  • products (bool) – include reaction product SMILES
  • starting_materials (bool) – include starting material SMILES
Return type:

str

class schrodinger.analysis.reaction.Reaction(name, smarts=None, lhs_classes=None, rhs_classes=None, inverse_smarts=None, tags=None, tier=None, allow_multiple_products=False, rxnfile=None, inverse_rxnfile=None, description=None, reagents_dict=None, long_name=None, ld_data=None)

Bases: future.types.newobject.newobject

A Reaction object represents a generic reaction, such as “amide coupling”. An actual instance of a reaction between specific reagents is a ReactionInstance (see below).

A Reaction may optionally be associated with “reagent classes” for the molecules on the left-hand-side and right-hand-side of the reaction. We avoid the terms “reactants” and “products” because they depend on the context; Reaction objects may be used for actual reactions, but also for retrosynthetic transforms (where “target” and “precursors” would be more appropriate), or for even for alchemical transformations.

A reagent class is just a name representing the type of compound involved in the reaction; the naming scheme is up to the caller. For example, for amide coupling, the reagent classes on one side might be “amine” and “acid”, and on the other “amide”.

apply(reactants)

Apply the reaction to the given reactants, returning a list of lists of products. The products are already sanitized.

Return type:list of list of Mol
asDict()

Return a dict representation of the reaction suitable for JSON serialization.

Returns:dict
Return type:dict
inverse()

Return a new Reaction object for the inverse of the current reaction.

class schrodinger.analysis.reaction.ReactionInstance(reaction, precursors)

Bases: future.types.newobject.newobject

A ReactionInstance is the application of a Reaction to a list of reagents/precursors. For example, “Amide syntesis” is a Reaction; but “Amide synthesis from acetic acid and ethylamine” is a ReactionInstance.

name

The name of the reaction.

class schrodinger.analysis.reaction.ReagentClass(name, reactive=False, description=None)

Bases: future.types.newobject.newobject

Struct-like class to hold metadata for a reagent class. Fields include name, description, and ‘reactive’. A reactive reagent is one which shouldn’t be analyzed retrosynthetically. For example, acyl chlorides.

class schrodinger.analysis.reaction.ReagentNode(mol=None, reagent_class=None, filename=None, smiles=None, smiles_list=None)

Bases: schrodinger.analysis.reaction.RouteNode

A node representing a starting material in a synthetic route. Unlike RouteNode, it cannot have any reaction instances. Reagent nodes are identified by a reagent class.

Reagents may optionally have a filename or a smiles or a list of smiles as a source of reagent molecules. If none of these is provided, the object can try to find a reagent file based on the reagent class alone.

findReagentFile()

First, look for structure files matching <reagent_class>.* in the CWD. If one is found, return it. If multiple matches are found, an exception is raised. If none are found, look for <reagent_class>.smi in the mmshare data directory and return it if it exists, or None otherwise.

Returns:path to reagent file, or None if not found
Return type:str
Raises:ValueError if multiple matches are found in the CWD.
class schrodinger.analysis.reaction.RetroSynthesisNode(mol=None, reagent_class=None)

Bases: schrodinger.analysis.reaction.Node

A node in a retrosynthetic analysis tree. A node may have one or more reaction instances, which represent the ways of synthesizing the node in a single step.

addReactionInstance(reaction, precursors)

Add a reaction instance to the current node. This represents a one-step synthesis of the node from a list of precursor nodes.

getRoutes(include_zero=False)

Enumerate all the possible routes to synthesize the target.

Parameters:include_zero (bool) – if True, the first route on the list will be the “zero-step route” where the target is the starting material.
Return type:list of RouteNode
class schrodinger.analysis.reaction.RouteNode(mol=None, reagent_class=None)

Bases: schrodinger.analysis.reaction.Node

A node in a synthetic route. Similar to RetroSynthesisNode, except that it can have one reaction instance at most. Also, RouteNode provides additional methods that only make sense for a synthetic route.

checkReactions(reqs)

Check that the route meets all requirements. Every element of ‘reqs’ must match a tag or reaction name for at least one of the reactions used by the route. Tag matching is exact; name matching uses shell-like globbing (*, ?, []).

Returns:True if route meets requirements.
Return type:bool
depth(_depth=0)

Return the maximum depth of the route. See example under steps().

Return type:int
getReactionSet()

Return the set of reactions used by the route.

getStartingNodes()

Search recursively and return the Node objects for all the starting materials in the route.

Return type:list of Node-derived objects
getTreeData()

Return a simple data structure, suitable for dumping to JSON, representing the route. See write() for more details.

isStartingMaterial()

Return True if the node represents a starting material (i.e., has no reaction instance).

precursors

The list of precursors of this node (may be empty).

reaction

The reaction associated with this node. If the node has no reaction instance, raises KeyError.

reaction_instance

The reaction instance associated with this node. If the node has no reaction instance, raises KeyError.

setReactionInstance(reaction, precursors)

Set the reaction instance to the current node. This represents a one-step synthesis of the node from a list of precursor nodes.

steps()

Return the total number of steps in the route. For example, the following synthesis has 3 steps but depth 2.

Target => A + B A => AA B => BB
Return type:int
write(filename)

Write a route file.

class schrodinger.analysis.reaction.RouteRenderer(plus_size=50, arrow_length=250, arrowhead_size=25, label_padding=25, label_font=('helvetica', 30), plus_font=('helvetica', 48), max_scale=0.3, mol_padding=50, scale=0.375)

Bases: future.types.newobject.newobject

A class for rendering a Route as an image.

Note: this class only supports “specific routes”, for which all nodes have a ‘mol’ attribute. Generic routes, in which nodes might have only a reagent class, are not supported yet.

renderToFile(route, filename)

Render a Route and save the image to a file.

class schrodinger.analysis.reaction.Synthesizer(route, id_property='s_m_title', allow_multiple_products=False)

Bases: future.types.newobject.newobject

A Synthesizer is a “machine” that given a RouteNode, knows how to apply all the reactions in the RouteNode in the right order to a list of starting materials to give the final product.

run(starting_materials)

Return the final product of the RouteNode given a list of starting materials.

Return type:Mol, or None if the synthesis failed
synthesizeCombinations(reagent_sources, start=0, stop=None)

A generator of all combinations (or a slice thereof) of products that can be synthesized by the route using the given sets of starting materials.

Parameters:
  • reagent_sources (iterable of iterables of Mol.) – List of reagent sources.
  • start (int) – Start yielding from this reagent combination index (counting from zero).
  • stop (int or NoneType) – Stop yielding when this product reagent combination index is reached. None means unlimited.
Returns:

Generator of synthesis products.

Return type:

generator of Mol

synthesizeRandomSample(reagent_sources, size, max_tries=None, seed=None)

Generate a random sample of unique products. This function works by repeatedly choosing a random reagent from each reagent source and keeping track of which products have been seen so far. Therefore, it is most efficient when only a fraction of the possible space of reagent combinations is sampled, because otherwise there may be many unproductive duplicates. Also, since it keeps the set of products seen so far, it uses memory proportional to ‘size’, so it is best if that number is not too large (thousands is fine).

Parameters:
  • reagent_sources (iterable of list of Mol) – List of reagent sources
  • max_tries (int) – maximum number of random attempts to make before giving up, even if not enough products have been synthesized. The default is a function of ‘size’ and the number of reactant combinations.
  • seed (int) – random seed. If None, a random random seed will be generated and logged as an info message.
Param:

size: desired sample size (number of products).

schrodinger.analysis.reaction.debug_mols(message, mols, separator=' + ')

Print a debug message (if the logger level indicates it), appending a list of SMILES representation of the molecules.

schrodinger.analysis.reaction.filter_reactions(reactions, exclude)

Return a shallow copy of a list of reactions, filtering out those matching any of the exclusion criteria.

Parameters:exclude (set of str) – Set of tags or reaction names to exclude. Tags are matched exactly; names are matched using shell globbing (*, ?, []).
Return type:list of reaction
schrodinger.analysis.reaction.get_default_reactions_filename()

Return the path to the default reactions file.

Returns:path
Return type:str
schrodinger.analysis.reaction.get_default_reagent_classes_filename()

Return the path to the default reagent classes file.

Returns:path
Return type:str
schrodinger.analysis.reaction.get_dummy_filter()

Return a filter which has as criteria the descriptors that are computed by combinatorial_synthesis.py, along with their suggested default limiters (ranges).

Return type:schrodinger.ui.qt.filter_dialog_dir.filter_core.Filter
schrodinger.analysis.reaction.get_mol_reader(filename, smiles_opts=None, random_access=False)

Return a Mol generator given a filename. For SMILES, use the RDKit SmilesMolSupplier; for other formats, use StructureReader but convert Structure to Mol before yielding each molecule.

Parameters:
  • smiles_opts (dict) – Keyword arguments to pass to SmilesMolSupplier().
  • random_access (bool) – should the reagent sources sources support random access in addition to iteration, possibly costing memory or speed?
Return type:

generator of Mol

schrodinger.analysis.reaction.get_one_step_route(rxn)

Create a route for a one-step synthesis given a Reaction.

Parameters:rxn (Reaction) – reaction object
Returns:new route object
Return type:RouteNode
schrodinger.analysis.reaction.get_reagent_sources(route, r_dict=None, smiles_opts=None, random_access=False)

Return a list of reagent sources given a route and a dictionary of reagent sources (each key is either a reagent index or reagent class name; each value is a filename).

Parameters:
  • smiles_opts – Dictionary to pass through to get_mol_reader.
  • random_access (bool) – should the reagent sources sources support random access in addition to iteration, possibly costing memory or speed?
Return type:

list of generators of Mol.

schrodinger.analysis.reaction.invert_reaction_smarts(smarts)

Given a reaction SMARTS, return the reaction SMARTS for the reverse reaction.

Return type:str
schrodinger.analysis.reaction.mol_to_qpicture(mol)

Generate a QPicture from an RDKit Mol.

Parameters:mol – molecule to render
Return type:QPicture
schrodinger.analysis.reaction.parse_reaction_data(raw_dict, reagents_dict=None)

Convert a “raw dict” (usually from a JSON file) into a dictionary of Reaction objects by name.

Return type:dict {str: Reaction}
schrodinger.analysis.reaction.parse_reagent_classes_data(raw_dict)

Convert a “raw dict” (usually from a JSON file) into a dictionary of ReagentClass objects by name.

Return type:dict {str: Reaction}
schrodinger.analysis.reaction.parse_route_data(json_data, reactions_dict)

Generate a Route from the raw dict/list-based data structure usually obtained from a route JSON file.

Parameters:reactions_dict (dict of {str: Reaction}) – dictionary of Reaction objects by name.
schrodinger.analysis.reaction.reaction_is_excluded(reaction, exclude)

Check if a reaction meets any of the exclusion criteria.

Parameters:exclude (set of str) – Set of tags or reaction names to exclude. Tags are matched exactly; names are matched using shell globbing (*, ?, []).
Returns:True if reaction is meets any of the exclusion criteria
Return type:bool
schrodinger.analysis.reaction.read_reactions_file(filename=None, reagents_dict=None)

Read a reactions file in JSON format and return a dictionary of reactions by name. If filename is None, read the standard reactions file from the mmshare data directory and add the ‘default’ tag to each reaction.

Parameters:reagents_dict (dict {str: ReagentClass}) – dictionary of reagent classes (normally from read_reagent_classes_file).
Return type:dict {str: Reaction}
schrodinger.analysis.reaction.read_reagent_classes_file(filename=None)

Read a reagent classes file in JSON format and return a dictionary of reagent classes by name. If filename is None, read the standard reactions file from the mmshare data directory.

Return type:dict {str: ReagentClass}
schrodinger.analysis.reaction.read_route_file(filename, reactions_dict)

Read a route file in JSON format, returning a RouteNode object.

Parameters:reactions_dict (dict of {str: Reaction}) – dictionary of Reaction objects by name.
schrodinger.analysis.reaction.retrosynthesize(target_mol, reactions_dict, max_depth=1, exclude=None)

Generate a retrosynthetic tree to the desired depth based on the target molecule.

Parameters:
  • reactions_dict (dict {str: Reaction}) – Reaction dictionary by name.
  • exclude (set of str) – Set of tags or reaction names to exclude. Tags are matched exactly; names are matched using shell globbing (*, ?, []).
Return type:

RetrosynthesisNode

schrodinger.analysis.reaction.write_reactions_file(reactions, filename)

Write a reactions file. :reactions: list or dict of reactions :type reactions: list or dict of Reaction