risk-network 0.0.3b1__py3-none-any.whl → 0.0.3b2__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 -1
- risk/stats/stats.py +36 -112
- {risk_network-0.0.3b1.dist-info → risk_network-0.0.3b2.dist-info}/METADATA +1 -1
- {risk_network-0.0.3b1.dist-info → risk_network-0.0.3b2.dist-info}/RECORD +7 -7
- {risk_network-0.0.3b1.dist-info → risk_network-0.0.3b2.dist-info}/LICENSE +0 -0
- {risk_network-0.0.3b1.dist-info → risk_network-0.0.3b2.dist-info}/WHEEL +0 -0
- {risk_network-0.0.3b1.dist-info → risk_network-0.0.3b2.dist-info}/top_level.txt +0 -0
risk/__init__.py
CHANGED
risk/stats/stats.py
CHANGED
@@ -3,40 +3,14 @@ risk/stats/stats
|
|
3
3
|
~~~~~~~~~~~~~~~~
|
4
4
|
"""
|
5
5
|
|
6
|
-
import
|
7
|
-
from
|
8
|
-
from
|
9
|
-
from typing import Any, Callable, Generator, Union
|
6
|
+
from multiprocessing import get_context, Manager
|
7
|
+
from tqdm import tqdm
|
8
|
+
from typing import Any, Callable, Dict, Union
|
10
9
|
|
11
10
|
import numpy as np
|
12
11
|
from statsmodels.stats.multitest import fdrcorrection
|
13
12
|
from threadpoolctl import threadpool_limits
|
14
13
|
|
15
|
-
|
16
|
-
def _is_notebook() -> bool:
|
17
|
-
"""Determine the type of interactive environment and return it as a dictionary.
|
18
|
-
|
19
|
-
Returns:
|
20
|
-
bool: True if the environment is a Jupyter notebook, False otherwise.
|
21
|
-
"""
|
22
|
-
try:
|
23
|
-
shell = get_ipython().__class__.__name__
|
24
|
-
if shell == "ZMQInteractiveShell":
|
25
|
-
return True # Jupyter notebook or qtconsole
|
26
|
-
elif shell == "TerminalInteractiveShell":
|
27
|
-
return False # Terminal running IPython
|
28
|
-
else:
|
29
|
-
return False # Other types of shell
|
30
|
-
except NameError:
|
31
|
-
return False # Standard Python interpreter
|
32
|
-
|
33
|
-
|
34
|
-
if _is_notebook():
|
35
|
-
from tqdm.notebook import tqdm
|
36
|
-
else:
|
37
|
-
from tqdm import tqdm
|
38
|
-
|
39
|
-
|
40
14
|
from risk.stats.permutation import (
|
41
15
|
compute_neighborhood_score_by_sum,
|
42
16
|
compute_neighborhood_score_by_stdev,
|
@@ -58,7 +32,7 @@ def compute_permutation(
|
|
58
32
|
num_permutations: int = 1000,
|
59
33
|
random_seed: int = 888,
|
60
34
|
max_workers: int = 1,
|
61
|
-
) ->
|
35
|
+
) -> Dict[str, Any]:
|
62
36
|
"""Compute permutation test for enrichment and depletion in neighborhoods.
|
63
37
|
|
64
38
|
Args:
|
@@ -78,6 +52,7 @@ def compute_permutation(
|
|
78
52
|
annotations = annotations.astype(np.float32)
|
79
53
|
# Retrieve the appropriate neighborhood score function based on the metric
|
80
54
|
neighborhood_score_func = DISPATCH_PERMUTATION_TABLE[score_metric]
|
55
|
+
|
81
56
|
# Run the permutation test to calculate depletion and enrichment counts
|
82
57
|
counts_depletion, counts_enrichment = _run_permutation_test(
|
83
58
|
neighborhoods=neighborhoods,
|
@@ -125,6 +100,7 @@ def _run_permutation_test(
|
|
125
100
|
"""
|
126
101
|
# Set the random seed for reproducibility
|
127
102
|
np.random.seed(random_seed)
|
103
|
+
|
128
104
|
# Determine the indices to use based on the null distribution type
|
129
105
|
if null_distribution == "network":
|
130
106
|
idxs = range(annotations.shape[0])
|
@@ -135,6 +111,7 @@ def _run_permutation_test(
|
|
135
111
|
annotations[np.isnan(annotations)] = 0
|
136
112
|
annotation_matrix_obsv = annotations[idxs]
|
137
113
|
neighborhoods_matrix_obsv = neighborhoods.T[idxs].T
|
114
|
+
|
138
115
|
# Calculate observed neighborhood scores
|
139
116
|
with np.errstate(invalid="ignore", divide="ignore"):
|
140
117
|
observed_neighborhood_scores = neighborhood_score_func(
|
@@ -144,14 +121,21 @@ def _run_permutation_test(
|
|
144
121
|
# Initialize count matrices for depletion and enrichment
|
145
122
|
counts_depletion = np.zeros(observed_neighborhood_scores.shape)
|
146
123
|
counts_enrichment = np.zeros(observed_neighborhood_scores.shape)
|
124
|
+
|
147
125
|
# Determine the number of permutations to run in each worker process
|
148
126
|
subset_size = num_permutations // max_workers
|
149
127
|
remainder = num_permutations % max_workers
|
150
128
|
|
151
129
|
# Use the spawn context for creating a new multiprocessing pool
|
152
130
|
ctx = get_context("spawn")
|
153
|
-
|
154
|
-
|
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
|
155
139
|
params_list = [
|
156
140
|
(
|
157
141
|
annotations,
|
@@ -160,14 +144,24 @@ def _run_permutation_test(
|
|
160
144
|
observed_neighborhood_scores,
|
161
145
|
neighborhood_score_func,
|
162
146
|
subset_size + (1 if i < remainder else 0),
|
163
|
-
|
164
|
-
max_workers,
|
165
|
-
True,
|
147
|
+
progress_counter,
|
166
148
|
)
|
167
149
|
for i in range(max_workers)
|
168
150
|
]
|
169
|
-
|
170
|
-
|
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():
|
171
165
|
counts_depletion = np.add(counts_depletion, local_counts_depletion)
|
172
166
|
counts_enrichment = np.add(counts_enrichment, local_counts_enrichment)
|
173
167
|
|
@@ -181,9 +175,7 @@ def _permutation_process_subset(
|
|
181
175
|
observed_neighborhood_scores: np.ndarray,
|
182
176
|
neighborhood_score_func: Callable,
|
183
177
|
subset_size: int,
|
184
|
-
|
185
|
-
max_workers: int,
|
186
|
-
use_lock: bool,
|
178
|
+
progress_counter,
|
187
179
|
) -> tuple:
|
188
180
|
"""Process a subset of permutations for the permutation test.
|
189
181
|
|
@@ -194,9 +186,7 @@ def _permutation_process_subset(
|
|
194
186
|
observed_neighborhood_scores (np.ndarray): Observed neighborhood scores.
|
195
187
|
neighborhood_score_func (Callable): Function to calculate neighborhood scores.
|
196
188
|
subset_size (int): Number of permutations to run in this subset.
|
197
|
-
|
198
|
-
max_workers (int): Number of worker processes.
|
199
|
-
use_lock (bool): Whether to use a lock for multiprocessing synchronization.
|
189
|
+
progress_counter: Shared counter for tracking progress.
|
200
190
|
|
201
191
|
Returns:
|
202
192
|
tuple: Local counts of depletion and enrichment.
|
@@ -205,13 +195,7 @@ def _permutation_process_subset(
|
|
205
195
|
local_counts_depletion = np.zeros(observed_neighborhood_scores.shape)
|
206
196
|
local_counts_enrichment = np.zeros(observed_neighborhood_scores.shape)
|
207
197
|
|
208
|
-
|
209
|
-
text = f"Worker {worker_id + 1} of {max_workers} progress"
|
210
|
-
leave = worker_id == max_workers - 1 # Only leave the progress bar for the last worker
|
211
|
-
|
212
|
-
with _tqdm_context(
|
213
|
-
total=subset_size, desc=text, position=0, leave=leave, use_lock=use_lock
|
214
|
-
) as progress:
|
198
|
+
with threadpool_limits(limits=1, user_api="blas"):
|
215
199
|
for _ in range(subset_size):
|
216
200
|
# Permute the annotation matrix
|
217
201
|
annotation_matrix_permut = annotation_matrix[np.random.permutation(idxs)]
|
@@ -228,72 +212,12 @@ def _permutation_process_subset(
|
|
228
212
|
local_counts_enrichment,
|
229
213
|
permuted_neighborhood_scores >= observed_neighborhood_scores,
|
230
214
|
)
|
231
|
-
# Update progress
|
232
|
-
|
215
|
+
# Update the shared progress counter
|
216
|
+
progress_counter.value += 1
|
233
217
|
|
234
218
|
return local_counts_depletion, local_counts_enrichment
|
235
219
|
|
236
220
|
|
237
|
-
def _init(lock_: Any) -> None:
|
238
|
-
"""Initialize a global lock for multiprocessing.
|
239
|
-
|
240
|
-
Args:
|
241
|
-
lock_ (Any): A lock object to be used in multiprocessing.
|
242
|
-
"""
|
243
|
-
global lock
|
244
|
-
lock = lock_ # Assign the provided lock to a global variable
|
245
|
-
|
246
|
-
|
247
|
-
@contextmanager
|
248
|
-
def _tqdm_context(
|
249
|
-
total: int, desc: str, position: int, leave: bool = False, use_lock: bool = False
|
250
|
-
) -> Generator:
|
251
|
-
"""A context manager for a `tqdm` progress bar.
|
252
|
-
|
253
|
-
Args:
|
254
|
-
total (int): The total number of iterations for the progress bar.
|
255
|
-
desc (str): Description for the progress bar.
|
256
|
-
position (int): The position of the progress bar (useful for multiple bars).
|
257
|
-
leave (bool): Whether to leave the progress bar after completion.
|
258
|
-
use_lock (bool): Whether to use a lock for multiprocessing synchronization.
|
259
|
-
|
260
|
-
Yields:
|
261
|
-
tqdm: A `tqdm` progress bar object.
|
262
|
-
"""
|
263
|
-
# Set default parameters for the progress bar
|
264
|
-
min_interval = 0.1
|
265
|
-
# Use a lock for multiprocessing synchronization if specified
|
266
|
-
if use_lock:
|
267
|
-
with lock:
|
268
|
-
# Create a progress bar with specified parameters and direct output to stderr
|
269
|
-
progress = tqdm(
|
270
|
-
total=total,
|
271
|
-
desc=desc,
|
272
|
-
position=position,
|
273
|
-
leave=leave,
|
274
|
-
mininterval=min_interval,
|
275
|
-
file=sys.stderr,
|
276
|
-
)
|
277
|
-
try:
|
278
|
-
yield progress # Yield the progress bar to the calling context
|
279
|
-
finally:
|
280
|
-
progress.close() # Ensure the progress bar is closed properly
|
281
|
-
else:
|
282
|
-
# Create a progress bar without using a lock
|
283
|
-
progress = tqdm(
|
284
|
-
total=total,
|
285
|
-
desc=desc,
|
286
|
-
position=position,
|
287
|
-
leave=leave,
|
288
|
-
mininterval=min_interval,
|
289
|
-
file=sys.stderr,
|
290
|
-
)
|
291
|
-
try:
|
292
|
-
yield progress # Yield the progress bar to the calling context
|
293
|
-
finally:
|
294
|
-
progress.close() # Ensure the progress bar is closed properly
|
295
|
-
|
296
|
-
|
297
221
|
def calculate_significance_matrices(
|
298
222
|
depletion_pvals: np.ndarray,
|
299
223
|
enrichment_pvals: np.ndarray,
|
@@ -1,4 +1,4 @@
|
|
1
|
-
risk/__init__.py,sha256=
|
1
|
+
risk/__init__.py,sha256=H7Oal2XxdwvgwfVdxjsgEpAPdyruGRh2shgYLfJXFCs,122
|
2
2
|
risk/constants.py,sha256=AICk3x5qRQhls_ijTb4VdbdxU6mZ1aLGbAjLEdBwfJI,550
|
3
3
|
risk/risk.py,sha256=cWpYogZ-vma4ZZjewVNRMzb2TqHv8YABuzP2brXpOqo,16399
|
4
4
|
risk/annotations/__init__.py,sha256=vUpVvMRE5if01Ic8QY6M2Ae3EFGJHdugEe9PdEkAW4Y,138
|
@@ -18,9 +18,9 @@ risk/network/io.py,sha256=KmdrsDZe-ZT4O59NYZM_nQd8Ew9qpbzQcqWS_PaE7eA,12559
|
|
18
18
|
risk/network/plot.py,sha256=fy21X677xqJPFkn564Jegxy05C9x0pJXovd5fm3NZ4Q,34554
|
19
19
|
risk/stats/__init__.py,sha256=4s9gdJo5B1G_cQc0iMoeIBt5OrQNXkdtNXkAMFQkLxc,103
|
20
20
|
risk/stats/permutation.py,sha256=xgaZbaxo57t_FzPlpcb2nsq8oCzc_wj-zAm-xj3P2dA,3404
|
21
|
-
risk/stats/stats.py,sha256=
|
22
|
-
risk_network-0.0.
|
23
|
-
risk_network-0.0.
|
24
|
-
risk_network-0.0.
|
25
|
-
risk_network-0.0.
|
26
|
-
risk_network-0.0.
|
21
|
+
risk/stats/stats.py,sha256=_3Fj5H8Nml4cExvLg7Mt_i1HCLAJJcJSDiiSzr3uFlo,15798
|
22
|
+
risk_network-0.0.3b2.dist-info/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
|
23
|
+
risk_network-0.0.3b2.dist-info/METADATA,sha256=y75hZFuUFJ99JoFX2koM3Xf_aI28MKXxiFKHV8iV4yw,43256
|
24
|
+
risk_network-0.0.3b2.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
|
25
|
+
risk_network-0.0.3b2.dist-info/top_level.txt,sha256=NX7C2PFKTvC1JhVKv14DFlFAIFnKc6Lpsu1ZfxvQwVw,5
|
26
|
+
risk_network-0.0.3b2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|