myokit 1.36.1__py3-none-any.whl → 1.37.1__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 +6 -19
- myokit/_aux.py +4 -0
- myokit/_datablock.py +55 -65
- myokit/_datalog.py +42 -7
- myokit/_err.py +26 -3
- myokit/_expressions.py +241 -127
- myokit/_model_api.py +19 -13
- myokit/_myokit_version.py +1 -1
- myokit/_sim/jacobian.py +3 -3
- myokit/_sim/openclsim.py +5 -5
- myokit/_sim/rhs.py +1 -1
- myokit/formats/__init__.py +4 -9
- myokit/formats/ansic/_ewriter.py +4 -20
- 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/_patchmaster.py +345 -115
- myokit/formats/opencl/_ewriter.py +3 -42
- myokit/formats/opencl/template/minilog.py +1 -1
- myokit/formats/sympy/_ereader.py +2 -1
- myokit/formats/wcp/_wcp.py +3 -3
- myokit/gui/datalog_viewer.py +28 -9
- myokit/lib/markov.py +2 -2
- myokit/lib/plots.py +4 -4
- myokit/tests/data/formats/wcp-file-empty.wcp +0 -0
- 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 +16 -16
- myokit/tests/test_datalog.py +24 -1
- myokit/tests/test_expressions.py +532 -251
- myokit/tests/test_formats_ansic.py +6 -18
- myokit/tests/test_formats_cpp.py +0 -5
- myokit/tests/test_formats_cuda.py +7 -15
- myokit/tests/test_formats_diffsl.py +728 -0
- myokit/tests/test_formats_easyml.py +4 -9
- myokit/tests/test_formats_exporters_run.py +3 -0
- myokit/tests/test_formats_latex.py +10 -11
- myokit/tests/test_formats_matlab.py +0 -8
- myokit/tests/test_formats_opencl.py +0 -29
- myokit/tests/test_formats_python.py +2 -19
- myokit/tests/test_formats_stan.py +0 -13
- myokit/tests/test_formats_sympy.py +3 -3
- myokit/tests/test_formats_wcp.py +15 -0
- myokit/tests/test_model.py +20 -20
- myokit/tests/test_parsing.py +19 -0
- {myokit-1.36.1.dist-info → myokit-1.37.1.dist-info}/METADATA +1 -1
- {myokit-1.36.1.dist-info → myokit-1.37.1.dist-info}/RECORD +65 -58
- {myokit-1.36.1.dist-info → myokit-1.37.1.dist-info}/LICENSE.txt +0 -0
- {myokit-1.36.1.dist-info → myokit-1.37.1.dist-info}/WHEEL +0 -0
- {myokit-1.36.1.dist-info → myokit-1.37.1.dist-info}/entry_points.txt +0 -0
- {myokit-1.36.1.dist-info → myokit-1.37.1.dist-info}/top_level.txt +0 -0
|
@@ -31,27 +31,6 @@ class OpenCLExpressionWriter(CBasedExpressionWriter):
|
|
|
31
31
|
self._sp = (precision == myokit.SINGLE_PRECISION)
|
|
32
32
|
self._nm = bool(native_math)
|
|
33
33
|
|
|
34
|
-
def _exc(self, e):
|
|
35
|
-
"""Returns ``ex(e)`` if ``e`` is a Condition, else ``ex(e != 0)``."""
|
|
36
|
-
# Can be removed after https://github.com/myokit/myokit/issues/1056
|
|
37
|
-
if isinstance(e, myokit.Condition):
|
|
38
|
-
return self.ex(e)
|
|
39
|
-
return self.ex(myokit.NotEqual(e, myokit.Number(0)))
|
|
40
|
-
|
|
41
|
-
def _ex_infix_comparison(self, e, op):
|
|
42
|
-
"""Handles ex() for infix condition operators (==, !=, > etc.)."""
|
|
43
|
-
# Can be removed after https://github.com/myokit/myokit/issues/1056
|
|
44
|
-
c1 = isinstance(e[0], myokit.Condition)
|
|
45
|
-
c2 = isinstance(e[1], myokit.Condition)
|
|
46
|
-
if (c1 and c2) or not (c1 or c2):
|
|
47
|
-
return f'({self.ex(e[0])} {op} {self.ex(e[1])})'
|
|
48
|
-
else:
|
|
49
|
-
return f'({self._exc(e[0])} {op} {self._exc(e[1])})'
|
|
50
|
-
|
|
51
|
-
def _ex_infix_logical(self, e, op):
|
|
52
|
-
# Can be removed after https://github.com/myokit/myokit/issues/1056
|
|
53
|
-
return f'({self._exc(e[0])} {op} {self._exc(e[1])})'
|
|
54
|
-
|
|
55
34
|
#def _ex_name(self, e):
|
|
56
35
|
#def _ex_derivative(self, e):
|
|
57
36
|
#def _ex_initial_value(self, e):
|
|
@@ -126,25 +105,7 @@ class OpenCLExpressionWriter(CBasedExpressionWriter):
|
|
|
126
105
|
|
|
127
106
|
#def _ex_and(self, e):
|
|
128
107
|
#def _ex_or(self, e):
|
|
129
|
-
|
|
130
|
-
def
|
|
131
|
-
|
|
132
|
-
return f'(!{self._exc(e[0])})'
|
|
133
|
-
|
|
134
|
-
def _ex_if(self, e):
|
|
135
|
-
# Can be removed after https://github.com/myokit/myokit/issues/1056
|
|
136
|
-
_if, _then, _else = self._exc(e._i), self.ex(e._t), self.ex(e._e)
|
|
137
|
-
return f'({_if} ? {_then} : {_else})'
|
|
138
|
-
|
|
139
|
-
def _ex_piecewise(self, e):
|
|
140
|
-
# Can be removed after https://github.com/myokit/myokit/issues/1056
|
|
141
|
-
_ifs = [self._exc(x) for x in e._i]
|
|
142
|
-
_thens = [self.ex(x) for x in e._e]
|
|
143
|
-
s = []
|
|
144
|
-
n = len(_ifs)
|
|
145
|
-
for _if, _then in zip(_ifs, _thens):
|
|
146
|
-
s.append(f'({_if} ? {_then} : ')
|
|
147
|
-
s.append(_thens[-1])
|
|
148
|
-
s.append(')' * len(_ifs))
|
|
149
|
-
return ''.join(s)
|
|
108
|
+
#def _ex_not(self, e):
|
|
109
|
+
#def _ex_if(self, e):
|
|
110
|
+
#def _ex_piecewise(self, e):
|
|
150
111
|
|
myokit/formats/sympy/_ereader.py
CHANGED
|
@@ -156,7 +156,8 @@ class SymPyExpressionReader:
|
|
|
156
156
|
def _ex_abs(self, e):
|
|
157
157
|
return myokit.Abs(self.ex(e.args[0]))
|
|
158
158
|
|
|
159
|
-
def _ex_not(self, e):
|
|
159
|
+
def _ex_not(self, e): # pragma: no cover
|
|
160
|
+
# Sympy turns not(a == b) into a != b etc., so can't test!
|
|
160
161
|
return myokit.Not(self.ex(e.args[0]))
|
|
161
162
|
|
|
162
163
|
def _ex_equal(self, e):
|
myokit/formats/wcp/_wcp.py
CHANGED
|
@@ -241,7 +241,7 @@ class WcpFile(myokit.formats.SweepSource):
|
|
|
241
241
|
|
|
242
242
|
def _channel_id(self, channel_id):
|
|
243
243
|
""" Checks an int or str channel id and returns a valid int. """
|
|
244
|
-
if self._nr == 0:
|
|
244
|
+
if self._nr == 0:
|
|
245
245
|
raise KeyError(f'Channel {channel_id} not found (empty file).')
|
|
246
246
|
|
|
247
247
|
# Handle string
|
|
@@ -314,7 +314,7 @@ class WcpFile(myokit.formats.SweepSource):
|
|
|
314
314
|
|
|
315
315
|
# Create log
|
|
316
316
|
log = myokit.DataLog()
|
|
317
|
-
if self._nr == 0:
|
|
317
|
+
if self._nr == 0:
|
|
318
318
|
return log
|
|
319
319
|
|
|
320
320
|
# Get channel names
|
|
@@ -433,7 +433,7 @@ class WcpFile(myokit.formats.SweepSource):
|
|
|
433
433
|
return self._nr
|
|
434
434
|
|
|
435
435
|
def records(self):
|
|
436
|
-
""" Deprecated alias of :meth:`
|
|
436
|
+
""" Deprecated alias of :meth:`record_count`. """
|
|
437
437
|
# Deprecated since 2023-06-22
|
|
438
438
|
import warnings
|
|
439
439
|
warnings.warn(
|
myokit/gui/datalog_viewer.py
CHANGED
|
@@ -641,13 +641,18 @@ class SweepSourceTab(GraphTabWidget):
|
|
|
641
641
|
def __init__(self, parent, source):
|
|
642
642
|
super().__init__(parent)
|
|
643
643
|
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
644
|
+
if source.sweep_count() > 0:
|
|
645
|
+
# Must have this condition to avoid getting exceptions with e.g.
|
|
646
|
+
# the empty WCP file in the test data set.
|
|
647
|
+
# myokit log myokit/tests/data/formats/wcp-file-empty.wcp
|
|
647
648
|
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
649
|
+
# Add A/D
|
|
650
|
+
for i in range(source.channel_count()):
|
|
651
|
+
self._add_graph_tab(source, i)
|
|
652
|
+
|
|
653
|
+
# Add D/A
|
|
654
|
+
for i in range(source.da_count()):
|
|
655
|
+
self._add_graph_tab(source, i, True)
|
|
651
656
|
|
|
652
657
|
# Add meta data
|
|
653
658
|
self._add_meta_tab(source)
|
|
@@ -846,6 +851,10 @@ class CsvTab(GraphTabWidget):
|
|
|
846
851
|
for k in keys:
|
|
847
852
|
self.addTab(self.create_graph_tab(k, groups.get(k)), k)
|
|
848
853
|
|
|
854
|
+
# Add meta data tab
|
|
855
|
+
if log.meta:
|
|
856
|
+
self.addTab(self.create_meta_tab(log.meta), 'info')
|
|
857
|
+
|
|
849
858
|
def create_graph_tab(self, key, indices=None):
|
|
850
859
|
""" Creates a widget displaying the data stored under ``key``. """
|
|
851
860
|
widget = QtWidgets.QWidget(self)
|
|
@@ -875,6 +884,18 @@ class CsvTab(GraphTabWidget):
|
|
|
875
884
|
self._axes.append(axes)
|
|
876
885
|
return widget
|
|
877
886
|
|
|
887
|
+
def create_meta_tab(self, meta):
|
|
888
|
+
"""
|
|
889
|
+
Returns a tab showing information from a DataLog meta data object.
|
|
890
|
+
"""
|
|
891
|
+
widget = QtWidgets.QTextEdit(self)
|
|
892
|
+
lines = []
|
|
893
|
+
for k, v in meta.items():
|
|
894
|
+
lines.append(f'{k}: {v}')
|
|
895
|
+
widget.setText('\n'.join(lines))
|
|
896
|
+
widget.setReadOnly(True)
|
|
897
|
+
return widget
|
|
898
|
+
|
|
878
899
|
|
|
879
900
|
class MatTab(GraphTabWidget):
|
|
880
901
|
""" A widget displaying a .mat file. """
|
|
@@ -992,9 +1013,7 @@ class TxtTab(GraphTabWidget):
|
|
|
992
1013
|
return
|
|
993
1014
|
|
|
994
1015
|
def create_graph_tab(self, time, data):
|
|
995
|
-
"""
|
|
996
|
-
Creates a widget displaying a time series.
|
|
997
|
-
"""
|
|
1016
|
+
""" Creates a widget displaying a time series. """
|
|
998
1017
|
widget = QtWidgets.QWidget(self)
|
|
999
1018
|
# Create figure
|
|
1000
1019
|
figure = matplotlib.figure.Figure()
|
myokit/lib/markov.py
CHANGED
|
@@ -1077,7 +1077,7 @@ class AnalyticalSimulation:
|
|
|
1077
1077
|
y0 = PI.dot(self._state.reshape((n, 1)))
|
|
1078
1078
|
|
|
1079
1079
|
# Reshape times array
|
|
1080
|
-
times = np.
|
|
1080
|
+
times = np.asarray(times).reshape((len(times),))
|
|
1081
1081
|
|
|
1082
1082
|
# Calculate state
|
|
1083
1083
|
x = P.dot(y0 * np.exp(times * E))
|
|
@@ -1223,7 +1223,7 @@ class DiscreteSimulation:
|
|
|
1223
1223
|
|
|
1224
1224
|
Returns a discretized state ``y`` where ``sum(y) = nchannels``.
|
|
1225
1225
|
"""
|
|
1226
|
-
x = np.
|
|
1226
|
+
x = np.asarray(x, dtype=float)
|
|
1227
1227
|
if (np.abs(1 - np.sum(x))) > 1e-6:
|
|
1228
1228
|
raise ValueError(
|
|
1229
1229
|
'The sum of fractions in the state to be discretized must'
|
myokit/lib/plots.py
CHANGED
|
@@ -62,28 +62,28 @@ def simulation_times(
|
|
|
62
62
|
def stair(ax, time, realtime, evaluations):
|
|
63
63
|
if time is None:
|
|
64
64
|
raise ValueError('This plotting mode requires "time" to be set.')
|
|
65
|
-
time = np.
|
|
65
|
+
time = np.asarray(time)
|
|
66
66
|
step = np.arange(0, len(time))
|
|
67
67
|
ax.step(time, step, label=label)
|
|
68
68
|
|
|
69
69
|
def stair_inverse(ax, time, realtime, evaluations):
|
|
70
70
|
if time is None:
|
|
71
71
|
raise ValueError('This plotting mode requires "time" to be set.')
|
|
72
|
-
time = np.
|
|
72
|
+
time = np.asarray(time)
|
|
73
73
|
step = np.arange(0, len(time))
|
|
74
74
|
ax.step(step, time, label=label)
|
|
75
75
|
|
|
76
76
|
def load(ax, time, realtime, evaluations):
|
|
77
77
|
if time is None:
|
|
78
78
|
raise ValueError('This plotting mode requires "time" to be set.')
|
|
79
|
-
time = np.
|
|
79
|
+
time = np.asarray(time)
|
|
80
80
|
size = np.log(1 / (time[1:] - time[:-1]))
|
|
81
81
|
ax.step(time[1:], size, label=label)
|
|
82
82
|
|
|
83
83
|
def histo(ax, time, realtime, evaluations):
|
|
84
84
|
if time is None:
|
|
85
85
|
raise ValueError('This plotting mode requires "time" to be set.')
|
|
86
|
-
time = np.
|
|
86
|
+
time = np.asarray(time)
|
|
87
87
|
zero = float(time[0])
|
|
88
88
|
bucket_w = (time[-1] - zero) / nbuckets
|
|
89
89
|
bucket_x = np.zeros(nbuckets)
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,105 +1 @@
|
|
|
1
|
-
|
|
2
|
-
name: beeler-1977
|
|
3
|
-
author: Michael Clerx
|
|
4
|
-
desc: """
|
|
5
|
-
The 1997 Beeler Reuter model of the AP in ventricular myocytes
|
|
6
|
-
|
|
7
|
-
Reference:
|
|
8
|
-
|
|
9
|
-
Beeler, Reuter (1976) Reconstruction of the action potential of ventricular
|
|
10
|
-
myocardial fibres
|
|
11
|
-
"""
|
|
12
|
-
f(x) = 4 * x
|
|
13
|
-
# Initial values:
|
|
14
|
-
membrane.V = -84.622
|
|
15
|
-
calcium.Cai = 2e-7
|
|
16
|
-
ina.m = 0.01
|
|
17
|
-
ina.h = 0.99
|
|
18
|
-
ina.j = 0.98
|
|
19
|
-
isi.d = 0.003
|
|
20
|
-
isi.f = 0.99
|
|
21
|
-
ix1.x1 = 0.0004
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
[engine]
|
|
25
|
-
time = 0 in [ms] bind time
|
|
26
|
-
pace = 0 bind pace
|
|
27
|
-
|
|
28
|
-
[membrane]
|
|
29
|
-
C = 1 [uF/cm^2] : The membrane capacitance
|
|
30
|
-
dot(V) = -(1/C) * (i_ion + i_stim)
|
|
31
|
-
in [mV]
|
|
32
|
-
label membrane_potential
|
|
33
|
-
desc: Membrane potential
|
|
34
|
-
i_ion = ik1.IK1 + ix1.Ix1 + ina.INa + isi.Isi
|
|
35
|
-
label cellular_current
|
|
36
|
-
in [uA/cm^2]
|
|
37
|
-
i_stim = engine.pace * amplitude
|
|
38
|
-
amplitude = -25 [uA/cm^2]
|
|
39
|
-
|
|
40
|
-
[ina]
|
|
41
|
-
use membrane.V as V
|
|
42
|
-
gNaBar = 4 [mS/cm^2]
|
|
43
|
-
gNaC = 0.003 [mS/cm^2]
|
|
44
|
-
ENa = 50 [mV]
|
|
45
|
-
INa = (gNaBar * m^3 * h * j + gNaC) * (V - ENa)
|
|
46
|
-
in [uA/cm^2]
|
|
47
|
-
desc: The excitatory inward sodium current
|
|
48
|
-
dot(m) = alpha * (1 - m) - beta * m
|
|
49
|
-
alpha = (V + 47) / (1 - exp(-0.1 * (V + 47)))
|
|
50
|
-
beta = 40 * exp(-0.056 * (V + 72))
|
|
51
|
-
desc: The activation parameter
|
|
52
|
-
dot(h) = alpha * (1 - h) - beta * h
|
|
53
|
-
alpha = 0.126 * exp(-0.25 * (V + 77))
|
|
54
|
-
beta = 1.7 / (1 + exp(-0.082 * (V + 22.5)))
|
|
55
|
-
desc: An inactivation parameter
|
|
56
|
-
dot(j) = alpha * (1 - j) - beta * j
|
|
57
|
-
alpha = 0.055 * exp(-0.25 * (V + 78)) / (1 + exp(-0.2 * (V + 78)))
|
|
58
|
-
beta = 0.3 / (1 + exp(-0.1 * (V + 32)))
|
|
59
|
-
desc: An inactivation parameter
|
|
60
|
-
|
|
61
|
-
[isi]
|
|
62
|
-
use membrane.V as V
|
|
63
|
-
gsBar = 0.09
|
|
64
|
-
Es = -82.3 - 13.0287 * log(calcium.Cai)
|
|
65
|
-
in [mV]
|
|
66
|
-
Isi = gsBar * d * f * (V - Es)
|
|
67
|
-
in [uA/cm^2]
|
|
68
|
-
desc: """
|
|
69
|
-
The slow inward current, primarily carried by calcium ions. Called either
|
|
70
|
-
"iCa" or "is" in the paper.
|
|
71
|
-
"""
|
|
72
|
-
dot(d) = alpha * (1 - d) - beta * d
|
|
73
|
-
alpha = 0.095 * exp(-0.01 * (V + -5)) / (exp(-0.072 * (V + -5)) + 1)
|
|
74
|
-
beta = 0.07 * exp(-0.017 * (V + 44)) / (exp(0.05 * (V + 44)) + 1)
|
|
75
|
-
dot(f) = alpha * (1 - f) - beta * f
|
|
76
|
-
alpha = 0.012 * exp(-0.008 * (V + 28)) / (exp(0.15 * (V + 28)) + 1)
|
|
77
|
-
beta = 0.0065 * exp(-0.02 * (V + 30)) / (exp(-0.2 * (V + 30)) + 1)
|
|
78
|
-
|
|
79
|
-
[calcium]
|
|
80
|
-
dot(Cai) = -1e-7 * isi.Isi + 0.07 * (1e-7 - Cai)
|
|
81
|
-
desc: The intracellular Calcium concentration
|
|
82
|
-
in [mol/L]
|
|
83
|
-
|
|
84
|
-
[ik1]
|
|
85
|
-
use membrane.V as V
|
|
86
|
-
IK1 = 0.35 * (
|
|
87
|
-
4 * (exp(0.04 * (V + 85)) - 1)
|
|
88
|
-
/ (exp(0.08 * (V + 53)) + exp(0.04 * (V + 53)))
|
|
89
|
-
+ 0.2 * (V + 23)
|
|
90
|
-
/ (1 - exp(-0.04 * (V + 23)))
|
|
91
|
-
)
|
|
92
|
-
in [uA/cm^2]
|
|
93
|
-
desc: """A time-independent outward potassium current exhibiting
|
|
94
|
-
inward-going rectification"""
|
|
95
|
-
|
|
96
|
-
[ix1]
|
|
97
|
-
use membrane.V as V
|
|
98
|
-
Ix1 = x1 * 0.8 * (exp(0.04 * (V + 77)) - 1) / exp(0.04 * (V + 35))
|
|
99
|
-
in [uA/cm^2]
|
|
100
|
-
desc: """A voltage- and time-dependent outward current, primarily carried
|
|
101
|
-
by potassium ions"""
|
|
102
|
-
dot(x1) = alpha * (1 - x1) - beta * x1
|
|
103
|
-
alpha = 0.0005 * exp(0.083 * (V + 50)) / (exp(0.057 * (V + 50)) + 1)
|
|
104
|
-
beta = 0.0013 * exp(-0.06 * (V + 20)) / (exp(-0.04 * (V + 333)) + 1)
|
|
105
|
-
|
|
1
|
+
;
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,105 +1 @@
|
|
|
1
|
-
|
|
2
|
-
name: beeler-1977
|
|
3
|
-
author: Michael Clerx
|
|
4
|
-
desc: """
|
|
5
|
-
The 1997 Beeler Reuter model of the AP in ventricular myocytes
|
|
6
|
-
|
|
7
|
-
Reference:
|
|
8
|
-
|
|
9
|
-
Beeler, Reuter (1976) Reconstruction of the action potential of ventricular
|
|
10
|
-
myocardial fibres
|
|
11
|
-
"""
|
|
12
|
-
f(x) = 4 * x
|
|
13
|
-
# Initial values:
|
|
14
|
-
membrane.V = -84.622
|
|
15
|
-
calcium.Cai = 2e-7
|
|
16
|
-
ina.m = 0.01
|
|
17
|
-
ina.h = 0.99
|
|
18
|
-
ina.j = 0.98
|
|
19
|
-
isi.d = 0.003
|
|
20
|
-
isi.f = 0.99
|
|
21
|
-
ix1.x1 = 0.0004
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
[engine]
|
|
25
|
-
time = 0 in [ms] bind time
|
|
26
|
-
pace = 0 bind pace
|
|
27
|
-
|
|
28
|
-
[membrane]
|
|
29
|
-
C = 1 [uF/cm^2] : The membrane capacitance
|
|
30
|
-
dot(V) = -(1/C) * (i_ion + i_stim)
|
|
31
|
-
in [mV]
|
|
32
|
-
label membrane_potential
|
|
33
|
-
desc: Membrane potential
|
|
34
|
-
i_ion = ik1.IK1 + ix1.Ix1 + ina.INa + isi.Isi
|
|
35
|
-
label cellular_current
|
|
36
|
-
in [uA/cm^2]
|
|
37
|
-
i_stim = engine.pace * amplitude
|
|
38
|
-
amplitude = -25 [uA/cm^2]
|
|
39
|
-
|
|
40
|
-
[ina]
|
|
41
|
-
use membrane.V as V
|
|
42
|
-
gNaBar = 4 [mS/cm^2]
|
|
43
|
-
gNaC = 0.003 [mS/cm^2]
|
|
44
|
-
ENa = 50 [mV]
|
|
45
|
-
INa = (gNaBar * m^3 * h * j + gNaC) * (V - ENa)
|
|
46
|
-
in [uA/cm^2]
|
|
47
|
-
desc: The excitatory inward sodium current
|
|
48
|
-
dot(m) = alpha * (1 - m) - beta * m
|
|
49
|
-
alpha = (V + 47) / (1 - exp(-0.1 * (V + 47)))
|
|
50
|
-
beta = 40 * exp(-0.056 * (V + 72))
|
|
51
|
-
desc: The activation parameter
|
|
52
|
-
dot(h) = alpha * (1 - h) - beta * h
|
|
53
|
-
alpha = 0.126 * exp(-0.25 * (V + 77))
|
|
54
|
-
beta = 1.7 / (1 + exp(-0.082 * (V + 22.5)))
|
|
55
|
-
desc: An inactivation parameter
|
|
56
|
-
dot(j) = alpha * (1 - j) - beta * j
|
|
57
|
-
alpha = 0.055 * exp(-0.25 * (V + 78)) / (1 + exp(-0.2 * (V + 78)))
|
|
58
|
-
beta = 0.3 / (1 + exp(-0.1 * (V + 32)))
|
|
59
|
-
desc: An inactivation parameter
|
|
60
|
-
|
|
61
|
-
[isi]
|
|
62
|
-
use membrane.V as V
|
|
63
|
-
gsBar = 0.09
|
|
64
|
-
Es = -82.3 - 13.0287 * log(calcium.Cai)
|
|
65
|
-
in [mV]
|
|
66
|
-
Isi = gsBar * d * f * (V - Es)
|
|
67
|
-
in [uA/cm^2]
|
|
68
|
-
desc: """
|
|
69
|
-
The slow inward current, primarily carried by calcium ions. Called either
|
|
70
|
-
"iCa" or "is" in the paper.
|
|
71
|
-
"""
|
|
72
|
-
dot(d) = alpha * (1 - d) - beta * d
|
|
73
|
-
alpha = 0.095 * exp(-0.01 * (V + -5)) / (exp(-0.072 * (V + -5)) + 1)
|
|
74
|
-
beta = 0.07 * exp(-0.017 * (V + 44)) / (exp(0.05 * (V + 44)) + 1)
|
|
75
|
-
dot(f) = alpha * (1 - f) - beta * f
|
|
76
|
-
alpha = 0.012 * exp(-0.008 * (V + 28)) / (exp(0.15 * (V + 28)) + 1)
|
|
77
|
-
beta = 0.0065 * exp(-0.02 * (V + 30)) / (exp(-0.2 * (V + 30)) + 1)
|
|
78
|
-
|
|
79
|
-
[calcium]
|
|
80
|
-
dot(Cai) = -1e-7 * isi.Isi + 0.07 * (1e-7 - Cai)
|
|
81
|
-
desc: The intracellular Calcium concentration
|
|
82
|
-
in [mol/L]
|
|
83
|
-
|
|
84
|
-
[ik1]
|
|
85
|
-
use membrane.V as V
|
|
86
|
-
IK1 = 0.35 * (
|
|
87
|
-
4 * (exp(0.04 * (V + 85)) - 1)
|
|
88
|
-
/ (exp(0.08 * (V + 53)) + exp(0.04 * (V + 53)))
|
|
89
|
-
+ 0.2 * (V + 23)
|
|
90
|
-
/ (1 - exp(-0.04 * (V + 23)))
|
|
91
|
-
)
|
|
92
|
-
in [uA/cm^2]
|
|
93
|
-
desc: """A time-independent outward potassium current exhibiting
|
|
94
|
-
inward-going rectification"""
|
|
95
|
-
|
|
96
|
-
[ix1]
|
|
97
|
-
use membrane.V as V
|
|
98
|
-
Ix1 = x1 * 0.8 * (exp(0.04 * (V + 77)) - 1) / exp(0.04 * (V + 35))
|
|
99
|
-
in [uA/cm^2]
|
|
100
|
-
desc: """A voltage- and time-dependent outward current, primarily carried
|
|
101
|
-
by potassium ions"""
|
|
102
|
-
dot(x1) = alpha * (1 - x1) - beta * x1
|
|
103
|
-
alpha = 0.0005 * exp(0.083 * (V + 50)) / (exp(0.057 * (V + 50)) + 1)
|
|
104
|
-
beta = 0.0013 * exp(-0.06 * (V + 20)) / (exp(-0.04 * (V + 333)) + 1)
|
|
105
|
-
|
|
1
|
+
;
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
[[model]]
|
|
2
|
+
author: Michael Clerx
|
|
3
|
+
desc: """
|
|
4
|
+
Implementation of the Luo-Rudy model I for the ventricular myocyte.
|
|
5
|
+
Based on an updated formulation downloaded from http://rudylab.wustl.edu
|
|
6
|
+
|
|
7
|
+
Original copyright notice:
|
|
8
|
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
9
|
+
Copyright (C) 2006 by Leonid Livshitz and Yoram Rudy
|
|
10
|
+
Email rudy@wustl.edu
|
|
11
|
+
|
|
12
|
+
This program is free software; you can redistribute it and/or modify
|
|
13
|
+
it under the terms of the GNU General Public License as published by
|
|
14
|
+
the Free Software Foundation; either version 2 of the License, or
|
|
15
|
+
(at your option) any later version.
|
|
16
|
+
|
|
17
|
+
This program is distributed in the hope that it will be useful,
|
|
18
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
19
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
20
|
+
GNU General Public License for more details.
|
|
21
|
+
|
|
22
|
+
You should have received a copy of the GNU General Public License
|
|
23
|
+
along with this program; if not, write to the
|
|
24
|
+
Free Software Foundation, Inc.,
|
|
25
|
+
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
26
|
+
"""
|
|
27
|
+
name: Luo-Rudy model (1991)
|
|
28
|
+
# Initial conditions
|
|
29
|
+
membrane.V = -84.5286
|
|
30
|
+
ina.m = 0.0017
|
|
31
|
+
ina.h = 0.9832
|
|
32
|
+
ina.j = 0.995484
|
|
33
|
+
ica.d = 0.000003
|
|
34
|
+
ica.f = 1
|
|
35
|
+
ik.x = 0.0057
|
|
36
|
+
ica.Ca_i = 0.0002
|
|
37
|
+
|
|
38
|
+
# Engine variables
|
|
39
|
+
[engine]
|
|
40
|
+
time = 0 bind time
|
|
41
|
+
pace = 1 bind pace # Set to 1 to test if it becomes 0 without a protocol
|
|
42
|
+
|
|
43
|
+
# Membrane potential and stimulus
|
|
44
|
+
[membrane]
|
|
45
|
+
dot(V) = -(i_ion + i_stim + i_diff)
|
|
46
|
+
label membrane_potential
|
|
47
|
+
in [mV]
|
|
48
|
+
desc: The membrane potential
|
|
49
|
+
i_ion = ina.INa + ik.IK + ib.Ib + ikp.IKp + ik1.IK1 + ica.ICa
|
|
50
|
+
i_stim = engine.pace * stim_amplitude
|
|
51
|
+
stim_amplitude = -80 [uA/cm^2]
|
|
52
|
+
desc: """
|
|
53
|
+
Stimulus amplitude.
|
|
54
|
+
The online matlab implementation features this 80 uA/cm^2, 0.5 millisecond
|
|
55
|
+
pulse. The cellml version uses a 2 millisecond 25.5 uA/cm^2 pulse.
|
|
56
|
+
"""
|
|
57
|
+
i_diff = 0 bind diffusion_current
|
|
58
|
+
in [uA/cm^2]
|
|
59
|
+
|
|
60
|
+
# Fast Sodium current
|
|
61
|
+
[ina]
|
|
62
|
+
use membrane.V as V
|
|
63
|
+
ENa = cell.RTF * log(cell.Na_o / cell.Na_i)
|
|
64
|
+
desc: Nernst potential of Na
|
|
65
|
+
in [mV]
|
|
66
|
+
a = 1 - 1 / (1 + exp(-(V + 40) / 0.24))
|
|
67
|
+
desc: Used instead of if statement.
|
|
68
|
+
dot(m) = alpha * (1 - m) - beta * m
|
|
69
|
+
alpha = if(V == -47.13, -3.2,
|
|
70
|
+
0.32 * (V + 47.13) / (1 - exp(-0.1 * (V + 47.13))))
|
|
71
|
+
beta = 0.08 * exp(-V / 11)
|
|
72
|
+
desc: """
|
|
73
|
+
Activation parameter of the fast sodium channel, based on Ebihara-Johnson
|
|
74
|
+
(E-J) model of cardiac cells (chicken embryo)
|
|
75
|
+
"""
|
|
76
|
+
dot(h) = alpha * (1 - h) - beta * h
|
|
77
|
+
alpha = a * 0.135 * exp((80 + V) / -6.8)
|
|
78
|
+
beta = a * (3.56 * exp(0.079 * V) + 3.1e5 * exp(0.35 * V)) \
|
|
79
|
+
+ (1 - a) / (0.13 * (1 + exp((V + 10.66) / -11.1)))
|
|
80
|
+
desc: """
|
|
81
|
+
(Fast) Inactivation parameter of the fast sodium channel, based on
|
|
82
|
+
Ebihara-Johnson (E-J) model of cardiac cells (chicken embryo)
|
|
83
|
+
"""
|
|
84
|
+
dot(j) = alpha * (1 - j) - beta * j
|
|
85
|
+
alpha = a * ( -127140 * exp(0.2444 * V) - 3.474e-5 * exp(-0.04391 * V)) \
|
|
86
|
+
* (V + 37.78) / (1 + exp(0.311 * (V + 79.23)))
|
|
87
|
+
beta = a * (0.1212 * exp(-0.01052 * V) / (1 + exp(-0.1378 * (V + 40.14)))) \
|
|
88
|
+
+ (1 - a) * (0.3 * exp(-2.535e-7 * V) / (1 + exp(-0.1 * (V + 32))))
|
|
89
|
+
desc: """
|
|
90
|
+
Slow inactivation gate. Inspired by Beeler-Reuter and Haas. Steady-state
|
|
91
|
+
value (j_inf) is set to value from h gate (h_inf). Time constant obtained
|
|
92
|
+
from Beeler-Reuter model.
|
|
93
|
+
"""
|
|
94
|
+
gNa = 16
|
|
95
|
+
INa = gNa * m^3 * h * j * (V - ENa)
|
|
96
|
+
desc: Fast sodium current
|
|
97
|
+
in [uA/cm^2]
|
|
98
|
+
|
|
99
|
+
# Time-dependent Potassium current
|
|
100
|
+
[ik]
|
|
101
|
+
use membrane.V as V
|
|
102
|
+
PNa_K = 0.01833 : Permability ratio of Na to K
|
|
103
|
+
gK = 0.282 * sqrt(cell.K_o / 5.4)
|
|
104
|
+
in [mS/uF]
|
|
105
|
+
E = cell.RTF * log((cell.K_o + PNa_K * cell.Na_o) / (cell.K_i + PNa_K * cell.Na_i))
|
|
106
|
+
in [mV]
|
|
107
|
+
xi = if(V < -100,
|
|
108
|
+
1,
|
|
109
|
+
if(V == -77,
|
|
110
|
+
2.837 * 0.04 / exp(0.04 * (V + 35)),
|
|
111
|
+
2.837 * (exp(0.04 * (V + 77)) - 1) / ((V + 77) * exp(0.04 * (V + 35)))
|
|
112
|
+
))
|
|
113
|
+
dot(x) = alpha * (1 - x) - beta * x
|
|
114
|
+
alpha = 0.0005 * exp(0.083 * (V + 50)) / (1 + exp(0.057 * (V + 50)))
|
|
115
|
+
beta = 0.0013 * exp(-0.06 * (V + 20)) / (1 + exp(-0.04 * (V + 20)))
|
|
116
|
+
IK = gK * xi * x * (V - E)
|
|
117
|
+
desc: Time-dependent Potassium current
|
|
118
|
+
|
|
119
|
+
# Plateau Potassium current
|
|
120
|
+
[ikp]
|
|
121
|
+
use membrane.V as V
|
|
122
|
+
gKp = 0.0183
|
|
123
|
+
IKp = gKp * (V + 87.8789) / (1 + exp((7.488 - V) / 5.98))
|
|
124
|
+
desc: Plateau Potassium current
|
|
125
|
+
|
|
126
|
+
# Slow inward Calcium current
|
|
127
|
+
[ica]
|
|
128
|
+
use membrane.V as V
|
|
129
|
+
dot(Ca_i) = -1e-4 * ICa + 0.07 * (1e-4 - Ca_i)
|
|
130
|
+
desc: Intracellular Calcium concentration
|
|
131
|
+
E = 7.7 - 13.0287 * log(Ca_i / cell.Ca_o)
|
|
132
|
+
desc: Nernst potential
|
|
133
|
+
in [mV]
|
|
134
|
+
dot(d) = alpha * (1 - d) - beta * d
|
|
135
|
+
alpha = 0.095 * exp(-0.01 * (V - 5)) / (1 + exp(-0.072 * (V - 5)))
|
|
136
|
+
beta = 0.07 * exp(-0.017 * (V + 44)) / (1 + exp(0.05 * (V + 44)))
|
|
137
|
+
dot(f) = alpha * (1-f) - beta * f
|
|
138
|
+
alpha = 0.012 * exp(-0.008 * (V + 28)) / (1 + exp(0.15 * (V + 28)))
|
|
139
|
+
beta = 0.0065 * exp(-0.02 * (V + 30)) / (1 + exp(-0.2 * (V + 30)))
|
|
140
|
+
gCa = 0.09
|
|
141
|
+
ICa = gCa * d * f * (V - E)
|
|
142
|
+
|
|
143
|
+
# Time-independent potassium current
|
|
144
|
+
[ik1]
|
|
145
|
+
use membrane.V as V
|
|
146
|
+
E = cell.RTF * log(cell.K_o / cell.K_i)
|
|
147
|
+
gK1 = 0.6047 * sqrt(cell.K_o / 5.4) * alpha / (alpha + beta)
|
|
148
|
+
alpha = 1.02 / (1 + exp(0.2385 * (V - E - 59.215)))
|
|
149
|
+
beta = (0.49124 * exp(0.08032 * (V - E + 5.476)) + exp(0.06175 * (V - E - 594.31))) \
|
|
150
|
+
/ (1 + exp(-0.5143 * (V - E + 4.753)))
|
|
151
|
+
IK1 = gK1 * (V - E)
|
|
152
|
+
|
|
153
|
+
# Background current
|
|
154
|
+
[ib]
|
|
155
|
+
gb = 0.03921
|
|
156
|
+
Ib = gb * (membrane.V + 59.87) : Background current
|
|
157
|
+
|
|
158
|
+
# Cell parameters (ventricular mammalian cell)
|
|
159
|
+
[cell]
|
|
160
|
+
K_o = 5.4 [mM]
|
|
161
|
+
K_i = 145 [mM]
|
|
162
|
+
Na_o = 140 [mM]
|
|
163
|
+
Na_i = 10 [mM]
|
|
164
|
+
Ca_o = 1.8 [mM]
|
|
165
|
+
RTF = R*T/F
|
|
166
|
+
R = 8.314 [J/K] : Gas constant
|
|
167
|
+
T = 273 + 37 [K] : Absolute temperature
|
|
168
|
+
F = 96.5 [C/mol] : Faraday constant
|
|
169
|
+
|
|
170
|
+
[[protocol]]
|
|
171
|
+
# Level Start Length Period Multiplier
|
|
172
|
+
1.0 1 0.5 1000 0
|
|
173
|
+
|
|
174
|
+
[[script]]
|
|
175
|
+
import matplotlib.pyplot as pl
|
|
176
|
+
import myokit
|
|
177
|
+
|
|
178
|
+
# Create simulation
|
|
179
|
+
m = get_model()
|
|
180
|
+
p = get_protocol()
|
|
181
|
+
s = myokit.SimulationOpenCL(m, p, 16)
|
|
182
|
+
|
|
183
|
+
# Run
|
|
184
|
+
d = s.run(5, log=['engine.time', 'membrane.V', 'engine.pace'])
|
|
185
|
+
b = d.block1d()
|
|
186
|
+
b.save('block1d.zip')
|
|
187
|
+
|
myokit/tests/test_aux.py
CHANGED
|
@@ -526,6 +526,10 @@ class AuxTest(unittest.TestCase):
|
|
|
526
526
|
self.assertEqual(a, b)
|
|
527
527
|
self.assertEqual(len(x), len(y))
|
|
528
528
|
|
|
529
|
+
# No issues when passing initial state from a model
|
|
530
|
+
# See https://github.com/myokit/myokit/pull/1083
|
|
531
|
+
myokit.step(m1, reference=m2, initial=m1.initial_values())
|
|
532
|
+
|
|
529
533
|
def test_strfloat(self):
|
|
530
534
|
# Deprecated alias of myokit.float.str
|
|
531
535
|
args = ['-1.234', True, myokit.SINGLE_PRECISION]
|