napistu 0.3.6__py3-none-any.whl → 0.3.7__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.
@@ -1,13 +1,13 @@
1
1
  napistu/__init__.py,sha256=dFXAhIqlTLJMwowS4BUDT08-Vy3Q0u1L0CMCErSZT1Y,239
2
- napistu/__main__.py,sha256=JnPRdK9Revwpi0pouC7ZIZAMEunh9NIFuaq91RlPaR0,28648
3
- napistu/consensus.py,sha256=jsWpoXOzmNklFKasgOa5NEqbhoZvsgY0rLMFQddi6Vo,69945
4
- napistu/constants.py,sha256=IhjZZgP0Yb3pPn5mV5SeTWiimRSG2hH02UX_Y6c_aOo,12388
2
+ napistu/__main__.py,sha256=cml91Be1r_eyWeel_KNSWC-42AbMXWsrKZGf4PVgkaE,28997
3
+ napistu/consensus.py,sha256=xWXiqIM6ot-SSPJZXTrVpohbINSCkZXBtRi-5REfk_g,69897
4
+ napistu/constants.py,sha256=dbofeN0HKdmjYluyKuj6nfiL88j69otPhuw2krEhHz8,13240
5
5
  napistu/identifiers.py,sha256=e2-nTVzr5AINa0y1ER9218bKXyF2kAeJ9At22S4Z00o,33914
6
- napistu/indices.py,sha256=E_djN1XWc6l1lrFw_QnQXfZTKYTaUv8-jFPP7cHkY5A,9780
7
- napistu/sbml_dfs_core.py,sha256=ntZfuKrjf42MV1EXhKUro298a1aSd6t6M-tt141x634,71129
8
- napistu/sbml_dfs_utils.py,sha256=aXbQIlx7Yv7TH_7YxSuHZLsf6w2UXd_iOzpALKzg608,43506
6
+ napistu/indices.py,sha256=Zjg3gE0JQ3T879lCPazYg-WXVE6hvcAr713ZKpJ32rk,9830
7
+ napistu/sbml_dfs_core.py,sha256=3Z2Kg-aVnZMGK9iK-_vztY2ORgNpta8BUMuWEZg80iE,73125
8
+ napistu/sbml_dfs_utils.py,sha256=M0qNbxWkVnPCeUYTBZAD5i4PgV66qu6JE36Eb1dKaMw,43617
9
9
  napistu/source.py,sha256=UGpN70bqbC9gnKmM0ivSdQYim9hfzgABeXoQKzRr9oU,13646
10
- napistu/utils.py,sha256=TcholWrFbRSu_sn9ODMA8y2YyAhekEKZjwf4S0WQNzI,33241
10
+ napistu/utils.py,sha256=ckYaIYjUOy22A3ojS7wSUabq_A1rJMMOk6QLrcbr3sU,33560
11
11
  napistu/context/__init__.py,sha256=LQBEqipcHKK0E5UlDEg1ct-ymCs93IlUrUaH8BCevf0,242
12
12
  napistu/context/discretize.py,sha256=Qq7zg46F_I-PvQIT2_pEDQV7YEtUQCxKoRvT5Gu9QsE,15052
13
13
  napistu/context/filtering.py,sha256=l1oq-43ysSGqU9VmhTOO_pYT4DSMf20yxvktPC1MI0I,13696
@@ -25,15 +25,15 @@ napistu/ingestion/napistu_edgelist.py,sha256=eVT9M7gmdBuGHcAYlvkD_zzvTtyzXufKWjw
25
25
  napistu/ingestion/obo.py,sha256=AQkIPWbjA464Lma0tx91JucWkIwLjC7Jgv5VHGRTDkE,9601
26
26
  napistu/ingestion/psi_mi.py,sha256=5eJjm7XWogL9oTyGqR52kntHClLwLsTePKqCvUGyi-w,10111
27
27
  napistu/ingestion/reactome.py,sha256=Hn9X-vDp4o_HK-OtaQvel3vJeZ8_TC1-4N2rruK9Oks,7099
28
- napistu/ingestion/sbml.py,sha256=N7neMwjTEF7OMhAcNvQJ29V_d3PqMLjLOZqvJTlK9q0,24743
29
- napistu/ingestion/string.py,sha256=eLboW-dkaaiypwW6DxM3P1mGVweM3wqGsJPYKyImMAI,11713
30
- napistu/ingestion/trrust.py,sha256=ccjZc_eF3PdxxurnukiEo_e0-aKc_3z22NYbaJBtHdY,9774
28
+ napistu/ingestion/sbml.py,sha256=l8Z98yWuOIRGns8G4UNnoQz7v_xmukZb_IZ_5ye34Ko,25296
29
+ napistu/ingestion/string.py,sha256=go1WGTkoLJejX7GQWf9bFeInFGAw4jNSpS2B_Zr5f_s,11364
30
+ napistu/ingestion/trrust.py,sha256=_6hIS48O3tRpMxX-FdIC57ekhCcV7J4owUzoaYnRqZo,9204
31
31
  napistu/ingestion/yeast.py,sha256=7XwdkmgOnG1MYauKSk9nSK6fHemDrtXEPcS4ebs1_so,5268
