import re from py4cytoscape import networks from py4cytoscape.network_selection import get_selected_nodes, select_edges from py4cytoscape.py4cytoscape_logger import cy_log from py4cytoscape.py4cytoscape_utils import * # type: ignore # noqa: F403 re_parenthesis_1 = re.compile(r'[(]+') re_parenthesis_2 = re.compile(r'[)]+') @cy_log def select_edges_connecting_selected_nodes(network=None, base_url=DEFAULT_BASE_URL): # noqa: F405 """Select edges in a Cytoscape Network connecting the selected nodes, including self loops connecting single nodes. Any edges selected beforehand are deselected before any new edges are selected Args: network (SUID or str or None): Name or SUID of a network. Default is the "current" network active in Cytoscape. base_url (str): Ignore unless you need to specify a custom domain, port or version to connect to the CyREST API. Default is http://127.0.0.1:1234 and the latest version of the CyREST API supported by this version of py4cytoscape. Returns: dict: {'nodes': [node list], 'edges': [edge list]} or None if no selected nodes Raises: CyError: if network name or SUID doesn't exist requests.exceptions.RequestException: if can't connect to Cytoscape or Cytoscape returns an error Examples: >>> select_edges_connecting_selected_nodes() None >>> select_edges_connecting_selected_nodes(network='My Network') {'nodes': [103990, 103991, ...], 'edges': [104432, 104431, ...]} >>> select_edges_connecting_selected_nodes(network=52) {'nodes': [103990, 103991, ...], 'edges': [104432, 104431, ...]} Note: In the return value node list is list of all selected nodes, and edge list is the SUIDs of selected edges -- dict is None if no nodes were selected or there were no newly created edges """ net_suid = networks.get_network_suid(network, base_url=base_url) selected_nodes = get_selected_nodes(network=net_suid, base_url=base_url) # TODO: In R version, NA test is after len() test ... shouldn't it be before? if not selected_nodes: return None all_edges = networks.get_all_edges(net_suid, base_url=base_url) selected_sources = set() selected_targets = set() for n in selected_nodes: n = re_parenthesis_1.sub('\(', n) # type: ignore n = re_parenthesis_2.sub('\)', n) # type: ignore selected_sources |= set(filter(re.compile('^' + n).search, all_edges)) # type: ignore selected_targets |= set(filter(re.compile(n + '$').search, all_edges)) # type: ignore selected_edges = list(selected_sources.intersection(selected_targets)) if len(selected_edges) == 0: return None res = select_edges( selected_edges, by_col='name', preserve_current_selection=False, network=net_suid, base_url=base_url, ) return res # TODO: isn't the pattern match a bit cheesy ... shouldn't it be ^+n+' (' and ') '+n+$ ???