pyCoReGraph 0.0.1a2__tar.gz → 0.0.1a4__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.
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/PKG-INFO +1 -1
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/pyproject.toml +1 -1
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/src/coregraph/__init__.py +2 -2
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/src/coregraph/analysis/bins.py +8 -3
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/src/coregraph/analysis/correlations.py +42 -7
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/src/coregraph/analysis/fdr.py +27 -6
- pycoregraph-0.0.1a4/src/coregraph/analysis/queries.py +206 -0
- pycoregraph-0.0.1a4/src/coregraph/analysis/reductions.py +113 -0
- pycoregraph-0.0.1a4/src/coregraph/graphics/animations.py +100 -0
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/src/coregraph/graphics/network.py +28 -25
- pycoregraph-0.0.1a4/src/coregraph/graphics/plots.py +140 -0
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/src/coregraph/models/coregraph.py +28 -11
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/src/coregraph/models/cors.py +0 -1
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/src/coregraph/models/graphics.py +0 -1
- pycoregraph-0.0.1a4/src/coregraph/models/stargraph.py +91 -0
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/src/coregraph/utils/formatting.py +3 -1
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/src/coregraph/utils/validation.py +17 -2
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/src/pyCoReGraph.egg-info/PKG-INFO +1 -1
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/src/pyCoReGraph.egg-info/SOURCES.txt +1 -1
- pycoregraph-0.0.1a2/src/coregraph/analysis/queries.py +0 -118
- pycoregraph-0.0.1a2/src/coregraph/analysis/subset.py +0 -64
- pycoregraph-0.0.1a2/src/coregraph/graphics/animations.py +0 -56
- pycoregraph-0.0.1a2/src/coregraph/graphics/plots.py +0 -85
- pycoregraph-0.0.1a2/src/coregraph/models/stargraph.py +0 -41
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/LICENSE +0 -0
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/README.md +0 -0
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/setup.cfg +0 -0
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/src/coregraph/analysis/__init__.py +0 -0
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/src/coregraph/graphics/__init__.py +0 -0
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/src/coregraph/graphics/colors.py +0 -0
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/src/coregraph/models/__init__.py +0 -0
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/src/coregraph/utils/__init__.py +0 -0
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/src/coregraph/utils/decorators.py +0 -0
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/src/pyCoReGraph.egg-info/dependency_links.txt +0 -0
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/src/pyCoReGraph.egg-info/requires.txt +0 -0
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/src/pyCoReGraph.egg-info/top_level.txt +0 -0
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/tests/test_coregraph.py +0 -0
- {pycoregraph-0.0.1a2 → pycoregraph-0.0.1a4}/tests/test_imports.py +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
__version__ = "0.0.
|
|
1
|
+
__version__ = "0.0.1a4"
|
|
2
2
|
|
|
3
3
|
# Models
|
|
4
4
|
from coregraph.models import (
|
|
@@ -32,7 +32,7 @@ from coregraph.graphics.network import (
|
|
|
32
32
|
animate_network,
|
|
33
33
|
)
|
|
34
34
|
|
|
35
|
-
from coregraph.analysis.
|
|
35
|
+
from coregraph.analysis.reductions import (
|
|
36
36
|
starry,
|
|
37
37
|
subset_coregraph,
|
|
38
38
|
)
|
|
@@ -3,9 +3,14 @@
|
|
|
3
3
|
import numpy as np
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
def _calculate_bins(
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
def _calculate_bins(
|
|
7
|
+
data,
|
|
8
|
+
pseudotime,
|
|
9
|
+
n_bins
|
|
10
|
+
):
|
|
11
|
+
'''
|
|
12
|
+
Discretize pseudotime expression in bins.
|
|
13
|
+
'''
|
|
9
14
|
bin_range = (pseudotime.max() - pseudotime.min())/n_bins
|
|
10
15
|
bin_seq = pseudotime.min() + np.arange(1,n_bins)*bin_range
|
|
11
16
|
bins = (np.digitize(pseudotime, bin_seq)*bin_range)+(bin_range/2)
|
|
@@ -3,8 +3,24 @@
|
|
|
3
3
|
import numpy as np
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
def _calculate_all_cors(
|
|
7
|
-
|
|
6
|
+
def _calculate_all_cors(
|
|
7
|
+
data,
|
|
8
|
+
window,
|
|
9
|
+
i,
|
|
10
|
+
tensor,
|
|
11
|
+
reflag,
|
|
12
|
+
MAC,
|
|
13
|
+
LAG_id,
|
|
14
|
+
LAG,
|
|
15
|
+
LAG_means,
|
|
16
|
+
dim3_start,
|
|
17
|
+
step = 1,
|
|
18
|
+
num_format = np.array([1,15]),
|
|
19
|
+
dtype = np.float64
|
|
20
|
+
):
|
|
21
|
+
'''
|
|
22
|
+
Calculate all lagged correlations for a unique given reference i.
|
|
23
|
+
'''
|
|
8
24
|
dim3 = dim3_start
|
|
9
25
|
n_genes, n_cells = data.shape
|
|
10
26
|
|
|
@@ -43,8 +59,17 @@ def _calculate_all_cors(data, window, i, tensor, reflag, MAC, LAG_id, LAG, LAG_m
|
|
|
43
59
|
|
|
44
60
|
return dim3, MAC, LAG_id, LAG, LAG_means
|
|
45
61
|
|
|
46
|
-
def _calculate_LEAP_cors(
|
|
47
|
-
|
|
62
|
+
def _calculate_LEAP_cors(
|
|
63
|
+
data,
|
|
64
|
+
window,
|
|
65
|
+
i = 0,
|
|
66
|
+
step = 1,
|
|
67
|
+
num_format = np.array([1,15]),
|
|
68
|
+
dtype = np.float64
|
|
69
|
+
):
|
|
70
|
+
'''
|
|
71
|
+
Calculate all lagged correlations for a unique given reference i using LEAP traditional algorithm.
|
|
72
|
+
'''
|
|
48
73
|
n_genes, n_cells = data.shape
|
|
49
74
|
MAC = np.zeros((n_genes, n_genes))
|
|
50
75
|
LAG = np.zeros((n_genes, n_genes))
|
|
@@ -76,9 +101,19 @@ def _calculate_LEAP_cors(data, window, i=0, step=1, num_format=np.array([1,15]),
|
|
|
76
101
|
return MAC, LAG
|
|
77
102
|
|
|
78
103
|
|
|
79
|
-
def _calculate_star_cors(
|
|
80
|
-
|
|
81
|
-
|
|
104
|
+
def _calculate_star_cors(
|
|
105
|
+
data,
|
|
106
|
+
target_row,
|
|
107
|
+
MAC,
|
|
108
|
+
window,
|
|
109
|
+
i,
|
|
110
|
+
step = 1,
|
|
111
|
+
num_format = np.array([1,15]),
|
|
112
|
+
dtype = np.float64
|
|
113
|
+
):
|
|
114
|
+
'''
|
|
115
|
+
Calculate all lagged correlations for a unique given reference i using a single reference row against all rows.
|
|
116
|
+
'''
|
|
82
117
|
n_genes, n_cells = data.shape
|
|
83
118
|
|
|
84
119
|
# Take reference row only
|
|
@@ -5,9 +5,19 @@ import numpy as np
|
|
|
5
5
|
from coregraph.analysis.correlations import (_calculate_LEAP_cors, _calculate_star_cors)
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
def _calculate_FDR(
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
def _calculate_FDR(
|
|
9
|
+
data,
|
|
10
|
+
MAC,
|
|
11
|
+
window,
|
|
12
|
+
n_perms = 100,
|
|
13
|
+
FDR_cutoffs = 101,
|
|
14
|
+
step = 1,
|
|
15
|
+
num_format = np.array([1,15]),
|
|
16
|
+
dtype = np.float64
|
|
17
|
+
):
|
|
18
|
+
'''
|
|
19
|
+
Calculate False Discovery Rate by permutations.
|
|
20
|
+
'''
|
|
11
21
|
MAC_true = np.absolute(MAC.copy())
|
|
12
22
|
samp_size = np.minimum(100, data.shape[0])
|
|
13
23
|
MACs_perm = np.zeros((n_perms, samp_size, samp_size))
|
|
@@ -51,9 +61,20 @@ def _calculate_FDR(data, MAC, window, n_perms = 100, FDR_cutoffs = 101, step=1,
|
|
|
51
61
|
|
|
52
62
|
return results[::-1]
|
|
53
63
|
|
|
54
|
-
def _calculate_star_FDR(
|
|
55
|
-
|
|
56
|
-
|
|
64
|
+
def _calculate_star_FDR(
|
|
65
|
+
data,
|
|
66
|
+
target_row,
|
|
67
|
+
MAC,
|
|
68
|
+
window,
|
|
69
|
+
n_perms = 100,
|
|
70
|
+
FDR_cutoffs = 101,
|
|
71
|
+
step = 1,
|
|
72
|
+
num_format = np.array([1,15]),
|
|
73
|
+
dtype = np.float64
|
|
74
|
+
):
|
|
75
|
+
'''
|
|
76
|
+
Calculate False Discovery Rate by permutations for a single reference row against all rows.
|
|
77
|
+
'''
|
|
57
78
|
MAC_true = np.absolute(MAC.copy())
|
|
58
79
|
samp_size = np.minimum(100, data.shape[0])
|
|
59
80
|
MACs_perm = np.zeros((n_perms, samp_size))
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
## QUERIES ##
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
import pandas as pd
|
|
7
|
+
|
|
8
|
+
from coregraph.utils.decorators import (requires_cors, requires_FDR)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@requires_cors
|
|
12
|
+
def get_correlation(
|
|
13
|
+
C: CoReGraph,
|
|
14
|
+
regulator: str,
|
|
15
|
+
target: str,
|
|
16
|
+
ref_lag: tuple[int, int]
|
|
17
|
+
) -> float :
|
|
18
|
+
'''
|
|
19
|
+
Get correlation value between two genes at a specific (reference, lag) window pair.
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
C : CoReGraph
|
|
24
|
+
CoReGraph object with calculated correlations
|
|
25
|
+
regulator : str
|
|
26
|
+
Gene to consider as regulator for the relationship
|
|
27
|
+
target : str
|
|
28
|
+
Gene to consider as regulated for the relationship
|
|
29
|
+
ref_lag : tuple[int, int]
|
|
30
|
+
Tuple containing reference and lagged window for regulator and target genes respectively
|
|
31
|
+
'''
|
|
32
|
+
ref, lag = ref_lag
|
|
33
|
+
|
|
34
|
+
if (ref % C.cors.step != 0) or (lag % C.cors.step != 0):
|
|
35
|
+
raise ValueError(f"ref_lag must be multiples of step={C.cors.step}")
|
|
36
|
+
|
|
37
|
+
reg_idx = C.gene_to_idx[regulator]
|
|
38
|
+
tar_idx = C.gene_to_idx[target]
|
|
39
|
+
|
|
40
|
+
if ref <= lag:
|
|
41
|
+
tensor_i = reg_idx
|
|
42
|
+
tensor_j = tar_idx
|
|
43
|
+
search_ref = ref
|
|
44
|
+
search_lag = lag
|
|
45
|
+
else:
|
|
46
|
+
tensor_i = tar_idx
|
|
47
|
+
tensor_j = reg_idx
|
|
48
|
+
search_ref = lag
|
|
49
|
+
search_lag = ref
|
|
50
|
+
|
|
51
|
+
dim3 = np.argwhere((C.cors.reflag[:, 0] == search_ref) & (C.cors.reflag[:, 1] == search_lag))[0][0]
|
|
52
|
+
|
|
53
|
+
value = (C.cors.tensor[tensor_i, tensor_j, dim3] / C.cors.num_format[0])
|
|
54
|
+
|
|
55
|
+
return float(value)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@requires_cors
|
|
59
|
+
def get_all_correlations(
|
|
60
|
+
C: CoReGraph,
|
|
61
|
+
regulator: str,
|
|
62
|
+
target: str,
|
|
63
|
+
ref: int
|
|
64
|
+
) -> np.ndarray :
|
|
65
|
+
'''
|
|
66
|
+
Get all lagged correlations between two genes for a fixed reference window.
|
|
67
|
+
|
|
68
|
+
Parameters
|
|
69
|
+
----------
|
|
70
|
+
C : CoReGraph
|
|
71
|
+
CoReGraph object with calculated correlations
|
|
72
|
+
regulator : str
|
|
73
|
+
Gene to consider as regulator for the relationship
|
|
74
|
+
target : str
|
|
75
|
+
Gene to consider as regulated for the relationship
|
|
76
|
+
ref : int
|
|
77
|
+
Reference window to consider
|
|
78
|
+
'''
|
|
79
|
+
if (ref % C.cors.step != 0) :
|
|
80
|
+
raise ValueError(f"ref must be a multiple of step={C.cors.step}")
|
|
81
|
+
|
|
82
|
+
correlations = np.empty(C.cors.n_steps, dtype=C.cors.dtype)
|
|
83
|
+
|
|
84
|
+
for i in range(C.cors.n_steps):
|
|
85
|
+
lag = i * C.cors.step
|
|
86
|
+
correlations[i] = get_correlation(C,regulator,target,(ref, lag))
|
|
87
|
+
|
|
88
|
+
return correlations
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@requires_cors
|
|
92
|
+
def get_mac(
|
|
93
|
+
C: CoReGraph,
|
|
94
|
+
regulator: str,
|
|
95
|
+
target: str
|
|
96
|
+
) -> dict :
|
|
97
|
+
'''
|
|
98
|
+
Get maximal absolute correlation (MAC) and corresponding reference/lag pair for two genes.
|
|
99
|
+
|
|
100
|
+
Parameters
|
|
101
|
+
----------
|
|
102
|
+
C : CoReGraph
|
|
103
|
+
CoReGraph object with calculated correlations
|
|
104
|
+
regulator : str
|
|
105
|
+
Gene to consider as regulator for the relationship
|
|
106
|
+
target : str
|
|
107
|
+
Gene to consider as regulated for the relationship
|
|
108
|
+
'''
|
|
109
|
+
reg_idx = C.gene_to_idx[regulator]
|
|
110
|
+
tar_idx = C.gene_to_idx[target]
|
|
111
|
+
|
|
112
|
+
return {
|
|
113
|
+
"ref": int(C.cors.LAG_id[0, reg_idx, tar_idx]),
|
|
114
|
+
"lag": int(C.cors.LAG_id[1, reg_idx, tar_idx]),
|
|
115
|
+
"cor": float(C.cors.MAC[reg_idx, tar_idx] / C.cors.num_format[0])
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
@requires_cors
|
|
120
|
+
def get_mac_results(C: CoReGraph) -> tuple[pd.DataFrame, pd.DataFrame] :
|
|
121
|
+
'''
|
|
122
|
+
Get MAC and LAG matrices.
|
|
123
|
+
|
|
124
|
+
Parameters
|
|
125
|
+
----------
|
|
126
|
+
C : CoReGraph
|
|
127
|
+
CoReGraph object with calculated correlations
|
|
128
|
+
'''
|
|
129
|
+
mac_df = pd.DataFrame(C.cors.MAC / C.cors.num_format[0], index=C.gene_id, columns=C.gene_id)
|
|
130
|
+
lag_df = pd.DataFrame(C.cors.LAG, index=C.gene_id, columns=C.gene_id)
|
|
131
|
+
|
|
132
|
+
return mac_df, lag_df
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
@requires_cors
|
|
136
|
+
@requires_FDR
|
|
137
|
+
def get_regulated_genes(
|
|
138
|
+
C: CoReGraph,
|
|
139
|
+
regulator: str,
|
|
140
|
+
cor_threshold: float = 0.0
|
|
141
|
+
) -> pd.DataFrame :
|
|
142
|
+
'''
|
|
143
|
+
Get genes regulated by a regulator gene.
|
|
144
|
+
|
|
145
|
+
Parameters
|
|
146
|
+
----------
|
|
147
|
+
C : CoReGraph
|
|
148
|
+
CoReGraph object with calculated correlations and FDR
|
|
149
|
+
regulator : str
|
|
150
|
+
Gene to consider as regulator for the relationship
|
|
151
|
+
cor_threshold : float
|
|
152
|
+
Correlation threshold required for genes to be considered as targets
|
|
153
|
+
'''
|
|
154
|
+
reg_idx = C.gene_to_idx[regulator]
|
|
155
|
+
|
|
156
|
+
values = (C.cors.MAC[reg_idx, :] / C.cors.num_format[0])
|
|
157
|
+
|
|
158
|
+
df = pd.DataFrame({
|
|
159
|
+
"gene": C.gene_id,
|
|
160
|
+
"correlation": values,
|
|
161
|
+
"lag": C.cors.LAG[reg_idx, :]
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
df = df[np.abs(df["correlation"]) > cor_threshold]
|
|
165
|
+
|
|
166
|
+
df = df.sort_values(by="correlation", key=np.abs, ascending=False)
|
|
167
|
+
|
|
168
|
+
return df.set_index("gene")
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
@requires_cors
|
|
172
|
+
@requires_FDR
|
|
173
|
+
def get_regulator_genes(
|
|
174
|
+
C: CoReGraph,
|
|
175
|
+
target: str,
|
|
176
|
+
cor_threshold: float = 0.0
|
|
177
|
+
) -> pd.DataFrame :
|
|
178
|
+
'''
|
|
179
|
+
Get genes regulating a target gene.
|
|
180
|
+
|
|
181
|
+
Parameters
|
|
182
|
+
----------
|
|
183
|
+
C : CoReGraph
|
|
184
|
+
CoReGraph object with calculated correlations and FDR
|
|
185
|
+
target : str
|
|
186
|
+
Gene to consider as target for the relationship
|
|
187
|
+
cor_threshold : float
|
|
188
|
+
Correlation threshold required for genes to be considered as regulators
|
|
189
|
+
'''
|
|
190
|
+
tar_idx = C.gene_to_idx[target]
|
|
191
|
+
|
|
192
|
+
values = (C.cors.MAC[:, tar_idx] / C.cors.num_format[0])
|
|
193
|
+
|
|
194
|
+
df = pd.DataFrame({
|
|
195
|
+
"gene": C.gene_id,
|
|
196
|
+
"correlation": values,
|
|
197
|
+
"lag": C.cors.LAG[:, tar_idx]
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
df = df[np.abs(df["correlation"]) > cor_threshold]
|
|
201
|
+
|
|
202
|
+
df = df.sort_values(by="correlation", key=np.abs, ascending=False)
|
|
203
|
+
|
|
204
|
+
return df.set_index("gene")
|
|
205
|
+
|
|
206
|
+
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
## REDUCTIONS ##
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
import pandas as pd
|
|
5
|
+
|
|
6
|
+
from tqdm import tqdm
|
|
7
|
+
|
|
8
|
+
from coregraph.models.coregraph import CoReGraph
|
|
9
|
+
from coregraph.models.stargraph import StarGraph
|
|
10
|
+
|
|
11
|
+
from coregraph.analysis.correlations import _calculate_star_cors
|
|
12
|
+
from coregraph.analysis.fdr import _calculate_star_FDR
|
|
13
|
+
from coregraph.utils.validation import _solve_step
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def starry(
|
|
17
|
+
C : CoReGraph,
|
|
18
|
+
central_gene : str,
|
|
19
|
+
window: int | None = None,
|
|
20
|
+
FDR_thr : float = 0.05,
|
|
21
|
+
n_perms : int = 100,
|
|
22
|
+
FDR_cutoffs : int = 501,
|
|
23
|
+
step: int | None = None,
|
|
24
|
+
n_steps: int | None = None,
|
|
25
|
+
verbose : bool = False
|
|
26
|
+
) -> StarGraph :
|
|
27
|
+
'''
|
|
28
|
+
Estimate starry gene regulatory network centered on a given gene
|
|
29
|
+
|
|
30
|
+
Parameters
|
|
31
|
+
----------
|
|
32
|
+
C : CoReGraph
|
|
33
|
+
CoReGraph object to turn into a stargraph object
|
|
34
|
+
central_gene : str
|
|
35
|
+
Central gene of the newly created stargraph
|
|
36
|
+
window : int | None
|
|
37
|
+
Number of cells in the window for applying lags (default : n_cells*2/3)
|
|
38
|
+
FDR_thr : float
|
|
39
|
+
Maximal FDR for genes to be selected as in relationship with the central gene
|
|
40
|
+
n_perms : int
|
|
41
|
+
Number of repetition of matrix permutation to establish FDR
|
|
42
|
+
FDR_cutoffs : int
|
|
43
|
+
Number of levels between 0 and 1 calculated to determine the FDR
|
|
44
|
+
step : int | None
|
|
45
|
+
Step to apply while shifting window
|
|
46
|
+
n_steps : int | None
|
|
47
|
+
Total number of steps to consider while shifting window
|
|
48
|
+
verbose : bool
|
|
49
|
+
Wether show progression bar (slightly slow down the process)
|
|
50
|
+
'''
|
|
51
|
+
if window is None:
|
|
52
|
+
window = round(C.n_cells*(2/3))
|
|
53
|
+
|
|
54
|
+
n_genes, n_cells = C.data.shape
|
|
55
|
+
target_row = C.gene_id.index(central_gene)
|
|
56
|
+
step, n_steps = _solve_step(step, n_steps, window, n_cells)
|
|
57
|
+
|
|
58
|
+
## Calculate MAC ##
|
|
59
|
+
MAC = np.zeros((n_genes), dtype=np.float64)
|
|
60
|
+
|
|
61
|
+
np.seterr(divide='ignore', invalid='ignore')
|
|
62
|
+
iterator = tqdm(range(0, n_cells-window+1, step), desc="Calculating Correlations", disable=not verbose)
|
|
63
|
+
for i in iterator:
|
|
64
|
+
MAC = _calculate_star_cors(C.data, target_row, MAC, window, i, step)
|
|
65
|
+
|
|
66
|
+
## Calculate FDR ##
|
|
67
|
+
FDR = _calculate_star_FDR(C.data, target_row, MAC, window, n_perms, FDR_cutoffs, step)
|
|
68
|
+
FDR = pd.DataFrame(FDR)
|
|
69
|
+
FDR.columns = ["cors", "MACs_observed", "MACs_ave_perm", "FDR"]
|
|
70
|
+
FDR[["MACs_observed"]] = FDR[["MACs_observed"]].astype(int)
|
|
71
|
+
|
|
72
|
+
cor_thr = min(FDR['cors'][FDR['FDR'] < FDR_thr])
|
|
73
|
+
MAC = pd.DataFrame(MAC, index=C.gene_id, columns=['MAC'])
|
|
74
|
+
MAC = MAC.sort_values(by='MAC', key=abs, ascending=False)
|
|
75
|
+
|
|
76
|
+
## Create a new object and fill in it ##
|
|
77
|
+
star = StarGraph()
|
|
78
|
+
star.central_gene = central_gene
|
|
79
|
+
star.window = window
|
|
80
|
+
star.step = step
|
|
81
|
+
star.n_steps = n_steps
|
|
82
|
+
star.MAC = MAC
|
|
83
|
+
star.FDR = FDR
|
|
84
|
+
star.set_FDR_threshold(FDR_thr)
|
|
85
|
+
|
|
86
|
+
return star
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def subset_coregraph(
|
|
90
|
+
C: CoReGraph,
|
|
91
|
+
gene_list : list[str],
|
|
92
|
+
) -> CoReGraph :
|
|
93
|
+
'''
|
|
94
|
+
Reduct a CoReGraph object based on a gene list.
|
|
95
|
+
|
|
96
|
+
Parameters
|
|
97
|
+
----------
|
|
98
|
+
C : CoReGraph
|
|
99
|
+
CoReGraph object to turn into a stargraph object
|
|
100
|
+
gene_list : str
|
|
101
|
+
List of genes to keep in subsetted object
|
|
102
|
+
'''
|
|
103
|
+
id_dict = {}
|
|
104
|
+
for i, b in enumerate(C.gene_id):
|
|
105
|
+
id_dict[b] = i
|
|
106
|
+
|
|
107
|
+
shared_id = [id_dict[g] for g in gene_list]
|
|
108
|
+
shared_id.sort()
|
|
109
|
+
subdata = C.data[shared_id,:]
|
|
110
|
+
subid = [C.gene_id[g] for g in shared_id]
|
|
111
|
+
|
|
112
|
+
subobject = CoReGraph(subdata, C.pseudotime, subid, C.cell_id)
|
|
113
|
+
return subobject
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
## ANIMATIONS ##
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
import matplotlib.pyplot as plt
|
|
7
|
+
import matplotlib.patches as patches
|
|
8
|
+
|
|
9
|
+
from matplotlib.animation import FuncAnimation
|
|
10
|
+
|
|
11
|
+
from coregraph.graphics.colors import ColorBlind
|
|
12
|
+
from coregraph.analysis.queries import (get_all_correlations)
|
|
13
|
+
from coregraph.utils.decorators import (requires_cors, requires_bins)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@requires_bins
|
|
17
|
+
@requires_cors
|
|
18
|
+
def animate_correlations(
|
|
19
|
+
C: CoReGraph,
|
|
20
|
+
regulator: str,
|
|
21
|
+
target: str,
|
|
22
|
+
ref: int,
|
|
23
|
+
scaled: bool = False,
|
|
24
|
+
decimals: int = 15,
|
|
25
|
+
color: tuple = (ColorBlind[0], ColorBlind[3]),
|
|
26
|
+
linewidth: float = 1 ,
|
|
27
|
+
figsize: tuple = (8,4)
|
|
28
|
+
):
|
|
29
|
+
'''
|
|
30
|
+
Animate lagged correlations.
|
|
31
|
+
|
|
32
|
+
Parameters
|
|
33
|
+
----------
|
|
34
|
+
C : CoReGraph
|
|
35
|
+
CoReGraph object with calculated correlations
|
|
36
|
+
regulator : str
|
|
37
|
+
Gene to consider as regulator for the relationship
|
|
38
|
+
target : str
|
|
39
|
+
Gene to consider as regulated for the relationship
|
|
40
|
+
ref : int
|
|
41
|
+
Reference window to consider
|
|
42
|
+
scaled : bool
|
|
43
|
+
Whether displayed expressions has to be scaled from 0 to 1
|
|
44
|
+
decimals : int
|
|
45
|
+
Number of decimals to display for correlation values
|
|
46
|
+
color : tuple
|
|
47
|
+
Colors for each considered gene
|
|
48
|
+
linewidth : float
|
|
49
|
+
Width of expression curves
|
|
50
|
+
figsize : tuple
|
|
51
|
+
Figure width and height
|
|
52
|
+
'''
|
|
53
|
+
if C.graphics.n_bins is None:
|
|
54
|
+
raise ValueError("Bins have not been calculated.")
|
|
55
|
+
|
|
56
|
+
values = (C.graphics.scaled if scaled else C.graphics.mean)
|
|
57
|
+
reg_idx = C.gene_to_idx[regulator]
|
|
58
|
+
tar_idx = C.gene_to_idx[target]
|
|
59
|
+
y_max = np.max([values[reg_idx, :], values[tar_idx, :]]) * 1.1
|
|
60
|
+
all_cors = get_all_correlations(C, regulator, target, ref)
|
|
61
|
+
all_cors_norm = (all_cors / np.max(np.abs(all_cors)))
|
|
62
|
+
|
|
63
|
+
vmin = min(all_cors_norm)
|
|
64
|
+
vmax = max(all_cors_norm)
|
|
65
|
+
|
|
66
|
+
fig, ax = plt.subplots(1, 2, figsize=figsize, width_ratios=[25, 1],)
|
|
67
|
+
x = np.unique(C.graphics.bin_id)
|
|
68
|
+
|
|
69
|
+
# Regulator and target lines
|
|
70
|
+
ax[0].plot(x, values[reg_idx, :], color=color[0], linewidth=linewidth)
|
|
71
|
+
ax[0].plot(x, values[tar_idx, :], color=color[1], linewidth=linewidth)
|
|
72
|
+
ax[1].set(xlim=[0,1], ylim=[-1 if vmin <= 0 else 0, 1 if vmax >= 0 else 0])
|
|
73
|
+
ax[1].yaxis.tick_right()
|
|
74
|
+
ax[1].set_xticks([])
|
|
75
|
+
#ax[1].axis('off')
|
|
76
|
+
|
|
77
|
+
fixed_rect = ax[0].add_patch(patches.Rectangle((ref, 0), C.cors.window, y_max, facecolor=color[0], alpha=0.1,))
|
|
78
|
+
moving_rect = ax[0].add_patch(patches.Rectangle((0, 0), C.cors.window, y_max, facecolor=color[1], alpha=0.1,))
|
|
79
|
+
moving_bar = ax[1].add_patch(patches.Rectangle((0, 0), 0, 0, facecolor=(1,1,1), edgecolor = None, fill=True, alpha=1))
|
|
80
|
+
|
|
81
|
+
def update(frame):
|
|
82
|
+
lag = frame * C.cors.step
|
|
83
|
+
moving_rect.set_x(lag)
|
|
84
|
+
moving_bar.set_bounds(0, 0, 1, all_cors_norm[frame])
|
|
85
|
+
if all_cors_norm[frame] >= 0:
|
|
86
|
+
moving_bar.set(facecolor=(1,(1-all_cors_norm[frame])/2,(1-all_cors_norm[frame])/2))
|
|
87
|
+
else:
|
|
88
|
+
moving_bar.set(facecolor=((1+all_cors_norm[frame])/2,(1+all_cors_norm[frame])/2,1))
|
|
89
|
+
|
|
90
|
+
cor = all_cors[frame]
|
|
91
|
+
ax[0].set_title(f"lag = {lag}\ncor = {np.round(cor, decimals)}")
|
|
92
|
+
ax[1].set_title(f"{np.absolute(round(all_cors_norm[frame]*100,1))}% of MAC\n ")
|
|
93
|
+
|
|
94
|
+
return (moving_rect, moving_bar)
|
|
95
|
+
|
|
96
|
+
ani = FuncAnimation(fig, update, frames=C.cors.n_steps, blit=True)
|
|
97
|
+
#HTML(ani.to_jshtml())
|
|
98
|
+
return ani
|
|
99
|
+
|
|
100
|
+
|
|
@@ -14,7 +14,11 @@ from coregraph.analysis.queries import (get_all_correlations, get_mac)
|
|
|
14
14
|
from coregraph.utils.decorators import (requires_cors, requires_FDR)
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
def _build_correlation_tensor(
|
|
17
|
+
def _build_correlation_tensor(
|
|
18
|
+
C,
|
|
19
|
+
genes,
|
|
20
|
+
correlation_threshold
|
|
21
|
+
):
|
|
18
22
|
'''
|
|
19
23
|
Build tensor (n_genes, n_genes, n_steps) containing all dynamic correlations.
|
|
20
24
|
'''
|
|
@@ -48,7 +52,11 @@ def _build_adjacency_tensor(cor_tensor):
|
|
|
48
52
|
return filtered
|
|
49
53
|
|
|
50
54
|
|
|
51
|
-
def _compute_node_sizes(
|
|
55
|
+
def _compute_node_sizes(
|
|
56
|
+
C,
|
|
57
|
+
genes,
|
|
58
|
+
node_ratio = 1
|
|
59
|
+
):
|
|
52
60
|
'''
|
|
53
61
|
Compute node size evolution through time.
|
|
54
62
|
'''
|
|
@@ -116,15 +124,15 @@ def _draw_network_frame(ax, G, pos, genes, adjacency_matrix, node_sizes, cmap, n
|
|
|
116
124
|
def animate_network(
|
|
117
125
|
C: CoReGraph,
|
|
118
126
|
genes: list[str],
|
|
119
|
-
fdr_threshold: float=0.01,
|
|
127
|
+
fdr_threshold: float = 0.01,
|
|
120
128
|
correlation_threshold: float | None = None,
|
|
121
|
-
edge_ratio: float=1,
|
|
122
|
-
node_ratio: float=1,
|
|
123
|
-
min_target_margin: float=15,
|
|
124
|
-
min_source_margin: float=15,
|
|
125
|
-
font_size: int=8,
|
|
126
|
-
figsize: tuple=(6, 6)
|
|
127
|
-
):
|
|
129
|
+
edge_ratio: float = 1,
|
|
130
|
+
node_ratio: float = 1,
|
|
131
|
+
min_target_margin: float = 15,
|
|
132
|
+
min_source_margin: float = 15,
|
|
133
|
+
font_size: int = 8,
|
|
134
|
+
figsize: tuple = (6, 6)
|
|
135
|
+
):
|
|
128
136
|
'''
|
|
129
137
|
Animate dynamic gene regulatory network.
|
|
130
138
|
|
|
@@ -132,25 +140,25 @@ def animate_network(
|
|
|
132
140
|
----------
|
|
133
141
|
C : CoreGraph
|
|
134
142
|
CoreGraph object.
|
|
135
|
-
|
|
136
143
|
genes : list[str]
|
|
137
144
|
Genes to include in network.
|
|
138
|
-
|
|
139
145
|
fdr_threshold : float
|
|
140
146
|
FDR threshold used to infer minimum correlation threshold.
|
|
141
|
-
|
|
142
147
|
correlation_threshold : float | None
|
|
143
148
|
Correlation threshold.
|
|
144
|
-
|
|
145
149
|
edge_ratio : float
|
|
146
150
|
Edge width scaling factor.
|
|
147
|
-
|
|
148
151
|
node_ratio : float
|
|
149
152
|
Node size scaling factor.
|
|
150
|
-
|
|
153
|
+
min_target_margin : float
|
|
154
|
+
The minimum margin (gap) at the end of the edge at the target.
|
|
155
|
+
min_source_margin : float
|
|
156
|
+
The minimum margin (gap) at the beginning of the edge at the source.
|
|
157
|
+
font_size : int
|
|
158
|
+
Text size
|
|
151
159
|
figsize : tuple
|
|
152
160
|
Figure size.
|
|
153
|
-
|
|
161
|
+
'''
|
|
154
162
|
# Validate threshold
|
|
155
163
|
if correlation_threshold is None:
|
|
156
164
|
correlation_threshold = np.min(C.cors.FDR.loc[C.cors.FDR["FDR"] < fdr_threshold, "cors"])
|
|
@@ -167,13 +175,9 @@ def animate_network(
|
|
|
167
175
|
# Figure
|
|
168
176
|
fig, ax = plt.subplots(figsize=figsize)
|
|
169
177
|
cmap = cm.bwr
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
if vmin == vmax:
|
|
174
|
-
vmax += 1e-10
|
|
175
|
-
|
|
176
|
-
norm = mcolors.TwoSlopeNorm(vmin=vmin, vcenter=0.0, vmax=vmax)
|
|
178
|
+
vmax = np.max(np.abs(cor_tensor))
|
|
179
|
+
|
|
180
|
+
norm = mcolors.TwoSlopeNorm(vmin=-vmax, vcenter=0, vmax=vmax)
|
|
177
181
|
|
|
178
182
|
# Edge normalization
|
|
179
183
|
if C.cors.dtype == np.int64:
|
|
@@ -181,7 +185,6 @@ def animate_network(
|
|
|
181
185
|
else:
|
|
182
186
|
edge_ratio *= 10
|
|
183
187
|
|
|
184
|
-
|
|
185
188
|
# Update function
|
|
186
189
|
def update(frame):
|
|
187
190
|
adjacency_matrix = cor_tensor[:, :, frame]
|