risk-network 0.0.9b30__tar.gz → 0.0.9b32__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.
Files changed (48) hide show
  1. {risk_network-0.0.9b30/risk_network.egg-info → risk_network-0.0.9b32}/PKG-INFO +1 -1
  2. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/__init__.py +1 -1
  3. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/stats/permutation/test_functions.py +9 -5
  4. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/stats/stat_tests.py +32 -62
  5. {risk_network-0.0.9b30 → risk_network-0.0.9b32/risk_network.egg-info}/PKG-INFO +1 -1
  6. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/LICENSE +0 -0
  7. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/MANIFEST.in +0 -0
  8. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/README.md +0 -0
  9. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/pyproject.toml +0 -0
  10. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/annotations/__init__.py +0 -0
  11. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/annotations/annotations.py +0 -0
  12. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/annotations/io.py +0 -0
  13. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/constants.py +0 -0
  14. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/log/__init__.py +0 -0
  15. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/log/console.py +0 -0
  16. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/log/parameters.py +0 -0
  17. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/neighborhoods/__init__.py +0 -0
  18. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/neighborhoods/api.py +0 -0
  19. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/neighborhoods/community.py +0 -0
  20. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/neighborhoods/domains.py +0 -0
  21. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/neighborhoods/neighborhoods.py +0 -0
  22. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/network/__init__.py +0 -0
  23. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/network/geometry.py +0 -0
  24. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/network/graph/__init__.py +0 -0
  25. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/network/graph/api.py +0 -0
  26. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/network/graph/graph.py +0 -0
  27. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/network/graph/summary.py +0 -0
  28. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/network/io.py +0 -0
  29. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/network/plotter/__init__.py +0 -0
  30. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/network/plotter/api.py +0 -0
  31. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/network/plotter/canvas.py +0 -0
  32. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/network/plotter/contour.py +0 -0
  33. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/network/plotter/labels.py +0 -0
  34. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/network/plotter/network.py +0 -0
  35. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/network/plotter/plotter.py +0 -0
  36. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/network/plotter/utils/colors.py +0 -0
  37. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/network/plotter/utils/layout.py +0 -0
  38. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/risk.py +0 -0
  39. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/stats/__init__.py +0 -0
  40. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/stats/permutation/__init__.py +0 -0
  41. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/stats/permutation/permutation.py +0 -0
  42. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk/stats/significance.py +0 -0
  43. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk_network.egg-info/SOURCES.txt +0 -0
  44. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk_network.egg-info/dependency_links.txt +0 -0
  45. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk_network.egg-info/requires.txt +0 -0
  46. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/risk_network.egg-info/top_level.txt +0 -0
  47. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/setup.cfg +0 -0
  48. {risk_network-0.0.9b30 → risk_network-0.0.9b32}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: risk-network
3
- Version: 0.0.9b30
3
+ Version: 0.0.9b32
4
4
  Summary: A Python package for biological network analysis
5
5
  Author: Ira Horecka
6
6
  Author-email: Ira Horecka <ira89@icloud.com>
@@ -7,4 +7,4 @@ RISK: Regional Inference of Significant Kinships
7
7
 
8
8
  from risk.risk import RISK
9
9
 
