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.
- napistu/__main__.py +20 -9
- napistu/consensus.py +19 -25
- napistu/constants.py +90 -64
- napistu/indices.py +3 -1
- napistu/ingestion/sbml.py +298 -295
- napistu/ingestion/string.py +14 -18
- napistu/ingestion/trrust.py +22 -27
- napistu/matching/species.py +1 -1
- napistu/ontologies/genodexito.py +5 -1
- napistu/ontologies/renaming.py +4 -0
- napistu/sbml_dfs_core.py +127 -64
- napistu/sbml_dfs_utils.py +4 -0
- napistu/utils.py +52 -41
- {napistu-0.3.6.dist-info → napistu-0.3.7.dist-info}/METADATA +1 -1
- {napistu-0.3.6.dist-info → napistu-0.3.7.dist-info}/RECORD +27 -27
- tests/conftest.py +70 -13
- tests/test_consensus.py +74 -5
- tests/test_gaps.py +26 -15
- tests/test_network_net_create.py +1 -1
- tests/test_network_precompute.py +1 -1
- tests/test_ontologies_renaming.py +28 -24
- tests/test_sbml_dfs_core.py +165 -15
- tests/test_utils.py +19 -0
- {napistu-0.3.6.dist-info → napistu-0.3.7.dist-info}/WHEEL +0 -0
- {napistu-0.3.6.dist-info → napistu-0.3.7.dist-info}/entry_points.txt +0 -0
- {napistu-0.3.6.dist-info → napistu-0.3.7.dist-info}/licenses/LICENSE +0 -0
- {napistu-0.3.6.dist-info → napistu-0.3.7.dist-info}/top_level.txt +0 -0
tests/test_sbml_dfs_core.py
CHANGED
@@ -5,6 +5,7 @@ import os
|
|
5
5
|
import numpy as np
|
6
6
|
import pandas as pd
|
7
7
|
import pytest
|
8
|
+
from napistu import identifiers
|
8
9
|
from napistu import sbml_dfs_core
|
9
10
|
from napistu.source import Source
|
10
11
|
from napistu.ingestion import sbml
|
@@ -25,11 +26,13 @@ from unittest.mock import patch
|
|
25
26
|
def test_data():
|
26
27
|
"""Create test data for SBML integration tests."""
|
27
28
|
|
29
|
+
blank_id = identifiers.Identifiers([])
|
30
|
+
|
28
31
|
# Test compartments
|
29
32
|
compartments_df = pd.DataFrame(
|
30
33
|
[
|
31
|
-
{
|
32
|
-
{
|
34
|
+
{SBML_DFS.C_NAME: "nucleus", SBML_DFS.C_IDENTIFIERS: blank_id},
|
35
|
+
{SBML_DFS.C_NAME: "cytoplasm", SBML_DFS.C_IDENTIFIERS: blank_id},
|
33
36
|
]
|
34
37
|
)
|
35
38
|
|
@@ -37,14 +40,18 @@ def test_data():
|
|
37
40
|
species_df = pd.DataFrame(
|
38
41
|
[
|
39
42
|
{
|
40
|
-
|
41
|
-
|
43
|
+
SBML_DFS.S_NAME: "TP53",
|
44
|
+
SBML_DFS.S_IDENTIFIERS: blank_id,
|
42
45
|
"gene_type": "tumor_suppressor",
|
43
46
|
},
|
44
|
-
{"s_name": "MDM2", "s_Identifiers": None, "gene_type": "oncogene"},
|
45
47
|
{
|
46
|
-
|
47
|
-
|
48
|
+
SBML_DFS.S_NAME: "MDM2",
|
49
|
+
SBML_DFS.S_IDENTIFIERS: blank_id,
|
50
|
+
"gene_type": "oncogene",
|
51
|
+
},
|
52
|
+
{
|
53
|
+
SBML_DFS.S_NAME: "CDKN1A",
|
54
|
+
SBML_DFS.S_IDENTIFIERS: blank_id,
|
48
55
|
"gene_type": "cell_cycle",
|
49
56
|
},
|
50
57
|
]
|
@@ -58,10 +65,10 @@ def test_data():
|
|
58
65
|
"downstream_name": "CDKN1A",
|
59
66
|
"upstream_compartment": "nucleus",
|
60
67
|
"downstream_compartment": "nucleus",
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
68
|
+
SBML_DFS.R_NAME: "TP53_activates_CDKN1A",
|
69
|
+
SBML_DFS.SBO_TERM: "SBO:0000459",
|
70
|
+
SBML_DFS.R_IDENTIFIERS: blank_id,
|
71
|
+
SBML_DFS.R_ISREVERSIBLE: False,
|
65
72
|
"confidence": 0.95,
|
66
73
|
},
|
67
74
|
{
|
@@ -69,10 +76,10 @@ def test_data():
|
|
69
76
|
"downstream_name": "TP53",
|
70
77
|
"upstream_compartment": "cytoplasm",
|
71
78
|
"downstream_compartment": "nucleus",
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
79
|
+
SBML_DFS.R_NAME: "MDM2_inhibits_TP53",
|
80
|
+
SBML_DFS.SBO_TERM: "SBO:0000020",
|
81
|
+
SBML_DFS.R_IDENTIFIERS: blank_id,
|
82
|
+
SBML_DFS.R_ISREVERSIBLE: False,
|
76
83
|
"confidence": 0.87,
|
77
84
|
},
|
78
85
|
]
|
@@ -611,3 +618,146 @@ def test_sbml_custom_stoichiometry(test_data):
|
|
611
618
|
stoichiometries = result.reaction_species["stoichiometry"].unique()
|
612
619
|
assert 2 in stoichiometries # upstream
|
613
620
|
assert 3 in stoichiometries # downstream
|
621
|
+
|
622
|
+
|
623
|
+
def test_validate_schema_missing(minimal_valid_sbml_dfs):
|
624
|
+
"""Test validation fails when schema is missing."""
|
625
|
+
delattr(minimal_valid_sbml_dfs, "schema")
|
626
|
+
with pytest.raises(ValueError, match="No schema found"):
|
627
|
+
minimal_valid_sbml_dfs.validate()
|
628
|
+
|
629
|
+
|
630
|
+
def test_validate_table(minimal_valid_sbml_dfs):
|
631
|
+
"""Test _validate_table fails for various table structure issues."""
|
632
|
+
# Wrong index name
|
633
|
+
sbml_dfs = minimal_valid_sbml_dfs.copy()
|
634
|
+
sbml_dfs.species.index.name = "wrong_name"
|
635
|
+
with pytest.raises(ValueError, match="the index name for species was not the pk"):
|
636
|
+
sbml_dfs.validate()
|
637
|
+
|
638
|
+
# Duplicate primary keys
|
639
|
+
sbml_dfs = minimal_valid_sbml_dfs.copy()
|
640
|
+
duplicate_species = pd.DataFrame(
|
641
|
+
{
|
642
|
+
SBML_DFS.S_NAME: ["ATP", "ADP"],
|
643
|
+
SBML_DFS.S_IDENTIFIERS: [
|
644
|
+
identifiers.Identifiers([]),
|
645
|
+
identifiers.Identifiers([]),
|
646
|
+
],
|
647
|
+
SBML_DFS.S_SOURCE: [Source(init=True), Source(init=True)],
|
648
|
+
},
|
649
|
+
index=pd.Index(["S00001", "S00001"], name=SBML_DFS.S_ID),
|
650
|
+
)
|
651
|
+
sbml_dfs.species = duplicate_species
|
652
|
+
with pytest.raises(ValueError, match="primary keys were duplicated"):
|
653
|
+
sbml_dfs.validate()
|
654
|
+
|
655
|
+
# Missing required variables
|
656
|
+
sbml_dfs = minimal_valid_sbml_dfs.copy()
|
657
|
+
sbml_dfs.species = sbml_dfs.species.drop(columns=[SBML_DFS.S_NAME])
|
658
|
+
with pytest.raises(ValueError, match="Missing .+ required variables for species"):
|
659
|
+
sbml_dfs.validate()
|
660
|
+
|
661
|
+
# Empty table
|
662
|
+
sbml_dfs = minimal_valid_sbml_dfs.copy()
|
663
|
+
sbml_dfs.species = pd.DataFrame(
|
664
|
+
{
|
665
|
+
SBML_DFS.S_NAME: [],
|
666
|
+
SBML_DFS.S_IDENTIFIERS: [],
|
667
|
+
SBML_DFS.S_SOURCE: [],
|
668
|
+
},
|
669
|
+
index=pd.Index([], name=SBML_DFS.S_ID),
|
670
|
+
)
|
671
|
+
with pytest.raises(ValueError, match="species contained no entries"):
|
672
|
+
sbml_dfs.validate()
|
673
|
+
|
674
|
+
|
675
|
+
def test_check_pk_fk_correspondence(minimal_valid_sbml_dfs):
|
676
|
+
"""Test _check_pk_fk_correspondence fails for various foreign key issues."""
|
677
|
+
# Missing species reference
|
678
|
+
sbml_dfs = minimal_valid_sbml_dfs.copy()
|
679
|
+
sbml_dfs.compartmentalized_species[SBML_DFS.S_ID] = ["S99999"]
|
680
|
+
with pytest.raises(
|
681
|
+
ValueError,
|
682
|
+
match="s_id values were found in compartmentalized_species but missing from species",
|
683
|
+
):
|
684
|
+
sbml_dfs.validate()
|
685
|
+
|
686
|
+
# Missing compartment reference
|
687
|
+
sbml_dfs = minimal_valid_sbml_dfs.copy()
|
688
|
+
sbml_dfs.compartmentalized_species[SBML_DFS.C_ID] = ["C99999"]
|
689
|
+
with pytest.raises(
|
690
|
+
ValueError,
|
691
|
+
match="c_id values were found in compartmentalized_species but missing from compartments",
|
692
|
+
):
|
693
|
+
sbml_dfs.validate()
|
694
|
+
|
695
|
+
# Null foreign keys
|
696
|
+
sbml_dfs = minimal_valid_sbml_dfs.copy()
|
697
|
+
sbml_dfs.compartmentalized_species[SBML_DFS.S_ID] = [None]
|
698
|
+
with pytest.raises(
|
699
|
+
ValueError, match="compartmentalized_species included missing s_id values"
|
700
|
+
):
|
701
|
+
sbml_dfs.validate()
|
702
|
+
|
703
|
+
|
704
|
+
def test_validate_reaction_species(minimal_valid_sbml_dfs):
|
705
|
+
"""Test _validate_reaction_species fails for various reaction species issues."""
|
706
|
+
# Null stoichiometry
|
707
|
+
sbml_dfs = minimal_valid_sbml_dfs.copy()
|
708
|
+
sbml_dfs.reaction_species[SBML_DFS.STOICHIOMETRY] = [None]
|
709
|
+
with pytest.raises(ValueError, match="All reaction_species.* must be not null"):
|
710
|
+
sbml_dfs.validate()
|
711
|
+
|
712
|
+
# Null SBO terms
|
713
|
+
sbml_dfs = minimal_valid_sbml_dfs.copy()
|
714
|
+
sbml_dfs.reaction_species[SBML_DFS.SBO_TERM] = [None]
|
715
|
+
with pytest.raises(
|
716
|
+
ValueError, match="sbo_terms were None; all terms should be defined"
|
717
|
+
):
|
718
|
+
sbml_dfs.validate()
|
719
|
+
|
720
|
+
# Invalid SBO terms
|
721
|
+
sbml_dfs = minimal_valid_sbml_dfs.copy()
|
722
|
+
sbml_dfs.reaction_species[SBML_DFS.SBO_TERM] = ["INVALID_SBO_TERM"]
|
723
|
+
with pytest.raises(ValueError, match="sbo_terms were not defined"):
|
724
|
+
sbml_dfs.validate()
|
725
|
+
|
726
|
+
|
727
|
+
def test_validate_identifiers(minimal_valid_sbml_dfs):
|
728
|
+
"""Test _validate_identifiers fails when identifiers are missing."""
|
729
|
+
minimal_valid_sbml_dfs.species[SBML_DFS.S_IDENTIFIERS] = [None]
|
730
|
+
with pytest.raises(ValueError, match="species has .+ missing ids"):
|
731
|
+
minimal_valid_sbml_dfs.validate()
|
732
|
+
|
733
|
+
|
734
|
+
def test_validate_sources(minimal_valid_sbml_dfs):
|
735
|
+
"""Test _validate_sources fails when sources are missing."""
|
736
|
+
minimal_valid_sbml_dfs.species[SBML_DFS.S_SOURCE] = [None]
|
737
|
+
with pytest.raises(ValueError, match="species has .+ missing sources"):
|
738
|
+
minimal_valid_sbml_dfs.validate()
|
739
|
+
|
740
|
+
|
741
|
+
def test_validate_species_data(minimal_valid_sbml_dfs):
|
742
|
+
"""Test _validate_species_data fails when species_data has invalid structure."""
|
743
|
+
invalid_data = pd.DataFrame(
|
744
|
+
{"extra_info": ["test"]}, index=pd.Index(["S99999"], name=SBML_DFS.S_ID)
|
745
|
+
) # Non-existent species
|
746
|
+
minimal_valid_sbml_dfs.species_data["invalid"] = invalid_data
|
747
|
+
with pytest.raises(ValueError, match="species data invalid was invalid"):
|
748
|
+
minimal_valid_sbml_dfs.validate()
|
749
|
+
|
750
|
+
|
751
|
+
def test_validate_reactions_data(minimal_valid_sbml_dfs):
|
752
|
+
"""Test _validate_reactions_data fails when reactions_data has invalid structure."""
|
753
|
+
invalid_data = pd.DataFrame(
|
754
|
+
{"extra_info": ["test"]}, index=pd.Index(["R99999"], name=SBML_DFS.R_ID)
|
755
|
+
) # Non-existent reaction
|
756
|
+
minimal_valid_sbml_dfs.reactions_data["invalid"] = invalid_data
|
757
|
+
with pytest.raises(ValueError, match="reactions data invalid was invalid"):
|
758
|
+
minimal_valid_sbml_dfs.validate()
|
759
|
+
|
760
|
+
|
761
|
+
def test_validate_passes_with_valid_data(minimal_valid_sbml_dfs):
|
762
|
+
"""Test that validation passes with completely valid data."""
|
763
|
+
minimal_valid_sbml_dfs.validate() # Should not raise any exceptions
|
tests/test_utils.py
CHANGED
@@ -686,3 +686,22 @@ def test_safe_fill():
|
|
686
686
|
"a_very_long\nstringggg",
|
687
687
|
"",
|
688
688
|
]
|
689
|
+
|
690
|
+
|
691
|
+
def test_update_pathological_names():
|
692
|
+
|
693
|
+
# All numeric
|
694
|
+
s = pd.Series(["1", "2", "3"])
|
695
|
+
out = utils.update_pathological_names(s, "prefix_")
|
696
|
+
assert all(x.startswith("prefix_") for x in out)
|
697
|
+
assert list(out) == ["prefix_1", "prefix_2", "prefix_3"]
|
698
|
+
|
699
|
+
# Mixed numeric and non-numeric
|
700
|
+
s2 = pd.Series(["1", "foo", "3"])
|
701
|
+
out2 = utils.update_pathological_names(s2, "prefix_")
|
702
|
+
assert list(out2) == ["1", "foo", "3"]
|
703
|
+
|
704
|
+
# All non-numeric
|
705
|
+
s3 = pd.Series(["foo", "bar", "baz"])
|
706
|
+
out3 = utils.update_pathological_names(s3, "prefix_")
|
707
|
+
assert list(out3) == ["foo", "bar", "baz"]
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|