myokit 1.33.9__py3-none-any.whl → 1.35.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.
- myokit/__init__.py +9 -36
- myokit/__main__.py +76 -142
- myokit/_aux.py +62 -16
- myokit/_bin/example.mmt +1 -2
- myokit/_bin/install-win/menu.json +7 -7
- myokit/_config.py +22 -31
- myokit/_datablock.py +30 -74
- myokit/_datalog.py +49 -72
- myokit/_err.py +25 -24
- myokit/_expressions.py +50 -68
- myokit/_io.py +15 -27
- myokit/_model_api.py +453 -249
- myokit/_myokit_version.py +1 -5
- myokit/_parsing.py +38 -44
- myokit/_progress.py +5 -8
- myokit/_protocol.py +99 -9
- myokit/_sim/__init__.py +7 -24
- myokit/_sim/cable.c +6 -8
- myokit/_sim/cable.py +6 -8
- myokit/_sim/cmodel.h +125 -70
- myokit/_sim/cmodel.py +12 -14
- myokit/_sim/compiler.py +1 -4
- myokit/_sim/cvodessim.c +196 -118
- myokit/_sim/cvodessim.py +130 -103
- myokit/_sim/differential.hpp +4 -4
- myokit/_sim/fiber_tissue.c +4 -8
- myokit/_sim/fiber_tissue.py +11 -13
- myokit/_sim/jacobian.cpp +2 -2
- myokit/_sim/jacobian.py +11 -8
- myokit/_sim/mcl.h +53 -55
- myokit/_sim/opencl.py +21 -27
- myokit/_sim/openclsim.c +3 -7
- myokit/_sim/openclsim.cl +3 -3
- myokit/_sim/openclsim.py +49 -40
- myokit/_sim/pacing.h +36 -16
- myokit/_sim/rhs.c +6 -13
- myokit/_sim/rhs.py +5 -14
- myokit/_sim/sundials.py +1 -4
- myokit/_system.py +10 -16
- myokit/_unit.py +4 -13
- myokit/float.py +0 -3
- myokit/formats/__init__.py +8 -10
- myokit/formats/ansic/__init__.py +0 -3
- myokit/formats/ansic/_ewriter.py +2 -4
- myokit/formats/ansic/_exporter.py +1 -4
- myokit/formats/ansic/template/cable.c +4 -4
- myokit/formats/ansic/template/euler.c +5 -5
- myokit/formats/ansic/template/sim.c +6 -6
- myokit/formats/axon/__init__.py +1 -3
- myokit/formats/axon/_abf.py +12 -17
- myokit/formats/axon/_atf.py +5 -6
- myokit/formats/axon/_importer.py +0 -3
- myokit/formats/cellml/__init__.py +0 -3
- myokit/formats/cellml/_ewriter.py +3 -6
- myokit/formats/cellml/_exporter.py +3 -6
- myokit/formats/cellml/_importer.py +1 -4
- myokit/formats/cellml/v1/__init__.py +0 -4
- myokit/formats/cellml/v1/_api.py +8 -11
- myokit/formats/cellml/v1/_parser.py +2 -5
- myokit/formats/cellml/v1/_writer.py +2 -11
- myokit/formats/cellml/v2/__init__.py +0 -3
- myokit/formats/cellml/v2/_api.py +8 -17
- myokit/formats/cellml/v2/_parser.py +2 -5
- myokit/formats/cellml/v2/_writer.py +1 -4
- myokit/formats/channelml/__init__.py +0 -3
- myokit/formats/channelml/_importer.py +11 -21
- myokit/formats/cpp/__init__.py +1 -3
- myokit/formats/cpp/_ewriter.py +0 -3
- myokit/formats/cuda/__init__.py +0 -3
- myokit/formats/cuda/_ewriter.py +2 -4
- myokit/formats/cuda/_exporter.py +0 -3
- myokit/formats/cuda/template/kernel.cu +8 -5
- myokit/formats/easyml/__init__.py +0 -3
- myokit/formats/easyml/_ewriter.py +9 -11
- myokit/formats/easyml/_exporter.py +2 -5
- myokit/formats/html/__init__.py +0 -3
- myokit/formats/html/_exporter.py +0 -3
- myokit/formats/html/_flatten.py +5 -21
- myokit/formats/latex/__init__.py +0 -3
- myokit/formats/latex/_ewriter.py +1 -4
- myokit/formats/latex/_exporter.py +4 -6
- myokit/formats/mathml/__init__.py +0 -3
- myokit/formats/mathml/_ewriter.py +2 -11
- myokit/formats/mathml/_parser.py +4 -6
- myokit/formats/matlab/__init__.py +0 -3
- myokit/formats/matlab/_ewriter.py +1 -4
- myokit/formats/matlab/_exporter.py +2 -5
- myokit/formats/matlab/template/main.m +3 -2
- myokit/formats/opencl/__init__.py +0 -3
- myokit/formats/opencl/_ewriter.py +2 -4
- myokit/formats/opencl/_exporter.py +2 -5
- myokit/formats/opencl/template/cable.c +10 -10
- myokit/formats/opencl/template/kernel.cl +1 -1
- myokit/formats/opencl/template/minilog.py +1 -1
- myokit/formats/python/__init__.py +0 -3
- myokit/formats/python/_ewriter.py +2 -5
- myokit/formats/python/_exporter.py +0 -3
- myokit/formats/python/template/sim.py +14 -14
- myokit/formats/sbml/__init__.py +0 -3
- myokit/formats/sbml/_api.py +50 -44
- myokit/formats/sbml/_importer.py +1 -4
- myokit/formats/sbml/_parser.py +2 -5
- myokit/formats/stan/__init__.py +0 -3
- myokit/formats/stan/_ewriter.py +2 -4
- myokit/formats/stan/_exporter.py +2 -5
- myokit/formats/stan/template/cell.stan +3 -3
- myokit/formats/sympy/__init__.py +0 -3
- myokit/formats/sympy/_ereader.py +1 -4
- myokit/formats/sympy/_ewriter.py +2 -5
- myokit/formats/wcp/__init__.py +0 -3
- myokit/formats/wcp/_wcp.py +2 -8
- myokit/formats/xml/__init__.py +0 -3
- myokit/formats/xml/_exporter.py +0 -3
- myokit/formats/xml/_split.py +0 -3
- myokit/gui/__init__.py +80 -246
- myokit/gui/datablock_viewer.py +103 -86
- myokit/gui/datalog_viewer.py +214 -66
- myokit/gui/explorer.py +15 -21
- myokit/gui/ide.py +171 -144
- myokit/gui/progress.py +9 -9
- myokit/gui/source.py +406 -375
- myokit/gui/vargrapher.py +2 -12
- myokit/lib/deps.py +12 -13
- myokit/lib/guess.py +3 -4
- myokit/lib/hh.py +20 -18
- myokit/lib/markov.py +21 -20
- myokit/lib/multi.py +1 -3
- myokit/lib/plots.py +20 -9
- myokit/pacing.py +0 -3
- myokit/pype.py +7 -18
- myokit/tests/__init__.py +3 -6
- myokit/tests/ansic_event_based_pacing.py +1 -4
- myokit/tests/ansic_fixed_form_pacing.py +3 -6
- myokit/tests/data/beeler-1977-model-compare-b.mmt +2 -2
- myokit/tests/data/clancy-1999-fitting.mmt +1 -0
- myokit/tests/test_aux.py +13 -28
- myokit/tests/test_cellml_v1_api.py +4 -19
- myokit/tests/test_cellml_v1_parser.py +0 -15
- myokit/tests/test_cellml_v1_writer.py +0 -9
- myokit/tests/test_cellml_v2_api.py +4 -19
- myokit/tests/test_cellml_v2_parser.py +0 -15
- myokit/tests/test_cellml_v2_writer.py +0 -9
- myokit/tests/test_cmodel.py +16 -22
- myokit/tests/test_compiler_detection.py +1 -11
- myokit/tests/test_component.py +108 -56
- myokit/tests/test_config.py +34 -67
- myokit/tests/test_datablock.py +1 -9
- myokit/tests/test_datalog.py +19 -24
- myokit/tests/test_dependency_checking.py +8 -23
- myokit/tests/test_expressions.py +0 -9
- myokit/tests/test_float.py +1 -5
- myokit/tests/test_formats.py +0 -9
- myokit/tests/test_formats_axon.py +1 -9
- myokit/tests/test_formats_cellml.py +0 -15
- myokit/tests/test_formats_channelml.py +0 -15
- myokit/tests/test_formats_easyml.py +0 -14
- myokit/tests/test_formats_exporters.py +1 -16
- myokit/tests/test_formats_expression_writers.py +1 -17
- myokit/tests/test_formats_html.py +0 -3
- myokit/tests/test_formats_importers.py +1 -16
- myokit/tests/test_formats_mathml_content.py +0 -9
- myokit/tests/test_formats_mathml_presentation.py +0 -9
- myokit/tests/test_formats_opencl.py +0 -10
- myokit/tests/test_formats_sbml.py +0 -15
- myokit/tests/test_formats_sympy.py +0 -9
- myokit/tests/test_formats_wcp.py +1 -3
- myokit/tests/test_io.py +27 -27
- myokit/tests/test_jacobian_calculator.py +6 -14
- myokit/tests/test_jacobian_tracer.py +0 -9
- myokit/tests/test_lib_deps.py +0 -9
- myokit/tests/test_lib_guess.py +0 -9
- myokit/tests/test_lib_hh.py +18 -12
- myokit/tests/test_lib_markov.py +21 -13
- myokit/tests/test_lib_multi.py +0 -9
- myokit/tests/test_lib_plots.py +13 -8
- myokit/tests/test_meta.py +0 -3
- myokit/tests/test_model.py +390 -96
- myokit/tests/test_model_building.py +44 -96
- myokit/tests/test_opencl_info.py +5 -14
- myokit/tests/test_pacing_factory.py +0 -3
- myokit/tests/test_pacing_system_c.py +1 -23
- myokit/tests/test_pacing_system_py.py +0 -9
- myokit/tests/test_parsing.py +139 -56
- myokit/tests/test_progress_reporters.py +0 -3
- myokit/tests/test_protocol.py +0 -9
- myokit/tests/test_protocol_floating_point.py +1 -10
- myokit/tests/test_protocol_time_series.py +82 -0
- myokit/tests/test_pype.py +0 -9
- myokit/tests/test_quantity.py +0 -9
- myokit/tests/test_rhs_benchmarker.py +1 -9
- myokit/tests/test_sbml_api.py +27 -42
- myokit/tests/test_sbml_parser.py +4 -19
- myokit/tests/test_simulation_1d.py +45 -25
- myokit/tests/test_simulation_cvodes.py +321 -55
- myokit/tests/test_simulation_cvodes_from_disk.py +0 -3
- myokit/tests/test_simulation_fiber_tissue.py +39 -12
- myokit/tests/test_simulation_log_interval.py +1 -431
- myokit/tests/test_simulation_opencl.py +69 -48
- myokit/tests/test_simulation_opencl_log_interval.py +1 -3
- myokit/tests/test_simulation_opencl_vs_cvode.py +1 -10
- myokit/tests/test_simulation_opencl_vs_sim1d.py +1 -10
- myokit/tests/test_system_info.py +1 -11
- myokit/tests/test_tools.py +0 -9
- myokit/tests/test_unit.py +1 -10
- myokit/tests/test_user_functions.py +0 -10
- myokit/tests/test_variable.py +231 -27
- myokit/tools.py +5 -21
- myokit/units.py +5 -3
- {myokit-1.33.9.dist-info → myokit-1.35.0.dist-info}/METADATA +12 -15
- myokit-1.35.0.dist-info/RECORD +391 -0
- {myokit-1.33.9.dist-info → myokit-1.35.0.dist-info}/WHEEL +1 -1
- {myokit-1.33.9.dist-info → myokit-1.35.0.dist-info}/entry_points.txt +0 -1
- myokit/_exec_new.py +0 -15
- myokit/_exec_old.py +0 -15
- myokit/_sim/cvodesim.c +0 -1551
- myokit/_sim/cvodesim.py +0 -674
- myokit/_sim/icsim.cpp +0 -563
- myokit/_sim/icsim.py +0 -363
- myokit/_sim/psim.cpp +0 -656
- myokit/_sim/psim.py +0 -493
- myokit/lib/common.py +0 -1094
- myokit/tests/test_lib_common.py +0 -130
- myokit/tests/test_simulation_cvode.py +0 -612
- myokit/tests/test_simulation_ic.py +0 -108
- myokit/tests/test_simulation_p.py +0 -223
- myokit-1.33.9.dist-info/RECORD +0 -403
- /myokit/formats/opencl/template/{test → test.sh} +0 -0
- {myokit-1.33.9.dist-info → myokit-1.35.0.dist-info}/LICENSE.txt +0 -0
- {myokit-1.33.9.dist-info → myokit-1.35.0.dist-info}/top_level.txt +0 -0
myokit/gui/vargrapher.py
CHANGED
|
@@ -4,23 +4,13 @@
|
|
|
4
4
|
# This file is part of Myokit.
|
|
5
5
|
# See http://myokit.org for copyright, sharing, and licensing details.
|
|
6
6
|
#
|
|
7
|
-
from __future__ import absolute_import, division
|
|
8
|
-
from __future__ import print_function, unicode_literals
|
|
9
|
-
|
|
10
|
-
# Standard library imports
|
|
11
|
-
|
|
12
|
-
# Myokit
|
|
13
7
|
import myokit
|
|
8
|
+
import myokit.gui
|
|
14
9
|
|
|
15
|
-
# Qt imports
|
|
16
10
|
from myokit.gui import QtGui, QtWidgets
|
|
17
11
|
|
|
18
|
-
# NumPy
|
|
19
12
|
import numpy as np
|
|
20
13
|
|
|
21
|
-
# GUI components
|
|
22
|
-
import myokit.gui
|
|
23
|
-
|
|
24
14
|
# Matplotlib (must be imported _after_ gui has had chance to set backend)
|
|
25
15
|
import matplotlib
|
|
26
16
|
import matplotlib.figure
|
|
@@ -50,7 +40,7 @@ class VarGrapher(QtWidgets.QDialog):
|
|
|
50
40
|
*Extends:* ``QtWidgets.QDialog``
|
|
51
41
|
"""
|
|
52
42
|
def __init__(self, parent, title, var, func, args):
|
|
53
|
-
super(
|
|
43
|
+
super().__init__(parent)
|
|
54
44
|
self.setFixedSize(700, 600)
|
|
55
45
|
self.setWindowTitle(title)
|
|
56
46
|
|
myokit/lib/deps.py
CHANGED
|
@@ -5,12 +5,11 @@
|
|
|
5
5
|
# This file is part of Myokit.
|
|
6
6
|
# See http://myokit.org for copyright, sharing, and licensing details.
|
|
7
7
|
#
|
|
8
|
-
from __future__ import absolute_import, division
|
|
9
|
-
from __future__ import print_function, unicode_literals
|
|
10
|
-
|
|
11
|
-
import random
|
|
12
8
|
import collections
|
|
9
|
+
import random
|
|
10
|
+
|
|
13
11
|
import myokit
|
|
12
|
+
|
|
14
13
|
# Don't import pyplot yet, this will crash if no window environment is loaded
|
|
15
14
|
|
|
16
15
|
|
|
@@ -52,7 +51,7 @@ def create_state_dependency_matrix(model, direct=False, knockout=None):
|
|
|
52
51
|
v = model.get(v, class_filter=myokit.Variable)
|
|
53
52
|
if not v.is_state():
|
|
54
53
|
raise ValueError('Knockout variables must be states.')
|
|
55
|
-
iknock.append(v.
|
|
54
|
+
iknock.append(v.index())
|
|
56
55
|
|
|
57
56
|
# Create matrix of direct dependencies
|
|
58
57
|
m = []
|
|
@@ -61,7 +60,7 @@ def create_state_dependency_matrix(model, direct=False, knockout=None):
|
|
|
61
60
|
if i not in iknock:
|
|
62
61
|
for dep in deep[var.lhs()]:
|
|
63
62
|
if dep.var().is_state():
|
|
64
|
-
j = dep.var().
|
|
63
|
+
j = dep.var().index()
|
|
65
64
|
if j not in iknock:
|
|
66
65
|
row[j] = 1
|
|
67
66
|
m.append(row)
|
|
@@ -174,7 +173,7 @@ def plot_state_dependency_matrix(
|
|
|
174
173
|
return a
|
|
175
174
|
|
|
176
175
|
|
|
177
|
-
class DiGraph
|
|
176
|
+
class DiGraph:
|
|
178
177
|
"""
|
|
179
178
|
A simple directed graph implementation.
|
|
180
179
|
|
|
@@ -182,7 +181,7 @@ class DiGraph(object):
|
|
|
182
181
|
for example ``matrix=[[0, 1, 1], [0, 1, 0], [0, 0, 0]]``
|
|
183
182
|
"""
|
|
184
183
|
def __init__(self, matrix=None):
|
|
185
|
-
super(
|
|
184
|
+
super().__init__()
|
|
186
185
|
if isinstance(matrix, DiGraph):
|
|
187
186
|
# Clone
|
|
188
187
|
self.nodes = collections.OrderedDict()
|
|
@@ -455,7 +454,7 @@ class DiGraph(object):
|
|
|
455
454
|
for n_runs in range(max_runs):
|
|
456
455
|
change = False
|
|
457
456
|
for i, layer in enumerate(layers):
|
|
458
|
-
# Set nodes to median of
|
|
457
|
+
# Set nodes to median of neighbors
|
|
459
458
|
for j, node in enumerate(layer):
|
|
460
459
|
n = len(node.edgi) + len(node.edgo)
|
|
461
460
|
if n > 0:
|
|
@@ -493,8 +492,8 @@ class DiGraph(object):
|
|
|
493
492
|
x2 = None
|
|
494
493
|
for k in range(j + 1, n):
|
|
495
494
|
if abs(layer[k].x - node.x) >= too_close:
|
|
496
|
-
x2 = layer[k].x
|
|
497
|
-
break
|
|
495
|
+
x2 = layer[k].x # pragma: no cover
|
|
496
|
+
break # pragma: no cover
|
|
498
497
|
eq.append(layer[k])
|
|
499
498
|
if x2 is None:
|
|
500
499
|
x2 = 1.0
|
|
@@ -526,7 +525,7 @@ class DiGraph(object):
|
|
|
526
525
|
return test
|
|
527
526
|
|
|
528
527
|
|
|
529
|
-
class Node
|
|
528
|
+
class Node:
|
|
530
529
|
"""
|
|
531
530
|
Defines a node in a graph
|
|
532
531
|
"""
|
|
@@ -534,7 +533,7 @@ class Node(object):
|
|
|
534
533
|
"""
|
|
535
534
|
Creates a new, graphless node with the given identifier
|
|
536
535
|
"""
|
|
537
|
-
super(
|
|
536
|
+
super().__init__()
|
|
538
537
|
self.graph = None
|
|
539
538
|
self.uid = uid
|
|
540
539
|
self.edgo = set()
|
myokit/lib/guess.py
CHANGED
|
@@ -5,9 +5,8 @@
|
|
|
5
5
|
# This file is part of Myokit.
|
|
6
6
|
# See http://myokit.org for copyright, sharing, and licensing details.
|
|
7
7
|
#
|
|
8
|
-
from __future__ import absolute_import, division
|
|
9
|
-
from __future__ import print_function, unicode_literals
|
|
10
8
|
import collections
|
|
9
|
+
|
|
11
10
|
import myokit
|
|
12
11
|
|
|
13
12
|
|
|
@@ -392,7 +391,7 @@ def membrane_potential(model):
|
|
|
392
391
|
# Common units for the membrane potential
|
|
393
392
|
common_units = [myokit.units.V]
|
|
394
393
|
|
|
395
|
-
# Non-
|
|
394
|
+
# Non-dimensionalized (e.g. Mitchell-Schaeffer) use [1]
|
|
396
395
|
# But this causes too many false positives
|
|
397
396
|
# common_units.append(myokit.units.dimensionless)
|
|
398
397
|
|
|
@@ -581,7 +580,7 @@ def stimulus_current(model):
|
|
|
581
580
|
myokit.units.A / myokit.units.m**2,
|
|
582
581
|
]
|
|
583
582
|
|
|
584
|
-
# Non-
|
|
583
|
+
# Non-dimensionalized (e.g. Mitchell-Schaeffer) use [mS/uF]
|
|
585
584
|
# But this causes too many false positives
|
|
586
585
|
# common_units.append(myokit.units.S / myokit.units.F)
|
|
587
586
|
|
myokit/lib/hh.py
CHANGED
|
@@ -4,14 +4,12 @@
|
|
|
4
4
|
# This file is part of Myokit.
|
|
5
5
|
# See http://myokit.org for copyright, sharing, and licensing details.
|
|
6
6
|
#
|
|
7
|
-
from __future__ import absolute_import, division
|
|
8
|
-
from __future__ import print_function, unicode_literals
|
|
9
|
-
|
|
10
7
|
import numpy as np
|
|
8
|
+
|
|
11
9
|
import myokit
|
|
12
10
|
|
|
13
11
|
|
|
14
|
-
class HHModel
|
|
12
|
+
class HHModel:
|
|
15
13
|
"""
|
|
16
14
|
Represents a Hodgkin-Huxley (HH)-style model of an ion channel, extracted
|
|
17
15
|
from a :class:`myokit.Model`.
|
|
@@ -29,7 +27,8 @@ class HHModel(object):
|
|
|
29
27
|
The model variables to treat as parameter are specified by the user when
|
|
30
28
|
the model is created. Any other variables, for example state variables such
|
|
31
29
|
as intercellular calcium or constants such as temperature, are fixed when
|
|
32
|
-
the current model is created and can no longer be changed.
|
|
30
|
+
the current model is created and can no longer be changed. Initial values
|
|
31
|
+
written as expressions are evaluated when the model is made.
|
|
33
32
|
|
|
34
33
|
The current variable is optional.
|
|
35
34
|
|
|
@@ -83,7 +82,7 @@ class HHModel(object):
|
|
|
83
82
|
# Load a model from disk
|
|
84
83
|
model = myokit.load_model('some-model.mmt')
|
|
85
84
|
|
|
86
|
-
# Extract a
|
|
85
|
+
# Extract a Hodgkin-Huxley style channel model
|
|
87
86
|
mm = hh.HHModel.from_component(model.get('ina'))
|
|
88
87
|
|
|
89
88
|
"""
|
|
@@ -93,7 +92,7 @@ class HHModel(object):
|
|
|
93
92
|
# A HHModel can return a function to calculate state values, but it never
|
|
94
93
|
# updates its internal state in any way.
|
|
95
94
|
def __init__(self, model, states, parameters=None, current=None, vm=None):
|
|
96
|
-
super(
|
|
95
|
+
super().__init__()
|
|
97
96
|
|
|
98
97
|
#
|
|
99
98
|
# Check input
|
|
@@ -183,15 +182,18 @@ class HHModel(object):
|
|
|
183
182
|
'The membrane potential should not be the current variable.')
|
|
184
183
|
del vm
|
|
185
184
|
|
|
185
|
+
# Get values of all states
|
|
186
|
+
# Note: Do this _before_ changing the model!
|
|
187
|
+
s = self._model.initial_values(True)
|
|
188
|
+
self._model.set_initial_values(s) # Remove expressions
|
|
189
|
+
self._default_state = np.array(
|
|
190
|
+
[v.initial_value(True) for v in self._states])
|
|
191
|
+
|
|
186
192
|
#
|
|
187
193
|
# Demote unnecessary states and remove bindings
|
|
188
194
|
#
|
|
189
|
-
# Get values of all states
|
|
190
|
-
# Note: Do this _before_ changing the model!
|
|
191
|
-
self._default_state = np.array([v.state_value() for v in self._states])
|
|
192
195
|
|
|
193
196
|
# Freeze remaining, non-current-model states
|
|
194
|
-
s = self._model.state() # Get state values before changing anything!
|
|
195
197
|
# Note: list() cast is required so that we iterate over a static list,
|
|
196
198
|
# otherwise we can get issues because the iterator depends on the model
|
|
197
199
|
# (which we're changing).
|
|
@@ -346,19 +348,19 @@ class HHModel(object):
|
|
|
346
348
|
|
|
347
349
|
def default_membrane_potential(self):
|
|
348
350
|
"""
|
|
349
|
-
Returns this
|
|
351
|
+
Returns this HH model's default membrane potential value.
|
|
350
352
|
"""
|
|
351
353
|
return self._default_inputs[0]
|
|
352
354
|
|
|
353
355
|
def default_parameters(self):
|
|
354
356
|
"""
|
|
355
|
-
Returns this
|
|
357
|
+
Returns this HH model's default parameter values
|
|
356
358
|
"""
|
|
357
359
|
return list(self._default_inputs[1:])
|
|
358
360
|
|
|
359
361
|
def default_state(self):
|
|
360
362
|
"""
|
|
361
|
-
Returns this
|
|
363
|
+
Returns this HH model's default state values.
|
|
362
364
|
"""
|
|
363
365
|
return list(self._default_state)
|
|
364
366
|
|
|
@@ -389,8 +391,8 @@ class HHModel(object):
|
|
|
389
391
|
# Get state variables
|
|
390
392
|
states = [x for x in component.variables(state=True)]
|
|
391
393
|
|
|
392
|
-
# Sort by state
|
|
393
|
-
states.sort(key=lambda x: x.
|
|
394
|
+
# Sort by state index
|
|
395
|
+
states.sort(key=lambda x: x.index())
|
|
394
396
|
|
|
395
397
|
else:
|
|
396
398
|
|
|
@@ -529,7 +531,7 @@ class HHModel(object):
|
|
|
529
531
|
return self._steady_state_function(*inputs)
|
|
530
532
|
|
|
531
533
|
|
|
532
|
-
class AnalyticalSimulation
|
|
534
|
+
class AnalyticalSimulation:
|
|
533
535
|
"""
|
|
534
536
|
Analytically evaluates a :class:`HHModel`'s state for a given set of points
|
|
535
537
|
in time.
|
|
@@ -579,7 +581,7 @@ class AnalyticalSimulation(object):
|
|
|
579
581
|
|
|
580
582
|
"""
|
|
581
583
|
def __init__(self, model, protocol=None):
|
|
582
|
-
super(
|
|
584
|
+
super().__init__()
|
|
583
585
|
|
|
584
586
|
# Check model
|
|
585
587
|
if not isinstance(model, HHModel):
|
myokit/lib/markov.py
CHANGED
|
@@ -4,16 +4,14 @@
|
|
|
4
4
|
# This file is part of Myokit.
|
|
5
5
|
# See http://myokit.org for copyright, sharing, and licensing details.
|
|
6
6
|
#
|
|
7
|
-
from __future__ import absolute_import, division
|
|
8
|
-
from __future__ import print_function, unicode_literals
|
|
9
|
-
|
|
10
7
|
import collections
|
|
8
|
+
|
|
11
9
|
import numpy as np
|
|
12
10
|
|
|
13
11
|
import myokit
|
|
14
12
|
|
|
15
13
|
|
|
16
|
-
class LinearModel
|
|
14
|
+
class LinearModel:
|
|
17
15
|
"""
|
|
18
16
|
Represents a linear Markov model of an ion channel extracted from a
|
|
19
17
|
:class:`myokit.Model`.
|
|
@@ -37,7 +35,8 @@ class LinearModel(object):
|
|
|
37
35
|
The model variables to treat as parameter are specified by the user when
|
|
38
36
|
the model is created. Any other variables, for example state variables such
|
|
39
37
|
as intercellular calcium or constants such as temperature, are fixed when
|
|
40
|
-
the markov model is created and can no longer be changed.
|
|
38
|
+
the markov model is created and can no longer be changed. Initial values
|
|
39
|
+
written as expressions are evaluated when the model is made.
|
|
41
40
|
|
|
42
41
|
To create a :class:`Markov`, pass in a :class:`myokit.Model` and select a
|
|
43
42
|
list of states. All other states will be fixed at their current value and
|
|
@@ -119,7 +118,7 @@ class LinearModel(object):
|
|
|
119
118
|
# for its default values or newly passed in values, but it never updates
|
|
120
119
|
# its internal state in any way!
|
|
121
120
|
def __init__(self, model, states, parameters=None, current=None, vm=None):
|
|
122
|
-
super(
|
|
121
|
+
super().__init__()
|
|
123
122
|
|
|
124
123
|
# Get a clone of the model, with all markov models written in full ODE
|
|
125
124
|
# form.
|
|
@@ -205,15 +204,17 @@ class LinearModel(object):
|
|
|
205
204
|
'The membrane potential should not be the current variable.')
|
|
206
205
|
del vm
|
|
207
206
|
|
|
207
|
+
# Get values of all states
|
|
208
|
+
# Note: Do this _before_ changing the model!
|
|
209
|
+
s = self._model.initial_values(True)
|
|
210
|
+
self._default_state = np.array(
|
|
211
|
+
[v.initial_value(True) for v in self._states])
|
|
212
|
+
|
|
208
213
|
#
|
|
209
214
|
# Demote unnecessary states, remove bindings and validate model.
|
|
210
215
|
#
|
|
211
|
-
# Get values of all states
|
|
212
|
-
# Note: Do this _before_ changing the model!
|
|
213
|
-
self._default_state = np.array([v.state_value() for v in self._states])
|
|
214
216
|
|
|
215
217
|
# Freeze remaining, non-markov-model states
|
|
216
|
-
s = self._model.state() # Get state values before changing anything!
|
|
217
218
|
for k, state in enumerate(self._model.states()):
|
|
218
219
|
if state not in self._states:
|
|
219
220
|
state.demote()
|
|
@@ -386,7 +387,7 @@ class LinearModel(object):
|
|
|
386
387
|
globl = {'numpy': np, 'n': n}
|
|
387
388
|
local = {}
|
|
388
389
|
|
|
389
|
-
|
|
390
|
+
exec(code, globl, local)
|
|
390
391
|
self._matrix_function = local['matrix_function']
|
|
391
392
|
|
|
392
393
|
#
|
|
@@ -405,7 +406,7 @@ class LinearModel(object):
|
|
|
405
406
|
code = head + '\n' + '\n'.join([' ' + line for line in body])
|
|
406
407
|
globl = {'numpy': np}
|
|
407
408
|
local = {}
|
|
408
|
-
|
|
409
|
+
exec(code, globl, local)
|
|
409
410
|
self._rate_list_function = local['rate_list_function']
|
|
410
411
|
|
|
411
412
|
def current(self):
|
|
@@ -460,8 +461,8 @@ class LinearModel(object):
|
|
|
460
461
|
# Get state variables
|
|
461
462
|
states = [x for x in component.variables(state=True)]
|
|
462
463
|
|
|
463
|
-
# Sort by state
|
|
464
|
-
states.sort(key=lambda x: x.
|
|
464
|
+
# Sort by state index
|
|
465
|
+
states.sort(key=lambda x: x.index())
|
|
465
466
|
|
|
466
467
|
else:
|
|
467
468
|
|
|
@@ -632,7 +633,7 @@ class LinearModel(object):
|
|
|
632
633
|
return x
|
|
633
634
|
|
|
634
635
|
|
|
635
|
-
class AnalyticalSimulation
|
|
636
|
+
class AnalyticalSimulation:
|
|
636
637
|
"""
|
|
637
638
|
Analytically evaluates a :class:`LinearModel`'s state over a given set of
|
|
638
639
|
points in time.
|
|
@@ -686,7 +687,7 @@ class AnalyticalSimulation(object):
|
|
|
686
687
|
|
|
687
688
|
"""
|
|
688
689
|
def __init__(self, model, protocol=None):
|
|
689
|
-
super(
|
|
690
|
+
super().__init__()
|
|
690
691
|
# Check model
|
|
691
692
|
if not isinstance(model, LinearModel):
|
|
692
693
|
raise ValueError('First parameter must be a `LinearModel`.')
|
|
@@ -1090,7 +1091,7 @@ class AnalyticalSimulation(object):
|
|
|
1090
1091
|
return list(self._state)
|
|
1091
1092
|
|
|
1092
1093
|
|
|
1093
|
-
class DiscreteSimulation
|
|
1094
|
+
class DiscreteSimulation:
|
|
1094
1095
|
"""
|
|
1095
1096
|
Performs stochastic simulations of a :class:`LinearModel`'s behavior for a
|
|
1096
1097
|
finite number of channels.
|
|
@@ -1225,7 +1226,7 @@ class DiscreteSimulation(object):
|
|
|
1225
1226
|
' equal 1.')
|
|
1226
1227
|
y = np.round(x * self._nchannels)
|
|
1227
1228
|
# To make sure it always sums to 1, correct the value found at the
|
|
1228
|
-
#
|
|
1229
|
+
# index with the biggest rounding error.
|
|
1229
1230
|
i = np.argmax(np.abs(x - y))
|
|
1230
1231
|
y[i] = 0
|
|
1231
1232
|
y[i] = self._nchannels - np.sum(y)
|
|
@@ -1560,7 +1561,7 @@ class DiscreteSimulation(object):
|
|
|
1560
1561
|
return list(self._state)
|
|
1561
1562
|
|
|
1562
1563
|
|
|
1563
|
-
class MarkovModel
|
|
1564
|
+
class MarkovModel:
|
|
1564
1565
|
"""
|
|
1565
1566
|
**Deprecated**: This class has been replaced by the classes
|
|
1566
1567
|
:class:`LinearModel` and :class:`AnalyticalSimulation`. Please update your
|
|
@@ -1701,7 +1702,7 @@ def _split_factor(term, variables):
|
|
|
1701
1702
|
'Non-linear function of ' + str(name) + ' found in '
|
|
1702
1703
|
+ str(term) + '.')
|
|
1703
1704
|
|
|
1704
|
-
#
|
|
1705
|
+
# Finalize multiplier
|
|
1705
1706
|
if m is None:
|
|
1706
1707
|
m = myokit.Number(1)
|
|
1707
1708
|
if not positive:
|
myokit/lib/multi.py
CHANGED
|
@@ -4,11 +4,9 @@
|
|
|
4
4
|
# This file is part of Myokit.
|
|
5
5
|
# See http://myokit.org for copyright, sharing, and licensing details.
|
|
6
6
|
#
|
|
7
|
-
|
|
8
|
-
from __future__ import print_function, unicode_literals
|
|
7
|
+
import os
|
|
9
8
|
|
|
10
9
|
import myokit
|
|
11
|
-
import os
|
|
12
10
|
|
|
13
11
|
|
|
14
12
|
#
|
myokit/lib/plots.py
CHANGED
|
@@ -5,10 +5,8 @@
|
|
|
5
5
|
# This file is part of Myokit.
|
|
6
6
|
# See http://myokit.org for copyright, sharing, and licensing details.
|
|
7
7
|
#
|
|
8
|
-
from __future__ import absolute_import, division
|
|
9
|
-
from __future__ import print_function, unicode_literals
|
|
10
|
-
|
|
11
8
|
import numpy as np
|
|
9
|
+
|
|
12
10
|
# Don't import pyplot yet, this will cause a crash if no window environment
|
|
13
11
|
# is loaded.
|
|
14
12
|
|
|
@@ -265,7 +263,8 @@ def current_arrows(log, voltage, currents, axes=None):
|
|
|
265
263
|
|
|
266
264
|
def cumulative_current(
|
|
267
265
|
log, currents, axes=None, labels=None, colors=None, integrate=False,
|
|
268
|
-
|
|
266
|
+
normalize=False, max_currents=None, line_args={}, fill_args={},
|
|
267
|
+
normalise=None):
|
|
269
268
|
"""
|
|
270
269
|
Plots a number of currents, one on top of the other, with the positive and
|
|
271
270
|
negative parts of the current plotted separately.
|
|
@@ -291,8 +290,8 @@ def cumulative_current(
|
|
|
291
290
|
current.
|
|
292
291
|
``integrate``
|
|
293
292
|
Set this to ``True`` to plot total carried charge instead of currents.
|
|
294
|
-
``
|
|
295
|
-
Set this to ``True`` to
|
|
293
|
+
``normalize``
|
|
294
|
+
Set this to ``True`` to normalize the graph at every point, so that the
|
|
296
295
|
relative contribution of each current is shown.
|
|
297
296
|
``max_currents``
|
|
298
297
|
Set this to any integer n to display only the first n currents, and
|
|
@@ -310,6 +309,15 @@ def cumulative_current(
|
|
|
310
309
|
import matplotlib
|
|
311
310
|
import matplotlib.pyplot as plt
|
|
312
311
|
|
|
312
|
+
# Deprecated on 2023-06-7
|
|
313
|
+
if normalize is not None:
|
|
314
|
+
import warnings
|
|
315
|
+
warnings.warn(
|
|
316
|
+
'The keyword argument `normalise` is deprecated. Please use'
|
|
317
|
+
' `normalize` instead.')
|
|
318
|
+
normalize = normalise
|
|
319
|
+
del normalise
|
|
320
|
+
|
|
313
321
|
# Get axes
|
|
314
322
|
if axes is None:
|
|
315
323
|
axes = plt.gca()
|
|
@@ -330,8 +338,8 @@ def cumulative_current(
|
|
|
330
338
|
neg = np.minimum(pos, 0)
|
|
331
339
|
pos = np.maximum(pos, 0)
|
|
332
340
|
|
|
333
|
-
#
|
|
334
|
-
if
|
|
341
|
+
# Normalize
|
|
342
|
+
if normalize:
|
|
335
343
|
pos /= np.maximum(np.sum(pos, axis=0), 1e-99)
|
|
336
344
|
neg /= -np.minimum(np.sum(neg, axis=0), -1e-99)
|
|
337
345
|
|
|
@@ -350,7 +358,10 @@ def cumulative_current(
|
|
|
350
358
|
colors.extend(colors)
|
|
351
359
|
else:
|
|
352
360
|
# Colormap
|
|
353
|
-
|
|
361
|
+
try:
|
|
362
|
+
cmap = matplotlib.colormaps['tab20']
|
|
363
|
+
except AttributeError: # pragma: no cover
|
|
364
|
+
cmap = matplotlib.cm.get_cmap(name='tab20')
|
|
354
365
|
colors = [cmap(i) for i in range(nc)]
|
|
355
366
|
|
|
356
367
|
# Line drawing keyword arguments
|
myokit/pacing.py
CHANGED
|
@@ -4,9 +4,6 @@
|
|
|
4
4
|
# This file is part of Myokit.
|
|
5
5
|
# See http://myokit.org for copyright, sharing, and licensing details.
|
|
6
6
|
#
|
|
7
|
-
from __future__ import absolute_import, division
|
|
8
|
-
from __future__ import print_function, unicode_literals
|
|
9
|
-
|
|
10
7
|
import myokit
|
|
11
8
|
"""
|
|
12
9
|
This module contains factory methods to create Protocol objects
|
myokit/pype.py
CHANGED
|
@@ -4,25 +4,14 @@
|
|
|
4
4
|
# This file is part of Myokit.
|
|
5
5
|
# See http://myokit.org for copyright, sharing, and licensing details.
|
|
6
6
|
#
|
|
7
|
-
from __future__ import absolute_import, division
|
|
8
|
-
from __future__ import print_function, unicode_literals
|
|
9
|
-
|
|
10
7
|
import ast
|
|
8
|
+
import io
|
|
11
9
|
import re
|
|
12
10
|
import sys
|
|
13
11
|
import traceback
|
|
14
12
|
|
|
15
|
-
import myokit
|
|
16
|
-
|
|
17
|
-
try:
|
|
18
|
-
# Python 2
|
|
19
|
-
from cStringIO import StringIO
|
|
20
|
-
except ImportError:
|
|
21
|
-
# Python3
|
|
22
|
-
from io import StringIO
|
|
23
|
-
|
|
24
13
|
|
|
25
|
-
class TemplateEngine
|
|
14
|
+
class TemplateEngine:
|
|
26
15
|
"""
|
|
27
16
|
A tiny templating engine using a php style syntax.
|
|
28
17
|
|
|
@@ -40,7 +29,7 @@ class TemplateEngine(object):
|
|
|
40
29
|
stream specified by the user.
|
|
41
30
|
"""
|
|
42
31
|
def __init__(self):
|
|
43
|
-
super(
|
|
32
|
+
super().__init__()
|
|
44
33
|
self.stream = None
|
|
45
34
|
self.error = None
|
|
46
35
|
|
|
@@ -71,8 +60,8 @@ class TemplateEngine(object):
|
|
|
71
60
|
script = self._convert(filename)
|
|
72
61
|
|
|
73
62
|
# Get or create output stream
|
|
74
|
-
stdout = self.stream if self.stream else StringIO()
|
|
75
|
-
stderr = StringIO()
|
|
63
|
+
stdout = self.stream if self.stream else io.StringIO()
|
|
64
|
+
stderr = io.StringIO()
|
|
76
65
|
|
|
77
66
|
# Run and handle errors
|
|
78
67
|
error = None
|
|
@@ -84,7 +73,7 @@ class TemplateEngine(object):
|
|
|
84
73
|
syserr = sys.stderr
|
|
85
74
|
sys.stdout = stdout
|
|
86
75
|
sys.stderr = stderr
|
|
87
|
-
|
|
76
|
+
exec(script, variables)
|
|
88
77
|
except Exception:
|
|
89
78
|
error = sys.exc_info()
|
|
90
79
|
finally:
|
|
@@ -245,5 +234,5 @@ class PypeError(Exception):
|
|
|
245
234
|
*Extends:* Exception
|
|
246
235
|
"""
|
|
247
236
|
def __init__(self, message):
|
|
248
|
-
super(
|
|
237
|
+
super().__init__(message)
|
|
249
238
|
|
myokit/tests/__init__.py
CHANGED
|
@@ -8,9 +8,6 @@
|
|
|
8
8
|
# The TemporaryDirectory class was adapted from Pints
|
|
9
9
|
# See: https://github.com/pints-team/pints
|
|
10
10
|
#
|
|
11
|
-
from __future__ import absolute_import, division
|
|
12
|
-
from __future__ import print_function, unicode_literals
|
|
13
|
-
|
|
14
11
|
import os
|
|
15
12
|
import tempfile
|
|
16
13
|
import warnings
|
|
@@ -43,14 +40,14 @@ if OpenCL_FOUND:
|
|
|
43
40
|
del info
|
|
44
41
|
|
|
45
42
|
|
|
46
|
-
class TemporaryDirectory
|
|
43
|
+
class TemporaryDirectory:
|
|
47
44
|
"""
|
|
48
45
|
ContextManager that provides a temporary directory to create temporary
|
|
49
46
|
files in. Deletes the directory and its contents when the context is
|
|
50
47
|
exited.
|
|
51
48
|
"""
|
|
52
49
|
def __init__(self):
|
|
53
|
-
super(
|
|
50
|
+
super().__init__()
|
|
54
51
|
self._dir = None
|
|
55
52
|
|
|
56
53
|
def __enter__(self):
|
|
@@ -138,7 +135,7 @@ class CancellingReporter(myokit.ProgressReporter):
|
|
|
138
135
|
return self.okays >= 0
|
|
139
136
|
|
|
140
137
|
|
|
141
|
-
class WarningCollector
|
|
138
|
+
class WarningCollector:
|
|
142
139
|
"""
|
|
143
140
|
Wrapper around warnings.catch_warnings() that gathers all messages into a
|
|
144
141
|
single string.
|
|
@@ -5,9 +5,6 @@
|
|
|
5
5
|
# This file is part of Myokit.
|
|
6
6
|
# See http://myokit.org for copyright, sharing, and licensing details.
|
|
7
7
|
#
|
|
8
|
-
from __future__ import absolute_import, division
|
|
9
|
-
from __future__ import print_function, unicode_literals
|
|
10
|
-
|
|
11
8
|
import os
|
|
12
9
|
|
|
13
10
|
import myokit
|
|
@@ -26,7 +23,7 @@ class AnsicEventBasedPacing(myokit.CModule):
|
|
|
26
23
|
_index = 0
|
|
27
24
|
|
|
28
25
|
def __init__(self, protocol):
|
|
29
|
-
super(
|
|
26
|
+
super().__init__()
|
|
30
27
|
|
|
31
28
|
# Unique id
|
|
32
29
|
AnsicEventBasedPacing._index += 1
|
|
@@ -5,9 +5,6 @@
|
|
|
5
5
|
# This file is part of Myokit.
|
|
6
6
|
# See http://myokit.org for copyright, sharing, and licensing details.
|
|
7
7
|
#
|
|
8
|
-
from __future__ import absolute_import, division
|
|
9
|
-
from __future__ import print_function, unicode_literals
|
|
10
|
-
|
|
11
8
|
import os
|
|
12
9
|
|
|
13
10
|
import myokit
|
|
@@ -24,8 +21,8 @@ class AnsicFixedFormPacing(myokit.CModule):
|
|
|
24
21
|
"""
|
|
25
22
|
_index = 0
|
|
26
23
|
|
|
27
|
-
def __init__(self,
|
|
28
|
-
super(
|
|
24
|
+
def __init__(self, protocol):
|
|
25
|
+
super().__init__()
|
|
29
26
|
|
|
30
27
|
# Unique id
|
|
31
28
|
AnsicFixedFormPacing._index += 1
|
|
@@ -43,7 +40,7 @@ class AnsicFixedFormPacing(myokit.CModule):
|
|
|
43
40
|
self._sys = self._compile(module_name, fname, args, libs, libd, incd)
|
|
44
41
|
|
|
45
42
|
# Initialize
|
|
46
|
-
self._sys.init(
|
|
43
|
+
self._sys.init(protocol)
|
|
47
44
|
|
|
48
45
|
def pace(self, time):
|
|
49
46
|
return self._sys.pace(time)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: beeler-1977-with-differences
|
|
3
3
|
desc: """
|
|
4
4
|
The 1997 Beeler Reuter model of the AP in ventricular myocytes.
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
This test version has some differences
|
|
7
7
|
|
|
8
8
|
Reference:
|
|
@@ -18,7 +18,7 @@ membrane.V = -84.622
|
|
|
18
18
|
calcium.Cai = 2e-7
|
|
19
19
|
ina.m = 0.01
|
|
20
20
|
ina.h = 1.0
|
|
21
|
-
ina.j = 0.
|
|
21
|
+
ina.j = 0.97 + 0.01
|
|
22
22
|
isiz.d = 0.003
|
|
23
23
|
isiz.f = 1.0
|
|
24
24
|
|