Getting started using Lomap#
Lomap plans networks of relative free energy calculations across a set of
ligands. Its interface provides
gufe bindings, so Lomap’s atom
mapping, scoring, and network planning interoperate with the rest of the
Open Free Energy ecosystem. The workflow is:
load your ligands, propose atom mappings between them, score
those mappings, and assemble them into a network. Each step is available on its
own, but most users only need generate_lomap_network(), covered at
the end of this guide.
These bindings require the optional gufe dependency
(see Installation).
All examples below use these two example ligands:
import importlib.resources
from gufe import SmallMoleculeComponent
data = importlib.resources.files("lomap.tests.data")
ligands = [
SmallMoleculeComponent.from_sdf_file(data / name)
for name in ["lig_41.sdf", "lig_74.sdf"]
]
Generating mappings#
A LomapAtomMapper proposes an atom mapping between a pair of
ligands. suggest_mappings yields LigandAtomMapping objects, or nothing
if the ligands share no suitable common substructure.
from lomap import LomapAtomMapper
mapper = LomapAtomMapper()
# suggest_mappings is a generator, so wrap it in list() to pull out all the possible mappings
mappings = list(mapper.suggest_mappings(ligands[0], ligands[1]))
mapping = mappings[0]
# atom indices in ligand A mapped onto the corresponding atoms in ligand B
print(mapping.componentA_to_componentB)
The mapper can be tuned with options such as time,
threed, max3d, element_change, seed, and shift. See the
API reference for details.
Generating scores#
A scorer takes a LigandAtomMapping and returns a value from 0.0 (worst)
to 1.0 (best).
default_lomap_score() is the standard Lomap
score, a product of sub-scores penalizing changes such as broken rings, altered
ring sizes, and net-charge differences.
from lomap import default_lomap_score
score = default_lomap_score(mapping)
print(f"{score:.3f}")
The score of 0.095 for this pair is expected. lig_41 and lig_74
differ at both ends; fused ring system is created on one end and the
heteroaryl head changes, leaving a relatively small shared core, along with
element and hybridization changes.
The sub-scores live in lomap.gufe_bindings.scorers if you need a custom
scorer.
Generating networks#
generate_lomap_network() combines the previous steps. Given a set of ligands, a
mapper, and a scorer, it proposes and scores edges and assembles a connected
LigandNetwork.
from lomap import LomapAtomMapper, default_lomap_score, generate_lomap_network
network = generate_lomap_network(
ligands=ligands,
mappers=LomapAtomMapper(),
scorer=default_lomap_score,
)
print(f"{len(network.nodes)} ligands, {len(network.edges)} edges")
network.nodes are the ligands and network.edges the scored mappings.
Options such as distance_cutoff, require_cycle_covering, and radial
are documented in the API reference.
Command line interface#
The legacy lomap command-line tool is deprecated and will be removed in the
next major release; use generate_lomap_network() instead. See
Lomap Legacy API.