32
32
  napistu/matching/__init__.py,sha256=dFXAhIqlTLJMwowS4BUDT08-Vy3Q0u1L0CMCErSZT1Y,239
33
33
  napistu/matching/constants.py,sha256=j4XSOE9Bpma9F6apVJ1LijKOUPgRk8Geo_u_rvNtpSU,610
34
34
  napistu/matching/interactions.py,sha256=XrzZvH1zgeaZLq3qhpsV0tx4BFgvNvkjM47l8ZUEOH4,18798
35
35
  napistu/matching/mount.py,sha256=8JEtiDIy7qdjWyDAs0vuVwEQkpwRf5ah4xMLZ4jKHag,19428
36
- napistu/matching/species.py,sha256=5-hmH8_UrvDmGfeJ1283trkCtPOC3BEmtYPcMHuZyNY,18893
36
+ napistu/matching/species.py,sha256=U8OfzmDN9dMwemdnzQdV19bWfjY8MLJ9-wf83siK1bM,18888
37
37
  napistu/mcp/__init__.py,sha256=EmtcdtYyfhXdxxPB5cY_pshXnFv6XZ5CtRU0JMHn3aQ,2074
38
38
  napistu/mcp/__main__.py,sha256=o9C4J3YHkfh_pQi-K9OC5bwFmsNWHuK2l8GL7M90uFc,8057
39
39
  napistu/mcp/client.py,sha256=Zyy7unFFq9XPBDrr2Hl7dMVDTGoZbtj_YFuUH18QScs,6350
@@ -71,9 +71,9 @@ napistu/network/precompute.py,sha256=pIXCCE6Mf6HY8o-fiwUaOxvQ_9_mevK0vaC8fND4RZk
71
71
  napistu/ontologies/__init__.py,sha256=dFXAhIqlTLJMwowS4BUDT08-Vy3Q0u1L0CMCErSZT1Y,239
72
72
  napistu/ontologies/constants.py,sha256=GyOFvezSxDK1VigATcruTKtNhjcYaid1ggulEf_HEtQ,4345
73
73
  napistu/ontologies/dogma.py,sha256=VVj6NKBgNym4SdOSu8g22OohALj7cbObhIJmdY2Sfy0,8860
74
- napistu/ontologies/genodexito.py,sha256=5_gtdVtKHp5z-jtPXkHlZRiTsuHdZeA3TVI9u4SXqrQ,24725
74
+ napistu/ontologies/genodexito.py,sha256=ZZmb7V38BmFjy9VOGdxbD3-BD5tKGl5izr0nwO_eEdA,24967
75
75
  napistu/ontologies/mygene.py,sha256=RMFQTWsLkeYxmsOPxxmeIya2phdcUMcF5V2abaS8MVg,11109
76
- napistu/ontologies/renaming.py,sha256=bL15T0CswjM81NFVIVp-3CEsa1kxIIk2xJ2kE5eTeeg,6817
76
+ napistu/ontologies/renaming.py,sha256=aZR5oxjeZhse026fuvFyQiKM8PVzbBT915J8AfXGv1M,7006
77
77
  napistu/rpy2/__init__.py,sha256=8WzSK_tmdcbyMUtb17OmqdQqbisqIBl8OQrDsaFDeX4,8356
78
78
  napistu/rpy2/callr.py,sha256=yFCGobZTVgH1vJc5h0njAflvFr6zmCWIP-uuLWnZL-g,3701
79
79
  napistu/rpy2/constants.py,sha256=3thZa4UUfpDpXaUzGcqfDEyEIQaf4a_C01-O2pciZ7c,2760
@@ -81,15 +81,15 @@ napistu/rpy2/rids.py,sha256=AfXLTfTdonfspgAHYO0Ph7jSUWv8YuyT8x3fyLfAqc8,3413
81
81
  napistu/scverse/__init__.py,sha256=Lgxr3iMQAkTzXE9BNz93CndNP5djzerLvmHM-D0PU3I,357
82
82
  napistu/scverse/constants.py,sha256=0iAkhyJUIeFGHdLLU3fCaEU1O3Oix4qAsxr3CxGTjVs,653
83
83
  napistu/scverse/loading.py,sha256=jqiE71XB-wdV50GyZrauFNY0Lai4bX9Fm2Gv80VR8t8,27016
84
- napistu-0.3.6.dist-info/licenses/LICENSE,sha256=kW8wVT__JWoHjl2BbbJDAZInWa9AxzJeR_uv6-i5x1g,1063
84
+ napistu-0.3.7.dist-info/licenses/LICENSE,sha256=kW8wVT__JWoHjl2BbbJDAZInWa9AxzJeR_uv6-i5x1g,1063
85
85
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
86
- tests/conftest.py,sha256=v8ZxJKqglEPlQ5ew3hM5eJQW2N0YhX9dOAaOQqdjyIc,4325
87
- tests/test_consensus.py,sha256=qnf6Ntc3q7oCji1aisH9Ziy6KbnQCf1REizinR8ier8,12454
86
+ tests/conftest.py,sha256=Tdw9-uYpnV1ZvdO9k9oto-JDEqMOTF05fsVps-EpmCE,6240
87
+ tests/test_consensus.py,sha256=Hzfrgp4SpkRDnEMVMD3f0UInSycndB8kKzC4wDDvRas,15076
88
88
  tests/test_constants.py,sha256=gJLDv7QMeeBiiupyMazj6mumk20KWvGMgm2myHMKKfc,531
