Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
CHANGELOG
*********

Unreleased
==========
- Replaced the ``molecules`` argument with ``ligands`` in ``generate_lomap_network()``. Argument name ``molecules`` will be deprecated.

2.3.0
=====
- Added shift option to MCS and cli (-s or --shift), this defaults to True. In combination with threed/-3 this option
Expand Down
22 changes: 11 additions & 11 deletions lomap/gufe_bindings/network_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@

from ..graphgen import GraphGen
from .._due import due, Doi

from ..utils import deprecated_kwargs

logger = logging.getLogger(__name__)


@deprecated_kwargs(name_mappings={'molecules':'ligands'})
@due.dcite(Doi("https://doi.org/10.1007/s10822-013-9678-y"), description="LOMAP")
def generate_lomap_network(
molecules: list[gufe.SmallMoleculeComponent],
ligands: list[gufe.SmallMoleculeComponent],
mappers: Union[AtomMapper, list[AtomMapper]],
scorer: Callable,
distance_cutoff: float = 0.4,
Expand All @@ -35,7 +35,7 @@ def generate_lomap_network(

Parameters
----------
molecules : list[SmallMoleculeComponent]
ligands : list[SmallMoleculeComponent]
molecules to map
mappers : list[AtomMapper] or AtomMapper
one or more Mapper functions to use to propose edges
Expand Down Expand Up @@ -67,17 +67,17 @@ def generate_lomap_network(
if isinstance(mappers, gufe.AtomMapper):
mappers = [mappers]
if actives is None:
actives = [False] * len(molecules)
actives = [False] * len(ligands)

# gen n x n mappings with scores
# initially all zero scores, i.e. impossible
mtx = np.zeros((len(molecules), len(molecules)), dtype=float)
mtx = np.zeros((len(ligands), len(ligands)), dtype=float)
# np array of mappings
mps = np.zeros_like(mtx, dtype=object)

# for all combinations of molecules
for i, j in itertools.combinations(range(len(molecules)), 2):
mA, mB = molecules[i], molecules[j]
# for all combinations of ligands
for i, j in itertools.combinations(range(len(ligands)), 2):
mA, mB = ligands[i], ligands[j]

# pick best score across all mappings from all mappings
best_mp: Optional[LigandAtomMapping] = None
Expand Down Expand Up @@ -107,7 +107,7 @@ def generate_lomap_network(

gg = GraphGen(score_matrix=mtx,
ids=list(range(mtx.shape[0])),
names=[m.name for m in molecules],
names=[m.name for m in ligands],
max_path_length=max_path_length,
actives=actives,
max_dist_from_active=max_dist_from_active,
Expand All @@ -121,7 +121,7 @@ def generate_lomap_network(

ln = LigandNetwork(
edges=[mps[i, j] for i, j in n.edges],
nodes=molecules,
nodes=ligands,
)

return ln
25 changes: 18 additions & 7 deletions lomap/tests/test_new_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,21 @@ def basic():


def test_generate_network_smoketest(basic):
network = lomap.generate_lomap_network(
molecules=basic,
mappers=lomap.LomapAtomMapper(),
scorer=lomap.default_lomap_score,
)

assert isinstance(network, gufe.LigandNetwork)
with pytest.deprecated_call(match="'molecules' is deprecated, please use 'ligands'"):
network = lomap.generate_lomap_network(
molecules=basic,
mappers=lomap.LomapAtomMapper(),
scorer=lomap.default_lomap_score,
)

assert isinstance(network, gufe.LigandNetwork)


def test_overdefined_deprecated_generate_network(basic):
with pytest.raises(ValueError, match="Both 'molecules' and 'ligands' are defined"):
lomap.generate_lomap_network(
molecules=basic,
ligands=basic,
mappers=lomap.LomapAtomMapper(),
scorer=lomap.default_lomap_score,
)
46 changes: 46 additions & 0 deletions lomap/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import functools
import warnings
from typing import Any, Callable, Dict


def rename_kwargs(
func_name: str, kwargs: Dict[str, Any], name_mappings: Dict[str, str]
):
"""Helper function for deprecating function arguments."""
for old_name, new_name in name_mappings.items():
deprecation_msg = (
f"{func_name} argument '{old_name}' is deprecated, please use '{new_name}' instead.",
)
if old_name in kwargs:
if new_name in kwargs:
raise ValueError(
f"Both '{old_name}' and '{new_name}' are defined for {func_name}."
+ f"'{old_name}' is deprecated, please use '{new_name}' instead."
)

else:
warnings.warn(deprecation_msg, DeprecationWarning)
kwargs[new_name] = kwargs.pop(old_name)
return kwargs


def deprecated_kwargs(name_mappings: Dict[str, str]) -> Callable:
"""Decorator for deprecating keyword arguments

e.g.
@deprecated_kwarg({'old_arg':'new_arg'})
def my_function(new_arg)
...
"""

def decorator(func: Callable) -> Callable:
@functools.wraps(func)
def wrapper(*args: Any, **kwargs: Any):
kwargs = rename_kwargs(
func_name=func.__name__, kwargs=kwargs, name_mappings=name_mappings
)
return func(*args, **kwargs)

return wrapper

return decorator
Loading