-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathtest_lint.py
More file actions
149 lines (115 loc) · 5.08 KB
/
test_lint.py
File metadata and controls
149 lines (115 loc) · 5.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
"""Test related to ``petab.v2.lint``."""
from copy import deepcopy
from petab.v2 import Problem
from petab.v2.lint import *
from petab.v2.models.sbml_model import SbmlModel
def test_check_experiments():
"""Test ``CheckExperimentTable``."""
problem = Problem()
check = CheckExperimentTable()
assert check.run(problem) is None
problem.add_experiment("e1", 0, "c1", 1, "c2")
problem.add_experiment("e2", "-inf", "c1", 1, "c2")
assert check.run(problem) is None
tmp_problem = deepcopy(problem)
tmp_problem["e1"].periods[0].time = tmp_problem["e1"].periods[1].time
assert check.run(tmp_problem) is not None
def test_check_incompatible_targets():
"""Multiple conditions with overlapping targets cannot be applied
at the same time."""
problem = Problem()
problem.model = SbmlModel.from_antimony("p1 = 1; p2 = 2")
problem.add_experiment("e1", 0, "c1", 1, "c2")
problem.add_condition("c1", p1="1")
problem.add_condition("c2", p1="2", p2="2")
check = CheckValidConditionTargets()
assert check.run(problem) is None
problem["e1"].periods[0].condition_ids.append("c2")
assert (error := check.run(problem)) is not None
assert "overlapping targets {'p1'}" in error.message
def test_invalid_model_id_in_measurements():
"""Test that measurements with an invalid model ID are caught."""
problem = Problem()
problem.models.append(SbmlModel.from_antimony("p1 = 1", model_id="model1"))
problem.add_observable("obs1", "A", 1)
problem.add_measurement("obs1", experiment_id="e1", time=0, measurement=1)
check = CheckMeasurementModelId()
# Single model -> model ID is optional
assert (error := check.run(problem)) is None, error
# Two models -> model ID must be set
problem.models.append(SbmlModel.from_antimony("p2 = 2", model_id="model2"))
assert (error := check.run(problem)) is not None
assert "multiple models" in error.message
# Set model ID to a non-existing model ID
problem.measurements[0].model_id = "invalid_model_id"
assert (error := check.run(problem)) is not None
assert "does not match" in error.message
# Use a valid model ID
problem.measurements[0].model_id = "model1"
assert (error := check.run(problem)) is None, error
def test_undefined_experiment_id_in_measurements():
"""Test that measurements with an undefined experiment ID are caught."""
problem = Problem()
problem.add_experiment("e1", 0, "c1")
problem.add_observable("obs1", "A", 1)
problem.add_measurement("obs1", experiment_id="e1", time=0, measurement=1)
check = CheckUndefinedExperiments()
# Valid experiment ID
assert (error := check.run(problem)) is None, error
# Invalid experiment ID
problem.measurements[0].experiment_id = "invalid_experiment_id"
assert (error := check.run(problem)) is not None
assert "not defined" in error.message
def test_validate_initial_change_symbols():
"""Test validation of symbols in target value expressions for changes
applied at the start of an experiment."""
problem = Problem()
problem.model = SbmlModel.from_antimony("p1 = 1; p2 = 2")
problem.add_experiment("e1", 0, "c1", 1, "c2")
problem.add_condition("c1", p1="p2 + time")
problem.add_condition("c2", p1="p2", p2="p1")
problem.add_parameter("p1", nominal_value=1, estimate=False)
problem.add_parameter("p2", nominal_value=2, estimate=False)
check = CheckInitialChangeSymbols()
assert check.run(problem) is None
# removing `p1` from the parameter table is okay, as `c2` is never
# used at the start of an experiment
problem.parameter_tables[0].parameters.remove(problem["p1"])
assert check.run(problem) is None
# removing `p2` is not okay, as it is used at the start of an experiment
problem.parameter_tables[0].parameters.remove(problem["p2"])
assert (error := check.run(problem)) is not None
assert "contains additional symbols: {'p2'}" in error.message
def test_check_mapping_table():
"""Test checks related to the mapping table."""
problem = Problem()
# PySB model from PEtab test suite
problem.model = SbmlModel.from_antimony("a.mean = 1")
problem.add_mapping(
petab_id="a_m",
model_id="a.mean",
name=None,
)
problem.add_parameter(
"a_m",
estimate=True,
nominal_value=2,
lb=0,
ub=10,
)
check = CheckMappingTable()
assert check.run(problem) is None
check = CheckAllParametersPresentInParameterTable()
assert check.run(problem) is None
# add a petab id without model id but with name for annotation
problem.add_mapping(petab_id="p2", model_id=None, name="Parameter 2")
problem.add_parameter("p2", estimate=True, nominal_value=1, lb=0, ub=10)
check = CheckMappingTable()
assert check.run(problem) is None
# Invalid: petabEntityId is referenced in the model
problem.model = SbmlModel.from_antimony("a.mean = 1; a_m = 2")
assert (error := check.run(problem)) is not None
assert (
"`a_m` is used in the mapping table and referenced directly"
in error.message
)