89
89
  tests/test_context_discretize.py,sha256=5Mr9WqwHGYMO37M1TnMmSfC64UZ73mnoCiEM2IQHVDY,1667
90
90
  tests/test_context_filtering.py,sha256=5dwC2d-99CpLdnzzTf2NvEzsRuwiIj-YU8NFqwtWp0g,9485
91
91
  tests/test_curation.py,sha256=-Q2J0D7qs9PGjHZX-rM4NxRLLdwxoapytSo_98q9ItY,3864
92
- tests/test_gaps.py,sha256=mGGeyx1vUnmEOF__bsqfCYq9Y8a1P-9mefqna4Qgc_k,4062
92
+ tests/test_gaps.py,sha256=GBRb0E0RUwhXz2PsnfTsGszKDsHHvH-E3x9hUZG1DhM,4550
93
93
  tests/test_gcs.py,sha256=p_uQWuY2TcGj3zV3qFC-GXBqj4St8YENR_XRpQ6UH5g,570
94
94
  tests/test_identifiers.py,sha256=9QlGCG27zposzEvazEuZqoMausNMLLuUwfA3FuYU1mc,8345
95
95
  tests/test_indices.py,sha256=e_8GSNzIT4JHGmelX9PseJzFXTxo-TQAus3r21AUt7I,4547
@@ -104,30 +104,30 @@ tests/test_mcp_server.py,sha256=bP3PWVQsEfX6-lAgXKP32njdg__o65n2WuLvkxTTHkQ,1121
104
104
  tests/test_network_data_handling.py,sha256=oBSZuB3IRG9bwmD6n8FY-UZLe2UqGzXpNSxVtkHRSvE,12605
105
105
  tests/test_network_ig_utils.py,sha256=Buoh570mNm5pcac3Hf6f3pevCjWfBwPfKuD8IkDLg58,2120
106
106
  tests/test_network_neighborhoods.py,sha256=8BV17m5X1OUd5FwasTTYUOkNYUHDPUkxOKH_VZCsyBE,631
107
- tests/test_network_net_create.py,sha256=VNFZTwQawAZQPDnVk_qFevgZErx5KyQZ24bMoZF4T4w,16462
107
+ tests/test_network_net_create.py,sha256=LDjkA9boX8kH4wCLOpa0ENwN6JZU2c29w3qpYlhQ6Rs,16456
108
108
  tests/test_network_net_propagation.py,sha256=9pKkUdduWejH4iKNCJXKFzAkdNpCfrMbiUWySgI_LH4,3244
109
109
  tests/test_network_ng_utils.py,sha256=CwDw4MKTPhVZXz2HA2XU2QjjBv8CXc1_yQ0drvkBkFw,724
110
110
  tests/test_network_paths.py,sha256=TWZnxY5bF3m6gahcxcYJGrBIawh2-_vUcec1LyPmXV8,1686
111
- tests/test_network_precompute.py,sha256=xMGmZI9DxcWhJxuP7GCZEqtmcOvDRNK2LSia0x94v0U,9018
111
+ tests/test_network_precompute.py,sha256=8HqTSXdxdXuQqNewP3xxsps9UEtw6OVgPN_lUywXiNg,9012
112
112
  tests/test_ontologies_genodexito.py,sha256=6fINyUiubHZqu7qxye09DQfJXw28ZMAJc3clPb-cCoY,2298
113
113
  tests/test_ontologies_mygene.py,sha256=VkdRcKIWmcG6V-2dpfvsBiOJN5dO-j0RqZNxtJRcyBU,1583
114
- tests/test_ontologies_renaming.py,sha256=k7bQzP24zG7W3fpULwk1me2sOWEWlxylr4Mhx1_gJJY,3740
114
+ tests/test_ontologies_renaming.py,sha256=pawp3pV1hxW8nskWc4f2YHwMUqTilEEBD2BtpcSay5Q,3839
115
115
  tests/test_pathwayannot.py,sha256=bceosccNy9tgxQei_7j7ATBSSvBSxOngJvK-mAzR_K0,3312
116
116
  tests/test_rpy2_callr.py,sha256=UVzXMvYN3wcc-ikDIjH2sA4BqkbwiNbMm561BcbnbD4,2936
117
117
  tests/test_rpy2_init.py,sha256=APrNt9GEQV9va3vU5k250TxFplAoWFc-FJRFhM2GcDk,5927
118
118
  tests/test_sbml.py,sha256=f25zj1NogYrmLluvBDboLameTuCiQ309433Qn3iPvhg,1483
119
- tests/test_sbml_dfs_core.py,sha256=Gef-wf0AI7adwS_CBUokiJCw7yyGzInwAUnAj7IRE-E,20311
119
+ tests/test_sbml_dfs_core.py,sha256=CH5OXNSAozWTl6qBvbHfgTG0NcgdlKJ_WcG0lTYBm3k,26217
120
120
  tests/test_sbml_dfs_utils.py,sha256=-EAW6N_elEOSQdsdRhnEdDhnZQH_weCGpnVOd2Xaepc,6963
121
121
  tests/test_sbo.py,sha256=x_PENFaXYsrZIzOZu9cj_Wrej7i7SNGxgBYYvcigLs0,308
122
122
  tests/test_scverse_loading.py,sha256=bnU1lQSYYWhOAs0IIBoi4ZohqPokDQJ0n_rtkAfEyMU,29948
123
123
  tests/test_set_coverage.py,sha256=J-6m6LuOjcQa9pxRuWglSfJk4Ltm7kt_eOrn_Q-7P6Q,1604
124
124
  tests/test_source.py,sha256=hT0IlpexR5zP0OhWl5BBaho9d1aCYQlFZLwRIRRnw_Y,1969
125
125
  tests/test_uncompartmentalize.py,sha256=nAk5kfAVLU9a2VWe2x2HYVcKqj-EnwmwddERIPRax8c,1289
126
- tests/test_utils.py,sha256=JRJFmjDNZpjG59a-73JkTyGqa_a7Z8d0fE2cZt0CRII,22580
126
+ tests/test_utils.py,sha256=ls0zETdSeupuWCsnycWbgBVwLs2aXLgrAO1jyEBrfao,23190
127
127
  tests/utils.py,sha256=SoWQ_5roJteFGcMaOeEiQ5ucwq3Z2Fa3AAs9iXHTsJY,749
128
128
  tests/test_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
129
- napistu-0.3.6.dist-info/METADATA,sha256=vJqqDnZ9MU1mmU_qTFgGnBgaYx4zt-yqg26H6VDkqz0,3414
130
- napistu-0.3.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
131
- napistu-0.3.6.dist-info/entry_points.txt,sha256=_QnaPOvJNA3IltxmZgWIiBoen-L1bPYX18YQfC7oJgQ,41
132
- napistu-0.3.6.dist-info/top_level.txt,sha256=Gpvk0a_PjrtqhYcQ9IDr3zR5LqpZ-uIHidQMIpjlvhY,14
133
- napistu-0.3.6.dist-info/RECORD,,
129
+ napistu-0.3.7.dist-info/METADATA,sha256=59xinCTQICD-lrDm7UR5wdnScq6LHsXy553S6vCRk4Q,3414
130
+ napistu-0.3.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
131
+ napistu-0.3.7.dist-info/entry_points.txt,sha256=_QnaPOvJNA3IltxmZgWIiBoen-L1bPYX18YQfC7oJgQ,41
132
+ napistu-0.3.7.dist-info/top_level.txt,sha256=Gpvk0a_PjrtqhYcQ9IDr3zR5LqpZ-uIHidQMIpjlvhY,14
133
+ napistu-0.3.7.dist-info/RECORD,,
tests/conftest.py CHANGED
@@ -5,15 +5,19 @@ import os
5
5
  import sys
6
6
  import threading
7
7
 
8
+ import pandas as pd
8
9
  import pytest
10
+ from pytest import fixture
11
+ from pytest import skip
9
12
 
10
13
  from napistu import consensus
11
14
  from napistu import indices
12
- from napistu import sbml_dfs_core
13
- from napistu.ingestion import sbml
14
- from napistu.network import net_create
15
- from pytest import fixture
16
- from pytest import skip
15
+ from napistu.identifiers import Identifiers
16
+ from napistu.sbml_dfs_core import SBML_dfs
17
+ from napistu.source import Source
18
+ from napistu.ingestion.sbml import SBML
19
+ from napistu.network.net_create import process_napistu_graph
20
+ from napistu.constants import SBML_DFS
17
21
 
18
22
 
19
23
  @fixture
@@ -28,13 +32,13 @@ def sbml_path():
28
32
 
29
33
  @fixture
30
34
  def sbml_model(sbml_path):
31
- sbml_model = sbml.SBML(sbml_path)
35
+ sbml_model = SBML(sbml_path)
32
36
  return sbml_model
33
37
 
34
38
 
35
39
  @fixture
36
40
  def sbml_dfs(sbml_model):
37
- sbml_dfs = sbml_dfs_core.SBML_dfs(sbml_model)
41
+ sbml_dfs = SBML_dfs(sbml_model)
38
42
  return sbml_dfs
39
43
 
40
44
 
@@ -56,20 +60,73 @@ def sbml_dfs_glucose_metabolism():
56
60
  test_data = os.path.join(test_path, "test_data")
57
61
  sbml_path = os.path.join(test_data, "reactome_glucose_metabolism.sbml")
58
62
 
59
- sbml_model = sbml.SBML(sbml_path).model
60
- sbml_dfs = sbml_dfs_core.SBML_dfs(sbml_model)
63
+ sbml_model = SBML(sbml_path)
64
+ sbml_dfs = SBML_dfs(sbml_model)
61
65
 
62
66
  return sbml_dfs
63
67
 
64
68
 
69
+ @pytest.fixture
70
+ def minimal_valid_sbml_dfs():
71
+ """Create a minimal valid SBML_dfs object for testing."""
72
+ blank_id = Identifiers([])
73
+ source = Source(init=True)
74
+
75
+ sbml_dict = {
76
+ SBML_DFS.COMPARTMENTS: pd.DataFrame(
77
+ {
78
+ SBML_DFS.C_NAME: ["cytosol"],
79
+ SBML_DFS.C_IDENTIFIERS: [blank_id],
80
+ SBML_DFS.C_SOURCE: [source],
81
+ },
82
+ index=pd.Index(["C00001"], name=SBML_DFS.C_ID),
83
+ ),
84
+ SBML_DFS.SPECIES: pd.DataFrame(
85
+ {
86
+ SBML_DFS.S_NAME: ["ATP"],
87
+ SBML_DFS.S_IDENTIFIERS: [blank_id],
88
+ SBML_DFS.S_SOURCE: [source],
89
+ },
90
+ index=pd.Index(["S00001"], name=SBML_DFS.S_ID),
91
+ ),
92
+ SBML_DFS.COMPARTMENTALIZED_SPECIES: pd.DataFrame(
93
+ {
94
+ SBML_DFS.SC_NAME: ["ATP [cytosol]"],
95
+ SBML_DFS.S_ID: ["S00001"],
96
+ SBML_DFS.C_ID: ["C00001"],
97
+ SBML_DFS.SC_SOURCE: [source],
98
+ },
99
+ index=pd.Index(["SC00001"], name=SBML_DFS.SC_ID),
100
+ ),
101
+ SBML_DFS.REACTIONS: pd.DataFrame(
102
+ {
103
+ SBML_DFS.R_NAME: ["test_reaction"],
104
+ SBML_DFS.R_IDENTIFIERS: [blank_id],
105
+ SBML_DFS.R_SOURCE: [source],
106
+ SBML_DFS.R_ISREVERSIBLE: [False],
107
+ },
108
+ index=pd.Index(["R00001"], name=SBML_DFS.R_ID),
109
+ ),
110
+ SBML_DFS.REACTION_SPECIES: pd.DataFrame(
111
+ {
112
+ SBML_DFS.R_ID: ["R00001"],
113
+ SBML_DFS.SC_ID: ["SC00001"],
114
+ SBML_DFS.STOICHIOMETRY: [1.0],
115
+ SBML_DFS.SBO_TERM: ["SBO:0000011"],
116
+ },
117
+ index=pd.Index(["RSC00001"], name=SBML_DFS.RSC_ID),
118
+ ),
119
+ }
120
+
121
+ return SBML_dfs(sbml_dict)
122
+
123
+
65
124
  @fixture
66
125
  def napistu_graph(sbml_dfs):
67
126
  """
68
127
  Pytest fixture to create a NapistuGraph from sbml_dfs with directed=True and topology weighting.
69
128
  """
70
- return net_create.process_napistu_graph(
71
- sbml_dfs, directed=True, weighting_strategy="topology"
72
- )
129
+ return process_napistu_graph(sbml_dfs, directed=True, weighting_strategy="topology")
73
130
 
74
131
 
75
132
  @fixture
@@ -77,7 +134,7 @@ def napistu_graph_undirected(sbml_dfs):
77
134
  """
78
135
  Pytest fixture to create a NapistuGraph from sbml_dfs with directed=False and topology weighting.
79
136
  """
80
- return net_create.process_napistu_graph(
137
+ return process_napistu_graph(
81
138
  sbml_dfs, directed=False, weighting_strategy="topology"
82
139
  )
83
140
 
tests/test_consensus.py CHANGED
@@ -5,12 +5,13 @@ import os
5
5
  import pandas as pd
6
6
  import pytest
7
7
  from napistu import consensus
8
+ from napistu import identifiers
8
9
  from napistu import indices
9
10
  from napistu import source
10
11
  from napistu import sbml_dfs_core
11
12
  from napistu.ingestion import sbml
12
13
  from napistu.modify import pathwayannot
13
- from napistu.constants import SBML_DFS, SBML_DFS_SCHEMA
14
+ from napistu.constants import SBML_DFS, SBML_DFS_SCHEMA, SCHEMA_DEFS, IDENTIFIERS, BQB
14
15
 
15
16
  test_path = os.path.abspath(os.path.join(__file__, os.pardir))
16
17
  test_data = os.path.join(test_path, "test_data")
@@ -21,11 +22,16 @@ def test_reduce_to_consensus_ids():
21
22
 
22
23
  # test aggregating by IDs, by moving from compartmentalized_species -> species
23
24
 
24
- sbml_model = sbml.SBML(sbml_path).model
25
- comp_species_df = sbml.setup_cspecies(sbml_model)
26
- comp_species_df.index.names = ["s_id"]
25
+ sbml_model = sbml.SBML(sbml_path)
26
+ comp_species_df = sbml_model._define_cspecies()
27
+ comp_species_df.index.names = [SBML_DFS.S_ID]
27
28
  consensus_species, species_lookup = consensus.reduce_to_consensus_ids(
28
- comp_species_df, {"pk": "s_id", "id": "s_Identifiers"}
29
+ comp_species_df,
30
+ {
31
+ SCHEMA_DEFS.PK: SBML_DFS.S_ID,
32
+ SCHEMA_DEFS.ID: SBML_DFS.S_IDENTIFIERS,
33
+ SCHEMA_DEFS.TABLE: SBML_DFS.SPECIES,
34
+ },
29
35
  )
30
36
 
31
37
  assert isinstance(consensus_species, pd.DataFrame)
@@ -333,6 +339,68 @@ def test_report_consensus_merges_reactions(tmp_path):
333
339
  # No assertion: this is a smoke test to ensure the Series output is handled without error
334
340
 
335
341
 
342
+ def test_build_consensus_identifiers_handles_merges_and_missing_ids():
343
+
344
+ # Three entities:
345
+ # - 'A' with identifier X
346
+ # - 'B' with no identifiers
347
+ # - 'C' with identifier X (should merge with 'A')
348
+ df = pd.DataFrame(
349
+ {
350
+ "s_id": ["A", "B", "C"],
351
+ "s_Identifiers": [
352
+ identifiers.Identifiers(
353
+ [
354
+ {
355
+ IDENTIFIERS.ONTOLOGY: "test",
356
+ IDENTIFIERS.IDENTIFIER: "X",
357
+ IDENTIFIERS.BQB: BQB.IS,
358
+ }
359
+ ]
360
+ ),
361
+ identifiers.Identifiers([]),
362
+ identifiers.Identifiers(
363
+ [
364
+ {
365
+ IDENTIFIERS.ONTOLOGY: "test",
366
+ IDENTIFIERS.IDENTIFIER: "X",
367
+ IDENTIFIERS.BQB: BQB.IS,
368
+ }
369
+ ]
370
+ ),
371
+ ],
372
+ }
373
+ ).set_index("s_id")
374
+
375
+ schema = SBML_DFS_SCHEMA.SCHEMA[SBML_DFS.SPECIES]
376
+
377
+ indexed_cluster, cluster_consensus_identifiers = (
378
+ consensus.build_consensus_identifiers(df, schema)
379
+ )
380
+
381
+ # All entities should be assigned to a cluster
382
+ assert set(indexed_cluster.index) == set(df.index)
383
+ assert not indexed_cluster.isnull().any()
384
+ # There should be a consensus identifier for each cluster
385
+ assert set(cluster_consensus_identifiers.index) == set(indexed_cluster.values)
386
+
387
+ # Entities 'A' and 'C' should be merged (same cluster)
388
+ assert indexed_cluster.loc["A"] == indexed_cluster.loc["C"]
389
+ # Entity 'B' should be in a different cluster
390
+ assert indexed_cluster.loc["B"] != indexed_cluster.loc["A"]
391
+
392
+ # The consensus identifier for the merged cluster should include identifier X
393
+ merged_cluster_id = indexed_cluster.loc["A"]
394
+ ids_obj = cluster_consensus_identifiers.loc[merged_cluster_id, schema["id"]]
395
+ assert any(i["identifier"] == "X" for i in getattr(ids_obj, "ids", []))
396
+
397
+ # The consensus identifier for the entity with no identifiers should be empty
398
+ noid_cluster_id = indexed_cluster.loc["B"]
399
+ ids_obj_noid = cluster_consensus_identifiers.loc[noid_cluster_id, schema["id"]]
400
+ assert hasattr(ids_obj_noid, "ids")
401
+ assert len(getattr(ids_obj_noid, "ids", [])) == 0
402
+
403
+
336
404
  ################################################
337
405
  # __main__
338
406
  ################################################
@@ -344,3 +412,4 @@ if __name__ == "__main__":
344
412
  test_passing_entity_data()
345
413
  test_consensus_ontology_check()
346
414
  test_report_consensus_merges_reactions()
415
+ test_build_consensus_identifiers_handles_merges_and_missing_ids()
tests/test_gaps.py CHANGED
@@ -3,21 +3,32 @@ import numpy as np
3
3
  import warnings
4
4
 
5
5
  from napistu.sbml_dfs_core import SBML_dfs
6
- from napistu.constants import SBML_DFS
7
- from napistu.constants import MINI_SBO_FROM_NAME
8
6
  from napistu.identifiers import Identifiers
9
-
7
+ from napistu.source import Source
10
8
  from napistu.modify import gaps
9
+ from napistu.constants import BQB
10
+ from napistu.constants import IDENTIFIERS
11
+ from napistu.constants import ONTOLOGIES
12
+ from napistu.constants import MINI_SBO_FROM_NAME
13
+ from napistu.constants import SBML_DFS
14
+ from napistu.ingestion.constants import EXCHANGE_COMPARTMENT, COMPARTMENTS
11
15
 
12
16
 
13
17
  # Minimal compartments table
14
18
  def _create_sbml_dfs_missing_transport_rxns():
15
19
 
20
+ blank_id = Identifiers([])
21
+ blank_source = Source(init=True)
22
+
16
23
  compartments = pd.DataFrame(
17
24
  {
18
- SBML_DFS.C_NAME: ["mitochondria", "nucleus", "cytosol"],
19
- SBML_DFS.C_IDENTIFIERS: [None],
20
- SBML_DFS.C_SOURCE: [None],
25
+ SBML_DFS.C_NAME: [
26
+ COMPARTMENTS.MITOCHONDRIA,
27
+ COMPARTMENTS.NUCLEUS,
28
+ EXCHANGE_COMPARTMENT,
29
+ ],
30
+ SBML_DFS.C_IDENTIFIERS: [blank_id],
31
+ SBML_DFS.C_SOURCE: [blank_source],
21
32
  },
22
33
  index=["c_mito", "c_nucl", "c_cytosol"],
23
34
  ).rename_axis(SBML_DFS.C_ID)
@@ -30,15 +41,15 @@ def _create_sbml_dfs_missing_transport_rxns():
30
41
  Identifiers(
31
42
  [
32
43
  {
33
- "ontology": "uniprot",
34
- "identifier": "PFAKE1",
35
- "bqb": "BQB_IS",
36
- "url": None,
44
+ IDENTIFIERS.ONTOLOGY: ONTOLOGIES.UNIPROT,
45
+ IDENTIFIERS.IDENTIFIER: "PFAKE1",
46
+ IDENTIFIERS.BQB: BQB.IS,
47
+ IDENTIFIERS.URL: None,
37
48
  }
38
49
  ]
39
50
  )
40
51
  ],
