Skip to content

Commit

Permalink
use Lomap package's bindings (#478)
Browse files Browse the repository at this point in the history
* use Lomap package's bindings

* fix mypy complaints

* Code via suggestions because local branch is borked

Why can't I push this from my local?

* Update openfe/setup/atom_mapping/lomap_scorers.py

* try exporting __all__ (make RTD happy too)

* guess mypy didn't like that at __all__

* Oh, *that* would be how to fix the warning about mocks

* Update environment.yaml

* Update environment.yml

* Update conf.py

* remove lomap docs

* try adding lomap to docs build

* try adding lomap scorer docs back

* add generate_lomap_network to docs

* Update environment.yml

---------

Co-authored-by: David W.H. Swenson <[email protected]>
  • Loading branch information
richardjgowers and dwhswenson authored Nov 3, 2023
1 parent 195b9e8 commit e60580c
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 530 deletions.
1 change: 0 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@

autodoc_mock_imports = [
"matplotlib",
"lomap",
"openmmtools",
"mdtraj",
"openmmforcefields",
Expand Down
1 change: 1 addition & 0 deletions docs/environment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ channels:
- https://conda.anaconda.org/conda-forge
dependencies:
- autodoc-pydantic<2.0
- lomap2>=3.0.0
- openff-models>=0.0.5
- openff-toolkit >=0.13.0
- openff-units
Expand Down
7 changes: 5 additions & 2 deletions docs/reference/api/ligand_network.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ Functions that build a :class:`.LigandNetwork` from a collection of :class:`Smal
generate_radial_network
generate_maximal_network
generate_minimal_spanning_network
generate_minimal_redundant_network
generate_lomap_network


.. _Ligand Network Loaders:

Expand Down Expand Up @@ -90,15 +93,15 @@ Atom Map Scorers

Scoring functions for a mapping between ligands. These are used as objective functions for :any:`Ligand Network Planners`.

LOMAP Scorers

Lomap Scorers
~~~~~~~~~~~~~

Scorers implemented by the `LOMAP <https://github.com/OpenFreeEnergy/Lomap>`_ package.

.. apparently we need the atom_mapping because internally autofunction is
trying ``import openfe.setup.lomap_scorers``, which doesn't work (whereas
``from openfe.setup import lomap_scorers`` does)
.. module:: openfe.setup.atom_mapping.lomap_scorers

.. autosummary::
Expand Down
1 change: 1 addition & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ channels:
- conda-forge
dependencies:
- duecredit
- lomap2>=3.0.0
- numpy<1.24
- networkx
- rdkit
Expand Down
70 changes: 1 addition & 69 deletions openfe/setup/atom_mapping/lomap_mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,72 +5,4 @@
The MCS class from Lomap shamelessly wrapped and used here to match our API.
"""
from lomap import mcs as lomap_mcs

from .ligandatommapper import LigandAtomMapper


class LomapAtomMapper(LigandAtomMapper):
time: int
threed: bool
max3d: float
element_change: bool
seed: str
shift: bool

def __init__(self, *, time: int = 20, threed: bool = True,
max3d: float = 1000.0, element_change: bool = True,
seed: str = '', shift: bool = True):
"""
Suggest atom mappings with the MCS atom mapper from Lomap.
Keyword arguments are passed directly to the MCS class from Lomap for
each mapping created.
Parameters
----------
time : int, optional
timeout of MCS algorithm, passed to RDKit
default 20
threed : bool, optional
if true, positional info is used to choose between symmetrically
equivalent mappings and prune the mapping, default True
max3d : float, optional
maximum discrepancy in Angstroms between atoms before mapping is not
allowed, default 1000.0, which effectively trims no atoms
element_change: bool, optional
whether to allow element changes in the mappings, default True
seed: str, optional
SMARTS string to use as seed for MCS searches. When used across an entire set
of ligands, this can create
shift: bool, optional
when determining 3D overlap, if to translate the two molecules MCS to minimise
RMSD to boost potential alignment.
"""
self.time = time
self.threed = threed
self.max3d = max3d
self.element_change = element_change
self.seed = seed
self.shift = shift

def _mappings_generator(self, componentA, componentB):
try:
mcs = lomap_mcs.MCS(componentA.to_rdkit(), componentB.to_rdkit(),
time=self.time,
threed=self.threed, max3d=self.max3d,
element_change=self.element_change, seed=self.seed,
shift=self.shift)
except ValueError:
# if no match found, Lomap throws ValueError, so we just yield
# generator with no contents
return

mapping_string = mcs.all_atom_match_list()
# lomap spits out "1:1,2:2,...,x:y", so split around commas,
# then colons and coerce to ints
mapping_dict = dict((map(int, v.split(':'))
for v in mapping_string.split(',')))

yield mapping_dict
return
from lomap import LomapAtomMapper
Loading

0 comments on commit e60580c

Please sign in to comment.