risk-network 0.0.3b3__py3-none-any.whl → 0.0.4__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.
- risk/__init__.py +1 -4
- risk/annotations/annotations.py +4 -2
- risk/annotations/io.py +1 -1
- risk/neighborhoods/neighborhoods.py +15 -2
- risk/network/geometry.py +2 -2
- risk/network/graph.py +4 -4
- risk/network/io.py +234 -53
- risk/network/plot.py +179 -58
- risk/risk.py +187 -75
- risk/stats/__init__.py +4 -1
- risk/stats/fisher_exact.py +132 -0
- risk/stats/hypergeom.py +131 -0
- risk/stats/permutation/__init__.py +6 -0
- risk/stats/permutation/permutation.py +212 -0
- risk/stats/{permutation.py → permutation/test_functions.py} +12 -39
- risk/stats/stats.py +1 -210
- {risk_network-0.0.3b3.dist-info → risk_network-0.0.4.dist-info}/METADATA +6 -6
- risk_network-0.0.4.dist-info/RECORD +30 -0
- {risk_network-0.0.3b3.dist-info → risk_network-0.0.4.dist-info}/WHEEL +1 -1
- risk_network-0.0.3b3.dist-info/RECORD +0 -26
- {risk_network-0.0.3b3.dist-info → risk_network-0.0.4.dist-info}/LICENSE +0 -0
- {risk_network-0.0.3b3.dist-info → risk_network-0.0.4.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,212 @@
|
|
1
|
+
"""
|
2
|
+
risk/stats/permutation/permutation
|
3
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
4
|
+
"""
|
5
|
+
|
6
|
+
from multiprocessing import get_context, Manager
|
7
|
+
from tqdm import tqdm
|
8
|
+
from typing import Any, Callable, Dict
|
9
|
+
|
10
|
+
import numpy as np
|
11
|
+
from threadpoolctl import threadpool_limits
|
12
|
+
|
13
|
+
from risk.stats.permutation.test_functions import DISPATCH_TEST_FUNCTIONS
|
14
|
+
|
15
|
+
|
16
|
+
def compute_permutation_test(
|
17
|
+
neighborhoods: np.ndarray,
|
18
|
+
annotations: np.ndarray,
|
19
|
+
score_metric: str = "sum",
|
20
|
+
null_distribution: str = "network",
|
21
|
+
num_permutations: int = 1000,
|
22
|
+
random_seed: int = 888,
|
23
|
+
max_workers: int = 1,
|
24
|
+
) -> Dict[str, Any]:
|
25
|
+
"""Compute permutation test for enrichment and depletion in neighborhoods.
|
26
|
+
|
27
|
+
Args:
|
28
|
+
neighborhoods (np.ndarray): Binary matrix representing neighborhoods.
|
29
|
+
annotations (np.ndarray): Binary matrix representing annotations.
|
30
|
+
score_metric (str, optional): Metric to use for scoring ('sum', 'mean', etc.). Defaults to "sum".
|
31
|
+
null_distribution (str, optional): Type of null distribution ('network' or other). Defaults to "network".
|
32
|
+
num_permutations (int, optional): Number of permutations to run. Defaults to 1000.
|
33
|
+
random_seed (int, optional): Seed for random number generation. Defaults to 888.
|
34
|
+
max_workers (int, optional): Number of workers for multiprocessing. Defaults to 1.
|
35
|
+
|
36
|
+
Returns:
|
37
|
+
dict: Dictionary containing depletion and enrichment p-values.
|
38
|
+
"""
|
39
|
+
# Ensure that the matrices are in the correct format and free of NaN values
|
40
|
+
neighborhoods = neighborhoods.astype(np.float32)
|
41
|
+
annotations = annotations.astype(np.float32)
|
42
|
+
# Retrieve the appropriate neighborhood score function based on the metric
|
43
|
+
neighborhood_score_func = DISPATCH_TEST_FUNCTIONS[score_metric]
|
44
|
+
|
45
|
+
# Run the permutation test to calculate depletion and enrichment counts
|
46
|
+
counts_depletion, counts_enrichment = _run_permutation_test(
|
47
|
+
neighborhoods=neighborhoods,
|
48
|
+
annotations=annotations,
|
49
|
+
neighborhood_score_func=neighborhood_score_func,
|
50
|
+
null_distribution=null_distribution,
|
51
|
+
num_permutations=num_permutations,
|
52
|
+
random_seed=random_seed,
|
53
|
+
max_workers=max_workers,
|
54
|
+
)
|
55
|
+
# Compute p-values for depletion and enrichment
|
56
|
+
# If counts are 0, set p-value to 1/num_permutations to avoid zero p-values
|
57
|
+
depletion_pvals = np.maximum(counts_depletion, 1) / num_permutations
|
58
|
+
enrichment_pvals = np.maximum(counts_enrichment, 1) / num_permutations
|
59
|
+
|
60
|
+
return {
|
61
|
+
"depletion_pvals": depletion_pvals,
|
62
|
+
"enrichment_pvals": enrichment_pvals,
|
63
|
+
}
|
64
|
+
|
65
|
+
|
66
|
+
def _run_permutation_test(
|
67
|
+
neighborhoods: np.ndarray,
|
68
|
+
annotations: np.ndarray,
|
69
|
+
neighborhood_score_func: Callable,
|
70
|
+
null_distribution: str = "network",
|
71
|
+
num_permutations: int = 1000,
|
72
|
+
random_seed: int = 888,
|
73
|
+
max_workers: int = 4,
|
74
|
+
) -> tuple:
|
75
|
+
"""Run a permutation test to calculate enrichment and depletion counts.
|
76
|
+
|
77
|
+
Args:
|
78
|
+
neighborhoods (np.ndarray): The neighborhood matrix.
|
79
|
+
annotations (np.ndarray): The annotation matrix.
|
80
|
+
neighborhood_score_func (Callable): Function to calculate neighborhood scores.
|
81
|
+
null_distribution (str, optional): Type of null distribution. Defaults to "network".
|
82
|
+
num_permutations (int, optional): Number of permutations. Defaults to 1000.
|
83
|
+
random_seed (int, optional): Seed for random number generation. Defaults to 888.
|
84
|
+
max_workers (int, optional): Number of workers for multiprocessing. Defaults to 4.
|
85
|
+
|
86
|
+
Returns:
|
87
|
+
tuple: Depletion and enrichment counts.
|
88
|
+
"""
|
89
|
+
# Initialize the RNG for reproducibility
|
90
|
+
rng = np.random.default_rng(seed=random_seed)
|
91
|
+
# Determine the indices to use based on the null distribution type
|
92
|
+
if null_distribution == "network":
|
93
|
+
idxs = range(annotations.shape[0])
|
94
|
+
else:
|
95
|
+
idxs = np.nonzero(np.sum(~np.isnan(annotations), axis=1))[0]
|
96
|
+
|
97
|
+
# Replace NaNs with zeros in the annotations matrix
|
98
|
+
annotations[np.isnan(annotations)] = 0
|
99
|
+
annotation_matrix_obsv = annotations[idxs]
|
100
|
+
neighborhoods_matrix_obsv = neighborhoods.T[idxs].T
|
101
|
+
# Calculate observed neighborhood scores
|
102
|
+
with np.errstate(invalid="ignore", divide="ignore"):
|
103
|
+
observed_neighborhood_scores = neighborhood_score_func(
|
104
|
+
neighborhoods_matrix_obsv, annotation_matrix_obsv
|
105
|
+
)
|
106
|
+
|
107
|
+
# Initialize count matrices for depletion and enrichment
|
108
|
+
counts_depletion = np.zeros(observed_neighborhood_scores.shape)
|
109
|
+
counts_enrichment = np.zeros(observed_neighborhood_scores.shape)
|
110
|
+
|
111
|
+
# Determine the number of permutations to run in each worker process
|
112
|
+
subset_size = num_permutations // max_workers
|
113
|
+
remainder = num_permutations % max_workers
|
114
|
+
|
115
|
+
# Use the spawn context for creating a new multiprocessing pool
|
116
|
+
ctx = get_context("spawn")
|
117
|
+
manager = Manager()
|
118
|
+
progress_counter = manager.Value("i", 0)
|
119
|
+
total_progress = num_permutations
|
120
|
+
|
121
|
+
# Execute the permutation test using multiprocessing
|
122
|
+
with ctx.Pool(max_workers) as pool:
|
123
|
+
with tqdm(total=total_progress, desc="Total progress", position=0) as progress:
|
124
|
+
# Prepare parameters for multiprocessing
|
125
|
+
params_list = [
|
126
|
+
(
|
127
|
+
annotations,
|
128
|
+
np.array(idxs),
|
129
|
+
neighborhoods_matrix_obsv,
|
130
|
+
observed_neighborhood_scores,
|
131
|
+
neighborhood_score_func,
|
132
|
+
subset_size + (1 if i < remainder else 0),
|
133
|
+
progress_counter,
|
134
|
+
rng, # Pass the RNG to each process
|
135
|
+
)
|
136
|
+
for i in range(max_workers)
|
137
|
+
]
|
138
|
+
|
139
|
+
# Start the permutation process in parallel
|
140
|
+
results = pool.starmap_async(_permutation_process_subset, params_list, chunksize=1)
|
141
|
+
|
142
|
+
# Update progress bar based on progress_counter
|
143
|
+
# NOTE: Waiting for results to be ready while updating progress bar gives a big improvement
|
144
|
+
# in performance, especially for large number of permutations and workers
|
145
|
+
while not results.ready():
|
146
|
+
progress.update(progress_counter.value - progress.n)
|
147
|
+
results.wait(0.05) # Wait for 50ms
|
148
|
+
# Ensure progress bar reaches 100%
|
149
|
+
progress.update(total_progress - progress.n)
|
150
|
+
|
151
|
+
# Accumulate results from each worker
|
152
|
+
for local_counts_depletion, local_counts_enrichment in results.get():
|
153
|
+
counts_depletion = np.add(counts_depletion, local_counts_depletion)
|
154
|
+
counts_enrichment = np.add(counts_enrichment, local_counts_enrichment)
|
155
|
+
|
156
|
+
return counts_depletion, counts_enrichment
|
157
|
+
|
158
|
+
|
159
|
+
def _permutation_process_subset(
|
160
|
+
annotation_matrix: np.ndarray,
|
161
|
+
idxs: np.ndarray,
|
162
|
+
neighborhoods_matrix_obsv: np.ndarray,
|
163
|
+
observed_neighborhood_scores: np.ndarray,
|
164
|
+
neighborhood_score_func: Callable,
|
165
|
+
subset_size: int,
|
166
|
+
progress_counter,
|
167
|
+
rng: np.random.Generator,
|
168
|
+
) -> tuple:
|
169
|
+
"""Process a subset of permutations for the permutation test.
|
170
|
+
|
171
|
+
Args:
|
172
|
+
annotation_matrix (np.ndarray): The annotation matrix.
|
173
|
+
idxs (np.ndarray): Indices of valid rows in the matrix.
|
174
|
+
neighborhoods_matrix_obsv (np.ndarray): Observed neighborhoods matrix.
|
175
|
+
observed_neighborhood_scores (np.ndarray): Observed neighborhood scores.
|
176
|
+
neighborhood_score_func (Callable): Function to calculate neighborhood scores.
|
177
|
+
subset_size (int): Number of permutations to run in this subset.
|
178
|
+
progress_counter: Shared counter for tracking progress.
|
179
|
+
rng (np.random.Generator): Random number generator object.
|
180
|
+
|
181
|
+
Returns:
|
182
|
+
tuple: Local counts of depletion and enrichment.
|
183
|
+
"""
|
184
|
+
# Initialize local count matrices for this worker
|
185
|
+
local_counts_depletion = np.zeros(observed_neighborhood_scores.shape)
|
186
|
+
local_counts_enrichment = np.zeros(observed_neighborhood_scores.shape)
|
187
|
+
# NOTE: Limit the number of threads used by NumPy's BLAS implementation to 1.
|
188
|
+
# This can help prevent oversubscription of CPU resources during multiprocessing,
|
189
|
+
# ensuring that each process doesn't use more than one CPU core.
|
190
|
+
with threadpool_limits(limits=1, user_api="blas"):
|
191
|
+
for _ in range(subset_size):
|
192
|
+
# Permute the annotation matrix using the RNG
|
193
|
+
annotation_matrix_permut = annotation_matrix[rng.permutation(idxs)]
|
194
|
+
# Calculate permuted neighborhood scores
|
195
|
+
with np.errstate(invalid="ignore", divide="ignore"):
|
196
|
+
permuted_neighborhood_scores = neighborhood_score_func(
|
197
|
+
neighborhoods_matrix_obsv, annotation_matrix_permut
|
198
|
+
)
|
199
|
+
|
200
|
+
# Update local depletion and enrichment counts based on permuted scores
|
201
|
+
local_counts_depletion = np.add(
|
202
|
+
local_counts_depletion, permuted_neighborhood_scores <= observed_neighborhood_scores
|
203
|
+
)
|
204
|
+
local_counts_enrichment = np.add(
|
205
|
+
local_counts_enrichment,
|
206
|
+
permuted_neighborhood_scores >= observed_neighborhood_scores,
|
207
|
+
)
|
208
|
+
|
209
|
+
# Update the shared progress counter
|
210
|
+
progress_counter.value += 1
|
211
|
+
|
212
|
+
return local_counts_depletion, local_counts_enrichment
|
@@ -1,12 +1,13 @@
|
|
1
1
|
"""
|
2
|
-
risk/stats/permutation
|
3
|
-
|
2
|
+
risk/stats/permutation/test_function
|
3
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
4
4
|
"""
|
5
5
|
|
6
6
|
import numpy as np
|
7
7
|
|
8
8
|
# Note: Cython optimizations provided minimal performance benefits.
|
9
9
|
# The final version with Cython is archived in the `cython_permutation` branch.
|
10
|
+
# DISPATCH_TEST_FUNCTIONS can be found at the end of the file.
|
10
11
|
|
11
12
|
|
12
13
|
def compute_neighborhood_score_by_sum(
|
@@ -22,8 +23,8 @@ def compute_neighborhood_score_by_sum(
|
|
22
23
|
np.ndarray: Sum of attribute values for each neighborhood.
|
23
24
|
"""
|
24
25
|
# Calculate the neighborhood score as the dot product of neighborhoods and annotations
|
25
|
-
|
26
|
-
return
|
26
|
+
neighborhood_sum = np.dot(neighborhoods_matrix, annotation_matrix)
|
27
|
+
return neighborhood_sum
|
27
28
|
|
28
29
|
|
29
30
|
def compute_neighborhood_score_by_stdev(
|
@@ -49,40 +50,12 @@ def compute_neighborhood_score_by_stdev(
|
|
49
50
|
# Calculate variance as EXX - M^2
|
50
51
|
variance = EXX - M**2
|
51
52
|
# Compute the standard deviation as the square root of the variance
|
52
|
-
|
53
|
-
return
|
54
|
-
|
55
|
-
|
56
|
-
def compute_neighborhood_score_by_z_score(
|
57
|
-
neighborhoods_matrix: np.ndarray, annotation_matrix: np.ndarray
|
58
|
-
) -> np.ndarray:
|
59
|
-
"""Compute Z-scores for neighborhood scores.
|
60
|
-
|
61
|
-
Args:
|
62
|
-
neighborhoods_matrix (np.ndarray): Binary matrix representing neighborhoods.
|
63
|
-
annotation_matrix (np.ndarray): Matrix representing annotation values.
|
53
|
+
neighborhood_stdev = np.sqrt(variance)
|
54
|
+
return neighborhood_stdev
|
64
55
|
|
65
|
-
Returns:
|
66
|
-
np.ndarray: Z-scores for each neighborhood.
|
67
|
-
"""
|
68
|
-
# Calculate the neighborhood score as the dot product of neighborhoods and annotations
|
69
|
-
neighborhood_score = np.dot(neighborhoods_matrix, annotation_matrix)
|
70
|
-
# Calculate the number of elements in each neighborhood
|
71
|
-
N = np.dot(
|
72
|
-
neighborhoods_matrix, np.ones(annotation_matrix.shape[1], dtype=annotation_matrix.dtype)
|
73
|
-
)
|
74
|
-
# Compute the mean of the neighborhood scores
|
75
|
-
M = neighborhood_score / N
|
76
|
-
# Compute the mean of squares (EXX)
|
77
|
-
EXX = np.dot(neighborhoods_matrix, annotation_matrix**2) / N
|
78
|
-
# Calculate the standard deviation for each neighborhood
|
79
|
-
variance = EXX - M**2
|
80
|
-
std = np.sqrt(variance)
|
81
|
-
# Calculate Z-scores, handling cases where std is 0 or N is less than 3
|
82
|
-
with np.errstate(divide="ignore", invalid="ignore"):
|
83
|
-
z_scores = M / std
|
84
|
-
z_scores[(std == 0) | (N < 3)] = (
|
85
|
-
np.nan
|
86
|
-
) # Handle division by zero and apply minimum threshold
|
87
56
|
|
88
|
-
|
57
|
+
# Dictionary to dispatch statistical test functions based on the score metric
|
58
|
+
DISPATCH_TEST_FUNCTIONS = {
|
59
|
+
"sum": compute_neighborhood_score_by_sum,
|
60
|
+
"stdev": compute_neighborhood_score_by_stdev,
|
61
|
+
}
|
risk/stats/stats.py
CHANGED
@@ -3,219 +3,10 @@ risk/stats/stats
|
|
3
3
|
~~~~~~~~~~~~~~~~
|
4
4
|
"""
|
5
5
|
|
6
|
-
from
|
7
|
-
from tqdm import tqdm
|
8
|
-
from typing import Any, Callable, Dict, Union
|
6
|
+
from typing import Union
|
9
7
|
|
10
8
|
import numpy as np
|
11
9
|
from statsmodels.stats.multitest import fdrcorrection
|
12
|
-
from threadpoolctl import threadpool_limits
|
13
|
-
|
14
|
-
from risk.stats.permutation import (
|
15
|
-
compute_neighborhood_score_by_sum,
|
16
|
-
compute_neighborhood_score_by_stdev,
|
17
|
-
compute_neighborhood_score_by_z_score,
|
18
|
-
)
|
19
|
-
|
20
|
-
DISPATCH_PERMUTATION_TABLE = {
|
21
|
-
"sum": compute_neighborhood_score_by_sum,
|
22
|
-
"stdev": compute_neighborhood_score_by_stdev,
|
23
|
-
"z_score": compute_neighborhood_score_by_z_score,
|
24
|
-
}
|
25
|
-
|
26
|
-
|
27
|
-
def compute_permutation(
|
28
|
-
neighborhoods: np.ndarray,
|
29
|
-
annotations: np.ndarray,
|
30
|
-
score_metric: str = "sum",
|
31
|
-
null_distribution: str = "network",
|
32
|
-
num_permutations: int = 1000,
|
33
|
-
random_seed: int = 888,
|
34
|
-
max_workers: int = 1,
|
35
|
-
) -> Dict[str, Any]:
|
36
|
-
"""Compute permutation test for enrichment and depletion in neighborhoods.
|
37
|
-
|
38
|
-
Args:
|
39
|
-
neighborhoods (np.ndarray): Binary matrix representing neighborhoods.
|
40
|
-
annotations (np.ndarray): Binary matrix representing annotations.
|
41
|
-
score_metric (str, optional): Metric to use for scoring ('sum', 'mean', etc.). Defaults to "sum".
|
42
|
-
null_distribution (str, optional): Type of null distribution ('network' or other). Defaults to "network".
|
43
|
-
num_permutations (int, optional): Number of permutations to run. Defaults to 1000.
|
44
|
-
random_seed (int, optional): Seed for random number generation. Defaults to 888.
|
45
|
-
max_workers (int, optional): Number of workers for multiprocessing. Defaults to 1.
|
46
|
-
|
47
|
-
Returns:
|
48
|
-
dict: Dictionary containing depletion and enrichment p-values.
|
49
|
-
"""
|
50
|
-
# Ensure that the matrices are in the correct format and free of NaN values
|
51
|
-
neighborhoods = neighborhoods.astype(np.float32)
|
52
|
-
annotations = annotations.astype(np.float32)
|
53
|
-
# Retrieve the appropriate neighborhood score function based on the metric
|
54
|
-
neighborhood_score_func = DISPATCH_PERMUTATION_TABLE[score_metric]
|
55
|
-
|
56
|
-
# Run the permutation test to calculate depletion and enrichment counts
|
57
|
-
counts_depletion, counts_enrichment = _run_permutation_test(
|
58
|
-
neighborhoods=neighborhoods,
|
59
|
-
annotations=annotations,
|
60
|
-
neighborhood_score_func=neighborhood_score_func,
|
61
|
-
null_distribution=null_distribution,
|
62
|
-
num_permutations=num_permutations,
|
63
|
-
random_seed=random_seed,
|
64
|
-
max_workers=max_workers,
|
65
|
-
)
|
66
|
-
|
67
|
-
# Compute p-values for depletion and enrichment
|
68
|
-
# If counts are 0, set p-value to 1/num_permutations to avoid zero p-values
|
69
|
-
depletion_pvals = np.maximum(counts_depletion, 1) / num_permutations
|
70
|
-
enrichment_pvals = np.maximum(counts_enrichment, 1) / num_permutations
|
71
|
-
|
72
|
-
return {
|
73
|
-
"depletion_pvals": depletion_pvals,
|
74
|
-
"enrichment_pvals": enrichment_pvals,
|
75
|
-
}
|
76
|
-
|
77
|
-
|
78
|
-
def _run_permutation_test(
|
79
|
-
neighborhoods: np.ndarray,
|
80
|
-
annotations: np.ndarray,
|
81
|
-
neighborhood_score_func: Callable,
|
82
|
-
null_distribution: str = "network",
|
83
|
-
num_permutations: int = 1000,
|
84
|
-
random_seed: int = 888,
|
85
|
-
max_workers: int = 4,
|
86
|
-
) -> tuple:
|
87
|
-
"""Run a permutation test to calculate enrichment and depletion counts.
|
88
|
-
|
89
|
-
Args:
|
90
|
-
neighborhoods (np.ndarray): The neighborhood matrix.
|
91
|
-
annotations (np.ndarray): The annotation matrix.
|
92
|
-
neighborhood_score_func (Callable): Function to calculate neighborhood scores.
|
93
|
-
null_distribution (str, optional): Type of null distribution. Defaults to "network".
|
94
|
-
num_permutations (int, optional): Number of permutations. Defaults to 1000.
|
95
|
-
random_seed (int, optional): Seed for random number generation. Defaults to 888.
|
96
|
-
max_workers (int, optional): Number of workers for multiprocessing. Defaults to 4.
|
97
|
-
|
98
|
-
Returns:
|
99
|
-
tuple: Depletion and enrichment counts.
|
100
|
-
"""
|
101
|
-
# Set the random seed for reproducibility
|
102
|
-
np.random.seed(random_seed)
|
103
|
-
|
104
|
-
# Determine the indices to use based on the null distribution type
|
105
|
-
if null_distribution == "network":
|
106
|
-
idxs = range(annotations.shape[0])
|
107
|
-
else:
|
108
|
-
idxs = np.nonzero(np.sum(~np.isnan(annotations), axis=1))[0]
|
109
|
-
|
110
|
-
# Replace NaNs with zeros in the annotations matrix
|
111
|
-
annotations[np.isnan(annotations)] = 0
|
112
|
-
annotation_matrix_obsv = annotations[idxs]
|
113
|
-
neighborhoods_matrix_obsv = neighborhoods.T[idxs].T
|
114
|
-
|
115
|
-
# Calculate observed neighborhood scores
|
116
|
-
with np.errstate(invalid="ignore", divide="ignore"):
|
117
|
-
observed_neighborhood_scores = neighborhood_score_func(
|
118
|
-
neighborhoods_matrix_obsv, annotation_matrix_obsv
|
119
|
-
)
|
120
|
-
|
121
|
-
# Initialize count matrices for depletion and enrichment
|
122
|
-
counts_depletion = np.zeros(observed_neighborhood_scores.shape)
|
123
|
-
counts_enrichment = np.zeros(observed_neighborhood_scores.shape)
|
124
|
-
|
125
|
-
# Determine the number of permutations to run in each worker process
|
126
|
-
subset_size = num_permutations // max_workers
|
127
|
-
remainder = num_permutations % max_workers
|
128
|
-
|
129
|
-
# Use the spawn context for creating a new multiprocessing pool
|
130
|
-
ctx = get_context("spawn")
|
131
|
-
manager = Manager()
|
132
|
-
progress_counter = manager.Value("i", 0)
|
133
|
-
total_progress = num_permutations
|
134
|
-
|
135
|
-
# Execute the permutation test using multiprocessing
|
136
|
-
with ctx.Pool(max_workers) as pool:
|
137
|
-
with tqdm(total=total_progress, desc="Total progress", position=0) as progress:
|
138
|
-
# Prepare parameters for multiprocessing
|
139
|
-
params_list = [
|
140
|
-
(
|
141
|
-
annotations,
|
142
|
-
np.array(idxs),
|
143
|
-
neighborhoods_matrix_obsv,
|
144
|
-
observed_neighborhood_scores,
|
145
|
-
neighborhood_score_func,
|
146
|
-
subset_size + (1 if i < remainder else 0),
|
147
|
-
progress_counter,
|
148
|
-
)
|
149
|
-
for i in range(max_workers)
|
150
|
-
]
|
151
|
-
|
152
|
-
# Start the permutation process in parallel
|
153
|
-
results = pool.starmap_async(_permutation_process_subset, params_list)
|
154
|
-
|
155
|
-
# Update progress bar based on progress_counter
|
156
|
-
while not results.ready():
|
157
|
-
progress.update(progress_counter.value - progress.n)
|
158
|
-
results.wait(0.1)
|
159
|
-
|
160
|
-
# Ensure progress bar reaches 100%
|
161
|
-
progress.update(total_progress - progress.n)
|
162
|
-
|
163
|
-
# Accumulate results from each worker
|
164
|
-
for local_counts_depletion, local_counts_enrichment in results.get():
|
165
|
-
counts_depletion = np.add(counts_depletion, local_counts_depletion)
|
166
|
-
counts_enrichment = np.add(counts_enrichment, local_counts_enrichment)
|
167
|
-
|
168
|
-
return counts_depletion, counts_enrichment
|
169
|
-
|
170
|
-
|
171
|
-
def _permutation_process_subset(
|
172
|
-
annotation_matrix: np.ndarray,
|
173
|
-
idxs: np.ndarray,
|
174
|
-
neighborhoods_matrix_obsv: np.ndarray,
|
175
|
-
observed_neighborhood_scores: np.ndarray,
|
176
|
-
neighborhood_score_func: Callable,
|
177
|
-
subset_size: int,
|
178
|
-
progress_counter,
|
179
|
-
) -> tuple:
|
180
|
-
"""Process a subset of permutations for the permutation test.
|
181
|
-
|
182
|
-
Args:
|
183
|
-
annotation_matrix (np.ndarray): The annotation matrix.
|
184
|
-
idxs (np.ndarray): Indices of valid rows in the matrix.
|
185
|
-
neighborhoods_matrix_obsv (np.ndarray): Observed neighborhoods matrix.
|
186
|
-
observed_neighborhood_scores (np.ndarray): Observed neighborhood scores.
|
187
|
-
neighborhood_score_func (Callable): Function to calculate neighborhood scores.
|
188
|
-
subset_size (int): Number of permutations to run in this subset.
|
189
|
-
progress_counter: Shared counter for tracking progress.
|
190
|
-
|
191
|
-
Returns:
|
192
|
-
tuple: Local counts of depletion and enrichment.
|
193
|
-
"""
|
194
|
-
# Initialize local count matrices for this worker
|
195
|
-
local_counts_depletion = np.zeros(observed_neighborhood_scores.shape)
|
196
|
-
local_counts_enrichment = np.zeros(observed_neighborhood_scores.shape)
|
197
|
-
|
198
|
-
with threadpool_limits(limits=1, user_api="blas"):
|
199
|
-
for _ in range(subset_size):
|
200
|
-
# Permute the annotation matrix
|
201
|
-
annotation_matrix_permut = annotation_matrix[np.random.permutation(idxs)]
|
202
|
-
# Calculate permuted neighborhood scores
|
203
|
-
with np.errstate(invalid="ignore", divide="ignore"):
|
204
|
-
permuted_neighborhood_scores = neighborhood_score_func(
|
205
|
-
neighborhoods_matrix_obsv, annotation_matrix_permut
|
206
|
-
)
|
207
|
-
# Update local depletion and enrichment counts based on permuted scores
|
208
|
-
local_counts_depletion = np.add(
|
209
|
-
local_counts_depletion, permuted_neighborhood_scores <= observed_neighborhood_scores
|
210
|
-
)
|
211
|
-
local_counts_enrichment = np.add(
|
212
|
-
local_counts_enrichment,
|
213
|
-
permuted_neighborhood_scores >= observed_neighborhood_scores,
|
214
|
-
)
|
215
|
-
# Update the shared progress counter
|
216
|
-
progress_counter.value += 1
|
217
|
-
|
218
|
-
return local_counts_depletion, local_counts_enrichment
|
219
10
|
|
220
11
|
|
221
12
|
def calculate_significance_matrices(
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: risk-network
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.4
|
4
4
|
Summary: A Python package for biological network analysis
|
5
5
|
Author: Ira Horecka
|
6
6
|
Author-email: Ira Horecka <ira89@icloud.com>
|
@@ -684,14 +684,14 @@ Classifier: Intended Audience :: Science/Research
|
|
684
684
|
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
685
685
|
Classifier: Operating System :: OS Independent
|
686
686
|
Classifier: Programming Language :: Python :: 3
|
687
|
-
Classifier: Programming Language :: Python :: 3.
|
687
|
+
Classifier: Programming Language :: Python :: 3.8
|
688
688
|
Classifier: Programming Language :: Python :: 3 :: Only
|
689
689
|
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
690
690
|
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
691
691
|
Classifier: Topic :: Scientific/Engineering :: Visualization
|
692
692
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
693
693
|
Classifier: Development Status :: 4 - Beta
|
694
|
-
Requires-Python: >=3.
|
694
|
+
Requires-Python: >=3.8
|
695
695
|
Description-Content-Type: text/markdown
|
696
696
|
License-File: LICENSE
|
697
697
|
Requires-Dist: ipywidgets
|
@@ -716,13 +716,13 @@ Requires-Dist: tqdm
|
|
716
716
|
|
717
717
|
<p align="center">
|
718
718
|
<a href="https://pypi.python.org/pypi/risk-network"><img src="https://img.shields.io/pypi/v/risk-network.svg" alt="pypiv"></a>
|
719
|
-
<a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.
|
719
|
+
<a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.8+-blue.svg" alt="Python 3.8+"></a>
|
720
720
|
<a href="https://raw.githubusercontent.com/irahorecka/chrono24/main/LICENSE"><img src="https://img.shields.io/badge/License-GPLv3-blue.svg" alt="License: GPL v3"></a>
|
721
721
|
</p>
|
722
722
|
|
723
723
|
## RISK
|
724
724
|
|
725
|
-
####
|
725
|
+
#### RISK Infers Spatial Kinships
|
726
726
|
|
727
727
|
RISK is a software tool for visualizing spatial relationships in networks. It aims to enhance network analysis by integrating advanced network annotation algorithms, such as Louvain and Markov Clustering, to identify key functional modules and pathways.
|
728
728
|
|
@@ -736,7 +736,7 @@ RISK is a software tool for visualizing spatial relationships in networks. It ai
|
|
736
736
|
|
737
737
|
*Saccharomyces cerevisiae* proteins oriented by physical interactions discovered through affinity enrichment and mass spectrometry (Michaelis et al., 2023).
|
738
738
|
|
739
|
-

|
740
740
|
|
741
741
|
## Installation
|
742
742
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
risk/__init__.py,sha256=5ydXZQ9nkGE0sf2oay7qxbSHwCkV1BqBqVoBIreNZog,104
|
2
|
+
risk/constants.py,sha256=AICk3x5qRQhls_ijTb4VdbdxU6mZ1aLGbAjLEdBwfJI,550
|
3
|
+
risk/risk.py,sha256=4Y-fViqdK9gvxEjJRYsV_7gbN0kh7eiTwD8eesd_M6o,21109
|
4
|
+
risk/annotations/__init__.py,sha256=vUpVvMRE5if01Ic8QY6M2Ae3EFGJHdugEe9PdEkAW4Y,138
|
5
|
+
risk/annotations/annotations.py,sha256=t4aLwROCFHcqk8g-viuwkFG--HqVpVN_2yVVcjhg6wI,10534
|
6
|
+
risk/annotations/io.py,sha256=TMicRACfY8bNtmbvVrxHoh8zkOVLOIhZwWrpxUlR28Q,7988
|
7
|
+
risk/log/__init__.py,sha256=xuLImfxFlKpnVhzi_gDYlr2_c9cLkrw2c_3iEsXb1as,107
|
8
|
+
risk/log/console.py,sha256=im9DRExwf6wHlcn9fewoDcKIpo3vPcorZIaNAl-0csY,355
|
9
|
+
risk/log/params.py,sha256=Tbb-sovFTptGBqPDKafUA8KOpby4zFObutAT_Iti1hE,6302
|
10
|
+
risk/neighborhoods/__init__.py,sha256=tKKEg4lsbqFukpgYlUGxU_v_9FOqK7V0uvM9T2QzoL0,206
|
11
|
+
risk/neighborhoods/community.py,sha256=eL2IGT-8sbiJIyfyb_FGngev7pEMxw7tZb8YzbzOYw8,6512
|
12
|
+
risk/neighborhoods/domains.py,sha256=HwuChmZH0RGD9eQOvk2-ezQDJRUHHn93vhVgHb-kX6I,10192
|
13
|
+
risk/neighborhoods/neighborhoods.py,sha256=SqYJaT49rUj77ts0XsPXb9cURM11aGh2Teks0nBH_4s,13939
|
14
|
+
risk/network/__init__.py,sha256=iEPeJdZfqp0toxtbElryB8jbz9_t_k4QQ3iDvKE8C_0,126
|
15
|
+
risk/network/geometry.py,sha256=H1yGVVqgbfpzBzJwEheDLfvGLSA284jGQQTn612L4Vc,6759
|
16
|
+
risk/network/graph.py,sha256=m3bFWU5528OEm246LPG5XP3l_30vaBiJv4AO4iq0pSA,11552
|
17
|
+
risk/network/io.py,sha256=otiRG6uT6HLgbbJql7X2wjYxab8OFJSgRoWJlcDoyu4,20291
|
18
|
+
risk/network/plot.py,sha256=yGmuQXcju2cWUcyJJALtNmIPPCFS2yusULJXka8263I,40080
|
19
|
+
risk/stats/__init__.py,sha256=e-BE_Dr_jgiK6hKM-T-tlG4yvHnId8e5qjnM0pdwNVc,230
|
20
|
+
risk/stats/fisher_exact.py,sha256=-bPwzu76-ob0HzrTV20mXUTot7v-MLuqFaAoab-QxPg,4966
|
21
|
+
risk/stats/hypergeom.py,sha256=lrIFdhCWRjvM4apYw1MlOKqT_IY5OjtCwrjdtJdt6Tg,4954
|
22
|
+
risk/stats/stats.py,sha256=kvShov-94W6ffgDUTb522vB9hDJQSyTsYif_UIaFfSM,7059
|
23
|
+
risk/stats/permutation/__init__.py,sha256=neJp7FENC-zg_CGOXqv-iIvz1r5XUKI9Ruxhmq7kDOI,105
|
24
|
+
risk/stats/permutation/permutation.py,sha256=qLWdwxEY6nmkYPxpM8HLDcd2mbqYv9Qr7CKtJvhLqIM,9220
|
25
|
+
risk/stats/permutation/test_functions.py,sha256=HuDIM-V1jkkfE1rlaIqrWWBSKZt3dQ1f-YEDjWpnLSE,2343
|
26
|
+
risk_network-0.0.4.dist-info/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
|
27
|
+
risk_network-0.0.4.dist-info/METADATA,sha256=3LgOrdx1WOC-0VC1ShUQo3EfGecyxBNy3dg1DDbrSfM,43234
|
28
|
+
risk_network-0.0.4.dist-info/WHEEL,sha256=UvcQYKBHoFqaQd6LKyqHw9fxEolWLQnlzP0h_LgJAfI,91
|
29
|
+
risk_network-0.0.4.dist-info/top_level.txt,sha256=NX7C2PFKTvC1JhVKv14DFlFAIFnKc6Lpsu1ZfxvQwVw,5
|
30
|
+
risk_network-0.0.4.dist-info/RECORD,,
|
@@ -1,26 +0,0 @@
|
|
1
|
-
risk/__init__.py,sha256=RJu5X2UMuCRnZae_KH4Fc7_o_P4sSfTDEBowiVZ2Go4,122
|
2
|
-
risk/constants.py,sha256=AICk3x5qRQhls_ijTb4VdbdxU6mZ1aLGbAjLEdBwfJI,550
|
3
|
-
risk/risk.py,sha256=cWpYogZ-vma4ZZjewVNRMzb2TqHv8YABuzP2brXpOqo,16399
|
4
|
-
risk/annotations/__init__.py,sha256=vUpVvMRE5if01Ic8QY6M2Ae3EFGJHdugEe9PdEkAW4Y,138
|
5
|
-
risk/annotations/annotations.py,sha256=gZ9gihK_eTWaX3eByh08xr97FX4-XKe6MBwCCjasEDU,10368
|
6
|
-
risk/annotations/io.py,sha256=ozi7aFn3_geB6G0kt7Ya1qVhNOqP6rB0YISjriSZyNw,7989
|
7
|
-
risk/log/__init__.py,sha256=xuLImfxFlKpnVhzi_gDYlr2_c9cLkrw2c_3iEsXb1as,107
|
8
|
-
risk/log/console.py,sha256=im9DRExwf6wHlcn9fewoDcKIpo3vPcorZIaNAl-0csY,355
|
9
|
-
risk/log/params.py,sha256=Tbb-sovFTptGBqPDKafUA8KOpby4zFObutAT_Iti1hE,6302
|
10
|
-
risk/neighborhoods/__init__.py,sha256=tKKEg4lsbqFukpgYlUGxU_v_9FOqK7V0uvM9T2QzoL0,206
|
11
|
-
risk/neighborhoods/community.py,sha256=eL2IGT-8sbiJIyfyb_FGngev7pEMxw7tZb8YzbzOYw8,6512
|
12
|
-
risk/neighborhoods/domains.py,sha256=HwuChmZH0RGD9eQOvk2-ezQDJRUHHn93vhVgHb-kX6I,10192
|
13
|
-
risk/neighborhoods/neighborhoods.py,sha256=zGtxVIs0_Bg0wt1By6d77_lqW0PGXpOtQxeCEtyZFzA,13475
|
14
|
-
risk/network/__init__.py,sha256=iEPeJdZfqp0toxtbElryB8jbz9_t_k4QQ3iDvKE8C_0,126
|
15
|
-
risk/network/geometry.py,sha256=euBMOVvxpj-0WZam40IbHdsT7E4WXpTwSxuGbmAGTDg,6757
|
16
|
-
risk/network/graph.py,sha256=a7gM1d2jHqscFVwn1GZaJWb3oZOFraNsQ2RxC4osaV4,11528
|
17
|
-
risk/network/io.py,sha256=KmdrsDZe-ZT4O59NYZM_nQd8Ew9qpbzQcqWS_PaE7eA,12559
|
18
|
-
risk/network/plot.py,sha256=fy21X677xqJPFkn564Jegxy05C9x0pJXovd5fm3NZ4Q,34554
|
19
|
-
risk/stats/__init__.py,sha256=4s9gdJo5B1G_cQc0iMoeIBt5OrQNXkdtNXkAMFQkLxc,103
|
20
|
-
risk/stats/permutation.py,sha256=xgaZbaxo57t_FzPlpcb2nsq8oCzc_wj-zAm-xj3P2dA,3404
|
21
|
-
risk/stats/stats.py,sha256=_3Fj5H8Nml4cExvLg7Mt_i1HCLAJJcJSDiiSzr3uFlo,15798
|
22
|
-
risk_network-0.0.3b3.dist-info/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
|
23
|
-
risk_network-0.0.3b3.dist-info/METADATA,sha256=4zGYMG1NL48Udn8jYkT8VCYDEEAuN5ycXBpvmxvdHtw,43256
|
24
|
-
risk_network-0.0.3b3.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
|
25
|
-
risk_network-0.0.3b3.dist-info/top_level.txt,sha256=NX7C2PFKTvC1JhVKv14DFlFAIFnKc6Lpsu1ZfxvQwVw,5
|
26
|
-
risk_network-0.0.3b3.dist-info/RECORD,,
|
File without changes
|
File without changes
|