10
- __version__ = "0.0.9-beta.30"
10
+ __version__ = "0.0.9-beta.32"
@@ -46,19 +46,23 @@ def compute_neighborhood_score_by_stdev(
46
46
  neighborhood_score = neighborhoods_matrix @ annotation_matrix # Sparse matrix multiplication
47
47
  # Calculate the number of elements in each neighborhood (sum of rows)
48
48
  N = neighborhoods_matrix.sum(axis=1).A.flatten() # Convert to 1D array
49
- # Avoid division by zero by replacing zeros in N with np.nan temporarily
50
- N[N == 0] = np.nan
49
+ if np.any(N == 0):
50
+ # Replace zeros in N with small positive values to avoid division errors
51
+ N = np.where(N == 0, np.nan, N)
52
+
51
53
  # Compute the mean of the neighborhood scores
52
54
  M = neighborhood_score.multiply(1 / N[:, None]).toarray() # Sparse element-wise division
53
55
  # Compute the mean of squares (EXX) directly using squared annotation matrix
54
56
  annotation_squared = annotation_matrix.multiply(annotation_matrix) # Element-wise squaring
55
57
  EXX = (neighborhoods_matrix @ annotation_squared).multiply(1 / N[:, None]).toarray()
56
- # Calculate variance as EXX - M^2
57
- variance = EXX - np.power(M, 2)
58
+
59
+ # Calculate variance as EXX - M^2, ensuring no negative variances
60
+ variance = np.maximum(EXX - np.power(M, 2), 0)
58
61
  # Compute the standard deviation as the square root of the variance
59
62
  neighborhood_stdev = np.sqrt(variance)
60
- # Replace np.nan back with zeros in case N was 0 (no elements in the neighborhood)
63
+ # Replace np.nan back with zeros for rows where N was 0
61
64
  neighborhood_stdev[np.isnan(neighborhood_stdev)] = 0
65
+
62
66
  return neighborhood_stdev
63
67
 
64
68
 
@@ -3,7 +3,6 @@ risk/stats/stat_tests
3
3
  ~~~~~~~~~~~~~~~~~~~~~
4
4
  """
5
5
 
6
- from concurrent.futures import ThreadPoolExecutor
7
6
  from typing import Any, Dict
8
7
 
9
8
  import numpy as np
@@ -121,80 +120,51 @@ def compute_hypergeom_test(
121
120
  annotations: csr_matrix,
122
121
  null_distribution: str = "network",
123
122
  ) -> Dict[str, Any]:
124
- """Compute hypergeometric test for enrichment and depletion in neighborhoods with selectable null distribution.
123
+ """
124
+ Compute hypergeometric test for enrichment and depletion in neighborhoods with selectable null distribution.
125
125
 
126
126
  Args:
127
127
  neighborhoods (csr_matrix): Sparse binary matrix representing neighborhoods.
128
128
  annotations (csr_matrix): Sparse binary matrix representing annotations.
129
- null_distribution (str, optional): Type of null distribution ('network' or 'annotations').
130
- Defaults to "network".
129
+ null_distribution (str, optional): Type of null distribution ('network' or 'annotations'). Defaults to "network".
131
130
 
132
131
  Returns:
133
132
  Dict[str, Any]: Dictionary containing depletion and enrichment p-values.
134
133
  """
135
134
  # Get the total number of nodes in the network
136
135
  total_nodes = neighborhoods.shape[1]
137
- # Calculate neighborhood and annotation sums
138
- neighborhood_sums = neighborhoods.sum(axis=0).A1 # A1 returns a 1D array
139
- annotation_sums = annotations.sum(axis=0).A1
140
136
 
141
- if null_distribution == "annotations":
142
- annotated_nodes = annotations.getnnz(axis=1) > 0 # Nodes with any annotation
143
- background_population = annotated_nodes.sum()
144
- neighborhoods = neighborhoods[annotated_nodes]
145
- annotations = annotations[annotated_nodes]
146
- neighborhood_sums = neighborhoods.sum(axis=0).A1
147
- annotation_sums = annotations.sum(axis=0).A1
148
- elif null_distribution == "network":
137
+ # Compute sums
138
+ neighborhood_sums = neighborhoods.sum(axis=0).A.flatten() # Convert to dense array
139
+ annotation_sums = annotations.sum(axis=0).A.flatten() # Convert to dense array
140
+
141
+ if null_distribution == "network":
149
142
  background_population = total_nodes
143
+ elif null_distribution == "annotations":
144
+ annotated_nodes = annotations.sum(axis=1).A.flatten() > 0 # Boolean mask
145
+ background_population = annotated_nodes.sum()
146
+ neighborhood_sums = neighborhoods[annotated_nodes].sum(axis=0).A.flatten()
147
+ annotation_sums = annotations[annotated_nodes].sum(axis=0).A.flatten()
150
148
  else:
151
- raise ValueError("Invalid null_distribution value. Choose 'network' or 'annotations'.")
152
-
153
- # Sparse matrix multiplication for observed counts
154
- annotated_in_neighborhood = neighborhoods.T @ annotations # Result is sparse
155
- # Determine the axis with fewer vectors
156
- axis_to_process = 0 if annotations.shape[0] < annotations.shape[1] else 1
157
-
158
- # Initialize p-value arrays
159
- depletion_pvals = np.empty(annotated_in_neighborhood.shape, dtype=np.float64)
160
- enrichment_pvals = np.empty(annotated_in_neighborhood.shape, dtype=np.float64)
161
-
162
- def compute_pvals_for_index(idx: int):
163
- """Compute p-values for a given index."""
164
- if axis_to_process == 0: # Process rows
165
- observed_counts = annotated_in_neighborhood[idx, :].toarray().flatten()
166
- neigh_total = neighborhood_sums[idx]
167
- return (
168
- idx,
169
- hypergeom.cdf(observed_counts, background_population, annotation_sums, neigh_total),
170
- hypergeom.sf(
171
- observed_counts - 1, background_population, annotation_sums, neigh_total
172
- ),
173
- )
174
- else: # Process columns
175
- observed_counts = annotated_in_neighborhood[:, idx].toarray().flatten()
176
- ann_total = annotation_sums[idx]
177
- return (
178
- idx,
179
- hypergeom.cdf(observed_counts, background_population, ann_total, neighborhood_sums),
180
- hypergeom.sf(
181
- observed_counts - 1, background_population, ann_total, neighborhood_sums
182
- ),
183
- )
184
-
185
- # Use ThreadPoolExecutor to process indices in parallel
186
- num_indices = annotations.shape[axis_to_process]
187
- with ThreadPoolExecutor() as executor:
188
- results = executor.map(compute_pvals_for_index, range(num_indices))
189
-
190
- # Collect results
191
- for idx, dep_pval, enr_pval in results:
192
- if axis_to_process == 0: # Rows
193
- depletion_pvals[idx, :] = dep_pval
194
- enrichment_pvals[idx, :] = enr_pval
195
- else: # Columns
196
- depletion_pvals[:, idx] = dep_pval
197
- enrichment_pvals[:, idx] = enr_pval
149
+ raise ValueError(
150
+ "Invalid null_distribution value. Choose either 'network' or 'annotations'."
151
+ )
152
+
153
+ # Observed counts
154
+ annotated_in_neighborhood = neighborhoods.T @ annotations # Sparse result
155
+ annotated_in_neighborhood = annotated_in_neighborhood.toarray() # Convert to dense
156
+ # Align shapes for broadcasting
157
+ neighborhood_sums = neighborhood_sums.reshape(-1, 1)
158
+ annotation_sums = annotation_sums.reshape(1, -1)
159
+ background_population = np.array(background_population).reshape(1, 1)
160
+
161
+ # Compute hypergeometric p-values
162
+ depletion_pvals = hypergeom.cdf(
163
+ annotated_in_neighborhood, background_population, annotation_sums, neighborhood_sums
164
+ )
165
+ enrichment_pvals = hypergeom.sf(
166
+ annotated_in_neighborhood - 1, background_population, annotation_sums, neighborhood_sums
167
+ )
198
168
 
199
169
  return {"depletion_pvals": depletion_pvals, "enrichment_pvals": enrichment_pvals}
200
170
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: risk-network
3
- Version: 0.0.9b30
3
+ Version: 0.0.9b32
4
4
  Summary: A Python package for biological network analysis
5
5
  Author: Ira Horecka
6
6
  Author-email: Ira Horecka <ira89@icloud.com>
File without changes