Explicitly Defining Ligand Networks#
OpenFE provides utilities for ingesting networks from ordinary Python datastructures like list[tuple[str, str]] and list[tuple[int, int]].
Each string or integer respectively names or indexes a ligand, and tuples represent edges in the network.
This explicit definition of networks supports use-cases where the desired edges are known and may be helpful for loading networks from other tools.
Although this is the most flexible way to define a LigandNetwork, we encourage you to use openfe helper functionality when possible for performance, reproducibility, and ease of use:
Load the ligands#
This cookbook assumes you’ve already loaded a collection of SmallMoleculeComponent objects into an iterable called ligands.
For more information, see Loading Small Molecules.
[1]:
%matplotlib inline
from rdkit import Chem
import openfe
supplier = Chem.SDMolSupplier("assets/somebenzenes.sdf", removeHs=False)
ligands = [openfe.SmallMoleculeComponent(mol) for mol in supplier]
ligands
[1]:
[SmallMoleculeComponent(name=benzene),
SmallMoleculeComponent(name=toluene),
SmallMoleculeComponent(name=phenol),
SmallMoleculeComponent(name=benzonitrile),
SmallMoleculeComponent(name=anisole),
SmallMoleculeComponent(name=benzaldehyde),
SmallMoleculeComponent(name=styrene)]
Select an atom mapper#
As we will only specify the topology of the network, OpenFE must generate atom mappings for us. For this, it needs an atom mapper; for more information, see Choose an Atom Mapper:
[2]:
mapper = openfe.setup.LomapAtomMapper(
threed=True, # Use atom positions to prune symmetric mappings
max3d=1.0, # Forbid mapping between atoms more than 1.0 Å apart
element_change=False, # Forbid mappings that change an atoms element
)
Define the network#
We can inspect the ligands to identify what we’re working with:
[3]:
print(*enumerate(ligands), sep="\n")
(0, SmallMoleculeComponent(name=benzene))
(1, SmallMoleculeComponent(name=toluene))
(2, SmallMoleculeComponent(name=phenol))
(3, SmallMoleculeComponent(name=benzonitrile))
(4, SmallMoleculeComponent(name=anisole))
(5, SmallMoleculeComponent(name=benzaldehyde))
(6, SmallMoleculeComponent(name=styrene))
Then, define the network topology by specifying transformations between ligands, either by name or index:
[4]:
topology_by_names = [
("styrene", "toluene"),
("benzonitrile", "toluene"),
("toluene", "benzene"),
("benzene", "phenol"),
("phenol", "anisole"),
("phenol", "benzaldehyde"),
]
topology_by_indices = [
(6, 1),
(3, 1),
(1, 0),
(0, 2),
(2, 4),
(2, 5),
]
Create the network#
[5]:
from openfe.setup import ligand_network_planning
Now create the LigandNetwork object from the specified edges:
[6]:
ligand_network_from_names = ligand_network_planning.generate_network_from_names(
ligands=ligands,
mapper=mapper,
names=topology_by_names,
)
ligand_network_from_indices = ligand_network_planning.generate_network_from_indices(
ligands=ligands,
mapper=mapper,
indices=topology_by_indices,
)
parallel map scoring
/Users/atravitz/micromamba/envs/openfe-notebooks/lib/python3.13/site-packages/gufe/components/explicitmoleculecomponent.py:74: UserWarning: RDKit does not preserve Mol properties when pickled by default, which may drop e.g. atom charges; consider setting `Chem.SetDefaultPickleProperties(Chem.PropertyPickleOptions.AllProps)`
warnings.warn(
parallel map scoring
/Users/atravitz/micromamba/envs/openfe-notebooks/lib/python3.13/site-packages/gufe/components/explicitmoleculecomponent.py:74: UserWarning: RDKit does not preserve Mol properties when pickled by default, which may drop e.g. atom charges; consider setting `Chem.SetDefaultPickleProperties(Chem.PropertyPickleOptions.AllProps)`
warnings.warn(
/Users/atravitz/micromamba/envs/openfe-notebooks/lib/python3.13/site-packages/gufe/components/explicitmoleculecomponent.py:74: UserWarning: RDKit does not preserve Mol properties when pickled by default, which may drop e.g. atom charges; consider setting `Chem.SetDefaultPickleProperties(Chem.PropertyPickleOptions.AllProps)`
warnings.warn(
Visualise the network#
For more ways to visualize a LigandNetwork, see Visualizing Ligand Networks.
[7]:
from openfe.utils.atommapping_network_plotting import plot_atommapping_network
plot_atommapping_network(ligand_network_from_names)
[7]: