risk-network 0.0.5b6__tar.gz → 0.0.6b1__tar.gz
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.
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/PKG-INFO +3 -4
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/README.md +2 -3
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/__init__.py +1 -1
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/annotations/io.py +15 -3
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/neighborhoods/community.py +7 -3
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/neighborhoods/neighborhoods.py +2 -2
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/network/io.py +30 -10
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/network/plot.py +343 -163
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/risk.py +6 -18
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk_network.egg-info/PKG-INFO +3 -4
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/LICENSE +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/MANIFEST.in +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/pyproject.toml +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/annotations/__init__.py +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/annotations/annotations.py +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/constants.py +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/log/__init__.py +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/log/console.py +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/log/params.py +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/neighborhoods/__init__.py +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/neighborhoods/domains.py +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/network/__init__.py +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/network/geometry.py +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/network/graph.py +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/stats/__init__.py +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/stats/fisher_exact.py +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/stats/hypergeom.py +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/stats/permutation/__init__.py +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/stats/permutation/permutation.py +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/stats/permutation/test_functions.py +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk/stats/stats.py +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk_network.egg-info/SOURCES.txt +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk_network.egg-info/dependency_links.txt +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk_network.egg-info/requires.txt +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/risk_network.egg-info/top_level.txt +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/setup.cfg +0 -0
- {risk_network-0.0.5b6 → risk_network-0.0.6b1}/setup.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: risk-network
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.6b1
|
4
4
|
Summary: A Python package for biological network analysis
|
5
5
|
Author: Ira Horecka
|
6
6
|
Author-email: Ira Horecka <ira89@icloud.com>
|
@@ -710,8 +710,7 @@ Requires-Dist: threadpoolctl
|
|
710
710
|
Requires-Dist: tqdm
|
711
711
|
|
712
712
|
<p align="center">
|
713
|
-
<img src="
|
714
|
-
<img src="./docs/github/risk-logo-light.png#gh-light-mode-only" width="400" />
|
713
|
+
<img src="https://i.imgur.com/Fo9EmnK.png" width="400" />
|
715
714
|
</p>
|
716
715
|
|
717
716
|
<p align="center">
|
@@ -736,7 +735,7 @@ RISK is a software tool for visualizing spatial relationships in networks. It ai
|
|
736
735
|
|
737
736
|
*Saccharomyces cerevisiae* proteins oriented by physical interactions discovered through affinity enrichment and mass spectrometry (Michaelis et al., 2023).
|
738
737
|
|
739
|
-

|
740
739
|
|
741
740
|
## Installation
|
742
741
|
|
@@ -1,6 +1,5 @@
|
|
1
1
|
<p align="center">
|
2
|
-
<img src="
|
3
|
-
<img src="./docs/github/risk-logo-light.png#gh-light-mode-only" width="400" />
|
2
|
+
<img src="https://i.imgur.com/Fo9EmnK.png" width="400" />
|
4
3
|
</p>
|
5
4
|
|
6
5
|
<p align="center">
|
@@ -25,7 +24,7 @@ RISK is a software tool for visualizing spatial relationships in networks. It ai
|
|
25
24
|
|
26
25
|
*Saccharomyces cerevisiae* proteins oriented by physical interactions discovered through affinity enrichment and mass spectrometry (Michaelis et al., 2023).
|
27
26
|
|
28
|
-

|
29
28
|
|
30
29
|
## Installation
|
31
30
|
|
@@ -36,13 +36,15 @@ class AnnotationsIO:
|
|
36
36
|
dict: A dictionary containing ordered nodes, ordered annotations, and the annotations matrix.
|
37
37
|
"""
|
38
38
|
filetype = "JSON"
|
39
|
+
# Log the loading of the JSON file
|
39
40
|
params.log_annotations(filepath=filepath, filetype=filetype)
|
40
41
|
_log_loading(filetype, filepath=filepath)
|
42
|
+
|
41
43
|
# Open and read the JSON file
|
42
44
|
with open(filepath, "r") as file:
|
43
45
|
annotations_input = json.load(file)
|
44
46
|
|
45
|
-
#
|
47
|
+
# Load the annotations into the provided network
|
46
48
|
return load_annotations(network, annotations_input)
|
47
49
|
|
48
50
|
def load_excel_annotation(
|
@@ -69,14 +71,18 @@ class AnnotationsIO:
|
|
69
71
|
linked to the provided network.
|
70
72
|
"""
|
71
73
|
filetype = "Excel"
|
74
|
+
# Log the loading of the Excel file
|
72
75
|
params.log_annotations(filepath=filepath, filetype=filetype)
|
73
76
|
_log_loading(filetype, filepath=filepath)
|
77
|
+
|
74
78
|
# Load the specified sheet from the Excel file
|
75
79
|
df = pd.read_excel(filepath, sheet_name=sheet_name)
|
76
80
|
# Split the nodes column by the specified nodes_delimiter
|
77
81
|
df[nodes_colname] = df[nodes_colname].apply(lambda x: x.split(nodes_delimiter))
|
78
82
|
# Convert the DataFrame to a dictionary pairing labels with their corresponding nodes
|
79
83
|
label_node_dict = df.set_index(label_colname)[nodes_colname].to_dict()
|
84
|
+
|
85
|
+
# Load the annotations into the provided network
|
80
86
|
return load_annotations(network, label_node_dict)
|
81
87
|
|
82
88
|
def load_csv_annotation(
|
@@ -101,13 +107,16 @@ class AnnotationsIO:
|
|
101
107
|
linked to the provided network.
|
102
108
|
"""
|
103
109
|
filetype = "CSV"
|
110
|
+
# Log the loading of the CSV file
|
104
111
|
params.log_annotations(filepath=filepath, filetype=filetype)
|
105
112
|
_log_loading(filetype, filepath=filepath)
|
113
|
+
|
106
114
|
# Load the CSV file into a dictionary
|
107
115
|
annotations_input = _load_matrix_file(
|
108
116
|
filepath, label_colname, nodes_colname, delimiter=",", nodes_delimiter=nodes_delimiter
|
109
117
|
)
|
110
|
-
|
118
|
+
|
119
|
+
# Load the annotations into the provided network
|
111
120
|
return load_annotations(network, annotations_input)
|
112
121
|
|
113
122
|
def load_tsv_annotation(
|
@@ -132,13 +141,16 @@ class AnnotationsIO:
|
|
132
141
|
linked to the provided network.
|
133
142
|
"""
|
134
143
|
filetype = "TSV"
|
144
|
+
# Log the loading of the TSV file
|
135
145
|
params.log_annotations(filepath=filepath, filetype=filetype)
|
136
146
|
_log_loading(filetype, filepath=filepath)
|
147
|
+
|
137
148
|
# Load the TSV file into a dictionary
|
138
149
|
annotations_input = _load_matrix_file(
|
139
150
|
filepath, label_colname, nodes_colname, delimiter="\t", nodes_delimiter=nodes_delimiter
|
140
151
|
)
|
141
|
-
|
152
|
+
|
153
|
+
# Load the annotations into the provided network
|
142
154
|
return load_annotations(network, annotations_input)
|
143
155
|
|
144
156
|
|
@@ -25,10 +25,14 @@ def calculate_dijkstra_neighborhoods(network: nx.Graph) -> np.ndarray:
|
|
25
25
|
|
26
26
|
# Populate the neighborhoods matrix based on Dijkstra's distances
|
27
27
|
for source, targets in all_dijkstra_paths.items():
|
28
|
+
max_length = max(targets.values()) if targets else 1 # Handle cases with no targets
|
28
29
|
for target, length in targets.items():
|
29
|
-
|
30
|
-
|
31
|
-
|
30
|
+
if np.isnan(length):
|
31
|
+
neighborhoods[source, target] = max_length # Use max distance for NaN
|
32
|
+
elif length == 0:
|
33
|
+
neighborhoods[source, target] = 1 # Assign 1 for zero-length paths (self-loops)
|
34
|
+
else:
|
35
|
+
neighborhoods[source, target] = 1 / length # Inverse of the distance
|
32
36
|
|
33
37
|
return neighborhoods
|
34
38
|
|
@@ -4,7 +4,7 @@ risk/neighborhoods/neighborhoods
|
|
4
4
|
"""
|
5
5
|
|
6
6
|
import warnings
|
7
|
-
from typing import Any, Dict, Tuple
|
7
|
+
from typing import Any, Dict, List, Tuple
|
8
8
|
|
9
9
|
import networkx as nx
|
10
10
|
import numpy as np
|
@@ -305,7 +305,7 @@ def _get_node_position(network: nx.Graph, node: Any) -> np.ndarray:
|
|
305
305
|
)
|
306
306
|
|
307
307
|
|
308
|
-
def _calculate_threshold(average_distances:
|
308
|
+
def _calculate_threshold(average_distances: List, distance_threshold: float) -> float:
|
309
309
|
"""Calculate the distance threshold based on the given average distances and a percentile threshold.
|
310
310
|
|
311
311
|
Args:
|
@@ -48,6 +48,7 @@ class NetworkIO:
|
|
48
48
|
self.min_edges_per_node = min_edges_per_node
|
49
49
|
self.include_edge_weight = include_edge_weight
|
50
50
|
self.weight_label = weight_label
|
51
|
+
# Log the initialization of the NetworkIO class
|
51
52
|
params.log_network(
|
52
53
|
compute_sphere=compute_sphere,
|
53
54
|
surface_depth=surface_depth,
|
@@ -98,11 +99,14 @@ class NetworkIO:
|
|
98
99
|
nx.Graph: Loaded and processed network.
|
99
100
|
"""
|
100
101
|
filetype = "GPickle"
|
102
|
+
# Log the loading of the GPickle file
|
101
103
|
params.log_network(filetype=filetype, filepath=filepath)
|
102
104
|
self._log_loading(filetype, filepath=filepath)
|
105
|
+
|
103
106
|
with open(filepath, "rb") as f:
|
104
107
|
G = pickle.load(f)
|
105
108
|
|
109
|
+
# Initialize the graph
|
106
110
|
return self._initialize_graph(G)
|
107
111
|
|
108
112
|
@classmethod
|
@@ -147,8 +151,11 @@ class NetworkIO:
|
|
147
151
|
nx.Graph: Processed network.
|
148
152
|
"""
|
149
153
|
filetype = "NetworkX"
|
154
|
+
# Log the loading of the NetworkX graph
|
150
155
|
params.log_network(filetype=filetype)
|
151
156
|
self._log_loading(filetype)
|
157
|
+
|
158
|
+
# Initialize the graph
|
152
159
|
return self._initialize_graph(network)
|
153
160
|
|
154
161
|
@classmethod
|
@@ -213,8 +220,10 @@ class NetworkIO:
|
|
213
220
|
nx.Graph: Loaded and processed network.
|
214
221
|
"""
|
215
222
|
filetype = "Cytoscape"
|
223
|
+
# Log the loading of the Cytoscape file
|
216
224
|
params.log_network(filetype=filetype, filepath=str(filepath))
|
217
225
|
self._log_loading(filetype, filepath=filepath)
|
226
|
+
|
218
227
|
cys_files = []
|
219
228
|
tmp_dir = ".tmp_cytoscape"
|
220
229
|
# Try / finally to remove unzipped files
|
@@ -295,6 +304,7 @@ class NetworkIO:
|
|
295
304
|
node
|
296
305
|
] # Assuming you have a dict `node_y_positions` for y coordinates
|
297
306
|
|
307
|
+
# Initialize the graph
|
298
308
|
return self._initialize_graph(G)
|
299
309
|
|
300
310
|
finally:
|
@@ -354,6 +364,7 @@ class NetworkIO:
|
|
354
364
|
NetworkX graph: Loaded and processed network.
|
355
365
|
"""
|
356
366
|
filetype = "Cytoscape JSON"
|
367
|
+
# Log the loading of the Cytoscape JSON file
|
357
368
|
params.log_network(filetype=filetype, filepath=str(filepath))
|
358
369
|
self._log_loading(filetype, filepath=filepath)
|
359
370
|
|
@@ -418,29 +429,37 @@ class NetworkIO:
|
|
418
429
|
return G
|
419
430
|
|
420
431
|
def _remove_invalid_graph_properties(self, G: nx.Graph) -> None:
|
421
|
-
"""Remove invalid properties from the graph
|
432
|
+
"""Remove invalid properties from the graph, including self-loops, nodes with fewer edges than
|
433
|
+
the threshold, and isolated nodes.
|
422
434
|
|
423
435
|
Args:
|
424
436
|
G (nx.Graph): A NetworkX graph object.
|
425
437
|
"""
|
426
|
-
#
|
438
|
+
# Count number of nodes and edges before cleaning
|
439
|
+
num_initial_nodes = G.number_of_nodes()
|
440
|
+
num_initial_edges = G.number_of_edges()
|
441
|
+
# Remove self-loops to ensure correct edge count
|
427
442
|
G.remove_edges_from(list(nx.selfloop_edges(G)))
|
428
|
-
#
|
443
|
+
# Iteratively remove nodes with fewer edges than the threshold
|
429
444
|
while True:
|
430
|
-
nodes_to_remove = [
|
431
|
-
node for node in G.nodes() if G.degree(node) < self.min_edges_per_node
|
432
|
-
]
|
445
|
+
nodes_to_remove = [node for node in G.nodes if G.degree(node) < self.min_edges_per_node]
|
433
446
|
if not nodes_to_remove:
|
434
|
-
break # Exit loop if no more nodes
|
435
|
-
|
436
|
-
# Remove the nodes and their associated edges
|
447
|
+
break # Exit loop if no more nodes need removal
|
437
448
|
G.remove_nodes_from(nodes_to_remove)
|
438
449
|
|
439
|
-
#
|
450
|
+
# Remove isolated nodes
|
440
451
|
isolated_nodes = list(nx.isolates(G))
|
441
452
|
if isolated_nodes:
|
442
453
|
G.remove_nodes_from(isolated_nodes)
|
443
454
|
|
455
|
+
# Log the number of nodes and edges before and after cleaning
|
456
|
+
num_final_nodes = G.number_of_nodes()
|
457
|
+
num_final_edges = G.number_of_edges()
|
458
|
+
print(f"Initial node count: {num_initial_nodes}")
|
459
|
+
print(f"Final node count: {num_final_nodes}")
|
460
|
+
print(f"Initial edge count: {num_initial_edges}")
|
461
|
+
print(f"Final edge count: {num_final_edges}")
|
462
|
+
|
444
463
|
def _assign_edge_weights(self, G: nx.Graph) -> None:
|
445
464
|
"""Assign weights to the edges in the graph.
|
446
465
|
|
@@ -502,6 +521,7 @@ class NetworkIO:
|
|
502
521
|
print(f"Edge weight: {'Included' if self.include_edge_weight else 'Excluded'}")
|
503
522
|
if self.include_edge_weight:
|
504
523
|
print(f"Weight label: {self.weight_label}")
|
524
|
+
print(f"Minimum edges per node: {self.min_edges_per_node}")
|
505
525
|
print(f"Projection: {'Sphere' if self.compute_sphere else 'Plane'}")
|
506
526
|
if self.compute_sphere:
|
507
527
|
print(f"Surface depth: {self.surface_depth}")
|