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/_sim/icsim.py
DELETED
|
@@ -1,363 +0,0 @@
|
|
|
1
|
-
#
|
|
2
|
-
# Simulation that integrates the Jacobian to obtain the partial derivatives of
|
|
3
|
-
# the state vector with respect to the initial conditions.
|
|
4
|
-
#
|
|
5
|
-
# This file is part of Myokit.
|
|
6
|
-
# See http://myokit.org for copyright, sharing, and licensing details.
|
|
7
|
-
#
|
|
8
|
-
from __future__ import absolute_import, division
|
|
9
|
-
from __future__ import print_function, unicode_literals
|
|
10
|
-
|
|
11
|
-
import os
|
|
12
|
-
import myokit
|
|
13
|
-
import numpy as np
|
|
14
|
-
import platform
|
|
15
|
-
import warnings
|
|
16
|
-
|
|
17
|
-
# Location of C template
|
|
18
|
-
SOURCE_FILE = 'icsim.cpp'
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class ICSimulation(myokit.CppModule):
|
|
22
|
-
"""
|
|
23
|
-
Runs a forward-Euler based simulation and calculates the partial
|
|
24
|
-
derivatives of the state vector with respect to the initial conditions.
|
|
25
|
-
|
|
26
|
-
This class is deprecated. Sensitivities with respect to initial conditions
|
|
27
|
-
can now be calculated with the :class:`Simulation` class.
|
|
28
|
-
|
|
29
|
-
The simulation is based on automatic differentiation implemented using a
|
|
30
|
-
C++ data type that replaces a single scalar float with a float and a list
|
|
31
|
-
of partial derivatives. Any operations on this pair update both the float
|
|
32
|
-
and the set of derivatives. A normal simulation starts with a state
|
|
33
|
-
``y(tmin)`` and a right-hand side function (RHS) ``f(y) = dy/dt``. It then
|
|
34
|
-
integrates ``f(y)`` from ``tmin`` to ``tmax`` resulting in an output state
|
|
35
|
-
``y(tmax)``. In this simulation the data type of ``f`` is replaced by a
|
|
36
|
-
``(f, df/dy)``, where ``df/dy`` is the matrix of partial derivatives of
|
|
37
|
-
``f`` with respect to ``y``. By integrating ``f`` from ``tmin`` to ``tmax``
|
|
38
|
-
we obtain the state at ``tmax``. This can be seen as a function
|
|
39
|
-
``F(y(tmin))``, that gives the state at ``tmax`` given ``y(tmin)``. By
|
|
40
|
-
integrating ``df/dy`` the derivative of ``F`` to ``y(tmin)`` is obtained.
|
|
41
|
-
This result allows the sensitivity of the system to its initial conditions
|
|
42
|
-
to be evaluated.
|
|
43
|
-
|
|
44
|
-
N.B. The partial derivatives can not be calculated for the following
|
|
45
|
-
functions: ``floor``, ``ceil``, ``abs``, quotients and remainders. If these
|
|
46
|
-
are encountered the resulting derivatives will be yielded as ``NaN``.
|
|
47
|
-
However, in many cases, these functions will only occur as part of a
|
|
48
|
-
condition in an if statement, so the ``NaN``'s won't propagate to the final
|
|
49
|
-
result.
|
|
50
|
-
|
|
51
|
-
The model passed to the simulation is cloned and stored internally, so
|
|
52
|
-
changes to the original model object will not affect the simulation.
|
|
53
|
-
|
|
54
|
-
A protocol can be passed in as ``protocol`` or set later using
|
|
55
|
-
:meth:`set_protocol`.
|
|
56
|
-
|
|
57
|
-
Simulations maintain an internal state consisting of
|
|
58
|
-
|
|
59
|
-
- the current simulation time
|
|
60
|
-
- the current state
|
|
61
|
-
- the derivatives of the current state with respect to the initial state
|
|
62
|
-
|
|
63
|
-
When a simulation is created, the simulation time is set to 0 and the
|
|
64
|
-
state is obtained from the given model. The initial derivatives matrix is
|
|
65
|
-
an identity matrix of size ``(n, n)``, where ``n`` is the number of states
|
|
66
|
-
in the model.
|
|
67
|
-
After each call to :meth:`run` the time, state and derivative variables are
|
|
68
|
-
updated so that each successive call to run continues where the previous
|
|
69
|
-
one left off. A :meth:`reset` method is provided that will set the
|
|
70
|
-
time back to 0, revert the current state to the default state and set the
|
|
71
|
-
derivatives back to ``I``.
|
|
72
|
-
|
|
73
|
-
The simulation provides two inputs a variable can bind to:
|
|
74
|
-
|
|
75
|
-
``time``
|
|
76
|
-
This variable contains the simulation time.
|
|
77
|
-
``pace``
|
|
78
|
-
This variable contains the current value of the pacing variable
|
|
79
|
-
as given by the protocol passed to the Simulation.
|
|
80
|
-
|
|
81
|
-
No labeled variables are required.
|
|
82
|
-
"""
|
|
83
|
-
_index = 0 # Simulation id
|
|
84
|
-
|
|
85
|
-
def __init__(self, model, protocol=None):
|
|
86
|
-
super(ICSimulation, self).__init__()
|
|
87
|
-
|
|
88
|
-
# Deprecated on 2021-02-25
|
|
89
|
-
warnings.warn(
|
|
90
|
-
'The class `ICSimulation` is deprecated. Sensitivities with'
|
|
91
|
-
' respect to initial conditions can now be calculated with the'
|
|
92
|
-
' single cell myokit.Simulation class.')
|
|
93
|
-
|
|
94
|
-
# Require a valid model
|
|
95
|
-
if not model.is_valid():
|
|
96
|
-
model.validate()
|
|
97
|
-
model = model.clone()
|
|
98
|
-
self._model = model
|
|
99
|
-
|
|
100
|
-
# Set protocol
|
|
101
|
-
self.set_protocol(protocol)
|
|
102
|
-
|
|
103
|
-
# Get state and default state from model
|
|
104
|
-
self._state = self._model.state()
|
|
105
|
-
self._default_state = list(self._state)
|
|
106
|
-
|
|
107
|
-
# Create initial list of derivatives
|
|
108
|
-
n = len(self._state)
|
|
109
|
-
self._deriv = [0.0] * n**2
|
|
110
|
-
for i in range(n):
|
|
111
|
-
self._deriv[i * (n + 1)] = 1.0
|
|
112
|
-
|
|
113
|
-
# Starting time
|
|
114
|
-
self._time = 0
|
|
115
|
-
|
|
116
|
-
# Default time step
|
|
117
|
-
self._dt = 0
|
|
118
|
-
self.set_step_size()
|
|
119
|
-
|
|
120
|
-
# Unique simulation id
|
|
121
|
-
ICSimulation._index += 1
|
|
122
|
-
module_name = 'myokit_ICSimulation_' + str(ICSimulation._index)
|
|
123
|
-
module_name += '_' + str(myokit.pid_hash())
|
|
124
|
-
|
|
125
|
-
# Arguments
|
|
126
|
-
args = {
|
|
127
|
-
'module_name': module_name,
|
|
128
|
-
'model': self._model,
|
|
129
|
-
}
|
|
130
|
-
fname = os.path.join(myokit.DIR_CFUNC, SOURCE_FILE)
|
|
131
|
-
|
|
132
|
-
# Define libraries
|
|
133
|
-
libs = []
|
|
134
|
-
if platform.system() != 'Windows': # pragma: no windows cover
|
|
135
|
-
libs.append('m')
|
|
136
|
-
|
|
137
|
-
# Create simulation
|
|
138
|
-
libd = []
|
|
139
|
-
incd = [myokit.DIR_CFUNC]
|
|
140
|
-
self._sim = self._compile(module_name, fname, args, libs, libd, incd)
|
|
141
|
-
|
|
142
|
-
def block(self, log, derivatives):
|
|
143
|
-
"""
|
|
144
|
-
Takes the output of a simulation (a simulation log and a list of
|
|
145
|
-
derivatives) and combines it into a single :class:`DataBlock2d` object.
|
|
146
|
-
|
|
147
|
-
Each entry in the log is converted to a 0d entry in the log. The
|
|
148
|
-
calculated derivatives are stored as the 2d field ``derivatives``.
|
|
149
|
-
"""
|
|
150
|
-
# Get time data
|
|
151
|
-
tvar = self._model.time().qname()
|
|
152
|
-
try:
|
|
153
|
-
time = log[tvar]
|
|
154
|
-
except KeyError:
|
|
155
|
-
raise ValueError(
|
|
156
|
-
'The given log must contain an entry for <' + tvar + '>.')
|
|
157
|
-
|
|
158
|
-
# Check shape of derivatives array
|
|
159
|
-
n = self._model.count_states()
|
|
160
|
-
shape = (len(time), n, n)
|
|
161
|
-
if derivatives.shape != shape:
|
|
162
|
-
raise ValueError(
|
|
163
|
-
'Wrong input: Expecting a derivatives array of shape '
|
|
164
|
-
+ str(shape) + '.')
|
|
165
|
-
|
|
166
|
-
# Create datablock
|
|
167
|
-
block = myokit.DataBlock2d(n, n, time)
|
|
168
|
-
for k, v in log.items():
|
|
169
|
-
if k != tvar:
|
|
170
|
-
block.set0d(k, v)
|
|
171
|
-
block.set2d('derivatives', derivatives)
|
|
172
|
-
return block
|
|
173
|
-
|
|
174
|
-
def default_state(self):
|
|
175
|
-
"""
|
|
176
|
-
Returns the default state.
|
|
177
|
-
"""
|
|
178
|
-
return list(self._default_state)
|
|
179
|
-
|
|
180
|
-
def derivatives(self):
|
|
181
|
-
"""
|
|
182
|
-
Return the partial derivatives of the current state with respect to the
|
|
183
|
-
initial state.
|
|
184
|
-
"""
|
|
185
|
-
n = len(self._state)
|
|
186
|
-
return np.array(self._deriv, copy=True).reshape((n, n))
|
|
187
|
-
|
|
188
|
-
def reset(self):
|
|
189
|
-
"""
|
|
190
|
-
Resets the simulation:
|
|
191
|
-
|
|
192
|
-
- The time variable is set to 0
|
|
193
|
-
- The state is set back to the default state
|
|
194
|
-
|
|
195
|
-
"""
|
|
196
|
-
# Reset time
|
|
197
|
-
self._time = 0
|
|
198
|
-
|
|
199
|
-
# Reset state
|
|
200
|
-
self._state = list(self._default_state)
|
|
201
|
-
|
|
202
|
-
# Reset derivatives
|
|
203
|
-
n = len(self._state)
|
|
204
|
-
self._deriv = [0.0] * n**2
|
|
205
|
-
for i in range(n):
|
|
206
|
-
self._deriv[i * (n + 1)] = 1.0
|
|
207
|
-
|
|
208
|
-
def run(self, duration, log=None, log_interval=5, progress=None,
|
|
209
|
-
msg='Running ICSimulation'):
|
|
210
|
-
"""
|
|
211
|
-
Runs a simulation and returns the logged results. Running a simulation
|
|
212
|
-
has the following effects:
|
|
213
|
-
|
|
214
|
-
- The internal state is updated to the last state in the simulation.
|
|
215
|
-
- The simulation's time variable is updated to reflect the time
|
|
216
|
-
elapsed during the simulation.
|
|
217
|
-
|
|
218
|
-
The number of time units to simulate can be set with ``duration``.
|
|
219
|
-
|
|
220
|
-
The variables to log can be indicated using the ``log`` argument. There
|
|
221
|
-
are several options for its value:
|
|
222
|
-
|
|
223
|
-
- ``None`` (default), to log all states.
|
|
224
|
-
- An integer flag or a combination of flags. Options:
|
|
225
|
-
``myokit.LOG_NONE``, ``myokit.LOG_STATE``, ``myokit.LOG_INTER``,
|
|
226
|
-
``myokit.LOG_BOUND``.
|
|
227
|
-
- A list of qnames or variable objects
|
|
228
|
-
- A :class:`myokit.DataLog` obtained from a previous simulation.
|
|
229
|
-
In this case, the newly logged data will be appended to the existing
|
|
230
|
-
log.
|
|
231
|
-
|
|
232
|
-
For more details on the ``log`` argument, see the function
|
|
233
|
-
:meth:`myokit.prepare_log`.
|
|
234
|
-
|
|
235
|
-
The method returns a :class:`myokit.DataLog` and a 3d numpy
|
|
236
|
-
array. In the returned array, the first axis represents the time,
|
|
237
|
-
the second axis is a state x and the third is a state y such that the
|
|
238
|
-
point ``(t, x, y)`` represents ``dx/dy(0)`` at time t. For example, if
|
|
239
|
-
``p`` is the array of derivatives, to get the derivative of state 0
|
|
240
|
-
with respect to the initial value of state 1, use ``p[:,0,1]``.
|
|
241
|
-
|
|
242
|
-
A log entry is created every time *at least* ``log_interval`` time
|
|
243
|
-
units have passed.
|
|
244
|
-
|
|
245
|
-
To obtain feedback on the simulation progress, an object implementing
|
|
246
|
-
the :class:`myokit.ProgressReporter` interface can be passed in.
|
|
247
|
-
passed in as ``progress``. An optional description of the current
|
|
248
|
-
simulation to use in the ProgressReporter can be passed in as `msg`.
|
|
249
|
-
"""
|
|
250
|
-
# Simulation times
|
|
251
|
-
if duration < 0:
|
|
252
|
-
raise ValueError('Simulation time can\'t be negative.')
|
|
253
|
-
tmin = self._time
|
|
254
|
-
tmax = tmin + duration
|
|
255
|
-
|
|
256
|
-
# Parse log argument
|
|
257
|
-
log = myokit.prepare_log(
|
|
258
|
-
log,
|
|
259
|
-
self._model,
|
|
260
|
-
if_empty=myokit.LOG_STATE + myokit.LOG_BOUND,
|
|
261
|
-
allowed_classes=myokit.LOG_STATE + myokit.LOG_BOUND
|
|
262
|
-
+ myokit.LOG_INTER,
|
|
263
|
-
)
|
|
264
|
-
|
|
265
|
-
# Logging period (0 = disabled)
|
|
266
|
-
log_interval = float(log_interval)
|
|
267
|
-
if log_interval < 0:
|
|
268
|
-
log_interval = 0
|
|
269
|
-
|
|
270
|
-
# Create empty list for derivative lists
|
|
271
|
-
derivs = []
|
|
272
|
-
|
|
273
|
-
# Get progress indication function (if any)
|
|
274
|
-
if progress is None:
|
|
275
|
-
progress = myokit._Simulation_progress
|
|
276
|
-
if progress:
|
|
277
|
-
if not isinstance(progress, myokit.ProgressReporter):
|
|
278
|
-
raise ValueError(
|
|
279
|
-
'The argument "progress" must be either a subclass of'
|
|
280
|
-
' myokit.ProgressReporter or None.')
|
|
281
|
-
|
|
282
|
-
# Run simulation
|
|
283
|
-
if duration > 0:
|
|
284
|
-
# Initialize
|
|
285
|
-
n = len(self._state)
|
|
286
|
-
state = [0] * n
|
|
287
|
-
deriv = [0] * (n ** 2)
|
|
288
|
-
self._sim.sim_init(
|
|
289
|
-
tmin,
|
|
290
|
-
tmax,
|
|
291
|
-
self._dt,
|
|
292
|
-
list(self._state),
|
|
293
|
-
list(self._deriv),
|
|
294
|
-
state,
|
|
295
|
-
deriv,
|
|
296
|
-
self._protocol,
|
|
297
|
-
log,
|
|
298
|
-
derivs,
|
|
299
|
-
log_interval,
|
|
300
|
-
)
|
|
301
|
-
t = tmin
|
|
302
|
-
try:
|
|
303
|
-
if progress:
|
|
304
|
-
# Loop with feedback
|
|
305
|
-
with progress.job(msg):
|
|
306
|
-
r = 1 / duration
|
|
307
|
-
while t < tmax:
|
|
308
|
-
t = self._sim.sim_step()
|
|
309
|
-
if not progress.update(min((t - tmin) * r, 1)):
|
|
310
|
-
raise myokit.SimulationCancelledError()
|
|
311
|
-
else:
|
|
312
|
-
# Loop without feedback
|
|
313
|
-
while t < tmax:
|
|
314
|
-
t = self._sim.sim_step()
|
|
315
|
-
finally:
|
|
316
|
-
# Clean even after KeyboardInterrupt or other Exception
|
|
317
|
-
self._sim.sim_clean()
|
|
318
|
-
# Update internal state
|
|
319
|
-
self._state = list(state)
|
|
320
|
-
self._deriv = list(deriv)
|
|
321
|
-
self._time += duration
|
|
322
|
-
# Convert derivatives to numpy arrays
|
|
323
|
-
# Using
|
|
324
|
-
# derivs = [np.array(x).reshape(n,n) for x in derivs]
|
|
325
|
-
# will create a list of views of arrays
|
|
326
|
-
# to avoid the overhead of views, perhaps it's better to copy this
|
|
327
|
-
# view into a new array explicitly?
|
|
328
|
-
derivs = np.array([
|
|
329
|
-
np.array(np.array(x).reshape(n, n), copy=True) for x in derivs
|
|
330
|
-
])
|
|
331
|
-
|
|
332
|
-
# Return
|
|
333
|
-
return log, derivs
|
|
334
|
-
|
|
335
|
-
def set_protocol(self, protocol=None):
|
|
336
|
-
"""
|
|
337
|
-
Changes the pacing protocol used by this simulation.
|
|
338
|
-
"""
|
|
339
|
-
if protocol is None:
|
|
340
|
-
self._protocol = None
|
|
341
|
-
else:
|
|
342
|
-
self._protocol = protocol.clone()
|
|
343
|
-
|
|
344
|
-
def set_step_size(self, dt=0.01):
|
|
345
|
-
"""
|
|
346
|
-
Sets the step size used in the forward Euler solving routine.
|
|
347
|
-
"""
|
|
348
|
-
dt = float(dt)
|
|
349
|
-
if dt <= 0:
|
|
350
|
-
raise ValueError('Step size must be greater than zero.')
|
|
351
|
-
self._dt = dt
|
|
352
|
-
|
|
353
|
-
def state(self):
|
|
354
|
-
"""
|
|
355
|
-
Returns the current state.
|
|
356
|
-
"""
|
|
357
|
-
return list(self._state)
|
|
358
|
-
|
|
359
|
-
def time(self):
|
|
360
|
-
"""
|
|
361
|
-
Returns the current simulation time.
|
|
362
|
-
"""
|
|
363
|
-
return self._time
|