napistu 0.3.6__py3-none-any.whl → 0.4.0__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.
- napistu/__main__.py +28 -13
- napistu/consensus.py +19 -25
- napistu/constants.py +102 -83
- napistu/indices.py +3 -1
- napistu/ingestion/napistu_edgelist.py +4 -4
- napistu/ingestion/sbml.py +298 -295
- napistu/ingestion/string.py +14 -18
- napistu/ingestion/trrust.py +22 -27
- napistu/matching/interactions.py +41 -39
- napistu/matching/species.py +1 -1
- napistu/modify/gaps.py +2 -1
- napistu/network/constants.py +61 -45
- napistu/network/data_handling.py +1 -1
- napistu/network/neighborhoods.py +3 -3
- napistu/network/net_create.py +440 -616
- napistu/network/net_create_utils.py +734 -0
- napistu/network/net_propagation.py +1 -1
- napistu/network/{napistu_graph_core.py → ng_core.py} +57 -15
- napistu/network/ng_utils.py +28 -21
- napistu/network/paths.py +4 -4
- napistu/network/precompute.py +35 -74
- napistu/ontologies/genodexito.py +5 -1
- napistu/ontologies/renaming.py +4 -0
- napistu/sbml_dfs_core.py +127 -64
- napistu/sbml_dfs_utils.py +50 -0
- napistu/utils.py +132 -46
- {napistu-0.3.6.dist-info → napistu-0.4.0.dist-info}/METADATA +2 -2
- {napistu-0.3.6.dist-info → napistu-0.4.0.dist-info}/RECORD +47 -44
- tests/conftest.py +171 -13
- tests/test_consensus.py +74 -5
- tests/test_gaps.py +26 -15
- tests/test_network_data_handling.py +5 -2
- tests/test_network_net_create.py +93 -202
- tests/test_network_net_create_utils.py +538 -0
- tests/test_network_ng_core.py +19 -0
- tests/test_network_ng_utils.py +1 -1
- tests/test_network_precompute.py +5 -4
- tests/test_ontologies_renaming.py +28 -24
- tests/test_rpy2_callr.py +0 -1
- tests/test_rpy2_init.py +0 -1
- tests/test_sbml_dfs_core.py +165 -15
- tests/test_sbml_dfs_utils.py +45 -0
- tests/test_utils.py +45 -2
- {napistu-0.3.6.dist-info → napistu-0.4.0.dist-info}/WHEEL +0 -0
- {napistu-0.3.6.dist-info → napistu-0.4.0.dist-info}/entry_points.txt +0 -0
- {napistu-0.3.6.dist-info → napistu-0.4.0.dist-info}/licenses/LICENSE +0 -0
- {napistu-0.3.6.dist-info → napistu-0.4.0.dist-info}/top_level.txt +0 -0
tests/test_network_net_create.py
CHANGED
@@ -1,125 +1,101 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import os
|
4
|
-
import pytest
|
5
4
|
|
6
5
|
import numpy as np
|
7
6
|
import pandas as pd
|
7
|
+
import pandas.testing as pdt
|
8
|
+
import pytest
|
8
9
|
|
9
10
|
from napistu import sbml_dfs_core
|
10
11
|
from napistu.ingestion import sbml
|
11
12
|
from napistu.network import net_create
|
13
|
+
from napistu.network import net_create_utils
|
12
14
|
from napistu.network import ng_utils
|
13
|
-
from napistu.constants import MINI_SBO_FROM_NAME
|
14
15
|
from napistu.constants import SBML_DFS
|
15
|
-
from napistu.network.constants import
|
16
|
-
|
17
|
-
|
16
|
+
from napistu.network.constants import (
|
17
|
+
DROP_REACTIONS_WHEN,
|
18
|
+
DEFAULT_WT_TRANS,
|
19
|
+
WEIGHTING_SPEC,
|
20
|
+
GRAPH_WIRING_APPROACHES,
|
21
|
+
NAPISTU_GRAPH_EDGES,
|
22
|
+
VALID_GRAPH_WIRING_APPROACHES,
|
23
|
+
)
|
18
24
|
|
19
25
|
test_path = os.path.abspath(os.path.join(__file__, os.pardir))
|
20
26
|
test_data = os.path.join(test_path, "test_data")
|
21
27
|
|
22
28
|
sbml_path = os.path.join(test_data, "R-HSA-1237044.sbml")
|
23
|
-
sbml_model = sbml.SBML(sbml_path)
|
29
|
+
sbml_model = sbml.SBML(sbml_path)
|
24
30
|
sbml_dfs = sbml_dfs_core.SBML_dfs(sbml_model)
|
25
31
|
|
26
32
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
"sbo_term": [
|
38
|
-
MINI_SBO_FROM_NAME["interactor"],
|
39
|
-
MINI_SBO_FROM_NAME["interactor"],
|
40
|
-
],
|
41
|
-
"sc_id": ["sc1", "sc2"],
|
42
|
-
"stoichiometry": [0, 0],
|
43
|
-
}
|
44
|
-
).set_index(["r_id", "sbo_term"])
|
45
|
-
d["invalid_interactor"] = pd.DataFrame(
|
46
|
-
{
|
47
|
-
"r_id": [r_id, r_id],
|
48
|
-
"sbo_term": [
|
49
|
-
MINI_SBO_FROM_NAME["interactor"],
|
50
|
-
MINI_SBO_FROM_NAME["product"],
|
51
|
-
],
|
52
|
-
"sc_id": ["sc1", "sc2"],
|
53
|
-
"stoichiometry": [0, 0],
|
54
|
-
}
|
55
|
-
).set_index(["r_id", "sbo_term"])
|
56
|
-
d["sub_and_prod"] = pd.DataFrame(
|
57
|
-
{
|
58
|
-
"r_id": [r_id, r_id],
|
59
|
-
"sbo_term": [MINI_SBO_FROM_NAME["reactant"], MINI_SBO_FROM_NAME["product"]],
|
60
|
-
"sc_id": ["sub", "prod"],
|
61
|
-
"stoichiometry": [-1, 1],
|
62
|
-
}
|
63
|
-
).set_index(["r_id", "sbo_term"])
|
64
|
-
d["stimulator"] = pd.DataFrame(
|
65
|
-
{
|
66
|
-
"r_id": [r_id, r_id, r_id],
|
67
|
-
"sbo_term": [
|
68
|
-
MINI_SBO_FROM_NAME["reactant"],
|
69
|
-
MINI_SBO_FROM_NAME["product"],
|
70
|
-
MINI_SBO_FROM_NAME["stimulator"],
|
71
|
-
],
|
72
|
-
"sc_id": ["sub", "prod", "stim"],
|
73
|
-
"stoichiometry": [-1, 1, 0],
|
74
|
-
}
|
75
|
-
).set_index(["r_id", "sbo_term"])
|
76
|
-
d["all_entities"] = pd.DataFrame(
|
77
|
-
{
|
78
|
-
"r_id": [r_id, r_id, r_id, r_id],
|
79
|
-
"sbo_term": [
|
80
|
-
MINI_SBO_FROM_NAME["reactant"],
|
81
|
-
MINI_SBO_FROM_NAME["product"],
|
82
|
-
MINI_SBO_FROM_NAME["stimulator"],
|
83
|
-
MINI_SBO_FROM_NAME["catalyst"],
|
84
|
-
],
|
85
|
-
"sc_id": ["sub", "prod", "stim", "cat"],
|
86
|
-
"stoichiometry": [-1, 1, 0, 0],
|
87
|
-
}
|
88
|
-
).set_index(["r_id", "sbo_term"])
|
89
|
-
d["no_substrate"] = pd.DataFrame(
|
90
|
-
{
|
91
|
-
"r_id": [r_id, r_id, r_id, r_id, r_id],
|
92
|
-
"sbo_term": [
|
93
|
-
MINI_SBO_FROM_NAME["product"],
|
94
|
-
MINI_SBO_FROM_NAME["stimulator"],
|
95
|
-
MINI_SBO_FROM_NAME["stimulator"],
|
96
|
-
MINI_SBO_FROM_NAME["inhibitor"],
|
97
|
-
MINI_SBO_FROM_NAME["catalyst"],
|
98
|
-
],
|
99
|
-
"sc_id": ["prod", "stim1", "stim2", "inh", "cat"],
|
100
|
-
"stoichiometry": [1, 0, 0, 0, 0],
|
101
|
-
}
|
102
|
-
).set_index(["r_id", "sbo_term"])
|
33
|
+
def test_create_napistu_graph():
|
34
|
+
_ = net_create.create_napistu_graph(
|
35
|
+
sbml_dfs, wiring_approach=GRAPH_WIRING_APPROACHES.BIPARTITE
|
36
|
+
)
|
37
|
+
_ = net_create.create_napistu_graph(
|
38
|
+
sbml_dfs, wiring_approach=GRAPH_WIRING_APPROACHES.REGULATORY
|
39
|
+
)
|
40
|
+
_ = net_create.create_napistu_graph(
|
41
|
+
sbml_dfs, wiring_approach=GRAPH_WIRING_APPROACHES.SURROGATE
|
42
|
+
)
|
103
43
|
|
104
|
-
return r_id, d
|
105
44
|
|
45
|
+
def test_bipartite_regression():
|
46
|
+
bipartite_og = net_create.create_napistu_graph(
|
47
|
+
sbml_dfs, wiring_approach="bipartite_og"
|
48
|
+
)
|
106
49
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
50
|
+
bipartite = net_create.create_napistu_graph(
|
51
|
+
sbml_dfs, wiring_approach=GRAPH_WIRING_APPROACHES.BIPARTITE
|
52
|
+
)
|
53
|
+
|
54
|
+
bipartite_og_edges = bipartite_og.get_edge_dataframe()
|
55
|
+
bipartite_edges = bipartite.get_edge_dataframe()
|
56
|
+
|
57
|
+
try:
|
58
|
+
pdt.assert_frame_equal(
|
59
|
+
bipartite_og_edges, bipartite_edges, check_like=True, check_dtype=False
|
60
|
+
)
|
61
|
+
except AssertionError as e:
|
62
|
+
# Print detailed differences
|
63
|
+
print("DataFrames are not equal!")
|
64
|
+
print(
|
65
|
+
"Shape original:",
|
66
|
+
bipartite_og_edges.shape,
|
67
|
+
"Shape new:",
|
68
|
+
bipartite_edges.shape,
|
69
|
+
)
|
70
|
+
print(
|
71
|
+
"Columns original:",
|
72
|
+
bipartite_og_edges.columns.tolist(),
|
73
|
+
"Columns new:",
|
74
|
+
bipartite_edges.columns.tolist(),
|
75
|
+
)
|
76
|
+
# Show head of both for quick inspection
|
77
|
+
print("Original head:\n", bipartite_og_edges.head())
|
78
|
+
print("New head:\n", bipartite_edges.head())
|
79
|
+
# Optionally, show where values differ
|
80
|
+
if bipartite_og_edges.shape == bipartite_edges.shape:
|
81
|
+
diff = bipartite_og_edges != bipartite_edges
|
82
|
+
print("Differences (first 5 rows):\n", diff.head())
|
83
|
+
raise e # Re-raise to fail the test
|
111
84
|
|
112
85
|
|
113
86
|
def test_create_napistu_graph_edge_reversed():
|
114
87
|
"""Test that edge_reversed=True properly reverses edges in the graph for all graph types."""
|
115
88
|
# Test each graph type
|
116
|
-
for
|
89
|
+
for wiring_approach in VALID_GRAPH_WIRING_APPROACHES:
|
117
90
|
# Create graphs with and without edge reversal
|
118
91
|
normal_graph = net_create.create_napistu_graph(
|
119
|
-
sbml_dfs,
|
92
|
+
sbml_dfs,
|
93
|
+
wiring_approach=wiring_approach,
|
94
|
+
directed=True,
|
95
|
+
edge_reversed=False,
|
120
96
|
)
|
121
97
|
reversed_graph = net_create.create_napistu_graph(
|
122
|
-
sbml_dfs,
|
98
|
+
sbml_dfs, wiring_approach=wiring_approach, directed=True, edge_reversed=True
|
123
99
|
)
|
124
100
|
|
125
101
|
# Get edge dataframes for comparison
|
@@ -127,53 +103,55 @@ def test_create_napistu_graph_edge_reversed():
|
|
127
103
|
reversed_edges = reversed_graph.get_edge_dataframe()
|
128
104
|
|
129
105
|
# Verify we have edges to test
|
130
|
-
assert len(normal_edges) > 0, f"No edges found in {
|
106
|
+
assert len(normal_edges) > 0, f"No edges found in {wiring_approach} graph"
|
131
107
|
assert len(normal_edges) == len(
|
132
108
|
reversed_edges
|
133
|
-
), f"Edge count mismatch in {
|
109
|
+
), f"Edge count mismatch in {wiring_approach} graph"
|
134
110
|
|
135
111
|
# Test edge reversal
|
136
112
|
# Check a few edges to verify from/to are swapped
|
137
113
|
for i in range(min(5, len(normal_edges))):
|
138
114
|
# Check from/to are swapped
|
139
115
|
assert (
|
140
|
-
normal_edges.iloc[i][
|
141
|
-
|
116
|
+
normal_edges.iloc[i][NAPISTU_GRAPH_EDGES.FROM]
|
117
|
+
== reversed_edges.iloc[i][NAPISTU_GRAPH_EDGES.TO]
|
118
|
+
), f"From/to not properly swapped in {wiring_approach} graph"
|
142
119
|
assert (
|
143
|
-
normal_edges.iloc[i][
|
144
|
-
|
120
|
+
normal_edges.iloc[i][NAPISTU_GRAPH_EDGES.TO]
|
121
|
+
== reversed_edges.iloc[i][NAPISTU_GRAPH_EDGES.FROM]
|
122
|
+
), f"From/to not properly swapped in {wiring_approach} graph"
|
145
123
|
|
146
124
|
# Check stoichiometry is negated
|
147
125
|
assert (
|
148
|
-
normal_edges.iloc[i][
|
149
|
-
== -reversed_edges.iloc[i][
|
150
|
-
), f"Stoichiometry not properly negated in {
|
126
|
+
normal_edges.iloc[i][SBML_DFS.STOICHIOMETRY]
|
127
|
+
== -reversed_edges.iloc[i][SBML_DFS.STOICHIOMETRY]
|
128
|
+
), f"Stoichiometry not properly negated in {wiring_approach} graph"
|
151
129
|
|
152
130
|
# Check direction attributes are properly swapped
|
153
131
|
if normal_edges.iloc[i]["direction"] == "forward":
|
154
132
|
assert (
|
155
133
|
reversed_edges.iloc[i]["direction"] == "reverse"
|
156
|
-
), f"Direction not properly reversed (forward->reverse) in {
|
134
|
+
), f"Direction not properly reversed (forward->reverse) in {wiring_approach} graph"
|
157
135
|
elif normal_edges.iloc[i]["direction"] == "reverse":
|
158
136
|
assert (
|
159
137
|
reversed_edges.iloc[i]["direction"] == "forward"
|
160
|
-
), f"Direction not properly reversed (reverse->forward) in {
|
138
|
+
), f"Direction not properly reversed (reverse->forward) in {wiring_approach} graph"
|
161
139
|
|
162
140
|
# Check parents/children are swapped
|
163
141
|
assert (
|
164
142
|
normal_edges.iloc[i]["sc_parents"]
|
165
143
|
== reversed_edges.iloc[i]["sc_children"]
|
166
|
-
), f"Parents/children not properly swapped in {
|
144
|
+
), f"Parents/children not properly swapped in {wiring_approach} graph"
|
167
145
|
assert (
|
168
146
|
normal_edges.iloc[i]["sc_children"]
|
169
147
|
== reversed_edges.iloc[i]["sc_parents"]
|
170
|
-
), f"Parents/children not properly swapped in {
|
148
|
+
), f"Parents/children not properly swapped in {wiring_approach} graph"
|
171
149
|
|
172
150
|
|
173
151
|
def test_create_napistu_graph_none_attrs():
|
174
152
|
# Should not raise when reaction_graph_attrs is None
|
175
153
|
_ = net_create.create_napistu_graph(
|
176
|
-
sbml_dfs, reaction_graph_attrs=None,
|
154
|
+
sbml_dfs, reaction_graph_attrs=None, wiring_approach="bipartite"
|
177
155
|
)
|
178
156
|
|
179
157
|
|
@@ -186,29 +164,29 @@ def test_process_napistu_graph_none_attrs():
|
|
186
164
|
def test_igraph_loading():
|
187
165
|
# test read/write of an igraph network
|
188
166
|
directeds = [True, False]
|
189
|
-
|
167
|
+
wiring_approaches = ["bipartite", "regulatory"]
|
190
168
|
|
191
169
|
ng_utils.export_networks(
|
192
170
|
sbml_dfs,
|
193
171
|
model_prefix="tmp",
|
194
172
|
outdir="/tmp",
|
195
173
|
directeds=directeds,
|
196
|
-
|
174
|
+
wiring_approaches=wiring_approaches,
|
197
175
|
)
|
198
176
|
|
199
|
-
for
|
177
|
+
for wiring_approach in wiring_approaches:
|
200
178
|
for directed in directeds:
|
201
179
|
import_pkl_path = ng_utils._create_network_save_string(
|
202
180
|
model_prefix="tmp",
|
203
181
|
outdir="/tmp",
|
204
182
|
directed=directed,
|
205
|
-
|
183
|
+
wiring_approach=wiring_approach,
|
206
184
|
)
|
207
185
|
network_graph = ng_utils.read_network_pkl(
|
208
186
|
model_prefix="tmp",
|
209
187
|
network_dir="/tmp",
|
210
188
|
directed=directed,
|
211
|
-
|
189
|
+
wiring_approach=wiring_approach,
|
212
190
|
)
|
213
191
|
|
214
192
|
assert network_graph.is_directed() == directed
|
@@ -216,102 +194,15 @@ def test_igraph_loading():
|
|
216
194
|
os.unlink(import_pkl_path)
|
217
195
|
|
218
196
|
|
219
|
-
def test_format_interactors(reaction_species_examples):
|
220
|
-
r_id, reaction_species_examples_dict = reaction_species_examples
|
221
|
-
# interactions are formatted
|
222
|
-
|
223
|
-
graph_hierarchy_df = net_create._create_graph_hierarchy_df("regulatory")
|
224
|
-
|
225
|
-
assert (
|
226
|
-
net_create._format_tiered_reaction_species(
|
227
|
-
r_id,
|
228
|
-
reaction_species_examples_dict["valid_interactor"],
|
229
|
-
sbml_dfs,
|
230
|
-
graph_hierarchy_df,
|
231
|
-
).shape[0]
|
232
|
-
== 1
|
233
|
-
)
|
234
|
-
|
235
|
-
print("Re-enable test once Issue #102 is solved")
|
236
|
-
|
237
|
-
# catch error from invalid interactor specification
|
238
|
-
# with pytest.raises(ValueError) as excinfo:
|
239
|
-
# net_create._format_tiered_reaction_species(
|
240
|
-
# r_id, reaction_species_examples_dict["invalid_interactor"], sbml_dfs
|
241
|
-
# )
|
242
|
-
# assert str(excinfo.value).startswith("Invalid combinations of SBO_terms")
|
243
|
-
|
244
|
-
# simple reaction with just substrates and products
|
245
|
-
assert (
|
246
|
-
net_create._format_tiered_reaction_species(
|
247
|
-
r_id,
|
248
|
-
reaction_species_examples_dict["sub_and_prod"],
|
249
|
-
sbml_dfs,
|
250
|
-
graph_hierarchy_df,
|
251
|
-
).shape[0]
|
252
|
-
== 2
|
253
|
-
)
|
254
|
-
|
255
|
-
# add a stimulator (activator)
|
256
|
-
rxn_edges = net_create._format_tiered_reaction_species(
|
257
|
-
r_id, reaction_species_examples_dict["stimulator"], sbml_dfs, graph_hierarchy_df
|
258
|
-
)
|
259
|
-
|
260
|
-
assert rxn_edges.shape[0] == 3
|
261
|
-
assert rxn_edges.iloc[0][["from", "to"]].tolist() == ["stim", "sub"]
|
262
|
-
|
263
|
-
# add catalyst + stimulator
|
264
|
-
rxn_edges = net_create._format_tiered_reaction_species(
|
265
|
-
r_id,
|
266
|
-
reaction_species_examples_dict["all_entities"],
|
267
|
-
sbml_dfs,
|
268
|
-
graph_hierarchy_df,
|
269
|
-
)
|
270
|
-
|
271
|
-
assert rxn_edges.shape[0] == 4
|
272
|
-
assert rxn_edges.iloc[0][["from", "to"]].tolist() == ["stim", "cat"]
|
273
|
-
assert rxn_edges.iloc[1][["from", "to"]].tolist() == ["cat", "sub"]
|
274
|
-
|
275
|
-
# no substrate
|
276
|
-
rxn_edges = net_create._format_tiered_reaction_species(
|
277
|
-
r_id,
|
278
|
-
reaction_species_examples_dict["no_substrate"],
|
279
|
-
sbml_dfs,
|
280
|
-
graph_hierarchy_df,
|
281
|
-
)
|
282
|
-
|
283
|
-
assert rxn_edges.shape[0] == 5
|
284
|
-
# stimulator -> reactant
|
285
|
-
assert rxn_edges.iloc[0][["from", "to"]].tolist() == ["stim1", "cat"]
|
286
|
-
assert rxn_edges.iloc[1][["from", "to"]].tolist() == ["stim2", "cat"]
|
287
|
-
assert rxn_edges.iloc[2][["from", "to"]].tolist() == ["inh", "cat"]
|
288
|
-
|
289
|
-
# use the surrogate model tiered layout also
|
290
|
-
|
291
|
-
graph_hierarchy_df = net_create._create_graph_hierarchy_df("surrogate")
|
292
|
-
|
293
|
-
rxn_edges = net_create._format_tiered_reaction_species(
|
294
|
-
r_id,
|
295
|
-
reaction_species_examples_dict["all_entities"],
|
296
|
-
sbml_dfs,
|
297
|
-
graph_hierarchy_df,
|
298
|
-
)
|
299
|
-
|
300
|
-
assert rxn_edges.shape[0] == 4
|
301
|
-
assert rxn_edges.iloc[0][["from", "to"]].tolist() == ["stim", "sub"]
|
302
|
-
assert rxn_edges.iloc[1][["from", "to"]].tolist() == ["sub", "cat"]
|
303
|
-
|
304
|
-
|
305
197
|
def test_reverse_network_edges(reaction_species_examples):
|
306
|
-
r_id, reaction_species_examples_dict = reaction_species_examples
|
307
198
|
|
308
|
-
graph_hierarchy_df =
|
199
|
+
graph_hierarchy_df = net_create_utils.create_graph_hierarchy_df("regulatory")
|
309
200
|
|
310
|
-
rxn_edges =
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
201
|
+
rxn_edges = net_create_utils.format_tiered_reaction_species(
|
202
|
+
rxn_species=reaction_species_examples["all_entities"],
|
203
|
+
r_id="foo",
|
204
|
+
graph_hierarchy_df=graph_hierarchy_df,
|
205
|
+
drop_reactions_when=DROP_REACTIONS_WHEN.SAME_TIER,
|
315
206
|
)
|
316
207
|
augmented_network_edges = rxn_edges.assign(r_isreversible=True)
|
317
208
|
augmented_network_edges["sc_parents"] = range(0, augmented_network_edges.shape[0])
|