myokit 1.37.0__py3-none-any.whl → 1.37.2__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.
- myokit/__init__.py +2 -2
- myokit/_aux.py +4 -0
- myokit/_datablock.py +10 -10
- myokit/_datalog.py +55 -11
- myokit/_myokit_version.py +1 -1
- myokit/_sim/cvodessim.py +3 -3
- myokit/formats/axon/_abf.py +11 -4
- myokit/formats/diffsl/__init__.py +60 -0
- myokit/formats/diffsl/_ewriter.py +145 -0
- myokit/formats/diffsl/_exporter.py +435 -0
- myokit/formats/heka/__init__.py +4 -0
- myokit/formats/heka/_patchmaster.py +408 -156
- myokit/formats/sbml/__init__.py +21 -1
- myokit/formats/sbml/_api.py +160 -6
- myokit/formats/sbml/_exporter.py +53 -0
- myokit/formats/sbml/_writer.py +355 -0
- myokit/gui/datalog_viewer.py +17 -3
- myokit/tests/data/io/bad1d-2-no-header.zip +0 -0
- myokit/tests/data/io/bad1d-3-no-data.zip +0 -0
- myokit/tests/data/io/bad1d-4-not-a-zip.zip +1 -105
- myokit/tests/data/io/bad1d-5-bad-data-type.zip +0 -0
- myokit/tests/data/io/bad1d-6-time-too-short.zip +0 -0
- myokit/tests/data/io/bad1d-7-0d-too-short.zip +0 -0
- myokit/tests/data/io/bad1d-8-1d-too-short.zip +0 -0
- myokit/tests/data/io/bad2d-2-no-header.zip +0 -0
- myokit/tests/data/io/bad2d-3-no-data.zip +0 -0
- myokit/tests/data/io/bad2d-4-not-a-zip.zip +1 -105
- myokit/tests/data/io/bad2d-5-bad-data-type.zip +0 -0
- myokit/tests/data/io/bad2d-8-2d-too-short.zip +0 -0
- myokit/tests/data/io/block1d.mmt +187 -0
- myokit/tests/data/io/datalog-18-duplicate-keys.csv +4 -0
- myokit/tests/test_aux.py +4 -0
- myokit/tests/test_datablock.py +6 -6
- myokit/tests/test_datalog.py +20 -0
- myokit/tests/test_formats_diffsl.py +728 -0
- myokit/tests/test_formats_exporters_run.py +6 -0
- myokit/tests/test_formats_sbml.py +57 -1
- myokit/tests/test_sbml_api.py +90 -0
- myokit/tests/test_sbml_export.py +327 -0
- {myokit-1.37.0.dist-info → myokit-1.37.2.dist-info}/LICENSE.txt +1 -1
- {myokit-1.37.0.dist-info → myokit-1.37.2.dist-info}/METADATA +4 -4
- {myokit-1.37.0.dist-info → myokit-1.37.2.dist-info}/RECORD +45 -36
- {myokit-1.37.0.dist-info → myokit-1.37.2.dist-info}/WHEEL +1 -1
- {myokit-1.37.0.dist-info → myokit-1.37.2.dist-info}/entry_points.txt +0 -0
- {myokit-1.37.0.dist-info → myokit-1.37.2.dist-info}/top_level.txt +0 -0
|
@@ -104,6 +104,9 @@ class ExportTest(unittest.TestCase):
|
|
|
104
104
|
name = 'test_' + name + '_exporter'
|
|
105
105
|
self.assertIn(name, methods)
|
|
106
106
|
|
|
107
|
+
def test_sbml_exporter(self):
|
|
108
|
+
self._test(myokit.formats.exporter('sbml'))
|
|
109
|
+
|
|
107
110
|
def test_ansic_exporter(self):
|
|
108
111
|
self._test(myokit.formats.exporter('ansic'))
|
|
109
112
|
|
|
@@ -128,6 +131,9 @@ class ExportTest(unittest.TestCase):
|
|
|
128
131
|
def test_cuda_kernel_rl_exporter(self):
|
|
129
132
|
self._test(myokit.formats.exporter('cuda-kernel-rl'))
|
|
130
133
|
|
|
134
|
+
def test_diffsl_exporter(self):
|
|
135
|
+
self._test(myokit.formats.exporter('diffsl'))
|
|
136
|
+
|
|
131
137
|
def test_easyml_exporter(self):
|
|
132
138
|
self._test(myokit.formats.exporter('easyml'))
|
|
133
139
|
|
|
@@ -15,7 +15,63 @@ import myokit.formats
|
|
|
15
15
|
import myokit.formats.sbml
|
|
16
16
|
|
|
17
17
|
# from shared import DIR_FORMATS, WarningCollector
|
|
18
|
-
from myokit.tests import DIR_FORMATS, WarningCollector
|
|
18
|
+
from myokit.tests import DIR_FORMATS, WarningCollector, TemporaryDirectory
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class SBMLExporterTest(unittest.TestCase):
|
|
22
|
+
"""
|
|
23
|
+
Tests for :class:`myokit.formats.sbml.SBMLExporter`.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def test_capability_reporting(self):
|
|
27
|
+
# Test if the right capabilities are reported.
|
|
28
|
+
e = myokit.formats.exporter('sbml')
|
|
29
|
+
self.assertTrue(e.supports_model())
|
|
30
|
+
self.assertFalse(e.supports_runnable())
|
|
31
|
+
|
|
32
|
+
def test_stimulus_generation(self):
|
|
33
|
+
# Tests if protocols allow a stimulus current to be added
|
|
34
|
+
|
|
35
|
+
e = myokit.formats.exporter('sbml')
|
|
36
|
+
i = myokit.formats.importer('sbml')
|
|
37
|
+
|
|
38
|
+
# Load input model
|
|
39
|
+
m1, p1, _ = myokit.load('example')
|
|
40
|
+
org_code = m1.code()
|
|
41
|
+
|
|
42
|
+
# 1. Export without a protocol
|
|
43
|
+
with TemporaryDirectory() as d:
|
|
44
|
+
path = d.path('model.sbml')
|
|
45
|
+
with WarningCollector() as w:
|
|
46
|
+
e.model(path, m1)
|
|
47
|
+
m2 = i.model(path)
|
|
48
|
+
self.assertFalse(w.has_warnings())
|
|
49
|
+
self.assertTrue(isinstance(m2.get('global.pace').rhs(), myokit.Number))
|
|
50
|
+
|
|
51
|
+
# 2. Export with protocol, but without variable bound to pacing
|
|
52
|
+
m1.get('engine.pace').set_binding(None)
|
|
53
|
+
with TemporaryDirectory() as d:
|
|
54
|
+
path = d.path('model.sbml')
|
|
55
|
+
with WarningCollector() as w:
|
|
56
|
+
e.model(path, m1, p1)
|
|
57
|
+
m2 = i.model(path)
|
|
58
|
+
self.assertTrue(w.has_warnings())
|
|
59
|
+
self.assertTrue(isinstance(m2.get('global.pace').rhs(), myokit.Number))
|
|
60
|
+
|
|
61
|
+
# 3. Export with protocol and variable bound to pacing
|
|
62
|
+
m1.get('engine.pace').set_binding('pace')
|
|
63
|
+
with TemporaryDirectory() as d:
|
|
64
|
+
path = d.path('model.cellml')
|
|
65
|
+
with WarningCollector() as w:
|
|
66
|
+
e.model(path, m1, p1)
|
|
67
|
+
m2 = i.model(path)
|
|
68
|
+
self.assertFalse(w.has_warnings())
|
|
69
|
+
rhs = m2.get('global.i_stim').rhs()
|
|
70
|
+
self.assertTrue(rhs, myokit.Multiply)
|
|
71
|
+
self.assertTrue(isinstance(rhs[0], myokit.Piecewise))
|
|
72
|
+
|
|
73
|
+
# Check original model is unchanged
|
|
74
|
+
self.assertEqual(org_code, m1.code())
|
|
19
75
|
|
|
20
76
|
|
|
21
77
|
class SBMLImporterTest(unittest.TestCase):
|
myokit/tests/test_sbml_api.py
CHANGED
|
@@ -2181,6 +2181,96 @@ class SBMLTestMyokitModel(unittest.TestCase):
|
|
|
2181
2181
|
myokit.Plus(myokit.Number(1), myokit.Name(m.time())))
|
|
2182
2182
|
|
|
2183
2183
|
|
|
2184
|
+
class SBMLTestModelFromMyokit(unittest.TestCase):
|
|
2185
|
+
def test_basic(self):
|
|
2186
|
+
m = myokit.Model()
|
|
2187
|
+
c = m.add_component('comp')
|
|
2188
|
+
v = c.add_variable('var')
|
|
2189
|
+
v.set_rhs(myokit.Number(3))
|
|
2190
|
+
t = c.add_variable('time')
|
|
2191
|
+
t.set_binding('time')
|
|
2192
|
+
t.set_rhs(myokit.Number(0))
|
|
2193
|
+
|
|
2194
|
+
s = sbml.Model.from_myokit_model(m)
|
|
2195
|
+
compartment_names = [c.sid() for c in s.compartments()]
|
|
2196
|
+
self.assertCountEqual(compartment_names, [])
|
|
2197
|
+
parameter_names = [v.sid() for v in s.parameters()]
|
|
2198
|
+
self.assertCountEqual(parameter_names, ['var'])
|
|
2199
|
+
|
|
2200
|
+
def test_vars_with_same_name(self):
|
|
2201
|
+
m = myokit.Model()
|
|
2202
|
+
c = m.add_component('comp')
|
|
2203
|
+
v = c.add_variable('var')
|
|
2204
|
+
v.set_rhs(myokit.Number(3))
|
|
2205
|
+
c = m.add_component('comp2')
|
|
2206
|
+
v = c.add_variable('var')
|
|
2207
|
+
v.set_rhs(myokit.Number(3))
|
|
2208
|
+
t = c.add_variable('time')
|
|
2209
|
+
t.set_binding('time')
|
|
2210
|
+
t.set_rhs(myokit.Number(0))
|
|
2211
|
+
|
|
2212
|
+
s = sbml.Model.from_myokit_model(m)
|
|
2213
|
+
compartment_names = [c.sid() for c in s.compartments()]
|
|
2214
|
+
self.assertCountEqual(compartment_names, [])
|
|
2215
|
+
parameter_names = [v.sid() for v in s.parameters()]
|
|
2216
|
+
self.assertCountEqual(parameter_names, ['comp2_var', 'comp_var'])
|
|
2217
|
+
|
|
2218
|
+
def test_rate_eqn_with_unit(self):
|
|
2219
|
+
m = myokit.Model()
|
|
2220
|
+
c = m.add_component('comp')
|
|
2221
|
+
|
|
2222
|
+
t = c.add_variable('time', rhs=myokit.Number(0))
|
|
2223
|
+
t.set_unit(myokit.units.second)
|
|
2224
|
+
t.set_binding('time')
|
|
2225
|
+
|
|
2226
|
+
p = c.add_variable('param')
|
|
2227
|
+
p.set_rhs(myokit.Number(2))
|
|
2228
|
+
|
|
2229
|
+
v = c.add_variable('var', initial_value=myokit.Number(1))
|
|
2230
|
+
v_unit = 1e3 * myokit.units.meter
|
|
2231
|
+
v.set_unit(v_unit)
|
|
2232
|
+
v.set_rhs(myokit.Multiply(myokit.Number(4), myokit.Name(p)))
|
|
2233
|
+
|
|
2234
|
+
v = c.add_variable('var2', initial_value=myokit.Number(1))
|
|
2235
|
+
v.set_unit(myokit.units.meter)
|
|
2236
|
+
v.set_rhs(myokit.Number(4))
|
|
2237
|
+
|
|
2238
|
+
s = sbml.Model.from_myokit_model(m)
|
|
2239
|
+
parameter_names = [v.sid() for v in s.parameters()]
|
|
2240
|
+
self.assertCountEqual(parameter_names, ['var', 'var2', 'param'])
|
|
2241
|
+
# only non-base unit is kilometer
|
|
2242
|
+
self.assertCountEqual(s.units().values(), [v_unit])
|
|
2243
|
+
self.assertEqual(s.time_units(), myokit.units.second)
|
|
2244
|
+
v = s.parameter('var')
|
|
2245
|
+
self.assertEqual(v.initial_value(), myokit.Number(1))
|
|
2246
|
+
self.assertEqual(
|
|
2247
|
+
v.value(),
|
|
2248
|
+
myokit.Multiply(myokit.Number(4), myokit.Name(p))
|
|
2249
|
+
)
|
|
2250
|
+
|
|
2251
|
+
def test_incompatible_unit(self):
|
|
2252
|
+
m = myokit.Model()
|
|
2253
|
+
c = m.add_component('comp')
|
|
2254
|
+
|
|
2255
|
+
t = c.add_variable('time', rhs=myokit.Number(0))
|
|
2256
|
+
t.set_unit(myokit.units.second)
|
|
2257
|
+
t.set_binding('time')
|
|
2258
|
+
|
|
2259
|
+
p = c.add_variable('param')
|
|
2260
|
+
p.set_rhs(myokit.Number(2))
|
|
2261
|
+
p.set_unit(myokit.units.meter)
|
|
2262
|
+
|
|
2263
|
+
v = c.add_variable('var', initial_value=myokit.Number(1))
|
|
2264
|
+
v.set_rhs(myokit.Plus(myokit.Name(p), myokit.Name(t)))
|
|
2265
|
+
|
|
2266
|
+
s = sbml.Model.from_myokit_model(m)
|
|
2267
|
+
parameter_names = [v.sid() for v in s.parameters()]
|
|
2268
|
+
self.assertCountEqual(parameter_names, ['var', 'param'])
|
|
2269
|
+
|
|
2270
|
+
p = s.parameter('var')
|
|
2271
|
+
self.assertIsNone(p.units())
|
|
2272
|
+
|
|
2273
|
+
|
|
2184
2274
|
if __name__ == '__main__':
|
|
2185
2275
|
import warnings
|
|
2186
2276
|
warnings.simplefilter('always')
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
#
|
|
3
|
+
# Tests Myokit's SBML support.
|
|
4
|
+
#
|
|
5
|
+
# This file is part of Myokit.
|
|
6
|
+
# See http://myokit.org for copyright, sharing, and licensing details.
|
|
7
|
+
#
|
|
8
|
+
import unittest
|
|
9
|
+
|
|
10
|
+
import myokit
|
|
11
|
+
import myokit.formats
|
|
12
|
+
|
|
13
|
+
import myokit.formats.sbml
|
|
14
|
+
from myokit.formats.sbml._api import Model
|
|
15
|
+
from myokit.formats.sbml._writer import write_string
|
|
16
|
+
import myokit.formats.sbml as sbml
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class TestSBMLExport(unittest.TestCase):
|
|
20
|
+
"""
|
|
21
|
+
Unit tests for the SBML export functionality.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def test_empty_model(self):
|
|
25
|
+
# Test exporting an empty model
|
|
26
|
+
model = Model()
|
|
27
|
+
sbml_str = write_string(model).decode("utf8")
|
|
28
|
+
self.assertIn("<sbml", sbml_str)
|
|
29
|
+
self.assertIn("</sbml>", sbml_str)
|
|
30
|
+
self.assertIn('<model id="unnamed_model"/>', sbml_str)
|
|
31
|
+
|
|
32
|
+
def test_time_unit(self):
|
|
33
|
+
# Test setting the time unit
|
|
34
|
+
model = Model()
|
|
35
|
+
model.set_time_units(myokit.units.second)
|
|
36
|
+
sbml_str = write_string(model).decode("utf8")
|
|
37
|
+
self.assertIn('timeUnits="second"', sbml_str)
|
|
38
|
+
|
|
39
|
+
model = Model()
|
|
40
|
+
model.set_time_units(1e3 * myokit.units.second)
|
|
41
|
+
sbml_str = write_string(model).decode("utf8")
|
|
42
|
+
self.assertIn('<listOfUnitDefinitions>', sbml_str)
|
|
43
|
+
self.assertIn('<unitDefinition id="s_times_1e3">', sbml_str)
|
|
44
|
+
|
|
45
|
+
def test_area_unit(self):
|
|
46
|
+
# Test setting the area unit
|
|
47
|
+
model = Model()
|
|
48
|
+
model.set_area_units(myokit.units.metre)
|
|
49
|
+
sbml_str = write_string(model).decode("utf8")
|
|
50
|
+
self.assertIn('areaUnits="metre"', sbml_str)
|
|
51
|
+
|
|
52
|
+
def test_volume_unit(self):
|
|
53
|
+
# Test setting the volume unit
|
|
54
|
+
model = Model()
|
|
55
|
+
model.set_volume_units(myokit.units.litre)
|
|
56
|
+
sbml_str = write_string(model).decode("utf8")
|
|
57
|
+
self.assertIn('volumeUnits="litre"', sbml_str)
|
|
58
|
+
|
|
59
|
+
def test_substance_unit(self):
|
|
60
|
+
# Test setting the substance unit
|
|
61
|
+
model = Model()
|
|
62
|
+
model.set_substance_units(myokit.units.mole)
|
|
63
|
+
sbml_str = write_string(model).decode("utf8")
|
|
64
|
+
self.assertIn('substanceUnits="mole"', sbml_str)
|
|
65
|
+
|
|
66
|
+
def test_extent_unit(self):
|
|
67
|
+
# Test setting the extent unit
|
|
68
|
+
model = Model()
|
|
69
|
+
model.set_extent_units(myokit.units.mole)
|
|
70
|
+
sbml_str = write_string(model).decode("utf8")
|
|
71
|
+
self.assertIn('extentUnits="mole"', sbml_str)
|
|
72
|
+
|
|
73
|
+
def test_length_unit(self):
|
|
74
|
+
# Test setting the length unit
|
|
75
|
+
model = Model()
|
|
76
|
+
model.set_length_units(myokit.units.metre)
|
|
77
|
+
sbml_str = write_string(model).decode("utf8")
|
|
78
|
+
self.assertIn('lengthUnits="metre"', sbml_str)
|
|
79
|
+
|
|
80
|
+
def test_list_of_unit_definitions(self):
|
|
81
|
+
# Test setting a list of unit definitions
|
|
82
|
+
model = Model()
|
|
83
|
+
model.add_unit("my_unit", myokit.units.ampere)
|
|
84
|
+
model.add_unit("my_unit2", 2 * myokit.units.dimensionless)
|
|
85
|
+
sbml_str = write_string(model).decode("utf8")
|
|
86
|
+
self.assertIn("<listOfUnitDefinitions>", sbml_str)
|
|
87
|
+
self.assertIn('<unitDefinition id="my_unit">', sbml_str)
|
|
88
|
+
self.assertIn(
|
|
89
|
+
'<unit kind="ampere" exponent="1.0" multiplier="1.0"/>',
|
|
90
|
+
sbml_str
|
|
91
|
+
)
|
|
92
|
+
self.assertIn('<unitDefinition id="my_unit2">', sbml_str)
|
|
93
|
+
self.assertIn(
|
|
94
|
+
'<unit kind="dimensionless" multiplier="2.0"/>',
|
|
95
|
+
sbml_str
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
def test_list_of_compartments(self):
|
|
99
|
+
# Test setting a list of compartments
|
|
100
|
+
model = Model()
|
|
101
|
+
c = model.add_compartment("my_compartment")
|
|
102
|
+
c.set_size_units(myokit.units.litre)
|
|
103
|
+
c.set_spatial_dimensions(3)
|
|
104
|
+
c = model.add_compartment("my_compartment2")
|
|
105
|
+
c.set_size_units(1e3 * myokit.units.metre ** 3)
|
|
106
|
+
sbml_str = write_string(model).decode("utf8")
|
|
107
|
+
self.assertIn("<listOfCompartments>", sbml_str)
|
|
108
|
+
self.assertIn(
|
|
109
|
+
'<compartment id="my_compartment" units="litre" spatialDimensions="3.0"/>', # noqa: E501
|
|
110
|
+
sbml_str
|
|
111
|
+
)
|
|
112
|
+
self.assertIn(
|
|
113
|
+
'<compartment id="my_compartment2" units="m3_times_1e3"/>',
|
|
114
|
+
sbml_str
|
|
115
|
+
)
|
|
116
|
+
self.assertIn("<listOfUnitDefinitions>", sbml_str)
|
|
117
|
+
self.assertIn('<unitDefinition id="m3_times_1e3">', sbml_str)
|
|
118
|
+
|
|
119
|
+
def test_constants_and_literals(self):
|
|
120
|
+
m = myokit.Model()
|
|
121
|
+
c = m.add_component('comp')
|
|
122
|
+
t = c.add_variable('time', rhs=myokit.Number(0))
|
|
123
|
+
t.set_unit(myokit.units.second)
|
|
124
|
+
t.set_binding('time')
|
|
125
|
+
v = c.add_variable('my_parameter')
|
|
126
|
+
v.set_rhs(myokit.Number(1))
|
|
127
|
+
v2 = c.add_variable('my_parameter2')
|
|
128
|
+
v2.set_rhs(myokit.Multiply(myokit.Number(2), myokit.Name(v)))
|
|
129
|
+
|
|
130
|
+
# check that the equation is exported correctly to sbml.Model
|
|
131
|
+
s = sbml.Model.from_myokit_model(m)
|
|
132
|
+
parameter_names = [v.sid() for v in s.parameters()]
|
|
133
|
+
self.assertCountEqual(
|
|
134
|
+
parameter_names, ['my_parameter', 'my_parameter2']
|
|
135
|
+
)
|
|
136
|
+
sbml_v = s.parameter('my_parameter')
|
|
137
|
+
sbml_v2 = s.parameter('my_parameter2')
|
|
138
|
+
self.assertEqual(sbml_v.value(), myokit.Number(1))
|
|
139
|
+
self.assertIsNone(sbml_v.initial_value())
|
|
140
|
+
self.assertEqual(
|
|
141
|
+
sbml_v2.initial_value(),
|
|
142
|
+
myokit.Multiply(myokit.Number(2), myokit.Name(v))
|
|
143
|
+
)
|
|
144
|
+
self.assertIsNone(sbml_v2.value())
|
|
145
|
+
self.assertTrue(sbml_v.is_constant())
|
|
146
|
+
self.assertTrue(sbml_v2.is_constant())
|
|
147
|
+
self.assertFalse(sbml_v2.is_literal())
|
|
148
|
+
self.assertTrue(sbml_v.is_literal())
|
|
149
|
+
|
|
150
|
+
def test_list_of_parameters(self):
|
|
151
|
+
# Test setting a list of parameters
|
|
152
|
+
model = Model()
|
|
153
|
+
p = model.add_parameter("my_parameter")
|
|
154
|
+
p.set_value(myokit.Number(1))
|
|
155
|
+
p = model.add_parameter("my_parameter2")
|
|
156
|
+
p.set_units(1e3 * myokit.units.metre / myokit.units.second)
|
|
157
|
+
p.set_value(myokit.Number(2))
|
|
158
|
+
sbml_str = write_string(model).decode("utf8")
|
|
159
|
+
self.assertIn("<listOfParameters>", sbml_str)
|
|
160
|
+
self.assertIn(
|
|
161
|
+
'<parameter id="my_parameter" constant="true" value="1.0"/>',
|
|
162
|
+
sbml_str
|
|
163
|
+
)
|
|
164
|
+
self.assertIn(
|
|
165
|
+
'<parameter id="my_parameter2" units="m_per_s_times_1e3" constant="true" value="2.0"/>', # noqa: E501
|
|
166
|
+
sbml_str
|
|
167
|
+
)
|
|
168
|
+
self.assertNotIn("<listOfRules>", sbml_str)
|
|
169
|
+
self.assertNotIn("<listOfInitialAssignments>", sbml_str)
|
|
170
|
+
self.assertIn("<listOfUnitDefinitions>", sbml_str)
|
|
171
|
+
self.assertIn('<unitDefinition id="m_per_s_times_1e3">', sbml_str)
|
|
172
|
+
|
|
173
|
+
# Test setting a constant parameter that depends on another parameter
|
|
174
|
+
model = Model()
|
|
175
|
+
p = model.add_parameter("my_parameter")
|
|
176
|
+
p.set_value(myokit.Number(1))
|
|
177
|
+
p = model.add_parameter("my_parameter2")
|
|
178
|
+
p.set_initial_value(
|
|
179
|
+
myokit.Multiply(myokit.Name("my_parameter"), myokit.Number(2))
|
|
180
|
+
)
|
|
181
|
+
sbml_str = write_string(model).decode("utf8")
|
|
182
|
+
self.assertIn("<listOfParameters>", sbml_str)
|
|
183
|
+
self.assertIn(
|
|
184
|
+
'<parameter id="my_parameter" constant="true" value="1.0"/>',
|
|
185
|
+
sbml_str
|
|
186
|
+
)
|
|
187
|
+
self.assertIn(
|
|
188
|
+
'<parameter id="my_parameter2" constant="true"/>', # noqa: E501
|
|
189
|
+
sbml_str
|
|
190
|
+
)
|
|
191
|
+
self.assertNotIn("<listOfRules>", sbml_str)
|
|
192
|
+
self.assertIn("<listOfInitialAssignments>", sbml_str)
|
|
193
|
+
self.assertIn('<initialAssignment symbol="my_parameter2">', sbml_str)
|
|
194
|
+
self.assertIn("<times/>\n <ci>my_parameter</ci>\n <cn>2.0</cn>", sbml_str) # noqa: E501
|
|
195
|
+
|
|
196
|
+
model = Model()
|
|
197
|
+
p = model.add_parameter("my_parameter", is_constant=False)
|
|
198
|
+
p.set_initial_value(myokit.Number(1))
|
|
199
|
+
p.set_value(myokit.Number(2))
|
|
200
|
+
sbml_str = write_string(model).decode("utf8")
|
|
201
|
+
self.assertIn("<listOfRules>", sbml_str)
|
|
202
|
+
self.assertIn('<assignmentRule variable="my_parameter">', sbml_str)
|
|
203
|
+
self.assertIn("<cn>2.0</cn>", sbml_str)
|
|
204
|
+
self.assertIn("<listOfInitialAssignments>", sbml_str)
|
|
205
|
+
self.assertIn('<initialAssignment symbol="my_parameter">', sbml_str)
|
|
206
|
+
self.assertIn("<cn>1.0</cn>", sbml_str)
|
|
207
|
+
|
|
208
|
+
def test_list_of_species(self):
|
|
209
|
+
# Test setting a list of species
|
|
210
|
+
model = Model()
|
|
211
|
+
c = model.add_compartment("my_compartment")
|
|
212
|
+
s = model.add_species(c, "my_species")
|
|
213
|
+
s.set_substance_units(myokit.units.mole / myokit.units.litre)
|
|
214
|
+
s.set_value(myokit.Number(1), True)
|
|
215
|
+
s.set_initial_value(myokit.Number(2))
|
|
216
|
+
s = model.add_species(c, "my_species2")
|
|
217
|
+
s.set_substance_units(myokit.units.mole)
|
|
218
|
+
s.set_value(myokit.Number(1), True)
|
|
219
|
+
s.set_initial_value(myokit.Number(2), in_amount=True)
|
|
220
|
+
s = model.add_species(c, "my_species3", is_amount=True)
|
|
221
|
+
s.set_value(myokit.Number(1), True)
|
|
222
|
+
s.set_initial_value(myokit.Number(2))
|
|
223
|
+
s = model.add_species(c, "my_species4", is_amount=True)
|
|
224
|
+
s.set_value(myokit.Number(1), True)
|
|
225
|
+
s.set_initial_value(myokit.Number(2), in_amount=False)
|
|
226
|
+
s = model.add_species(c, "my_species5")
|
|
227
|
+
s.set_value(myokit.Number(1), False)
|
|
228
|
+
sbml_str = write_string(model).decode("utf8")
|
|
229
|
+
self.assertIn("<listOfSpecies>", sbml_str)
|
|
230
|
+
self.assertIn(
|
|
231
|
+
'<species id="my_species" compartment="my_compartment" initialConcentration="2.0" constant="False" units="M" boundaryCondition="False"/>', # noqa: E501
|
|
232
|
+
sbml_str,
|
|
233
|
+
)
|
|
234
|
+
self.assertIn(
|
|
235
|
+
'<species id="my_species2" compartment="my_compartment" initialAmount="2.0" constant="False" units="mole" boundaryCondition="False"/>', # noqa: E501
|
|
236
|
+
sbml_str,
|
|
237
|
+
)
|
|
238
|
+
self.assertIn(
|
|
239
|
+
'<species id="my_species3" compartment="my_compartment" initialAmount="2.0" constant="False" boundaryCondition="False"/>', # noqa: E501
|
|
240
|
+
sbml_str,
|
|
241
|
+
)
|
|
242
|
+
self.assertIn(
|
|
243
|
+
'<species id="my_species4" compartment="my_compartment" initialConcentration="2.0" constant="False" boundaryCondition="False"/>', # noqa: E501
|
|
244
|
+
sbml_str,
|
|
245
|
+
)
|
|
246
|
+
self.assertIn("<listOfRules>", sbml_str)
|
|
247
|
+
self.assertIn('<rateRule variable="my_species">', sbml_str)
|
|
248
|
+
self.assertIn("<cn>1.0</cn>", sbml_str)
|
|
249
|
+
self.assertIn('<assignmentRule variable="my_species5">', sbml_str)
|
|
250
|
+
|
|
251
|
+
def test_list_of_reactions(self):
|
|
252
|
+
# test kinetic law
|
|
253
|
+
model = Model()
|
|
254
|
+
c = model.add_compartment("my_compartment")
|
|
255
|
+
s = model.add_species(c, "my_species")
|
|
256
|
+
s2 = model.add_species(c, "my_species2")
|
|
257
|
+
r = model.add_reaction("my_reaction")
|
|
258
|
+
r.add_reactant(s, "my_reaction_reactant")
|
|
259
|
+
r.add_product(s)
|
|
260
|
+
r.add_modifier(s)
|
|
261
|
+
r.add_modifier(s2, "my_modifier")
|
|
262
|
+
r.set_kinetic_law(myokit.Number(1))
|
|
263
|
+
sbml_str = write_string(model).decode("utf8")
|
|
264
|
+
self.assertIn("<listOfReactions>", sbml_str)
|
|
265
|
+
self.assertIn('<reaction id="my_reaction">', sbml_str)
|
|
266
|
+
self.assertIn("<listOfReactants>", sbml_str)
|
|
267
|
+
self.assertIn("<listOfProducts>", sbml_str)
|
|
268
|
+
self.assertIn('<speciesReference species="my_species"/>', sbml_str)
|
|
269
|
+
self.assertIn('<speciesReference species="my_species" id="my_reaction_reactant"/>', sbml_str) # noqa: E501
|
|
270
|
+
self.assertIn("<listOfModifiers>", sbml_str)
|
|
271
|
+
self.assertIn(
|
|
272
|
+
'<modifierSpeciesReference species="my_species"/>',
|
|
273
|
+
sbml_str
|
|
274
|
+
)
|
|
275
|
+
self.assertIn(
|
|
276
|
+
'<modifierSpeciesReference species="my_species2" id="my_modifier"/>', # noqa: E501
|
|
277
|
+
sbml_str
|
|
278
|
+
)
|
|
279
|
+
self.assertIn("<kineticLaw>", sbml_str)
|
|
280
|
+
self.assertIn("<cn>1.0</cn>", sbml_str)
|
|
281
|
+
|
|
282
|
+
# test stochoimetry
|
|
283
|
+
model = Model()
|
|
284
|
+
c = model.add_compartment("my_compartment")
|
|
285
|
+
s = model.add_species(c, "my_species")
|
|
286
|
+
r = model.add_reaction("my_reaction")
|
|
287
|
+
react = r.add_reactant(s)
|
|
288
|
+
react.set_value(myokit.Number(1))
|
|
289
|
+
r.add_product(s)
|
|
290
|
+
sbml_str = write_string(model).decode("utf8")
|
|
291
|
+
self.assertIn(
|
|
292
|
+
'<speciesReference species="my_species" stoichiometry="1.0"/>',
|
|
293
|
+
sbml_str
|
|
294
|
+
)
|
|
295
|
+
|
|
296
|
+
def test_expressions_multiple_compartments(self):
|
|
297
|
+
m = myokit.Model()
|
|
298
|
+
c = m.add_component('comp')
|
|
299
|
+
t = c.add_variable('time', rhs=myokit.Number(0))
|
|
300
|
+
t.set_unit(myokit.units.second)
|
|
301
|
+
t.set_binding('time')
|
|
302
|
+
c2 = m.add_component('comp2')
|
|
303
|
+
v = c.add_variable('var', initial_value=3)
|
|
304
|
+
v.set_rhs(myokit.Name(t))
|
|
305
|
+
v2 = c2.add_variable('var', initial_value=3)
|
|
306
|
+
v2.set_rhs(myokit.Name(v))
|
|
307
|
+
|
|
308
|
+
# check that the equation is exported correctly to sbml.Model
|
|
309
|
+
s = sbml.Model.from_myokit_model(m)
|
|
310
|
+
parameter_names = [v.sid() for v in s.parameters()]
|
|
311
|
+
self.assertCountEqual(parameter_names, ['comp_var', 'comp2_var'])
|
|
312
|
+
v2_sbml = s.parameter('comp2_var')
|
|
313
|
+
self.assertEqual(
|
|
314
|
+
v2_sbml.value(),
|
|
315
|
+
myokit.Name(v)
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
# check that the equation is exported correctly to sbml string
|
|
319
|
+
sbml_str = write_string(s).decode("utf8")
|
|
320
|
+
self.assertIn('<rateRule variable="comp2_var">', sbml_str)
|
|
321
|
+
self.assertIn('<ci>comp_var</ci>', sbml_str)
|
|
322
|
+
self.assertIn('<rateRule variable="comp_var">', sbml_str)
|
|
323
|
+
self.assertIn(
|
|
324
|
+
'<ci>http://www.sbml.org/sbml/symbols/time</ci>',
|
|
325
|
+
sbml_str
|
|
326
|
+
)
|
|
327
|
+
|
|
@@ -3,7 +3,7 @@ BSD 3-Clause License
|
|
|
3
3
|
Copyright (c) 2011-2017 Maastricht University. All rights reserved.
|
|
4
4
|
Copyright (c) 2017-2020 University of Oxford. All rights reserved.
|
|
5
5
|
(University of Oxford means the Chancellor, Masters and Scholars of the University of Oxford, having an administrative office at Wellington Square, Oxford OX1 2JD, UK).
|
|
6
|
-
Copyright (c) 2020-
|
|
6
|
+
Copyright (c) 2020-2025 University of Nottingham. All rights reserved.
|
|
7
7
|
|
|
8
8
|
Redistribution and use in source and binary forms, with or without
|
|
9
9
|
modification, are permitted provided that the following conditions are met:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: myokit
|
|
3
|
-
Version: 1.37.
|
|
3
|
+
Version: 1.37.2
|
|
4
4
|
Summary: A modeling and simulation tool for cardiac cellular electrophysiology
|
|
5
5
|
Home-page: http://myokit.org
|
|
6
6
|
Author: Michael Clerx
|
|
@@ -25,14 +25,14 @@ Description-Content-Type: text/markdown
|
|
|
25
25
|
License-File: LICENSE.txt
|
|
26
26
|
Requires-Dist: configparser
|
|
27
27
|
Requires-Dist: lxml
|
|
28
|
-
Requires-Dist: matplotlib
|
|
28
|
+
Requires-Dist: matplotlib >=2.2
|
|
29
29
|
Requires-Dist: numpy
|
|
30
30
|
Requires-Dist: setuptools
|
|
31
31
|
Provides-Extra: dev
|
|
32
32
|
Requires-Dist: coverage ; extra == 'dev'
|
|
33
|
-
Requires-Dist: flake8
|
|
33
|
+
Requires-Dist: flake8 >=3 ; extra == 'dev'
|
|
34
34
|
Provides-Extra: docs
|
|
35
|
-
Requires-Dist: sphinx
|
|
35
|
+
Requires-Dist: sphinx >=1.7.4 ; extra == 'docs'
|
|
36
36
|
Provides-Extra: gui
|
|
37
37
|
Requires-Dist: pyqt6 ; extra == 'gui'
|
|
38
38
|
Requires-Dist: sip ; extra == 'gui'
|