verify Cyto API conn, add docs
This commit is contained in:
Binary file not shown.
@@ -10,6 +10,7 @@ LOGGING_LEVEL_GRAPHS: Final[LoggingLevels] = LoggingLevels.INFO
|
||||
LOGGING_LEVEL_TIMELINE: Final[LoggingLevels] = LoggingLevels.DEBUG
|
||||
LOGGING_LEVEL_TOKEN_ANALYSIS: Final[LoggingLevels] = LoggingLevels.INFO
|
||||
LOGGING_LEVEL_SHARED_HELPERS: Final[LoggingLevels] = LoggingLevels.INFO
|
||||
LOGGING_LEVEL_RENDERING: Final[LoggingLevels] = LoggingLevels.INFO
|
||||
|
||||
logger_shared_helpers = logging.getLogger('lang_main.shared')
|
||||
logger_shared_helpers.setLevel(LOGGING_LEVEL_SHARED_HELPERS)
|
||||
@@ -23,3 +24,5 @@ logger_token_analysis.setLevel(LOGGING_LEVEL_TOKEN_ANALYSIS)
|
||||
logger_preprocess.setLevel(LOGGING_LEVEL_PREPROCESS)
|
||||
logger_pipelines = logging.getLogger('lang_main.pipelines')
|
||||
logger_pipelines.setLevel(LOGGING_LEVEL_PIPELINES)
|
||||
logger_rendering = logging.getLogger('lang_main.render')
|
||||
logger_rendering.setLevel(LOGGING_LEVEL_RENDERING)
|
||||
|
||||
@@ -295,14 +295,15 @@ class Pipeline(BasePipeline):
|
||||
else:
|
||||
args = ret
|
||||
|
||||
if args is not None and action_kwargs:
|
||||
if args is not None:
|
||||
ret = action(*args, **action_kwargs)
|
||||
elif args is not None:
|
||||
ret = action(*args)
|
||||
elif args is None and action_kwargs:
|
||||
ret = action(**action_kwargs)
|
||||
# elif args is not None:
|
||||
# ret = action(*args)
|
||||
# elif args is None and action_kwargs:
|
||||
# ret = action(**action_kwargs)
|
||||
else:
|
||||
ret = action()
|
||||
# ret = action()
|
||||
ret = action(**action_kwargs)
|
||||
|
||||
if ret is not None and not isinstance(ret, tuple):
|
||||
ret = (ret,)
|
||||
|
||||
@@ -182,6 +182,7 @@ def build_tk_graph_rescaling_pipe() -> Pipeline:
|
||||
return pipe_graph_rescaling
|
||||
|
||||
|
||||
# ** token analysis: rendering
|
||||
def build_tk_graph_rendering_pipe() -> Pipeline:
|
||||
pipe_graph_rendering = Pipeline(
|
||||
name='Graph_Static-Rendering',
|
||||
|
||||
@@ -5,6 +5,8 @@ from typing import cast
|
||||
|
||||
import py4cytoscape as p4c
|
||||
from networkx import DiGraph, Graph
|
||||
from py4cytoscape.exceptions import CyError
|
||||
from requests.exceptions import RequestException
|
||||
|
||||
from lang_main.constants import (
|
||||
CYTO_BASE_NETWORK_NAME,
|
||||
@@ -19,6 +21,7 @@ from lang_main.constants import (
|
||||
PROPERTY_NAME_DEGREE_WEIGHTED,
|
||||
SAVE_PATH_FOLDER,
|
||||
)
|
||||
from lang_main.loggers import logger_rendering as logger
|
||||
from lang_main.types import (
|
||||
CytoExportFileTypes,
|
||||
CytoExportPageSizes,
|
||||
@@ -29,9 +32,40 @@ from lang_main.types import (
|
||||
|
||||
|
||||
# ** Cytoscape API related, using py4cytoscape
|
||||
def verify_connection():
|
||||
"""Cytoscape: checks if CyREST and Cytoscape versions are compatible nad
|
||||
if Cytoscape API endpoint is reachable
|
||||
|
||||
Raises
|
||||
------
|
||||
CyError
|
||||
incompatible CyREST or Cytoscape versions
|
||||
RequestException
|
||||
API endpoint not reachable
|
||||
"""
|
||||
try:
|
||||
p4c.cytoscape_ping()
|
||||
except CyError as error:
|
||||
logger.error('[CyError] CyREST or Cytoscape version not supported.')
|
||||
raise error
|
||||
except RequestException as error:
|
||||
logger.error('[CytoAPIConnection] Connection to CyREST API failed.')
|
||||
raise error
|
||||
|
||||
|
||||
def import_to_cytoscape(
|
||||
graph: DiGraph | Graph,
|
||||
) -> None:
|
||||
"""Cytoscape: import NetworkX graph as new network collection
|
||||
|
||||
Parameters
|
||||
----------
|
||||
graph : DiGraph | Graph
|
||||
NetworkX graph object
|
||||
"""
|
||||
logger.debug('Checking Cytoscape connection...')
|
||||
verify_connection()
|
||||
logger.debug('Importing network to Cytoscape...')
|
||||
p4c.delete_all_networks()
|
||||
p4c.create_network_from_networkx(
|
||||
graph,
|
||||
@@ -39,9 +73,11 @@ def import_to_cytoscape(
|
||||
collection=CYTO_COLLECTION_NAME,
|
||||
)
|
||||
p4c.analyze_network(directed=False)
|
||||
logger.debug('Importing network to Cytoscape successful.')
|
||||
|
||||
|
||||
def reset_current_network_to_base() -> None:
|
||||
"""resets to currently selected network in Cytoscape back to the base one"""
|
||||
p4c.set_current_network(CYTO_BASE_NETWORK_NAME)
|
||||
|
||||
|
||||
@@ -51,7 +87,21 @@ def export_network_to_image(
|
||||
network_name: str = CYTO_BASE_NETWORK_NAME,
|
||||
pdf_export_page_size: CytoExportPageSizes = 'A4',
|
||||
) -> None:
|
||||
# target_folder = Path.cwd() / 'results'
|
||||
"""Cytoscape: export current selected view as image
|
||||
|
||||
Parameters
|
||||
----------
|
||||
filename : str
|
||||
export filename
|
||||
filetype : CytoExportFileTypes, optional
|
||||
export filetype supported by Cytoscape, by default 'SVG'
|
||||
network_name : str, optional
|
||||
network to export, by default CYTO_BASE_NETWORK_NAME
|
||||
pdf_export_page_size : CytoExportPageSizes, optional
|
||||
page size which should be used for PDF exports supported by Cytoscape,
|
||||
by default 'A4'
|
||||
"""
|
||||
logger.debug('Exporting image to file...')
|
||||
target_folder = SAVE_PATH_FOLDER
|
||||
if not target_folder.exists():
|
||||
target_folder.mkdir(parents=True)
|
||||
@@ -70,6 +120,7 @@ def export_network_to_image(
|
||||
export_text_as_font=text_as_font,
|
||||
page_size=pdf_export_page_size,
|
||||
)
|
||||
logger.debug('Exporting image to file successful.')
|
||||
|
||||
|
||||
def layout_network(
|
||||
@@ -77,15 +128,52 @@ def layout_network(
|
||||
layout_properties: CytoLayoutProperties = CYTO_LAYOUT_PROPERTIES,
|
||||
network_name: str = CYTO_BASE_NETWORK_NAME,
|
||||
) -> None:
|
||||
"""Cytoscape: apply a supported layout algorithm to currently selected
|
||||
network
|
||||
|
||||
Parameters
|
||||
----------
|
||||
layout_name : CytoLayouts, optional
|
||||
layout algorithm supported by Cytoscape (name of the CyREST API, does not
|
||||
necessarily match the name in the Cytoscape UI),
|
||||
by default CYTO_LAYOUT_NAME
|
||||
layout_properties : CytoLayoutProperties, optional
|
||||
configuration of parameters for the given layout algorithm, by default CYTO_LAYOUT_PROPERTIES
|
||||
network_name : str, optional
|
||||
network to apply the layout algorithm on, by default CYTO_BASE_NETWORK_NAME
|
||||
"""
|
||||
logger.debug('Applying layout to network...')
|
||||
p4c.set_layout_properties(layout_name, layout_properties)
|
||||
p4c.layout_network(layout_name=layout_name, network=network_name)
|
||||
p4c.fit_content(selected_only=False, network=network_name)
|
||||
logger.debug('Layout application to network successful.')
|
||||
|
||||
|
||||
def apply_style_to_network(
|
||||
style_name: str = CYTO_STYLESHEET_NAME,
|
||||
pth_to_stylesheet: Path = CYTO_PATH_STYLESHEET,
|
||||
network_name: str = CYTO_BASE_NETWORK_NAME,
|
||||
) -> None:
|
||||
"""Cytoscape: apply a chosen Cytoscape style to the defined network
|
||||
|
||||
Parameters
|
||||
----------
|
||||
style_name : str, optional
|
||||
Cytoscape name of the style which should be applied,
|
||||
by default CYTO_STYLESHEET_NAME
|
||||
pth_to_stylesheet : Path, optional
|
||||
path where the stylesheet definition in Cytoscape's XML format can
|
||||
be found,
|
||||
by default CYTO_PATH_STYLESHEET
|
||||
network_name : str, optional
|
||||
network to apply the style on, by default CYTO_BASE_NETWORK_NAME
|
||||
|
||||
Raises
|
||||
------
|
||||
FileNotFoundError
|
||||
if provided stylesheet can not be found under the provided path
|
||||
"""
|
||||
logger.debug('Applying style to network...')
|
||||
styles_avail = cast(list[str], p4c.get_visual_style_names())
|
||||
if CYTO_STYLESHEET_NAME not in styles_avail:
|
||||
if not pth_to_stylesheet.exists():
|
||||
@@ -96,15 +184,36 @@ def apply_style_to_network(
|
||||
)
|
||||
p4c.import_visual_styles(str(pth_to_stylesheet))
|
||||
|
||||
p4c.set_visual_style(CYTO_STYLESHEET_NAME, network=network_name)
|
||||
p4c.set_visual_style(style_name, network=network_name)
|
||||
time.sleep(1) # if not waited image export could be without applied style
|
||||
p4c.fit_content(selected_only=False, network=network_name)
|
||||
logger.debug('Style application to network successful.')
|
||||
|
||||
|
||||
def get_subgraph_node_selection(
|
||||
network_name: str = CYTO_BASE_NETWORK_NAME,
|
||||
property_degree_weighted: str = PROPERTY_NAME_DEGREE_WEIGHTED,
|
||||
num_subgraphs: int = CYTO_NUMBER_SUBGRAPHS,
|
||||
) -> list[CytoNodeID]:
|
||||
"""Cytoscape: obtain the relevant nodes for iterative subgraph generation
|
||||
|
||||
Parameters
|
||||
----------
|
||||
network_name : str, optional
|
||||
network to retrieve the nodes from, by default CYTO_BASE_NETWORK_NAME
|
||||
property_degree_weighted : str, optional
|
||||
property name which contains the weighted degree,
|
||||
by default PROPERTY_NAME_DEGREE_WEIGHTED
|
||||
num_subgraphs : int, optional
|
||||
number of relevant nodes which form the basis to generate subgraphs from,
|
||||
by default CYTO_NUMBER_SUBGRAPHS
|
||||
|
||||
Returns
|
||||
-------
|
||||
list[CytoNodeID]
|
||||
list containing all relevant Cytoscape nodes
|
||||
"""
|
||||
logger.debug('Selecting nodes for subgraph generation...')
|
||||
node_table = p4c.get_table_columns(network=network_name)
|
||||
node_table['stress_norm'] = node_table['Stress'] / node_table['Stress'].max()
|
||||
node_table[CYTO_SELECTION_PROPERTY] = (
|
||||
@@ -113,22 +222,42 @@ def get_subgraph_node_selection(
|
||||
* node_table['stress_norm']
|
||||
)
|
||||
node_table = node_table.sort_values(by=CYTO_SELECTION_PROPERTY, ascending=False)
|
||||
node_table_choice = node_table.iloc[:CYTO_NUMBER_SUBGRAPHS, :]
|
||||
node_table_choice = node_table.iloc[:num_subgraphs, :]
|
||||
logger.debug('Selection of nodes for subgraph generation successful.')
|
||||
|
||||
return node_table_choice['SUID'].to_list()
|
||||
|
||||
|
||||
def select_neighbours_of_node(
|
||||
node: CytoNodeID,
|
||||
neighbour_iter_depth: int = CYTO_ITER_NEIGHBOUR_DEPTH,
|
||||
network_name: str = CYTO_BASE_NETWORK_NAME,
|
||||
) -> None:
|
||||
"""Cytoscape: iterative selection of a node's neighbouring nodes and
|
||||
their connecting edges
|
||||
|
||||
Parameters
|
||||
----------
|
||||
node : CytoNodeID
|
||||
node which neighbours should be selected
|
||||
neighbour_iter_depth : int, optional
|
||||
indicates how many levels of neighbours should be choosen, e.g. 1 --> only
|
||||
first-level neighbours are considered which are directly connected to the node,
|
||||
2 --> all nodes with iteration depth of 1 are chosen and additionally their
|
||||
direct neighbours,
|
||||
by default CYTO_ITER_NEIGHBOUR_DEPTH
|
||||
network_name : str, optional
|
||||
network to perform action on, by default CYTO_BASE_NETWORK_NAME
|
||||
"""
|
||||
logger.debug('Selecting node neighbours for %s...', node)
|
||||
p4c.clear_selection(network=network_name)
|
||||
p4c.select_nodes(node, network=network_name)
|
||||
|
||||
for _ in range(CYTO_ITER_NEIGHBOUR_DEPTH):
|
||||
for _ in range(neighbour_iter_depth):
|
||||
_ = p4c.select_first_neighbors(network=network_name)
|
||||
|
||||
_ = p4c.select_edges_connecting_selected_nodes()
|
||||
logger.debug('Selection of node neighbours for %s successful.', node)
|
||||
|
||||
|
||||
def make_subnetwork(
|
||||
@@ -136,6 +265,19 @@ def make_subnetwork(
|
||||
network_name: str = CYTO_BASE_NETWORK_NAME,
|
||||
export_image: bool = True,
|
||||
) -> None:
|
||||
"""Cytoscape: generate a new subnetwork based on the currently
|
||||
selected nodes and edges
|
||||
|
||||
Parameters
|
||||
----------
|
||||
index : int
|
||||
id-like property to identify the subnetwork relative to its parent
|
||||
network_name : str, optional
|
||||
network to generate subnetwork from, by default CYTO_BASE_NETWORK_NAME
|
||||
export_image : bool, optional
|
||||
trigger image export of newly generated subnetwork, by default True
|
||||
"""
|
||||
logger.debug('Generating subnetwork with index %d...', index)
|
||||
subnetwork_name = network_name + f'_sub_{index+1}'
|
||||
p4c.create_subnetwork(
|
||||
nodes='selected',
|
||||
@@ -146,14 +288,33 @@ def make_subnetwork(
|
||||
p4c.set_current_network(subnetwork_name)
|
||||
p4c.fit_content(selected_only=False, network=subnetwork_name)
|
||||
if export_image:
|
||||
time.sleep(1)
|
||||
export_network_to_image(filename=subnetwork_name, network_name=subnetwork_name)
|
||||
|
||||
logger.debug('Generation of subnetwork with index %d successful.', index)
|
||||
|
||||
|
||||
def build_subnetworks(
|
||||
nodes_to_analyse: Iterable[CytoNodeID],
|
||||
network_name: str = CYTO_BASE_NETWORK_NAME,
|
||||
export_image: bool = True,
|
||||
) -> None:
|
||||
"""Cytoscape: iteratively build subnetworks from a collection of nodes
|
||||
and their respective neighbouring nodes
|
||||
|
||||
Parameters
|
||||
----------
|
||||
nodes_to_analyse : Iterable[CytoNodeID]
|
||||
collection of nodes to make subnetworks from, for each node a dedicated
|
||||
subnetwork will be generated
|
||||
network_name : str, optional
|
||||
network which contains the provided nodes,
|
||||
by default CYTO_BASE_NETWORK_NAME
|
||||
export_image : bool, optional
|
||||
trigger image export of newly generated subnetworks, by default True
|
||||
"""
|
||||
logger.debug('Generating all subnetworks for node selection...')
|
||||
for idx, node in enumerate(nodes_to_analyse):
|
||||
select_neighbours_of_node(node=node, network_name=network_name)
|
||||
make_subnetwork(index=idx, network_name=network_name, export_image=export_image)
|
||||
logger.debug('Generation of all subnetworks for node selection successful.')
|
||||
|
||||
Reference in New Issue
Block a user