risk-network 0.0.11__py3-none-any.whl → 0.0.12b1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. risk/__init__.py +1 -1
  2. risk/annotations/__init__.py +4 -1
  3. risk/annotations/io.py +48 -47
  4. risk/annotations/nltk_setup.py +2 -1
  5. risk/log/__init__.py +1 -1
  6. risk/log/parameters.py +21 -22
  7. risk/neighborhoods/__init__.py +0 -1
  8. risk/neighborhoods/api.py +2 -2
  9. risk/neighborhoods/community.py +33 -4
  10. risk/neighborhoods/domains.py +6 -4
  11. risk/neighborhoods/neighborhoods.py +7 -1
  12. risk/neighborhoods/stats/__init__.py +13 -0
  13. risk/neighborhoods/stats/permutation/__init__.py +6 -0
  14. risk/{stats → neighborhoods/stats}/permutation/permutation.py +7 -4
  15. risk/{stats → neighborhoods/stats}/permutation/test_functions.py +2 -2
  16. risk/{stats/stat_tests.py → neighborhoods/stats/tests.py} +21 -13
  17. risk/network/__init__.py +0 -2
  18. risk/network/graph/__init__.py +0 -2
  19. risk/network/graph/api.py +2 -2
  20. risk/network/graph/graph.py +56 -57
  21. risk/{stats/significance.py → network/graph/stats.py} +2 -2
  22. risk/network/graph/summary.py +2 -3
  23. risk/network/io.py +151 -8
  24. risk/network/plotter/__init__.py +0 -2
  25. risk/network/plotter/api.py +1 -1
  26. risk/network/plotter/canvas.py +35 -35
  27. risk/network/plotter/contour.py +11 -12
  28. risk/network/plotter/labels.py +257 -246
  29. risk/network/plotter/plotter.py +2 -4
  30. risk/network/plotter/utils/colors.py +3 -0
  31. risk/risk.py +5 -5
  32. risk_network-0.0.12b1.dist-info/METADATA +122 -0
  33. risk_network-0.0.12b1.dist-info/RECORD +40 -0
  34. {risk_network-0.0.11.dist-info → risk_network-0.0.12b1.dist-info}/WHEEL +1 -1
  35. risk/network/geometry.py +0 -150
  36. risk/stats/__init__.py +0 -15
  37. risk/stats/permutation/__init__.py +0 -6
  38. risk_network-0.0.11.dist-info/METADATA +0 -798
  39. risk_network-0.0.11.dist-info/RECORD +0 -41
  40. {risk_network-0.0.11.dist-info → risk_network-0.0.12b1.dist-info/licenses}/LICENSE +0 -0
  41. {risk_network-0.0.11.dist-info → risk_network-0.0.12b1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,122 @@
1
+ Metadata-Version: 2.4
2
+ Name: risk-network
3
+ Version: 0.0.12b1
4
+ Summary: A Python package for biological network analysis
5
+ Author-email: Ira Horecka <ira89@icloud.com>
6
+ License: GPL-3.0-or-later
7
+ Project-URL: Homepage, https://github.com/riskportal/network
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: Intended Audience :: Science/Research
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3 :: Only
14
+ Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
15
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
16
+ Classifier: Topic :: Scientific/Engineering :: Visualization
17
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
+ Classifier: Development Status :: 4 - Beta
19
+ Requires-Python: >=3.8
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: ipywidgets
23
+ Requires-Dist: leidenalg
24
+ Requires-Dist: markov_clustering
25
+ Requires-Dist: matplotlib
26
+ Requires-Dist: networkx
27
+ Requires-Dist: nltk
28
+ Requires-Dist: numpy
29
+ Requires-Dist: openpyxl
30
+ Requires-Dist: pandas
31
+ Requires-Dist: python-igraph
32
+ Requires-Dist: python-louvain
33
+ Requires-Dist: scikit-learn
34
+ Requires-Dist: scipy
35
+ Requires-Dist: statsmodels
36
+ Requires-Dist: threadpoolctl
37
+ Requires-Dist: tqdm
38
+ Dynamic: license-file
39
+
40
+ # RISK Network
41
+
42
+ <p align="center">
43
+ <img src="https://i.imgur.com/8TleEJs.png" width="50%" />
44
+ </p>
45
+
46
+ <br>
47
+
48
+ ![Python](https://img.shields.io/badge/python-3.8%2B-yellow)
49
+ [![pypiv](https://img.shields.io/pypi/v/risk-network.svg)](https://pypi.python.org/pypi/risk-network)
50
+ ![License](https://img.shields.io/badge/license-GPLv3-purple)
51
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.xxxxxxx.svg)](https://doi.org/10.5281/zenodo.xxxxxxx)
52
+ ![Downloads](https://img.shields.io/pypi/dm/risk-network)
53
+ ![Tests](https://github.com/riskportal/network/actions/workflows/ci.yml/badge.svg)
54
+
55
+ **RISK** (Regional Inference of Significant Kinships) is a next-generation tool for biological network annotation and visualization. RISK integrates community detection-based clustering, rigorous statistical enrichment analysis, and a modular framework to uncover biologically meaningful relationships and generate high-resolution visualizations. RISK supports diverse data formats and is optimized for large-scale network analysis, making it a valuable resource for researchers in systems biology and beyond.
56
+
57
+ ## Documentation and Tutorial
58
+
59
+ Full documentation is available at:
60
+
61
+ - **Docs:** [https://riskportal.github.io/network-tutorial](https://riskportal.github.io/network-tutorial)
62
+ - **Tutorial Jupyter Notebook Repository:** [https://github.com/riskportal/network-tutorial](https://github.com/riskportal/network-tutorial)
63
+
64
+ ## Installation
65
+
66
+ RISK is compatible with Python 3.8 or later and runs on all major operating systems. To install the latest version of RISK, run:
67
+
68
+ ```bash
69
+ pip install risk-network --upgrade
70
+ ```
71
+
72
+ ## Features
73
+
74
+ - **Comprehensive Network Analysis**: Analyze biological networks (e.g., protein–protein interaction and genetic interaction networks) as well as non-biological networks.
75
+ - **Advanced Clustering Algorithms**: Supports Louvain, Leiden, Markov Clustering, Greedy Modularity, Label Propagation, Spinglass, and Walktrap for identifying structured network regions.
76
+ - **Flexible Visualization**: Produce customizable, high-resolution network visualizations with kernel density estimate overlays, adjustable node and edge attributes, and export options in SVG, PNG, and PDF formats.
77
+ - **Efficient Data Handling**: Supports multiple input/output formats, including JSON, CSV, TSV, Excel, Cytoscape, and GPickle.
78
+ - **Statistical Analysis**: Assess functional enrichment using hypergeometric, permutation (network-aware), binomial, chi-squared, Poisson, and z-score tests, ensuring statistical adaptability across datasets.
79
+ - **Cross-Domain Applicability**: Suitable for network analysis across biological and non-biological domains, including social and communication networks.
80
+
81
+ ## Example Usage
82
+
83
+ We applied RISK to a *Saccharomyces cerevisiae* protein–protein interaction network from Michaelis et al. (2023), filtering for proteins with six or more interactions to emphasize core functional relationships. RISK identified compact, statistically enriched clusters corresponding to biological processes such as ribosomal assembly and mitochondrial organization.
84
+
85
+ [![Figure 1](https://i.imgur.com/lJHJrJr.jpeg)](https://i.imgur.com/lJHJrJr.jpeg)
86
+
87
+ This figure highlights RISK’s capability to detect both established and novel functional modules within the yeast interactome.
88
+
89
+ ## Citation
90
+
91
+ If you use RISK in your research, please cite:
92
+
93
+ **Horecka et al.**, "RISK: a next-generation tool for biological network annotation and visualization", **Bioinformatics**, 2025. DOI: [10.1234/zenodo.xxxxxxx](https://doi.org/10.1234/zenodo.xxxxxxx)
94
+
95
+ ## Software Architecture and Implementation
96
+
97
+ RISK features a streamlined, modular architecture designed to meet diverse research needs. RISK’s modular design enables users to run individual components—such as clustering, statistical testing, or visualization—independently or in combination, depending on the analysis workflow. It includes dedicated modules for:
98
+
99
+ - **Data I/O**: Supports JSON, CSV, TSV, Excel, Cytoscape, and GPickle formats.
100
+ - **Clustering**: Supports multiple clustering methods, including Louvain, Leiden, Markov Clustering, Greedy Modularity, Label Propagation, Spinglass, and Walktrap. Provides flexible distance metrics tailored to network structure.
101
+ - **Statistical Analysis**: Provides a suite of tests for overrepresentation analysis of annotations.
102
+ - **Visualization**: Offers customizable, high-resolution output in multiple formats, including SVG, PNG, and PDF.
103
+ - **Configuration Management**: Centralized parameters in risk.params ensure reproducibility and easy tuning for large-scale analyses.
104
+
105
+ ## Performance and Efficiency
106
+
107
+ Benchmarking results demonstrate that RISK efficiently scales to networks exceeding hundreds of thousands of edges, maintaining low execution times and optimal memory usage across statistical tests.
108
+
109
+ ## Contributing
110
+
111
+ We welcome contributions from the community:
112
+
113
+ - [Issues Tracker](https://github.com/riskportal/network/issues)
114
+ - [Source Code](https://github.com/riskportal/network/tree/main/risk)
115
+
116
+ ## Support
117
+
118
+ If you encounter issues or have suggestions for new features, please use the [Issues Tracker](https://github.com/riskportal/network/issues) on GitHub.
119
+
120
+ ## License
121
+
122
+ RISK is open source under the [GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.en.html).
@@ -0,0 +1,40 @@
1
+ risk/__init__.py,sha256=ADVxFWQawaQ0uFwnpUUmlwzs9FIxFA9tFem9_pB5rn4,127
2
+ risk/risk.py,sha256=_Zs8cC4V0eqzfaMbq9M50ir815dbYS-oyTPlrySuMLw,1121
3
+ risk/annotations/__init__.py,sha256=cW2qf4se_Ehmo69mZE3aKy_LzWlTnffcI8KOKqqCock,192
4
+ risk/annotations/annotations.py,sha256=KtFyCiCnoAkhin3HKDBtkNcz5imjpysrmEfQKUwyqh8,14737
5
+ risk/annotations/io.py,sha256=_VAr_6SqzrFzmYt75WZ029871EYlHrJ72yoo-kR5uBE,10748
6
+ risk/annotations/nltk_setup.py,sha256=VRLXIxYRBEzTwAsOD2X48NjRAQJHPwqJPDjLGW6SZCY,3554
7
+ risk/log/__init__.py,sha256=en-hKzuFtQWos4oZd8PxJ9u9Pe5bdihiqH9-qk_5ppw,217
8
+ risk/log/console.py,sha256=PgjyEvyhYLUSHXPUKEqOmxsDsfrjPICIgqo_cAHq0N8,4575
9
+ risk/log/parameters.py,sha256=yGbV5VWSgoTD5w9D3iC-McyOoAJioeuCwl2Z-T-951M,5808
10
+ risk/neighborhoods/__init__.py,sha256=CNS0VNbh_IdxldXjDkPqeTrxgY4hqi_Tc_MTADW_tzQ,182
11
+ risk/neighborhoods/api.py,sha256=ibU9uyOmIWVIjRnFIas77ylEo5cH2T78Bn4fZmUozT8,23355
12
+ risk/neighborhoods/community.py,sha256=0YdTh6wgMLiGMdtlaD7Vu_uxOVoZ9vDBjxbkglkrTV8,17808
13
+ risk/neighborhoods/domains.py,sha256=oveQhhhF-X5cef7PWGdAf1hp_e1fRTNAq_dgzkupzig,14790
14
+ risk/neighborhoods/neighborhoods.py,sha256=DuItwOhLc7IuuEDqNuYgdDnvLaNVyc0J_2IvkcnD2IM,21675
15
+ risk/neighborhoods/stats/__init__.py,sha256=1evLEAa7trCWj2DapCV4vW_f0zsyKHqTsn4--E_fDPg,306
16
+ risk/neighborhoods/stats/tests.py,sha256=RMGEULBIDueqgl95_mz_8YJjayj__llpKr_gqpjSmFU,12107
17
+ risk/neighborhoods/stats/permutation/__init__.py,sha256=V-uLSoi4SIPKjSRl7rhcDR4HJ4tquAn3QxNTXH9KzK8,169
18
+ risk/neighborhoods/stats/permutation/permutation.py,sha256=YJ9bvQy6BNWje5UZrjeOfpBudE0i-G7eRcCkWvYDfcE,10695
19
+ risk/neighborhoods/stats/permutation/test_functions.py,sha256=uppxrrlqSLOvZGCG67E1G8TpVPkGreU1T5quVCzq1PM,3149
20
+ risk/network/__init__.py,sha256=C9GisdyJM7fizwUIipy1vC4lbry9ceqLn1iBcW0-mZg,34
21
+ risk/network/io.py,sha256=KXtQPFXYMBe8QNZQtp75AJHzaQhzJX9au4ZrVCZhaJg,27886
22
+ risk/network/graph/__init__.py,sha256=iG6IlE8xtAyF6_NuCBUpsJrjrjd1vsXO1Ajsr0K8EA0,46
23
+ risk/network/graph/api.py,sha256=ThlQ3MCCa4EkDWfflY_RcBsK_ekxe-dyhkSLEY9-udo,8550
24
+ risk/network/graph/graph.py,sha256=69frjpl2z7JjIyVqBhlOUzv4keDXOBDzwKcrCNS1KGM,12334
25
+ risk/network/graph/stats.py,sha256=xITodchaF8Pgngynil_GM9IeMBtxuraPX-Gjp6WBEMY,7338
26
+ risk/network/graph/summary.py,sha256=_3zuPFSDegti23uRpa24pbE6sUYCt7ucYQXtFNKMbX4,10277
27
+ risk/network/plotter/__init__.py,sha256=9kdeONe8NaJvJ5FO7eOdZiobqL4CeR7q2MghG4z6Kt8,50
28
+ risk/network/plotter/api.py,sha256=GFP0n_0-tSdCZQd6cuaH3w55953sXCR02nwyJhAEqK4,1789
29
+ risk/network/plotter/canvas.py,sha256=U4u5XCER8k3rUB_au7YxB0S5yMDiFkz-6xHiaxdSGG0,13610
30
+ risk/network/plotter/contour.py,sha256=Ybqfz2UJZ2Woe4J48UkMYxUbmGB4D3elyZJla2P5ohU,15505
31
+ risk/network/plotter/labels.py,sha256=TJ67Oe4mN1ZPiCAUvbJESCcO3EkAg-l_ehy-rWBWOd8,46745
32
+ risk/network/plotter/network.py,sha256=0VySlJ4n3tkHsOhVVSa3yiSppT8y1dmIwa-DhRn0tcM,14131
33
+ risk/network/plotter/plotter.py,sha256=KJ_7Ye98ha6mchEaNY8kT0qCHAiGWZUzPiI3RCI9Wx0,5975
34
+ risk/network/plotter/utils/colors.py,sha256=Pqa5pYZi8qdP9AsdXVY6u4a8sEKM3cF8gBP9TQwDTfI,19015
35
+ risk/network/plotter/utils/layout.py,sha256=OPqV8jzV9dpnOhYU4SYMSfsIXalVzESrlBSI_Y43OGU,3640
36
+ risk_network-0.0.12b1.dist-info/licenses/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
37
+ risk_network-0.0.12b1.dist-info/METADATA,sha256=Lyrx0dcjEsfc-hC8GS82asYFs-BSySsTI1UFhKdoX4A,6667
38
+ risk_network-0.0.12b1.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
39
+ risk_network-0.0.12b1.dist-info/top_level.txt,sha256=NX7C2PFKTvC1JhVKv14DFlFAIFnKc6Lpsu1ZfxvQwVw,5
40
+ risk_network-0.0.12b1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (76.0.0)
2
+ Generator: setuptools (79.0.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
risk/network/geometry.py DELETED
@@ -1,150 +0,0 @@
1
- """
2
- risk/network/geometry
3
- ~~~~~~~~~~~~~~~~~~~~~
4
- """
5
-
6
- import networkx as nx
7
- import numpy as np
8
-
9
-
10
- def assign_edge_lengths(
11
- G: nx.Graph,
12
- compute_sphere: bool = True,
13
- surface_depth: float = 0.0,
14
- ) -> nx.Graph:
15
- """Assign edge lengths in the graph, optionally mapping nodes to a sphere.
16
-
17
- Args:
18
- G (nx.Graph): The input graph.
19
- compute_sphere (bool): Whether to map nodes to a sphere. Defaults to True.
20
- surface_depth (float): The surface depth for mapping to a sphere. Defaults to 0.0.
21
-
22
- Returns:
23
- nx.Graph: The graph with applied edge lengths.
24
- """
25
-
26
- def compute_distance_vectorized(coords, is_sphere):
27
- """Compute distances between pairs of coordinates."""
28
- u_coords, v_coords = coords[:, 0, :], coords[:, 1, :]
29
- if is_sphere:
30
- u_coords /= np.linalg.norm(u_coords, axis=1, keepdims=True)
31
- v_coords /= np.linalg.norm(v_coords, axis=1, keepdims=True)
32
- dot_products = np.einsum("ij,ij->i", u_coords, v_coords)
33
- return np.arccos(np.clip(dot_products, -1.0, 1.0))
34
- return np.linalg.norm(u_coords - v_coords, axis=1)
35
-
36
- # Normalize graph coordinates
37
- _normalize_graph_coordinates(G)
38
-
39
- # Map nodes to sphere and adjust depth if required
40
- if compute_sphere:
41
- _map_to_sphere(G)
42
- G_depth = _create_depth(G, surface_depth=surface_depth)
43
- else:
44
- G_depth = G
45
-
46
- # Precompute edge coordinate arrays and compute distances in bulk
47
- edge_data = np.array(
48
- [
49
- [
50
- np.array(
51
- [G_depth.nodes[u]["x"], G_depth.nodes[u]["y"], G_depth.nodes[u].get("z", 0)]
52
- ),
53
- np.array(
54
- [G_depth.nodes[v]["x"], G_depth.nodes[v]["y"], G_depth.nodes[v].get("z", 0)]
55
- ),
56
- ]
57
- for u, v in G_depth.edges
58
- ]
59
- )
60
- # Compute distances
61
- distances = compute_distance_vectorized(edge_data, compute_sphere)
62
- # Assign distances back to the graph
63
- for (u, v), distance in zip(G_depth.edges, distances):
64
- G.edges[u, v]["length"] = distance
65
-
66
- return G
67
-
68
-
69
- def _map_to_sphere(G: nx.Graph) -> None:
70
- """Map the x and y coordinates of graph nodes onto a 3D sphere.
71
-
72
- Args:
73
- G (nx.Graph): The input graph with nodes having 'x' and 'y' coordinates.
74
- """
75
- # Extract x, y coordinates as a NumPy array
76
- nodes = list(G.nodes)
77
- xy_coords = np.array([[G.nodes[node]["x"], G.nodes[node]["y"]] for node in nodes])
78
- # Normalize coordinates between [0, 1]
79
- min_vals = xy_coords.min(axis=0)
80
- max_vals = xy_coords.max(axis=0)
81
- normalized_xy = (xy_coords - min_vals) / (max_vals - min_vals)
82
- # Convert normalized coordinates to spherical coordinates
83
- theta = normalized_xy[:, 0] * np.pi * 2
84
- phi = normalized_xy[:, 1] * np.pi
85
- # Compute 3D Cartesian coordinates
86
- x = np.sin(phi) * np.cos(theta)
87
- y = np.sin(phi) * np.sin(theta)
88
- z = np.cos(phi)
89
- # Assign coordinates back to graph nodes in bulk
90
- xyz_coords = {node: {"x": x[i], "y": y[i], "z": z[i]} for i, node in enumerate(nodes)}
91
- nx.set_node_attributes(G, xyz_coords)
92
-
93
-
94
- def _normalize_graph_coordinates(G: nx.Graph) -> None:
95
- """Normalize the x and y coordinates of the nodes in the graph to the [0, 1] range.
96
-
97
- Args:
98
- G (nx.Graph): The input graph with nodes having 'x' and 'y' coordinates.
99
- """
100
- # Extract x, y coordinates from the graph nodes
101
- xy_coords = np.array([[G.nodes[node]["x"], G.nodes[node]["y"]] for node in G.nodes()])
102
- # Calculate min and max values for x and y
103
- min_vals = np.min(xy_coords, axis=0)
104
- max_vals = np.max(xy_coords, axis=0)
105
- # Normalize the coordinates to [0, 1]
106
- normalized_xy = (xy_coords - min_vals) / (max_vals - min_vals)
107
- # Update the node coordinates with the normalized values
108
- for i, node in enumerate(G.nodes()):
109
- G.nodes[node]["x"], G.nodes[node]["y"] = normalized_xy[i]
110
-
111
-
112
- def _create_depth(G: nx.Graph, surface_depth: float = 0.0) -> nx.Graph:
113
- """Adjust the 'z' attribute of each node based on the subcluster strengths and normalized surface depth.
114
-
115
- Args:
116
- G (nx.Graph): The input graph.
117
- surface_depth (float): The maximum surface depth to apply for the strongest subcluster.
118
-
119
- Returns:
120
- nx.Graph: The graph with adjusted 'z' attribute for each node.
121
- """
122
- if surface_depth >= 1.0:
123
- surface_depth -= 1e-6 # Cap the surface depth to prevent a value of 1.0
124
-
125
- # Compute subclusters as connected components
126
- connected_components = list(nx.connected_components(G))
127
- subcluster_strengths = {}
128
- max_strength = 0
129
- # Precompute strengths and track the maximum strength
130
- for component in connected_components:
131
- size = len(component)
132
- max_strength = max(max_strength, size)
133
- for node in component:
134
- subcluster_strengths[node] = size
135
-
136
- # Avoid repeated lookups and computations by pre-fetching node data
137
- nodes = list(G.nodes(data=True))
138
- node_updates = {}
139
- for node, attrs in nodes:
140
- strength = subcluster_strengths[node]
141
- normalized_surface_depth = (strength / max_strength) * surface_depth
142
- x, y, z = attrs["x"], attrs["y"], attrs["z"]
143
- norm = np.sqrt(x**2 + y**2 + z**2)
144
- adjusted_z = z - (z / norm) * normalized_surface_depth
145
- node_updates[node] = {"z": adjusted_z}
146
-
147
- # Batch update node attributes
148
- nx.set_node_attributes(G, node_updates)
149
-
150
- return G
risk/stats/__init__.py DELETED
@@ -1,15 +0,0 @@
1
- """
2
- risk/stats
3
- ~~~~~~~~~~
4
- """
5
-
6
- from risk.stats.permutation import compute_permutation_test
7
- from risk.stats.stat_tests import (
8
- compute_binom_test,
9
- compute_chi2_test,
10
- compute_hypergeom_test,
11
- compute_poisson_test,
12
- compute_zscore_test,
13
- )
14
-
15
- from risk.stats.significance import calculate_significance_matrices
@@ -1,6 +0,0 @@
1
- """
2
- risk/stats/permutation
3
- ~~~~~~~~~~~~~~~~~~~~~~
4
- """
5
-
6
- from risk.stats.permutation.permutation import compute_permutation_test