From 569895a46b6d67ef14fba6056b0777c1e3a21937 Mon Sep 17 00:00:00 2001 From: riesben Date: Tue, 3 Sep 2024 08:43:47 +0200 Subject: [PATCH 01/18] draft for Konnektor integration --- environment.yml | 1 + openfe/setup/ligand_network_planning.py | 192 +++++++------------- openfe/tests/setup/test_network_planning.py | 2 +- 3 files changed, 71 insertions(+), 124 deletions(-) diff --git a/environment.yml b/environment.yml index 259518f60..a83a0a170 100644 --- a/environment.yml +++ b/environment.yml @@ -4,6 +4,7 @@ channels: dependencies: - duecredit<0.10 - kartograf>=1.0.0 + - konnektor>=1.0.0 - lomap2>=3.0.0 - numpy - networkx diff --git a/openfe/setup/ligand_network_planning.py b/openfe/setup/ligand_network_planning.py index 99aa2ee87..112112255 100644 --- a/openfe/setup/ligand_network_planning.py +++ b/openfe/setup/ligand_network_planning.py @@ -17,6 +17,10 @@ from lomap import generate_lomap_network, LomapAtomMapper from lomap.dbmol import _find_common_core +from konnektor.network_planners import (StarNetworkGenerator, + MaximalNetworkGenerator, + RedundantMinimalSpanningTreeNetworkGenerator, + MinimalSpanningTreeNetworkGenerator) def _hasten_lomap(mapper, ligands): @@ -39,9 +43,10 @@ def _hasten_lomap(mapper, ligands): def generate_radial_network( ligands: Iterable[SmallMoleculeComponent], - central_ligand: Union[SmallMoleculeComponent, str, int], - mappers: Union[AtomMapper, Iterable[AtomMapper]], + mapper: AtomMapper, + central_ligand: Union[SmallMoleculeComponent, str, int] = None, scorer: Optional[Callable[[LigandAtomMapping], float]] = None, + n_processes: int = 1, ) -> LigandNetwork: """ Plan a radial network with all ligands connected to a central node. @@ -80,20 +85,25 @@ def generate_radial_network( If no scorer is supplied, the first mapping provided by the iterable of mappers will be used. """ - if isinstance(mappers, AtomMapper): - mappers = [mappers] - mappers = [_hasten_lomap(m, ligands) if isinstance(m, LomapAtomMapper) - else m for m in mappers] + if isinstance(mapper, LomapAtomMapper): + mapper = _hasten_lomap(mapper, ligands) + nodes = list(ligands) + + # Construct network + network_planner = StarNetworkGenerator(mapper=mapper, + scorer=scorer, + progress = progress, + n_processes = n_processes, + ) - # handle central_ligand arg possibilities - # after this, central_ligand is resolved to a SmallMoleculeComponent if isinstance(central_ligand, int): ligands = list(ligands) try: central_ligand = ligands[central_ligand] except IndexError: - raise ValueError(f"index '{central_ligand}' out of bounds, there are " - f"{len(ligands)} ligands") + raise ValueError( + f"index '{central_ligand}' out of bounds, there are " + f"{len(ligands)} ligands") elif isinstance(central_ligand, str): ligands = list(ligands) possibles = [l for l in ligands if l.name == central_ligand] @@ -104,45 +114,17 @@ def generate_radial_network( raise ValueError(f"Multiple ligands called '{central_ligand}'") central_ligand = possibles[0] - edges = [] - - for ligand in ligands: - if ligand == central_ligand: - wmsg = (f"The central_ligand {ligand.name} was also found in " - "the list of ligands to arrange around the " - "central_ligand this will be ignored.") - warnings.warn(wmsg) - continue - best_score = 0.0 - best_mapping = None - - for mapping in itertools.chain.from_iterable( - mapper.suggest_mappings(central_ligand, ligand) - for mapper in mappers - ): - if not scorer: - best_mapping = mapping - break - - score = scorer(mapping) - mapping = mapping.with_annotations({"score": score}) + network = network_planner.generate_ligand_network(nodes, central_component=central_ligand) - if score > best_score: - best_mapping = mapping - best_score = score - - if best_mapping is None: - raise ValueError(f"No mapping found for {ligand}") - edges.append(best_mapping) - - return LigandNetwork(edges) + return network def generate_maximal_network( ligands: Iterable[SmallMoleculeComponent], - mappers: Union[AtomMapper, Iterable[AtomMapper]], + mapper: AtomMapper, scorer: Optional[Callable[[LigandAtomMapping], float]] = None, progress: Union[bool, Callable[[Iterable], Iterable]] = True, + n_processes: int = 1, ) -> LigandNetwork: """ Plan a network with all possible proposed mappings. @@ -160,7 +142,7 @@ def generate_maximal_network( ---------- ligands : Iterable[SmallMoleculeComponent] the ligands to include in the LigandNetwork - mappers : AtomMapper or Iterable[AtomMapper] + mapper : AtomMapper or Iterable[AtomMapper] the AtomMapper(s) to use to propose mappings. At least 1 required, but many can be given. scorer : Scoring function @@ -169,42 +151,31 @@ def generate_maximal_network( progress bar: if False, no progress bar will be shown. If True, use a tqdm progress bar that only appears after 1.5 seconds. You can also provide a custom progress bar wrapper as a callable. + n_processes: int + parallelization of network generation. """ - if isinstance(mappers, AtomMapper): - mappers = [mappers] - mappers = [_hasten_lomap(m, ligands) if isinstance(m, LomapAtomMapper) - else m for m in mappers] - + if isinstance(mapper, LomapAtomMapper): + mapper = _hasten_lomap(mapper, ligands) nodes = list(ligands) - if progress is True: - # default is a tqdm progress bar - total = len(nodes) * (len(nodes) - 1) // 2 - progress = functools.partial(tqdm, total=total, delay=1.5) - elif progress is False: - def progress(x): return x - # otherwise, it should be a user-defined callable - - mapping_generator = itertools.chain.from_iterable( - mapper.suggest_mappings(molA, molB) - for molA, molB in progress(itertools.combinations(nodes, 2)) - for mapper in mappers + # Construct network + network_planner = MaximalNetworkGenerator(mapper=mapper, + scorer=scorer, + progress = progress, + n_processes = n_processes, ) - if scorer: - mappings = [mapping.with_annotations({'score': scorer(mapping)}) - for mapping in mapping_generator] - else: - mappings = list(mapping_generator) - network = LigandNetwork(mappings, nodes=nodes) + network = network_planner.generate_ligand_network(nodes) + return network def generate_minimal_spanning_network( ligands: Iterable[SmallMoleculeComponent], - mappers: Union[AtomMapper, Iterable[AtomMapper]], + mapper: AtomMapper, scorer: Callable[[LigandAtomMapping], float], progress: Union[bool, Callable[[Iterable], Iterable]] = True, + n_processes: int = 1, ) -> LigandNetwork: """ Plan a network with as few edges as possible with maximum total score @@ -224,39 +195,29 @@ def generate_minimal_spanning_network( tqdm progress bar that only appears after 1.5 seconds. You can also provide a custom progress bar wrapper as a callable. """ - if isinstance(mappers, AtomMapper): - mappers = [mappers] - mappers = [_hasten_lomap(m, ligands) if isinstance(m, LomapAtomMapper) - else m for m in mappers] - - # First create a network with all the proposed mappings (scored) - network = generate_maximal_network(ligands, mappers, scorer, progress) + if isinstance(mapper, LomapAtomMapper): + mapper = _hasten_lomap(mapper, ligands) + nodes = list(ligands) - # Flip network scores so we can use minimal algorithm - g2 = nx.MultiGraph() - for e1, e2, d in network.graph.edges(data=True): - g2.add_edge(e1, e2, weight=-d['score'], object=d['object']) + # Construct network + network_planner = MinimalSpanningTreeNetworkGenerator(mapper=mapper, + scorer=scorer, + progress = progress, + n_processes = n_processes, + ) - # Next analyze that network to create minimal spanning network. Because - # we carry the original (directed) LigandAtomMapping, we don't lose - # direction information when converting to an undirected graph. - min_edges = nx.minimum_spanning_edges(g2) - min_mappings = [edge_data['object'] for _, _, _, edge_data in min_edges] - min_network = LigandNetwork(min_mappings) - missing_nodes = set(network.nodes) - set(min_network.nodes) - if missing_nodes: - raise RuntimeError("Unable to create edges to some nodes: " - f"{list(missing_nodes)}") + network = network_planner.generate_ligand_network(nodes) - return min_network + return network def generate_minimal_redundant_network( ligands: Iterable[SmallMoleculeComponent], - mappers: Union[AtomMapper, Iterable[AtomMapper]], + mapper: AtomMapper, scorer: Callable[[LigandAtomMapping], float], progress: Union[bool, Callable[[Iterable], Iterable]] = True, mst_num: int = 2, + n_processes: int = 1, ) -> LigandNetwork: """ Plan a network with a specified amount of redundancy for each node @@ -283,40 +244,25 @@ def generate_minimal_redundant_network( Minimum Spanning Tree number: the number of minimum spanning trees to generate. If two, the second-best edges are included in the returned network. If three, the third-best edges are also included, etc. + n_processes: int + """ - if isinstance(mappers, AtomMapper): - mappers = [mappers] - mappers = [_hasten_lomap(m, ligands) if isinstance(m, LomapAtomMapper) - else m for m in mappers] - - # First create a network with all the proposed mappings (scored) - network = generate_maximal_network(ligands, mappers, scorer, progress) - - # Flip network scores so we can use minimal algorithm - g2 = nx.MultiGraph() - for e1, e2, d in network.graph.edges(data=True): - g2.add_edge(e1, e2, weight=-d['score'], object=d['object']) - - # As in .generate_minimal_spanning_network(), use nx to get the minimal - # network. But now also remove those edges from the fully-connected - # network, then get the minimal network again. Add mappings from all - # minimal networks together. - mappings = [] - for _ in range(mst_num): # can increase range here for more redundancy - # get list from generator so that we don't adjust network by calling it: - current_best_edges = list(nx.minimum_spanning_edges(g2)) - - g2.remove_edges_from(current_best_edges) - for _, _, _, edge_data in current_best_edges: - mappings.append(edge_data['object']) - - redund_network = LigandNetwork(mappings) - missing_nodes = set(network.nodes) - set(redund_network.nodes) - if missing_nodes: - raise RuntimeError("Unable to create edges to some nodes: " - f"{list(missing_nodes)}") - - return redund_network + + if isinstance(mapper, LomapAtomMapper): + mapper = _hasten_lomap(mapper, ligands) + nodes = list(ligands) + + # Construct network + network_planner = RedundantMinimalSpanningTreeNetworkGenerator(mapper=mapper, + scorer=scorer, + progress = progress, + n_redundancy=mst_num, + n_processes = n_processes, + ) + + network = network_planner.generate_ligand_network(nodes) + + return network def generate_network_from_names( diff --git a/openfe/tests/setup/test_network_planning.py b/openfe/tests/setup/test_network_planning.py index e52dcd867..c63040eeb 100644 --- a/openfe/tests/setup/test_network_planning.py +++ b/openfe/tests/setup/test_network_planning.py @@ -220,7 +220,7 @@ def scoring_func(mapping): network = openfe.setup.ligand_network_planning.generate_maximal_network( ligands=others + [toluene], - mappers=mappers, + mapper=mappers, scorer=scorer, progress=with_progress, ) From f73dea5de4ffbd82d7feeb3d812ca6c703bf24b6 Mon Sep 17 00:00:00 2001 From: riesben Date: Tue, 3 Sep 2024 08:46:15 +0200 Subject: [PATCH 02/18] draft for Konnektor integration --- openfe/setup/ligand_network_planning.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/openfe/setup/ligand_network_planning.py b/openfe/setup/ligand_network_planning.py index 112112255..2f455727e 100644 --- a/openfe/setup/ligand_network_planning.py +++ b/openfe/setup/ligand_network_planning.py @@ -89,13 +89,7 @@ def generate_radial_network( mapper = _hasten_lomap(mapper, ligands) nodes = list(ligands) - # Construct network - network_planner = StarNetworkGenerator(mapper=mapper, - scorer=scorer, - progress = progress, - n_processes = n_processes, - ) - + # Get central Component if isinstance(central_ligand, int): ligands = list(ligands) try: @@ -114,6 +108,14 @@ def generate_radial_network( raise ValueError(f"Multiple ligands called '{central_ligand}'") central_ligand = possibles[0] + + # Construct network + network_planner = StarNetworkGenerator(mapper=mapper, + scorer=scorer, + progress = progress, + n_processes = n_processes, + ) + network = network_planner.generate_ligand_network(nodes, central_component=central_ligand) return network From 85f2ff4ca9e96532c53d53b2ee8bfe6a91ac1a7c Mon Sep 17 00:00:00 2001 From: riesben Date: Wed, 4 Sep 2024 09:38:44 +0200 Subject: [PATCH 03/18] changing back to mappers iterable as parameter --- openfe/setup/ligand_network_planning.py | 97 +++++++++++-------------- 1 file changed, 41 insertions(+), 56 deletions(-) diff --git a/openfe/setup/ligand_network_planning.py b/openfe/setup/ligand_network_planning.py index 2f455727e..31948e2b4 100644 --- a/openfe/setup/ligand_network_planning.py +++ b/openfe/setup/ligand_network_planning.py @@ -20,7 +20,8 @@ from konnektor.network_planners import (StarNetworkGenerator, MaximalNetworkGenerator, RedundantMinimalSpanningTreeNetworkGenerator, - MinimalSpanningTreeNetworkGenerator) + MinimalSpanningTreeNetworkGenerator, + ExplicitNetworkGenerator,) def _hasten_lomap(mapper, ligands): @@ -43,10 +44,11 @@ def _hasten_lomap(mapper, ligands): def generate_radial_network( ligands: Iterable[SmallMoleculeComponent], - mapper: AtomMapper, + mappers: Union[AtomMapper, Iterable[AtomMapper]], central_ligand: Union[SmallMoleculeComponent, str, int] = None, scorer: Optional[Callable[[LigandAtomMapping], float]] = None, n_processes: int = 1, + progress: bool = False, ) -> LigandNetwork: """ Plan a radial network with all ligands connected to a central node. @@ -85,11 +87,13 @@ def generate_radial_network( If no scorer is supplied, the first mapping provided by the iterable of mappers will be used. """ - if isinstance(mapper, LomapAtomMapper): - mapper = _hasten_lomap(mapper, ligands) - nodes = list(ligands) + if isinstance(mappers, AtomMapper): + mappers = [mappers] + mappers = [_hasten_lomap(m, ligands) if isinstance(m, LomapAtomMapper) + else m for m in mappers] - # Get central Component + # handle central_ligand arg possibilities + # after this, central_ligand is resolved to a SmallMoleculeComponent if isinstance(central_ligand, int): ligands = list(ligands) try: @@ -110,20 +114,20 @@ def generate_radial_network( # Construct network - network_planner = StarNetworkGenerator(mapper=mapper, + network_planner = StarNetworkGenerator(mappers=mappers, scorer=scorer, progress = progress, n_processes = n_processes, ) - network = network_planner.generate_ligand_network(nodes, central_component=central_ligand) + network = network_planner.generate_ligand_network(components=ligands, central_component=central_ligand) return network def generate_maximal_network( ligands: Iterable[SmallMoleculeComponent], - mapper: AtomMapper, + mappers: Union[AtomMapper, Iterable[AtomMapper]], scorer: Optional[Callable[[LigandAtomMapping], float]] = None, progress: Union[bool, Callable[[Iterable], Iterable]] = True, n_processes: int = 1, @@ -156,12 +160,14 @@ def generate_maximal_network( n_processes: int parallelization of network generation. """ - if isinstance(mapper, LomapAtomMapper): - mapper = _hasten_lomap(mapper, ligands) + if isinstance(mappers, AtomMapper): + mappers = [mappers] + mappers = [_hasten_lomap(m, ligands) if isinstance(m, LomapAtomMapper) + else m for m in mappers] nodes = list(ligands) # Construct network - network_planner = MaximalNetworkGenerator(mapper=mapper, + network_planner = MaximalNetworkGenerator(mappers=mappers, scorer=scorer, progress = progress, n_processes = n_processes, @@ -174,7 +180,7 @@ def generate_maximal_network( def generate_minimal_spanning_network( ligands: Iterable[SmallMoleculeComponent], - mapper: AtomMapper, + mappers: Union[AtomMapper, Iterable[AtomMapper]], scorer: Callable[[LigandAtomMapping], float], progress: Union[bool, Callable[[Iterable], Iterable]] = True, n_processes: int = 1, @@ -197,12 +203,14 @@ def generate_minimal_spanning_network( tqdm progress bar that only appears after 1.5 seconds. You can also provide a custom progress bar wrapper as a callable. """ - if isinstance(mapper, LomapAtomMapper): - mapper = _hasten_lomap(mapper, ligands) + if isinstance(mappers, AtomMapper): + mappers = [mappers] + mappers = [_hasten_lomap(m, ligands) if isinstance(m, LomapAtomMapper) + else m for m in mappers] nodes = list(ligands) # Construct network - network_planner = MinimalSpanningTreeNetworkGenerator(mapper=mapper, + network_planner = MinimalSpanningTreeNetworkGenerator(mappers=mappers, scorer=scorer, progress = progress, n_processes = n_processes, @@ -215,7 +223,7 @@ def generate_minimal_spanning_network( def generate_minimal_redundant_network( ligands: Iterable[SmallMoleculeComponent], - mapper: AtomMapper, + mappers: Union[AtomMapper, Iterable[AtomMapper]], scorer: Callable[[LigandAtomMapping], float], progress: Union[bool, Callable[[Iterable], Iterable]] = True, mst_num: int = 2, @@ -249,13 +257,14 @@ def generate_minimal_redundant_network( n_processes: int """ - - if isinstance(mapper, LomapAtomMapper): - mapper = _hasten_lomap(mapper, ligands) + if isinstance(mappers, AtomMapper): + mappers = [mappers] + mappers = [_hasten_lomap(m, ligands) if isinstance(m, LomapAtomMapper) + else m for m in mappers] nodes = list(ligands) # Construct network - network_planner = RedundantMinimalSpanningTreeNetworkGenerator(mapper=mapper, + network_planner = RedundantMinimalSpanningTreeNetworkGenerator(mappers=mappers, scorer=scorer, progress = progress, n_redundancy=mst_num, @@ -269,7 +278,7 @@ def generate_minimal_redundant_network( def generate_network_from_names( ligands: list[SmallMoleculeComponent], - mapper: AtomMapper, + mappers: Union[AtomMapper, Iterable[AtomMapper]], names: list[tuple[str, str]], ) -> LigandNetwork: """ @@ -298,28 +307,18 @@ def generate_network_from_names( if multiple molecules have the same name (this would otherwise be problematic) """ - nm2idx = {l.name: i for i, l in enumerate(ligands)} + nodes = list(ligands) - if len(nm2idx) < len(ligands): - dupes = Counter((l.name for l in ligands)) - dupe_names = [k for k, v in dupes.items() if v > 1] - raise ValueError(f"Duplicate names: {dupe_names}") + network_planner = ExplicitNetworkGenerator(mappers=mappers, scorer=None) - try: - ids = [(nm2idx[nm1], nm2idx[nm2]) for nm1, nm2 in names] - except KeyError: - badnames = [nm for nm in itertools.chain.from_iterable(names) - if nm not in nm2idx] - available = [ligand.name for ligand in ligands] - raise KeyError(f"Invalid name(s) requested {badnames}. " - f"Available: {available}") + network = network_planner.generate_network_from_names(ligands=nodes, names=names) - return generate_network_from_indices(ligands, mapper, ids) + return network def generate_network_from_indices( ligands: list[SmallMoleculeComponent], - mapper: AtomMapper, + mappers: Union[AtomMapper, Iterable[AtomMapper]], indices: list[tuple[int, int]], ) -> LigandNetwork: """ @@ -345,30 +344,16 @@ def generate_network_from_indices( IndexError if an invalid ligand index is requested """ - edges = [] - - for i, j in indices: - try: - m1, m2 = ligands[i], ligands[j] - except IndexError: - raise IndexError(f"Invalid ligand id, requested {i} {j} " - f"with {len(ligands)} available") - - mapping = next(mapper.suggest_mappings(m1, m2)) - - edges.append(mapping) - - network = LigandNetwork(edges=edges, nodes=ligands) - - if not network.is_connected(): - warnings.warn("Generated network is not fully connected") + nodes = list(ligands) + network_planner = ExplicitNetworkGenerator(mappers=mappers, scorer=None) + network = network_planner.generate_network_from_indices(ligands=nodes, names=indices) return network def load_orion_network( ligands: list[SmallMoleculeComponent], - mapper: AtomMapper, + mappers: Union[AtomMapper, Iterable[AtomMapper]], network_file: Union[str, Path], ) -> LigandNetwork: """Load a :class:`.LigandNetwork` from an Orion NES network file. @@ -410,7 +395,7 @@ def load_orion_network( def load_fepplus_network( ligands: list[SmallMoleculeComponent], - mapper: AtomMapper, + mappers: Union[AtomMapper, Iterable[AtomMapper]], network_file: Union[str, Path], ) -> LigandNetwork: """Load a :class:`.LigandNetwork` from an FEP+ edges network file. From eab323883c5bce8334ab421bf5d23a1815ab78f9 Mon Sep 17 00:00:00 2001 From: riesben Date: Wed, 4 Sep 2024 10:02:04 +0200 Subject: [PATCH 04/18] consistently using Konnektor also in loading fep or orion net --- openfe/setup/ligand_network_planning.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/openfe/setup/ligand_network_planning.py b/openfe/setup/ligand_network_planning.py index 31948e2b4..e1eabef8b 100644 --- a/openfe/setup/ligand_network_planning.py +++ b/openfe/setup/ligand_network_planning.py @@ -347,7 +347,7 @@ def generate_network_from_indices( nodes = list(ligands) network_planner = ExplicitNetworkGenerator(mappers=mappers, scorer=None) - network = network_planner.generate_network_from_indices(ligands=nodes, names=indices) + network = network_planner.generate_network_from_indices(ligands=nodes, indices=indices) return network @@ -390,7 +390,10 @@ def load_orion_network( names.append((entry[0], entry[2])) - return generate_network_from_names(ligands, mapper, names) + network_planner = ExplicitNetworkGenerator(mappers=mappers, scorer=None) + network = network_planner.generate_network_from_names(ligands=ligands, names=names) + + return network def load_fepplus_network( @@ -432,4 +435,7 @@ def load_fepplus_network( names.append((entry[2], entry[4])) - return generate_network_from_names(ligands, mapper, names) + network_planner = ExplicitNetworkGenerator(mappers=mappers, scorer=None) + network = network_planner.generate_network_from_names(ligands=ligands, + names=names) + return network From 639ef19388757a0c06995d005f56e4b374c51970 Mon Sep 17 00:00:00 2001 From: riesben Date: Wed, 4 Sep 2024 10:35:28 +0200 Subject: [PATCH 05/18] adding handles for Konnektor functionality. --- openfe/setup/ligand_network_planning.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openfe/setup/ligand_network_planning.py b/openfe/setup/ligand_network_planning.py index e1eabef8b..fa5b7b5e0 100644 --- a/openfe/setup/ligand_network_planning.py +++ b/openfe/setup/ligand_network_planning.py @@ -23,6 +23,9 @@ MinimalSpanningTreeNetworkGenerator, ExplicitNetworkGenerator,) +#Konnektor handles: +from konnektor import network_analysis, network_planners, network_tools + def _hasten_lomap(mapper, ligands): """take a mapper and some ligands, put a common core arg into the mapper """ From d36d37d934ee6d7e68a90129866ba5263454caae Mon Sep 17 00:00:00 2001 From: riesben Date: Wed, 4 Sep 2024 10:38:17 +0200 Subject: [PATCH 06/18] used black for formatting. --- openfe/setup/ligand_network_planning.py | 149 ++++++++++++++---------- 1 file changed, 86 insertions(+), 63 deletions(-) diff --git a/openfe/setup/ligand_network_planning.py b/openfe/setup/ligand_network_planning.py index fa5b7b5e0..359741c9a 100644 --- a/openfe/setup/ligand_network_planning.py +++ b/openfe/setup/ligand_network_planning.py @@ -17,31 +17,37 @@ from lomap import generate_lomap_network, LomapAtomMapper from lomap.dbmol import _find_common_core -from konnektor.network_planners import (StarNetworkGenerator, - MaximalNetworkGenerator, - RedundantMinimalSpanningTreeNetworkGenerator, - MinimalSpanningTreeNetworkGenerator, - ExplicitNetworkGenerator,) - -#Konnektor handles: +from konnektor.network_planners import ( + StarNetworkGenerator, + MaximalNetworkGenerator, + RedundantMinimalSpanningTreeNetworkGenerator, + MinimalSpanningTreeNetworkGenerator, + ExplicitNetworkGenerator, +) + +# Konnektor handles: from konnektor import network_analysis, network_planners, network_tools def _hasten_lomap(mapper, ligands): - """take a mapper and some ligands, put a common core arg into the mapper """ + """take a mapper and some ligands, put a common core arg into the mapper""" if mapper.seed: return mapper try: - core = _find_common_core([m.to_rdkit() for m in ligands], - element_change=mapper.element_change) + core = _find_common_core( + [m.to_rdkit() for m in ligands], element_change=mapper.element_change + ) except RuntimeError: # in case MCS throws a hissy fit core = "" return LomapAtomMapper( - time=mapper.time, threed=mapper.threed, max3d=mapper.max3d, - element_change=mapper.element_change, seed=core, - shift=mapper.shift + time=mapper.time, + threed=mapper.threed, + max3d=mapper.max3d, + element_change=mapper.element_change, + seed=core, + shift=mapper.shift, ) @@ -92,8 +98,10 @@ def generate_radial_network( """ if isinstance(mappers, AtomMapper): mappers = [mappers] - mappers = [_hasten_lomap(m, ligands) if isinstance(m, LomapAtomMapper) - else m for m in mappers] + mappers = [ + _hasten_lomap(m, ligands) if isinstance(m, LomapAtomMapper) else m + for m in mappers + ] # handle central_ligand arg possibilities # after this, central_ligand is resolved to a SmallMoleculeComponent @@ -104,26 +112,31 @@ def generate_radial_network( except IndexError: raise ValueError( f"index '{central_ligand}' out of bounds, there are " - f"{len(ligands)} ligands") + f"{len(ligands)} ligands" + ) elif isinstance(central_ligand, str): ligands = list(ligands) possibles = [l for l in ligands if l.name == central_ligand] if not possibles: - raise ValueError(f"No ligand called '{central_ligand}' " - f"available: {', '.join(l.name for l in ligands)}") + raise ValueError( + f"No ligand called '{central_ligand}' " + f"available: {', '.join(l.name for l in ligands)}" + ) if len(possibles) > 1: raise ValueError(f"Multiple ligands called '{central_ligand}'") central_ligand = possibles[0] - # Construct network - network_planner = StarNetworkGenerator(mappers=mappers, + network_planner = StarNetworkGenerator( + mappers=mappers, scorer=scorer, - progress = progress, - n_processes = n_processes, + progress=progress, + n_processes=n_processes, ) - network = network_planner.generate_ligand_network(components=ligands, central_component=central_ligand) + network = network_planner.generate_ligand_network( + components=ligands, central_component=central_ligand + ) return network @@ -165,15 +178,18 @@ def generate_maximal_network( """ if isinstance(mappers, AtomMapper): mappers = [mappers] - mappers = [_hasten_lomap(m, ligands) if isinstance(m, LomapAtomMapper) - else m for m in mappers] + mappers = [ + _hasten_lomap(m, ligands) if isinstance(m, LomapAtomMapper) else m + for m in mappers + ] nodes = list(ligands) # Construct network - network_planner = MaximalNetworkGenerator(mappers=mappers, + network_planner = MaximalNetworkGenerator( + mappers=mappers, scorer=scorer, - progress = progress, - n_processes = n_processes, + progress=progress, + n_processes=n_processes, ) network = network_planner.generate_ligand_network(nodes) @@ -208,15 +224,18 @@ def generate_minimal_spanning_network( """ if isinstance(mappers, AtomMapper): mappers = [mappers] - mappers = [_hasten_lomap(m, ligands) if isinstance(m, LomapAtomMapper) - else m for m in mappers] + mappers = [ + _hasten_lomap(m, ligands) if isinstance(m, LomapAtomMapper) else m + for m in mappers + ] nodes = list(ligands) # Construct network - network_planner = MinimalSpanningTreeNetworkGenerator(mappers=mappers, + network_planner = MinimalSpanningTreeNetworkGenerator( + mappers=mappers, scorer=scorer, - progress = progress, - n_processes = n_processes, + progress=progress, + n_processes=n_processes, ) network = network_planner.generate_ligand_network(nodes) @@ -262,16 +281,19 @@ def generate_minimal_redundant_network( """ if isinstance(mappers, AtomMapper): mappers = [mappers] - mappers = [_hasten_lomap(m, ligands) if isinstance(m, LomapAtomMapper) - else m for m in mappers] + mappers = [ + _hasten_lomap(m, ligands) if isinstance(m, LomapAtomMapper) else m + for m in mappers + ] nodes = list(ligands) # Construct network - network_planner = RedundantMinimalSpanningTreeNetworkGenerator(mappers=mappers, + network_planner = RedundantMinimalSpanningTreeNetworkGenerator( + mappers=mappers, scorer=scorer, - progress = progress, + progress=progress, n_redundancy=mst_num, - n_processes = n_processes, + n_processes=n_processes, ) network = network_planner.generate_ligand_network(nodes) @@ -280,9 +302,9 @@ def generate_minimal_redundant_network( def generate_network_from_names( - ligands: list[SmallMoleculeComponent], - mappers: Union[AtomMapper, Iterable[AtomMapper]], - names: list[tuple[str, str]], + ligands: list[SmallMoleculeComponent], + mappers: Union[AtomMapper, Iterable[AtomMapper]], + names: list[tuple[str, str]], ) -> LigandNetwork: """ Generate a :class:`.LigandNetwork` by specifying edges as tuples of names. @@ -320,9 +342,9 @@ def generate_network_from_names( def generate_network_from_indices( - ligands: list[SmallMoleculeComponent], - mappers: Union[AtomMapper, Iterable[AtomMapper]], - indices: list[tuple[int, int]], + ligands: list[SmallMoleculeComponent], + mappers: Union[AtomMapper, Iterable[AtomMapper]], + indices: list[tuple[int, int]], ) -> LigandNetwork: """ Generate a :class:`.LigandNetwork` by specifying edges as tuples of indices. @@ -350,14 +372,16 @@ def generate_network_from_indices( nodes = list(ligands) network_planner = ExplicitNetworkGenerator(mappers=mappers, scorer=None) - network = network_planner.generate_network_from_indices(ligands=nodes, indices=indices) + network = network_planner.generate_network_from_indices( + ligands=nodes, indices=indices + ) return network def load_orion_network( - ligands: list[SmallMoleculeComponent], - mappers: Union[AtomMapper, Iterable[AtomMapper]], - network_file: Union[str, Path], + ligands: list[SmallMoleculeComponent], + mappers: Union[AtomMapper, Iterable[AtomMapper]], + network_file: Union[str, Path], ) -> LigandNetwork: """Load a :class:`.LigandNetwork` from an Orion NES network file. @@ -380,15 +404,13 @@ def load_orion_network( If an unexpected line format is encountered. """ - with open(network_file, 'r') as f: - network_lines = [l.strip().split(' ') for l in f - if not l.startswith('#')] + with open(network_file, "r") as f: + network_lines = [l.strip().split(" ") for l in f if not l.startswith("#")] names = [] for entry in network_lines: if len(entry) != 3 or entry[1] != ">>": - errmsg = ("line does not match expected name >> name format: " - f"{entry}") + errmsg = "line does not match expected name >> name format: " f"{entry}" raise KeyError(errmsg) names.append((entry[0], entry[2])) @@ -400,9 +422,9 @@ def load_orion_network( def load_fepplus_network( - ligands: list[SmallMoleculeComponent], - mappers: Union[AtomMapper, Iterable[AtomMapper]], - network_file: Union[str, Path], + ligands: list[SmallMoleculeComponent], + mappers: Union[AtomMapper, Iterable[AtomMapper]], + network_file: Union[str, Path], ) -> LigandNetwork: """Load a :class:`.LigandNetwork` from an FEP+ edges network file. @@ -425,20 +447,21 @@ def load_fepplus_network( If an unexpected line format is encountered. """ - with open(network_file, 'r') as f: + with open(network_file, "r") as f: network_lines = [l.split() for l in f.readlines()] names = [] for entry in network_lines: - if len(entry) != 5 or entry[1] != '#' or entry[3] != '->': - errmsg = ("line does not match expected format " - f"hash:hash # name -> name\n" - "line format: {entry}") + if len(entry) != 5 or entry[1] != "#" or entry[3] != "->": + errmsg = ( + "line does not match expected format " + f"hash:hash # name -> name\n" + "line format: {entry}" + ) raise KeyError(errmsg) names.append((entry[2], entry[4])) network_planner = ExplicitNetworkGenerator(mappers=mappers, scorer=None) - network = network_planner.generate_network_from_names(ligands=ligands, - names=names) + network = network_planner.generate_network_from_names(ligands=ligands, names=names) return network From 2e0878fe7d62465af14a5b8be0696539b65c4d46 Mon Sep 17 00:00:00 2001 From: riesben Date: Wed, 4 Sep 2024 10:41:23 +0200 Subject: [PATCH 07/18] used black for formatting. --- openfe/setup/ligand_network_planning.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/openfe/setup/ligand_network_planning.py b/openfe/setup/ligand_network_planning.py index 359741c9a..e9642a745 100644 --- a/openfe/setup/ligand_network_planning.py +++ b/openfe/setup/ligand_network_planning.py @@ -36,7 +36,8 @@ def _hasten_lomap(mapper, ligands): try: core = _find_common_core( - [m.to_rdkit() for m in ligands], element_change=mapper.element_change + [m.to_rdkit() for m in ligands], + element_change=mapper.element_change, ) except RuntimeError: # in case MCS throws a hissy fit core = "" @@ -336,7 +337,9 @@ def generate_network_from_names( network_planner = ExplicitNetworkGenerator(mappers=mappers, scorer=None) - network = network_planner.generate_network_from_names(ligands=nodes, names=names) + network = network_planner.generate_network_from_names( + ligands=nodes, names=names + ) return network @@ -405,18 +408,24 @@ def load_orion_network( """ with open(network_file, "r") as f: - network_lines = [l.strip().split(" ") for l in f if not l.startswith("#")] + network_lines = [ + line.strip().split(" ") for line in f if not line.startswith("#") + ] names = [] for entry in network_lines: if len(entry) != 3 or entry[1] != ">>": - errmsg = "line does not match expected name >> name format: " f"{entry}" + errmsg = ( + "line does not match expected name >> name format: " f"{entry}" + ) raise KeyError(errmsg) names.append((entry[0], entry[2])) network_planner = ExplicitNetworkGenerator(mappers=mappers, scorer=None) - network = network_planner.generate_network_from_names(ligands=ligands, names=names) + network = network_planner.generate_network_from_names( + ligands=ligands, names=names + ) return network @@ -463,5 +472,7 @@ def load_fepplus_network( names.append((entry[2], entry[4])) network_planner = ExplicitNetworkGenerator(mappers=mappers, scorer=None) - network = network_planner.generate_network_from_names(ligands=ligands, names=names) + network = network_planner.generate_network_from_names( + ligands=ligands, names=names + ) return network From 92c5b7c16bbfc4199294a3d6a8d533633e7049f0 Mon Sep 17 00:00:00 2001 From: Benjamin Ries Date: Thu, 17 Oct 2024 13:18:44 +0200 Subject: [PATCH 08/18] Update environment.yml --- environment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment.yml b/environment.yml index a83a0a170..2d5c7f3ba 100644 --- a/environment.yml +++ b/environment.yml @@ -4,7 +4,7 @@ channels: dependencies: - duecredit<0.10 - kartograf>=1.0.0 - - konnektor>=1.0.0 + - konnektor - lomap2>=3.0.0 - numpy - networkx From 6a37703b5821d8d7c27447326e35afc75e9890d7 Mon Sep 17 00:00:00 2001 From: Benjamin Ries Date: Thu, 17 Oct 2024 13:50:44 +0200 Subject: [PATCH 09/18] Update test_network_planning.py fix for tests --- openfe/tests/setup/test_network_planning.py | 22 ++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/openfe/tests/setup/test_network_planning.py b/openfe/tests/setup/test_network_planning.py index c63040eeb..54606fe83 100644 --- a/openfe/tests/setup/test_network_planning.py +++ b/openfe/tests/setup/test_network_planning.py @@ -220,7 +220,7 @@ def scoring_func(mapping): network = openfe.setup.ligand_network_planning.generate_maximal_network( ligands=others + [toluene], - mapper=mappers, + mappers=mappers, scorer=scorer, progress=with_progress, ) @@ -454,7 +454,7 @@ def test_network_from_names(atom_mapping_basic_test_files, lomap_old_mapper): network = openfe.setup.ligand_network_planning.generate_network_from_names( ligands=ligs, names=requested, - mapper=lomap_old_mapper, + mappers=lomap_old_mapper, ) assert len(network.nodes) == len(ligs) @@ -478,7 +478,7 @@ def test_network_from_names_bad_name( _ = openfe.setup.ligand_network_planning.generate_network_from_names( ligands=ligs, names=requested, - mapper=lomap_old_mapper, + mappers=lomap_old_mapper, ) @@ -497,7 +497,7 @@ def test_network_from_names_duplicate_name( _ = openfe.setup.ligand_network_planning.generate_network_from_names( ligands=ligs, names=requested, - mapper=lomap_old_mapper, + mappers=lomap_old_mapper, ) @@ -511,7 +511,7 @@ def test_network_from_indices( network = openfe.setup.ligand_network_planning.generate_network_from_indices( ligands=ligs, indices=requested, - mapper=lomap_old_mapper, + mappers=lomap_old_mapper, ) assert len(network.nodes) == len(ligs) @@ -536,7 +536,7 @@ def test_network_from_indices_indexerror( network = openfe.setup.ligand_network_planning.generate_network_from_indices( ligands=ligs, indices=requested, - mapper=lomap_old_mapper, + mappers=lomap_old_mapper, ) @@ -550,7 +550,7 @@ def test_network_from_indices_disconnected_warning( _ = openfe.setup.ligand_network_planning.generate_network_from_indices( ligands=ligs, indices=requested, - mapper=lomap_old_mapper, + mappers=lomap_old_mapper, ) @@ -567,7 +567,7 @@ def test_network_from_external(file_fixture, loader, request, network = loader( ligands=[l for l in benzene_modifications.values()], - mapper=openfe.LomapAtomMapper(), + mappers=openfe.LomapAtomMapper(), network_file=network_file, ) @@ -603,7 +603,7 @@ def test_network_from_external_unknown_edge(file_fixture, loader, request, with pytest.raises(KeyError, match="Invalid name"): network = loader( ligands=ligs, - mapper=openfe.LomapAtomMapper(), + mappers=openfe.LomapAtomMapper(), network_file=network_file, ) @@ -628,7 +628,7 @@ def test_bad_orion_network(benzene_modifications, tmpdir): with pytest.raises(KeyError, match="line does not match"): network = openfe.setup.ligand_network_planning.load_orion_network( ligands=[l for l in benzene_modifications.values()], - mapper=openfe.LomapAtomMapper(), + mappers=openfe.LomapAtomMapper(), network_file='bad_orion_net.dat', ) @@ -651,6 +651,6 @@ def test_bad_edges_network(benzene_modifications, tmpdir): with pytest.raises(KeyError, match="line does not match"): network = openfe.setup.ligand_network_planning.load_fepplus_network( ligands=[l for l in benzene_modifications.values()], - mapper=openfe.LomapAtomMapper(), + mappers=openfe.LomapAtomMapper(), network_file='bad_edges.edges', ) From be12620c2eaba54f2f28eb9db754bd5466eadbb9 Mon Sep 17 00:00:00 2001 From: RiesBen Date: Tue, 22 Oct 2024 16:13:36 +0200 Subject: [PATCH 10/18] fixes for unittests: - fix removing the central ligand from list. --- openfe/setup/ligand_network_planning.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openfe/setup/ligand_network_planning.py b/openfe/setup/ligand_network_planning.py index e9642a745..fcb1f6f21 100644 --- a/openfe/setup/ligand_network_planning.py +++ b/openfe/setup/ligand_network_planning.py @@ -110,6 +110,7 @@ def generate_radial_network( ligands = list(ligands) try: central_ligand = ligands[central_ligand] + ligands.remove(central_ligand) except IndexError: raise ValueError( f"index '{central_ligand}' out of bounds, there are " @@ -126,6 +127,7 @@ def generate_radial_network( if len(possibles) > 1: raise ValueError(f"Multiple ligands called '{central_ligand}'") central_ligand = possibles[0] + ligands.remove(central_ligand) # Construct network network_planner = StarNetworkGenerator( From 6ef48f7927f6e38caa9ff02de7cdebc0ffadf3bc Mon Sep 17 00:00:00 2001 From: Benjamin Ries Date: Tue, 29 Oct 2024 23:38:54 +0100 Subject: [PATCH 11/18] Update test_network_planning.py remove test for testing if a central component is part of the other component list. This can not happen anymore with the current Konnektor implementation, therefore I propose removing the test. --- openfe/tests/setup/test_network_planning.py | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/openfe/tests/setup/test_network_planning.py b/openfe/tests/setup/test_network_planning.py index 54606fe83..feb456359 100644 --- a/openfe/tests/setup/test_network_planning.py +++ b/openfe/tests/setup/test_network_planning.py @@ -130,21 +130,7 @@ def test_radial_network_index_error(toluene_vs_others, lomap_old_mapper): ligands=ligands, central_ligand=2077, mappers=lomap_old_mapper, scorer=None, ) - - -def test_radial_network_self_central(toluene_vs_others, lomap_old_mapper): - # issue #544, include the central ligand in "ligands", - # shouldn't get self edge - ligs = [toluene_vs_others[0]] + toluene_vs_others[1] - - with pytest.warns(UserWarning, match="The central_ligand"): - network = openfe.setup.ligand_network_planning.generate_radial_network( - ligands=ligs, central_ligand=ligs[0], - mappers=lomap_old_mapper, scorer=None - ) - - assert len(network.edges) == len(ligs) - 1 - + def test_radial_network_with_scorer(toluene_vs_others, lomap_old_mapper): toluene, others = toluene_vs_others From 92fc8681fce4a828a6a2ca3d3273fd7ec76450b2 Mon Sep 17 00:00:00 2001 From: Alyssa Travitz Date: Wed, 6 Nov 2024 10:36:13 -0800 Subject: [PATCH 12/18] updating docstrings --- openfe/setup/ligand_network_planning.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/openfe/setup/ligand_network_planning.py b/openfe/setup/ligand_network_planning.py index fcb1f6f21..c0b56c7ac 100644 --- a/openfe/setup/ligand_network_planning.py +++ b/openfe/setup/ligand_network_planning.py @@ -24,8 +24,6 @@ MinimalSpanningTreeNetworkGenerator, ExplicitNetworkGenerator, ) - -# Konnektor handles: from konnektor import network_analysis, network_planners, network_tools @@ -71,16 +69,22 @@ def generate_radial_network( ligands : iterable of SmallMoleculeComponents the ligands to arrange around the central ligand. If the central ligand is present it will be ignored (i.e. avoiding a self edge) + mappers : AtomMapper or iterable of AtomMappers + mapper(s) to use, at least 1 required central_ligand : SmallMoleculeComponent or str or int the ligand to use as the hub/central ligand. If this is a string, this should match to one and only one ligand name. If this is an integer, this refers to the index from within ligands - mappers : AtomMapper or iterable of AtomMappers - mapper(s) to use, at least 1 required scorer : scoring function, optional a callable which returns a float for any LigandAtomMapping. Used to assign scores to potential mappings; higher scores indicate better mappings. + progress : Union[bool, Callable[Iterable], Iterable] + progress bar: if False, no progress bar will be shown. If True, use a + tqdm progress bar that only appears after 1.5 seconds. You can also + provide a custom progress bar wrapper as a callable. + n_processes: int + number of threads to use if parallelizing network generation. Raises ------ @@ -177,7 +181,7 @@ def generate_maximal_network( tqdm progress bar that only appears after 1.5 seconds. You can also provide a custom progress bar wrapper as a callable. n_processes: int - parallelization of network generation. + number of threads to use if parallelizing network generation. """ if isinstance(mappers, AtomMapper): mappers = [mappers] @@ -224,6 +228,8 @@ def generate_minimal_spanning_network( progress bar: if False, no progress bar will be shown. If True, use a tqdm progress bar that only appears after 1.5 seconds. You can also provide a custom progress bar wrapper as a callable. + n_processes: int + number of threads to use if parallelizing network generation. """ if isinstance(mappers, AtomMapper): mappers = [mappers] @@ -275,11 +281,12 @@ def generate_minimal_redundant_network( progress bar: if False, no progress bar will be shown. If True, use a tqdm progress bar that only appears after 1.5 seconds. You can also provide a custom progress bar wrapper as a callable. - mst_num: int + mst_num : int Minimum Spanning Tree number: the number of minimum spanning trees to generate. If two, the second-best edges are included in the returned network. If three, the third-best edges are also included, etc. n_processes: int + number of threads to use if parallelizing network generation """ if isinstance(mappers, AtomMapper): From 609ddc645ff3574a57282b97cf9f87f9007fbdaf Mon Sep 17 00:00:00 2001 From: Alyssa Travitz Date: Wed, 6 Nov 2024 10:37:59 -0800 Subject: [PATCH 13/18] adjusting n_processes docstring language --- openfe/setup/ligand_network_planning.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openfe/setup/ligand_network_planning.py b/openfe/setup/ligand_network_planning.py index c0b56c7ac..5689a38c7 100644 --- a/openfe/setup/ligand_network_planning.py +++ b/openfe/setup/ligand_network_planning.py @@ -84,7 +84,7 @@ def generate_radial_network( tqdm progress bar that only appears after 1.5 seconds. You can also provide a custom progress bar wrapper as a callable. n_processes: int - number of threads to use if parallelizing network generation. + number of cpu processes to use if parallelizing network generation. Raises ------ @@ -181,7 +181,7 @@ def generate_maximal_network( tqdm progress bar that only appears after 1.5 seconds. You can also provide a custom progress bar wrapper as a callable. n_processes: int - number of threads to use if parallelizing network generation. + number of cpu processes to use if parallelizing network generation. """ if isinstance(mappers, AtomMapper): mappers = [mappers] @@ -229,7 +229,7 @@ def generate_minimal_spanning_network( tqdm progress bar that only appears after 1.5 seconds. You can also provide a custom progress bar wrapper as a callable. n_processes: int - number of threads to use if parallelizing network generation. + number of cpu processes to use if parallelizing network generation. """ if isinstance(mappers, AtomMapper): mappers = [mappers] From 69eea0db332498b632b63bf896a5f8a143303dbe Mon Sep 17 00:00:00 2001 From: Alyssa Travitz Date: Wed, 6 Nov 2024 10:58:55 -0800 Subject: [PATCH 14/18] fixing central_ligand default --- openfe/setup/ligand_network_planning.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfe/setup/ligand_network_planning.py b/openfe/setup/ligand_network_planning.py index 5689a38c7..8835c9735 100644 --- a/openfe/setup/ligand_network_planning.py +++ b/openfe/setup/ligand_network_planning.py @@ -53,7 +53,7 @@ def _hasten_lomap(mapper, ligands): def generate_radial_network( ligands: Iterable[SmallMoleculeComponent], mappers: Union[AtomMapper, Iterable[AtomMapper]], - central_ligand: Union[SmallMoleculeComponent, str, int] = None, + central_ligand: Union[SmallMoleculeComponent, str, int, None], scorer: Optional[Callable[[LigandAtomMapping], float]] = None, n_processes: int = 1, progress: bool = False, From db191f44a87eecc7293a60817881156ba06f3a50 Mon Sep 17 00:00:00 2001 From: Alyssa Travitz Date: Wed, 6 Nov 2024 10:59:28 -0800 Subject: [PATCH 15/18] rename mappers to mapper to avoid api break --- openfe/setup/ligand_network_planning.py | 23 +++++----- openfe/tests/setup/test_network_planning.py | 48 ++++++++++----------- 2 files changed, 35 insertions(+), 36 deletions(-) diff --git a/openfe/setup/ligand_network_planning.py b/openfe/setup/ligand_network_planning.py index 8835c9735..18f7334f7 100644 --- a/openfe/setup/ligand_network_planning.py +++ b/openfe/setup/ligand_network_planning.py @@ -70,7 +70,7 @@ def generate_radial_network( the ligands to arrange around the central ligand. If the central ligand is present it will be ignored (i.e. avoiding a self edge) mappers : AtomMapper or iterable of AtomMappers - mapper(s) to use, at least 1 required + mapper(s) to use to construct edges, at least 1 required central_ligand : SmallMoleculeComponent or str or int the ligand to use as the hub/central ligand. If this is a string, this should match to one and only one ligand name. @@ -171,9 +171,8 @@ def generate_maximal_network( ---------- ligands : Iterable[SmallMoleculeComponent] the ligands to include in the LigandNetwork - mapper : AtomMapper or Iterable[AtomMapper] - the AtomMapper(s) to use to propose mappings. At least 1 required, - but many can be given. + mappers : AtomMapper or iterable of AtomMappers + mapper(s) to use to construct edges, at least 1 required scorer : Scoring function any callable which takes a LigandAtomMapping and returns a float progress : Union[bool, Callable[Iterable], Iterable] @@ -323,8 +322,8 @@ def generate_network_from_names( ---------- ligands : list of SmallMoleculeComponent the small molecules to place into the network - mapper: AtomMapper - the atom mapper to use to construct edges + mappers : AtomMapper or iterable of AtomMappers + mapper(s) to use, at least 1 required names : list of tuples of names the edges to form where the values refer to names of the small molecules, eg `[('benzene', 'toluene'), ...]` will create an edge between the @@ -365,8 +364,8 @@ def generate_network_from_indices( ---------- ligands : list of SmallMoleculeComponent the small molecules to place into the network - mapper: AtomMapper - the atom mapper to use to construct edges + mappers : AtomMapper or iterable of AtomMappers + mapper(s) to use to construct edges, at least 1 required indices : list of tuples of indices the edges to form where the values refer to names of the small molecules, eg `[(3, 4), ...]` will create an edge between the 3rd and 4th molecules @@ -401,8 +400,8 @@ def load_orion_network( ---------- ligands : list of SmallMoleculeComponent the small molecules to place into the network - mapper: AtomMapper - the atom mapper to use to construct edges + mappers : AtomMapper or iterable of AtomMappers + mapper(s) to use to construct edges, at least 1 required network_file : str path to NES network file. @@ -450,8 +449,8 @@ def load_fepplus_network( ---------- ligands : list of SmallMoleculeComponent the small molecules to place into the network - mapper: AtomMapper - the atom mapper to use to construct edges + mappers : AtomMapper or iterable of AtomMappers + mapper(s) to use to construct edges, at least 1 required network_file : str path to edges network file. diff --git a/openfe/tests/setup/test_network_planning.py b/openfe/tests/setup/test_network_planning.py index feb456359..83bfa0ca0 100644 --- a/openfe/tests/setup/test_network_planning.py +++ b/openfe/tests/setup/test_network_planning.py @@ -62,7 +62,7 @@ def test_radial_network( network = openfe.setup.ligand_network_planning.generate_radial_network( ligands=others, central_ligand=toluene, - mappers=mapper, scorer=None, + mapper=mapper, scorer=None, ) # couple sanity checks assert len(network.nodes) == len(atom_mapping_basic_test_files) @@ -84,7 +84,7 @@ def test_radial_network_int_str(atom_mapping_basic_test_files, toluene_vs_others network = openfe.setup.ligand_network_planning.generate_radial_network( ligands=ligands, central_ligand=central_ligand_arg, - mappers=lomap_old_mapper, scorer=None, + mapper=lomap_old_mapper, scorer=None, ) assert len(network.nodes) == len(ligands) assert len(network.edges) == len(others) @@ -104,7 +104,7 @@ def test_radial_network_bad_str(toluene_vs_others, lomap_old_mapper): with pytest.raises(ValueError, match='No ligand called'): network = openfe.setup.ligand_network_planning.generate_radial_network( ligands=ligands, central_ligand='unobtainium', - mappers=lomap_old_mapper, scorer=None, + mapper=lomap_old_mapper, scorer=None, ) @@ -116,7 +116,7 @@ def test_radial_network_multiple_str(toluene_vs_others, lomap_old_mapper): with pytest.raises(ValueError, match='Multiple ligands called'): network = openfe.setup.ligand_network_planning.generate_radial_network( ligands=ligands, central_ligand='toluene', - mappers=lomap_old_mapper, scorer=None, + mapper=lomap_old_mapper, scorer=None, ) @@ -128,7 +128,7 @@ def test_radial_network_index_error(toluene_vs_others, lomap_old_mapper): with pytest.raises(ValueError, match='out of bounds'): network = openfe.setup.ligand_network_planning.generate_radial_network( ligands=ligands, central_ligand=2077, - mappers=lomap_old_mapper, scorer=None, + mapper=lomap_old_mapper, scorer=None, ) @@ -141,7 +141,7 @@ def scorer(mapping): network = openfe.setup.ligand_network_planning.generate_radial_network( ligands=others, central_ligand=toluene, - mappers=[BadMapper(), lomap_old_mapper], + mapper=[BadMapper(), lomap_old_mapper], scorer=scorer ) assert len(network.edges) == len(others) @@ -163,7 +163,7 @@ def test_radial_network_multiple_mappers_no_scorer(toluene_vs_others, network = openfe.setup.ligand_network_planning.generate_radial_network( ligands=others, central_ligand=toluene, - mappers=mappers, + mapper=mappers, ) assert len(network.edges) == len(others) @@ -178,7 +178,7 @@ def test_radial_network_failure(atom_mapping_basic_test_files, lomap_old_mapper) network = openfe.setup.ligand_network_planning.generate_radial_network( ligands=[nigel], central_ligand=atom_mapping_basic_test_files['toluene'], - mappers=[lomap_old_mapper], + mapper=[lomap_old_mapper], scorer=None ) @@ -206,7 +206,7 @@ def scoring_func(mapping): network = openfe.setup.ligand_network_planning.generate_maximal_network( ligands=others + [toluene], - mappers=mappers, + mapper=mappers, scorer=scorer, progress=with_progress, ) @@ -247,7 +247,7 @@ def scorer(mapping): network = openfe.ligand_network_planning.generate_minimal_spanning_network( ligands=ligands, - mappers=mappers, + mapper=mappers, scorer=scorer, ) @@ -266,7 +266,7 @@ def scorer(mapping): network = openfe.setup.ligand_network_planning.generate_minimal_spanning_network( ligands=others + [toluene], - mappers=mappers, + mapper=mappers, scorer=scorer ) return network @@ -322,7 +322,7 @@ def scorer(mapping): with pytest.raises(RuntimeError, match="Unable to create edges"): network = openfe.setup.ligand_network_planning.generate_minimal_spanning_network( ligands=others + [toluene, nimrod], - mappers=[lomap_old_mapper], + mapper=[lomap_old_mapper], scorer=scorer ) @@ -338,7 +338,7 @@ def scorer(mapping): network = openfe.setup.ligand_network_planning.generate_minimal_redundant_network( ligands=others + [toluene], - mappers=mappers, + mapper=mappers, scorer=scorer, mst_num=2 ) @@ -424,7 +424,7 @@ def scorer(mapping): with pytest.raises(RuntimeError, match="Unable to create edges"): network = openfe.setup.ligand_network_planning.generate_minimal_redundant_network( ligands=others + [toluene, nimrod], - mappers=[lomap_old_mapper], + mapper=[lomap_old_mapper], scorer=scorer ) @@ -440,7 +440,7 @@ def test_network_from_names(atom_mapping_basic_test_files, lomap_old_mapper): network = openfe.setup.ligand_network_planning.generate_network_from_names( ligands=ligs, names=requested, - mappers=lomap_old_mapper, + mapper=lomap_old_mapper, ) assert len(network.nodes) == len(ligs) @@ -464,7 +464,7 @@ def test_network_from_names_bad_name( _ = openfe.setup.ligand_network_planning.generate_network_from_names( ligands=ligs, names=requested, - mappers=lomap_old_mapper, + mapper=lomap_old_mapper, ) @@ -483,7 +483,7 @@ def test_network_from_names_duplicate_name( _ = openfe.setup.ligand_network_planning.generate_network_from_names( ligands=ligs, names=requested, - mappers=lomap_old_mapper, + mapper=lomap_old_mapper, ) @@ -497,7 +497,7 @@ def test_network_from_indices( network = openfe.setup.ligand_network_planning.generate_network_from_indices( ligands=ligs, indices=requested, - mappers=lomap_old_mapper, + mapper=lomap_old_mapper, ) assert len(network.nodes) == len(ligs) @@ -522,7 +522,7 @@ def test_network_from_indices_indexerror( network = openfe.setup.ligand_network_planning.generate_network_from_indices( ligands=ligs, indices=requested, - mappers=lomap_old_mapper, + mapper=lomap_old_mapper, ) @@ -536,7 +536,7 @@ def test_network_from_indices_disconnected_warning( _ = openfe.setup.ligand_network_planning.generate_network_from_indices( ligands=ligs, indices=requested, - mappers=lomap_old_mapper, + mapper=lomap_old_mapper, ) @@ -553,7 +553,7 @@ def test_network_from_external(file_fixture, loader, request, network = loader( ligands=[l for l in benzene_modifications.values()], - mappers=openfe.LomapAtomMapper(), + mapper=openfe.LomapAtomMapper(), network_file=network_file, ) @@ -589,7 +589,7 @@ def test_network_from_external_unknown_edge(file_fixture, loader, request, with pytest.raises(KeyError, match="Invalid name"): network = loader( ligands=ligs, - mappers=openfe.LomapAtomMapper(), + mapper=openfe.LomapAtomMapper(), network_file=network_file, ) @@ -614,7 +614,7 @@ def test_bad_orion_network(benzene_modifications, tmpdir): with pytest.raises(KeyError, match="line does not match"): network = openfe.setup.ligand_network_planning.load_orion_network( ligands=[l for l in benzene_modifications.values()], - mappers=openfe.LomapAtomMapper(), + mapper=openfe.LomapAtomMapper(), network_file='bad_orion_net.dat', ) @@ -637,6 +637,6 @@ def test_bad_edges_network(benzene_modifications, tmpdir): with pytest.raises(KeyError, match="line does not match"): network = openfe.setup.ligand_network_planning.load_fepplus_network( ligands=[l for l in benzene_modifications.values()], - mappers=openfe.LomapAtomMapper(), + mapper=openfe.LomapAtomMapper(), network_file='bad_edges.edges', ) From 7f0cfe1fa781b3471911a942347a0728bfbe2c72 Mon Sep 17 00:00:00 2001 From: Alyssa Travitz Date: Wed, 6 Nov 2024 11:04:44 -0800 Subject: [PATCH 16/18] Revert "rename mappers to mapper to avoid api break" This reverts commit bf82085d7a86be63d2eaca11e105261107229ecc. --- openfe/setup/ligand_network_planning.py | 23 +++++----- openfe/tests/setup/test_network_planning.py | 48 ++++++++++----------- 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/openfe/setup/ligand_network_planning.py b/openfe/setup/ligand_network_planning.py index 18f7334f7..8835c9735 100644 --- a/openfe/setup/ligand_network_planning.py +++ b/openfe/setup/ligand_network_planning.py @@ -70,7 +70,7 @@ def generate_radial_network( the ligands to arrange around the central ligand. If the central ligand is present it will be ignored (i.e. avoiding a self edge) mappers : AtomMapper or iterable of AtomMappers - mapper(s) to use to construct edges, at least 1 required + mapper(s) to use, at least 1 required central_ligand : SmallMoleculeComponent or str or int the ligand to use as the hub/central ligand. If this is a string, this should match to one and only one ligand name. @@ -171,8 +171,9 @@ def generate_maximal_network( ---------- ligands : Iterable[SmallMoleculeComponent] the ligands to include in the LigandNetwork - mappers : AtomMapper or iterable of AtomMappers - mapper(s) to use to construct edges, at least 1 required + mapper : AtomMapper or Iterable[AtomMapper] + the AtomMapper(s) to use to propose mappings. At least 1 required, + but many can be given. scorer : Scoring function any callable which takes a LigandAtomMapping and returns a float progress : Union[bool, Callable[Iterable], Iterable] @@ -322,8 +323,8 @@ def generate_network_from_names( ---------- ligands : list of SmallMoleculeComponent the small molecules to place into the network - mappers : AtomMapper or iterable of AtomMappers - mapper(s) to use, at least 1 required + mapper: AtomMapper + the atom mapper to use to construct edges names : list of tuples of names the edges to form where the values refer to names of the small molecules, eg `[('benzene', 'toluene'), ...]` will create an edge between the @@ -364,8 +365,8 @@ def generate_network_from_indices( ---------- ligands : list of SmallMoleculeComponent the small molecules to place into the network - mappers : AtomMapper or iterable of AtomMappers - mapper(s) to use to construct edges, at least 1 required + mapper: AtomMapper + the atom mapper to use to construct edges indices : list of tuples of indices the edges to form where the values refer to names of the small molecules, eg `[(3, 4), ...]` will create an edge between the 3rd and 4th molecules @@ -400,8 +401,8 @@ def load_orion_network( ---------- ligands : list of SmallMoleculeComponent the small molecules to place into the network - mappers : AtomMapper or iterable of AtomMappers - mapper(s) to use to construct edges, at least 1 required + mapper: AtomMapper + the atom mapper to use to construct edges network_file : str path to NES network file. @@ -449,8 +450,8 @@ def load_fepplus_network( ---------- ligands : list of SmallMoleculeComponent the small molecules to place into the network - mappers : AtomMapper or iterable of AtomMappers - mapper(s) to use to construct edges, at least 1 required + mapper: AtomMapper + the atom mapper to use to construct edges network_file : str path to edges network file. diff --git a/openfe/tests/setup/test_network_planning.py b/openfe/tests/setup/test_network_planning.py index 83bfa0ca0..feb456359 100644 --- a/openfe/tests/setup/test_network_planning.py +++ b/openfe/tests/setup/test_network_planning.py @@ -62,7 +62,7 @@ def test_radial_network( network = openfe.setup.ligand_network_planning.generate_radial_network( ligands=others, central_ligand=toluene, - mapper=mapper, scorer=None, + mappers=mapper, scorer=None, ) # couple sanity checks assert len(network.nodes) == len(atom_mapping_basic_test_files) @@ -84,7 +84,7 @@ def test_radial_network_int_str(atom_mapping_basic_test_files, toluene_vs_others network = openfe.setup.ligand_network_planning.generate_radial_network( ligands=ligands, central_ligand=central_ligand_arg, - mapper=lomap_old_mapper, scorer=None, + mappers=lomap_old_mapper, scorer=None, ) assert len(network.nodes) == len(ligands) assert len(network.edges) == len(others) @@ -104,7 +104,7 @@ def test_radial_network_bad_str(toluene_vs_others, lomap_old_mapper): with pytest.raises(ValueError, match='No ligand called'): network = openfe.setup.ligand_network_planning.generate_radial_network( ligands=ligands, central_ligand='unobtainium', - mapper=lomap_old_mapper, scorer=None, + mappers=lomap_old_mapper, scorer=None, ) @@ -116,7 +116,7 @@ def test_radial_network_multiple_str(toluene_vs_others, lomap_old_mapper): with pytest.raises(ValueError, match='Multiple ligands called'): network = openfe.setup.ligand_network_planning.generate_radial_network( ligands=ligands, central_ligand='toluene', - mapper=lomap_old_mapper, scorer=None, + mappers=lomap_old_mapper, scorer=None, ) @@ -128,7 +128,7 @@ def test_radial_network_index_error(toluene_vs_others, lomap_old_mapper): with pytest.raises(ValueError, match='out of bounds'): network = openfe.setup.ligand_network_planning.generate_radial_network( ligands=ligands, central_ligand=2077, - mapper=lomap_old_mapper, scorer=None, + mappers=lomap_old_mapper, scorer=None, ) @@ -141,7 +141,7 @@ def scorer(mapping): network = openfe.setup.ligand_network_planning.generate_radial_network( ligands=others, central_ligand=toluene, - mapper=[BadMapper(), lomap_old_mapper], + mappers=[BadMapper(), lomap_old_mapper], scorer=scorer ) assert len(network.edges) == len(others) @@ -163,7 +163,7 @@ def test_radial_network_multiple_mappers_no_scorer(toluene_vs_others, network = openfe.setup.ligand_network_planning.generate_radial_network( ligands=others, central_ligand=toluene, - mapper=mappers, + mappers=mappers, ) assert len(network.edges) == len(others) @@ -178,7 +178,7 @@ def test_radial_network_failure(atom_mapping_basic_test_files, lomap_old_mapper) network = openfe.setup.ligand_network_planning.generate_radial_network( ligands=[nigel], central_ligand=atom_mapping_basic_test_files['toluene'], - mapper=[lomap_old_mapper], + mappers=[lomap_old_mapper], scorer=None ) @@ -206,7 +206,7 @@ def scoring_func(mapping): network = openfe.setup.ligand_network_planning.generate_maximal_network( ligands=others + [toluene], - mapper=mappers, + mappers=mappers, scorer=scorer, progress=with_progress, ) @@ -247,7 +247,7 @@ def scorer(mapping): network = openfe.ligand_network_planning.generate_minimal_spanning_network( ligands=ligands, - mapper=mappers, + mappers=mappers, scorer=scorer, ) @@ -266,7 +266,7 @@ def scorer(mapping): network = openfe.setup.ligand_network_planning.generate_minimal_spanning_network( ligands=others + [toluene], - mapper=mappers, + mappers=mappers, scorer=scorer ) return network @@ -322,7 +322,7 @@ def scorer(mapping): with pytest.raises(RuntimeError, match="Unable to create edges"): network = openfe.setup.ligand_network_planning.generate_minimal_spanning_network( ligands=others + [toluene, nimrod], - mapper=[lomap_old_mapper], + mappers=[lomap_old_mapper], scorer=scorer ) @@ -338,7 +338,7 @@ def scorer(mapping): network = openfe.setup.ligand_network_planning.generate_minimal_redundant_network( ligands=others + [toluene], - mapper=mappers, + mappers=mappers, scorer=scorer, mst_num=2 ) @@ -424,7 +424,7 @@ def scorer(mapping): with pytest.raises(RuntimeError, match="Unable to create edges"): network = openfe.setup.ligand_network_planning.generate_minimal_redundant_network( ligands=others + [toluene, nimrod], - mapper=[lomap_old_mapper], + mappers=[lomap_old_mapper], scorer=scorer ) @@ -440,7 +440,7 @@ def test_network_from_names(atom_mapping_basic_test_files, lomap_old_mapper): network = openfe.setup.ligand_network_planning.generate_network_from_names( ligands=ligs, names=requested, - mapper=lomap_old_mapper, + mappers=lomap_old_mapper, ) assert len(network.nodes) == len(ligs) @@ -464,7 +464,7 @@ def test_network_from_names_bad_name( _ = openfe.setup.ligand_network_planning.generate_network_from_names( ligands=ligs, names=requested, - mapper=lomap_old_mapper, + mappers=lomap_old_mapper, ) @@ -483,7 +483,7 @@ def test_network_from_names_duplicate_name( _ = openfe.setup.ligand_network_planning.generate_network_from_names( ligands=ligs, names=requested, - mapper=lomap_old_mapper, + mappers=lomap_old_mapper, ) @@ -497,7 +497,7 @@ def test_network_from_indices( network = openfe.setup.ligand_network_planning.generate_network_from_indices( ligands=ligs, indices=requested, - mapper=lomap_old_mapper, + mappers=lomap_old_mapper, ) assert len(network.nodes) == len(ligs) @@ -522,7 +522,7 @@ def test_network_from_indices_indexerror( network = openfe.setup.ligand_network_planning.generate_network_from_indices( ligands=ligs, indices=requested, - mapper=lomap_old_mapper, + mappers=lomap_old_mapper, ) @@ -536,7 +536,7 @@ def test_network_from_indices_disconnected_warning( _ = openfe.setup.ligand_network_planning.generate_network_from_indices( ligands=ligs, indices=requested, - mapper=lomap_old_mapper, + mappers=lomap_old_mapper, ) @@ -553,7 +553,7 @@ def test_network_from_external(file_fixture, loader, request, network = loader( ligands=[l for l in benzene_modifications.values()], - mapper=openfe.LomapAtomMapper(), + mappers=openfe.LomapAtomMapper(), network_file=network_file, ) @@ -589,7 +589,7 @@ def test_network_from_external_unknown_edge(file_fixture, loader, request, with pytest.raises(KeyError, match="Invalid name"): network = loader( ligands=ligs, - mapper=openfe.LomapAtomMapper(), + mappers=openfe.LomapAtomMapper(), network_file=network_file, ) @@ -614,7 +614,7 @@ def test_bad_orion_network(benzene_modifications, tmpdir): with pytest.raises(KeyError, match="line does not match"): network = openfe.setup.ligand_network_planning.load_orion_network( ligands=[l for l in benzene_modifications.values()], - mapper=openfe.LomapAtomMapper(), + mappers=openfe.LomapAtomMapper(), network_file='bad_orion_net.dat', ) @@ -637,6 +637,6 @@ def test_bad_edges_network(benzene_modifications, tmpdir): with pytest.raises(KeyError, match="line does not match"): network = openfe.setup.ligand_network_planning.load_fepplus_network( ligands=[l for l in benzene_modifications.values()], - mapper=openfe.LomapAtomMapper(), + mappers=openfe.LomapAtomMapper(), network_file='bad_edges.edges', ) From 144d345ca015400a833b60774c9271a3fc0d5f6f Mon Sep 17 00:00:00 2001 From: Alyssa Travitz Date: Wed, 6 Nov 2024 11:16:29 -0800 Subject: [PATCH 17/18] fixing mapper/s to avoid api break --- openfe/setup/ligand_network_planning.py | 16 ++++++++-------- openfe/tests/setup/test_network_planning.py | 20 ++++++++++---------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/openfe/setup/ligand_network_planning.py b/openfe/setup/ligand_network_planning.py index 8835c9735..8cd120314 100644 --- a/openfe/setup/ligand_network_planning.py +++ b/openfe/setup/ligand_network_planning.py @@ -313,7 +313,7 @@ def generate_minimal_redundant_network( def generate_network_from_names( ligands: list[SmallMoleculeComponent], - mappers: Union[AtomMapper, Iterable[AtomMapper]], + mapper: AtomMapper, names: list[tuple[str, str]], ) -> LigandNetwork: """ @@ -344,7 +344,7 @@ def generate_network_from_names( """ nodes = list(ligands) - network_planner = ExplicitNetworkGenerator(mappers=mappers, scorer=None) + network_planner = ExplicitNetworkGenerator(mappers=mapper, scorer=None) network = network_planner.generate_network_from_names( ligands=nodes, names=names @@ -355,7 +355,7 @@ def generate_network_from_names( def generate_network_from_indices( ligands: list[SmallMoleculeComponent], - mappers: Union[AtomMapper, Iterable[AtomMapper]], + mapper: AtomMapper, indices: list[tuple[int, int]], ) -> LigandNetwork: """ @@ -383,7 +383,7 @@ def generate_network_from_indices( """ nodes = list(ligands) - network_planner = ExplicitNetworkGenerator(mappers=mappers, scorer=None) + network_planner = ExplicitNetworkGenerator(mappers=mapper, scorer=None) network = network_planner.generate_network_from_indices( ligands=nodes, indices=indices ) @@ -392,7 +392,7 @@ def generate_network_from_indices( def load_orion_network( ligands: list[SmallMoleculeComponent], - mappers: Union[AtomMapper, Iterable[AtomMapper]], + mapper: AtomMapper, network_file: Union[str, Path], ) -> LigandNetwork: """Load a :class:`.LigandNetwork` from an Orion NES network file. @@ -431,7 +431,7 @@ def load_orion_network( names.append((entry[0], entry[2])) - network_planner = ExplicitNetworkGenerator(mappers=mappers, scorer=None) + network_planner = ExplicitNetworkGenerator(mappers=mapper, scorer=None) network = network_planner.generate_network_from_names( ligands=ligands, names=names ) @@ -441,7 +441,7 @@ def load_orion_network( def load_fepplus_network( ligands: list[SmallMoleculeComponent], - mappers: Union[AtomMapper, Iterable[AtomMapper]], + mapper: AtomMapper, network_file: Union[str, Path], ) -> LigandNetwork: """Load a :class:`.LigandNetwork` from an FEP+ edges network file. @@ -480,7 +480,7 @@ def load_fepplus_network( names.append((entry[2], entry[4])) - network_planner = ExplicitNetworkGenerator(mappers=mappers, scorer=None) + network_planner = ExplicitNetworkGenerator(mappers=mapper, scorer=None) network = network_planner.generate_network_from_names( ligands=ligands, names=names ) diff --git a/openfe/tests/setup/test_network_planning.py b/openfe/tests/setup/test_network_planning.py index feb456359..9992fc0c5 100644 --- a/openfe/tests/setup/test_network_planning.py +++ b/openfe/tests/setup/test_network_planning.py @@ -440,7 +440,7 @@ def test_network_from_names(atom_mapping_basic_test_files, lomap_old_mapper): network = openfe.setup.ligand_network_planning.generate_network_from_names( ligands=ligs, names=requested, - mappers=lomap_old_mapper, + mapper=lomap_old_mapper, ) assert len(network.nodes) == len(ligs) @@ -464,7 +464,7 @@ def test_network_from_names_bad_name( _ = openfe.setup.ligand_network_planning.generate_network_from_names( ligands=ligs, names=requested, - mappers=lomap_old_mapper, + mapper=lomap_old_mapper, ) @@ -483,7 +483,7 @@ def test_network_from_names_duplicate_name( _ = openfe.setup.ligand_network_planning.generate_network_from_names( ligands=ligs, names=requested, - mappers=lomap_old_mapper, + mapper=lomap_old_mapper, ) @@ -497,7 +497,7 @@ def test_network_from_indices( network = openfe.setup.ligand_network_planning.generate_network_from_indices( ligands=ligs, indices=requested, - mappers=lomap_old_mapper, + mapper=lomap_old_mapper, ) assert len(network.nodes) == len(ligs) @@ -522,7 +522,7 @@ def test_network_from_indices_indexerror( network = openfe.setup.ligand_network_planning.generate_network_from_indices( ligands=ligs, indices=requested, - mappers=lomap_old_mapper, + mapper=lomap_old_mapper, ) @@ -536,7 +536,7 @@ def test_network_from_indices_disconnected_warning( _ = openfe.setup.ligand_network_planning.generate_network_from_indices( ligands=ligs, indices=requested, - mappers=lomap_old_mapper, + mapper=lomap_old_mapper, ) @@ -553,7 +553,7 @@ def test_network_from_external(file_fixture, loader, request, network = loader( ligands=[l for l in benzene_modifications.values()], - mappers=openfe.LomapAtomMapper(), + mapper=openfe.LomapAtomMapper(), network_file=network_file, ) @@ -589,7 +589,7 @@ def test_network_from_external_unknown_edge(file_fixture, loader, request, with pytest.raises(KeyError, match="Invalid name"): network = loader( ligands=ligs, - mappers=openfe.LomapAtomMapper(), + mapper=openfe.LomapAtomMapper(), network_file=network_file, ) @@ -614,7 +614,7 @@ def test_bad_orion_network(benzene_modifications, tmpdir): with pytest.raises(KeyError, match="line does not match"): network = openfe.setup.ligand_network_planning.load_orion_network( ligands=[l for l in benzene_modifications.values()], - mappers=openfe.LomapAtomMapper(), + mapper=openfe.LomapAtomMapper(), network_file='bad_orion_net.dat', ) @@ -637,6 +637,6 @@ def test_bad_edges_network(benzene_modifications, tmpdir): with pytest.raises(KeyError, match="line does not match"): network = openfe.setup.ligand_network_planning.load_fepplus_network( ligands=[l for l in benzene_modifications.values()], - mappers=openfe.LomapAtomMapper(), + mapper=openfe.LomapAtomMapper(), network_file='bad_edges.edges', ) From 6d3e59a2af8ed42a01358e89fa55469dda1e694b Mon Sep 17 00:00:00 2001 From: Alyssa Travitz Date: Wed, 6 Nov 2024 12:01:43 -0800 Subject: [PATCH 18/18] switching arg names from 'ligands' to new 'components' keyword to match konnektor --- openfe/setup/ligand_network_planning.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openfe/setup/ligand_network_planning.py b/openfe/setup/ligand_network_planning.py index 8cd120314..c6ec47e3c 100644 --- a/openfe/setup/ligand_network_planning.py +++ b/openfe/setup/ligand_network_planning.py @@ -347,7 +347,7 @@ def generate_network_from_names( network_planner = ExplicitNetworkGenerator(mappers=mapper, scorer=None) network = network_planner.generate_network_from_names( - ligands=nodes, names=names + components=nodes, names=names ) return network @@ -433,7 +433,7 @@ def load_orion_network( network_planner = ExplicitNetworkGenerator(mappers=mapper, scorer=None) network = network_planner.generate_network_from_names( - ligands=ligands, names=names + components=ligands, names=names ) return network @@ -482,6 +482,6 @@ def load_fepplus_network( network_planner = ExplicitNetworkGenerator(mappers=mapper, scorer=None) network = network_planner.generate_network_from_names( - ligands=ligands, names=names + components=ligands, names=names ) return network