41
- SBML_DFS.S_SOURCE: [None],
52
+ SBML_DFS.S_SOURCE: [blank_source],
42
53
  },
43
54
  index=["s_A"],
44
55
  ).rename_axis(SBML_DFS.S_ID)
@@ -49,7 +60,7 @@ def _create_sbml_dfs_missing_transport_rxns():
49
60
  SBML_DFS.SC_NAME: ["A [mitochondria]", "A [nucleus]"],
50
61
  SBML_DFS.S_ID: ["s_A", "s_A"],
51
62
  SBML_DFS.C_ID: ["c_mito", "c_nucl"],
52
- SBML_DFS.SC_SOURCE: [None],
63
+ SBML_DFS.SC_SOURCE: [blank_source],
53
64
  },
54
65
  index=["sc_A_mito", "sc_A_nucl"],
55
66
  ).rename_axis(SBML_DFS.SC_ID)
@@ -58,8 +69,8 @@ def _create_sbml_dfs_missing_transport_rxns():
58
69
  reactions = pd.DataFrame(
59
70
  {
60
71
  SBML_DFS.R_NAME: ["A [mito] -> A [mito]", "A [nucl] -> A [nucl]"],
61
- SBML_DFS.R_IDENTIFIERS: [None],
62
- SBML_DFS.R_SOURCE: [None],
72
+ SBML_DFS.R_IDENTIFIERS: [blank_id],
73
+ SBML_DFS.R_SOURCE: [blank_source],
63
74
  SBML_DFS.R_ISREVERSIBLE: [True, True],
64
75
  },
65
76
  index=["r_A_mito", "r_A_nucl"],
@@ -105,7 +116,7 @@ def test_add_transportation_reactions():
105
116
 
106
117
  sbml_dfs = _create_sbml_dfs_missing_transport_rxns()
107
118
  sbml_dfs_w_transport = gaps.update_sbml_df_with_exchange(
108
- np.array(["s_A"]), sbml_dfs, exchange_compartment="cytosol"
119
+ np.array(["s_A"]), sbml_dfs, exchange_compartment=EXCHANGE_COMPARTMENT
109
120
  )
110
121
  assert sbml_dfs_w_transport.reactions.shape[0] == 4, "Should add 2 reactions"
111
122
  assert sbml_dfs_w_transport.reactions[
@@ -20,7 +20,7 @@ test_path = os.path.abspath(os.path.join(__file__, os.pardir))
20
20
  test_data = os.path.join(test_path, "test_data")
21
21
 
22
22
  sbml_path = os.path.join(test_data, "R-HSA-1237044.sbml")
23
- sbml_model = sbml.SBML(sbml_path).model
23
+ sbml_model = sbml.SBML(sbml_path)
24
24
  sbml_dfs = sbml_dfs_core.SBML_dfs(sbml_model)
25
25
 
26
26
 
@@ -18,7 +18,7 @@ sbml_path = os.path.join(test_path, "test_data", "reactome_glucose_metabolism.sb
18
18
  if not os.path.isfile(sbml_path):
19
19
  raise ValueError(f"{sbml_path} not found")
20
20
 
21
- sbml_model = sbml.SBML(sbml_path).model
21
+ sbml_model = sbml.SBML(sbml_path)
22
22
  sbml_dfs = sbml_dfs_core.SBML_dfs(sbml_model)
23
23
  sbml_dfs.validate()
24
24
 
@@ -1,14 +1,16 @@
1
1
  """Tests for the ontology aliases module."""
2
2
 
3
+ from unittest.mock import patch
4
+
3
5
  import pytest
4
6
  import pandas as pd
5
7
  from napistu import identifiers
6
- from napistu.constants import IDENTIFIERS, SBML_DFS
8
+ from napistu.constants import IDENTIFIERS, SBML_DFS, ONTOLOGIES
7
9
  from napistu.ontologies import renaming
8
10
 
9
11
 
10
12
  @pytest.fixture
11
- def mock_sbml_dfs():
13
+ def mock_sbml_dfs(sbml_dfs):
12
14
  """Create a mock SBML_dfs object for testing."""
13
15
  # Create a simple species DataFrame with identifiers
14
16
  s1_ids = identifiers.Identifiers(
@@ -39,32 +41,27 @@ def mock_sbml_dfs():
39
41
  ]
40
42
  )
41
43
 
44
+ s3_ids = identifiers.Identifiers([])
45
+
42
46
  species_df = pd.DataFrame(
43
- {"s_name": ["gene1", "gene2"], SBML_DFS.S_IDENTIFIERS: [s1_ids, s2_ids]}
47
+ {
48
+ SBML_DFS.S_NAME: ["gene1", "gene2", "gene3"],
49
+ SBML_DFS.S_IDENTIFIERS: [s1_ids, s2_ids, s3_ids],
50
+ }
44
51
  )
45
52
 
46
- # Create mock SBML_dfs object
47
- class MockSBMLDfs:
48
- def __init__(self):
49
- self.species = species_df
50
- self.schema = {"species": {"pk": "s_id", "id": SBML_DFS.S_IDENTIFIERS}}
51
-
52
- def get_identifiers(self, table_name):
53
- if table_name == SBML_DFS.SPECIES:
54
- all_ids = []
55
- for idx, row in self.species.iterrows():
56
- for id_dict in row[SBML_DFS.S_IDENTIFIERS].ids:
57
- all_ids.append({"s_id": idx, **id_dict})
58
- return pd.DataFrame(all_ids)
59
- return pd.DataFrame()
60
-
61
- return MockSBMLDfs()
53
+ # Patch the species attribute only for the duration of the test
54
+ with patch.object(sbml_dfs, "species", new=species_df):
55
+ yield sbml_dfs # All methods are real, only .species is patched
62
56
 
63
57
 
64
58
  def test_rename_species_ontologies_basic(mock_sbml_dfs):
65
59
  """Test basic alias updating functionality."""
66
60
  # Define test aliases
67
- test_aliases = {"ncbi_entrez_gene": {"ncbigene"}, "uniprot": {"uniprot_id"}}
61
+ test_aliases = {
62
+ ONTOLOGIES.NCBI_ENTREZ_GENE: {"ncbigene"},
63
+ ONTOLOGIES.UNIPROT: {"uniprot_id"},
64
+ }
68
65
 
69
66
  # Update aliases
70
67
  renaming.rename_species_ontologies(mock_sbml_dfs, test_aliases)
@@ -73,11 +70,18 @@ def test_rename_species_ontologies_basic(mock_sbml_dfs):
73
70
  updated_ids = mock_sbml_dfs.get_identifiers(SBML_DFS.SPECIES)
74
71
 
75
72
  # Check that ontologies were updated correctly
76
- assert "ncbi_entrez_gene" in set(updated_ids[IDENTIFIERS.ONTOLOGY])
77
- assert "uniprot" in set(updated_ids[IDENTIFIERS.ONTOLOGY])
73
+ assert ONTOLOGIES.NCBI_ENTREZ_GENE in set(updated_ids[IDENTIFIERS.ONTOLOGY])
74
+ assert ONTOLOGIES.UNIPROT in set(updated_ids[IDENTIFIERS.ONTOLOGY])
78
75
  assert "ncbigene" not in set(updated_ids[IDENTIFIERS.ONTOLOGY])
79
76
  assert "uniprot_id" not in set(updated_ids[IDENTIFIERS.ONTOLOGY])
80
77
 
78
+ # verify that all the species have Identifiers object
79
+ for row in mock_sbml_dfs.species.itertuples():
80
+ val = getattr(row, SBML_DFS.S_IDENTIFIERS)
81
+ assert val is not None and isinstance(
82
+ val, identifiers.Identifiers
83
+ ), f"Bad value: {val} in row {row}"
84
+
81
85
 
82
86
  def test_rename_species_ontologies_no_overlap(mock_sbml_dfs):
83
87
  """Test that error is raised when no aliases overlap with data."""
@@ -93,7 +97,7 @@ def test_rename_species_ontologies_partial_update(mock_sbml_dfs):
93
97
  """Test that partial updates work correctly."""
94
98
  # Define aliases that only update some ontologies
95
99
  test_aliases = {
96
- "ncbi_entrez_gene": {"ncbigene"}
100
+ ONTOLOGIES.NCBI_ENTREZ_GENE: {"ncbigene"}
97
101
  # Don't include uniprot_id mapping
98
102
  }
99
103
 
@@ -104,7 +108,7 @@ def test_rename_species_ontologies_partial_update(mock_sbml_dfs):
104
108
  updated_ids = mock_sbml_dfs.get_identifiers(SBML_DFS.SPECIES)
105
109
 
106
110
  # Check that only ncbigene was updated
107
- assert "ncbi_entrez_gene" in set(updated_ids[IDENTIFIERS.ONTOLOGY])
111
+ assert ONTOLOGIES.NCBI_ENTREZ_GENE in set(updated_ids[IDENTIFIERS.ONTOLOGY])
108
112
  assert "uniprot_id" in set(
109
113
  updated_ids[IDENTIFIERS.ONTOLOGY]
110
114
  ) # Should remain unchanged