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/pacing.h
CHANGED
|
@@ -353,9 +353,7 @@ ESys_Populate(ESys sys, PyObject* protocol)
|
|
|
353
353
|
if (protocol != Py_None) {
|
|
354
354
|
|
|
355
355
|
// Get PyList from protocol (will need to decref!)
|
|
356
|
-
|
|
357
|
-
// This should have been const char* and has been fixed in python 3
|
|
358
|
-
PyObject* list = PyObject_CallMethod(protocol, (char*)"events", NULL); // Returns a new reference
|
|
356
|
+
PyObject* list = PyObject_CallMethod(protocol, "events", NULL); // Returns a new reference
|
|
359
357
|
if(list == NULL) return ESys_POPULATE_INVALID_PROTOCOL;
|
|
360
358
|
if(!PyList_Check(list)) {
|
|
361
359
|
Py_DECREF(list);
|
|
@@ -368,7 +366,7 @@ ESys_Populate(ESys sys, PyObject* protocol)
|
|
|
368
366
|
// since they are tested by the Python code already!
|
|
369
367
|
if(n > 0) {
|
|
370
368
|
PyObject *item, *attr;
|
|
371
|
-
events = (ESys_Event)malloc((size_t)n*sizeof(struct ESys_Event_mem));
|
|
369
|
+
events = (ESys_Event)malloc((size_t)n * sizeof(struct ESys_Event_mem));
|
|
372
370
|
e = events;
|
|
373
371
|
for(i=0; i<n; i++) {
|
|
374
372
|
item = PyList_GetItem(list, i); // Don't decref!
|
|
@@ -620,6 +618,7 @@ typedef int FSys_Flag;
|
|
|
620
618
|
#define FSys_POPULATE_INVALID_TIMES_DATA -24
|
|
621
619
|
#define FSys_POPULATE_INVALID_VALUES_DATA -25
|
|
622
620
|
#define FSys_POPULATE_DECREASING_TIMES_DATA -26
|
|
621
|
+
#define FSys_POPULATE_INVALID_PROTOCOL -27
|
|
623
622
|
|
|
624
623
|
/*
|
|
625
624
|
* Sets a python exception based on a fixed-form pacing error flag.
|
|
@@ -647,6 +646,9 @@ FSys_SetPyErr(FSys_Flag flag)
|
|
|
647
646
|
PyErr_SetString(PyExc_Exception, "F-Pacing error: Pacing system not populated.");
|
|
648
647
|
break;
|
|
649
648
|
// Populate
|
|
649
|
+
case FSys_POPULATE_INVALID_PROTOCOL:
|
|
650
|
+
PyErr_SetString(PyExc_Exception, "F-Pacing error: Invalid protocol python object passed.");
|
|
651
|
+
break;
|
|
650
652
|
case FSys_POPULATE_INVALID_TIMES:
|
|
651
653
|
PyErr_SetString(PyExc_Exception, "F-Pacing error: Invalid times array passed.");
|
|
652
654
|
break;
|
|
@@ -750,28 +752,34 @@ FSys_Destroy(FSys sys)
|
|
|
750
752
|
* Returns a fixed-form pacing error flag.
|
|
751
753
|
*/
|
|
752
754
|
FSys_Flag
|
|
753
|
-
FSys_Populate(FSys sys, PyObject*
|
|
755
|
+
FSys_Populate(FSys sys, PyObject* protocol)
|
|
754
756
|
{
|
|
755
757
|
int i;
|
|
756
758
|
Py_ssize_t n;
|
|
759
|
+
PyObject *times_list, *values_list;
|
|
757
760
|
|
|
758
761
|
// Check ESys
|
|
759
762
|
if(sys == 0) return FSys_INVALID_SYSTEM;
|
|
760
763
|
if (sys->n_points != -1) return FSys_POPULATED_SYSTEM;
|
|
764
|
+
if (protocol == Py_None) return FSys_POPULATE_INVALID_PROTOCOL;
|
|
765
|
+
|
|
766
|
+
// Get PyList from protocol (will need to decref!)
|
|
767
|
+
times_list = PyObject_CallMethod(protocol, "times", NULL); // Returns a new reference
|
|
768
|
+
if(times_list == NULL) return FSys_POPULATE_INVALID_PROTOCOL;
|
|
769
|
+
if(!PyList_Check(times_list)) {
|
|
770
|
+
Py_DECREF(times_list);
|
|
771
|
+
return FSys_POPULATE_INVALID_TIMES;
|
|
772
|
+
}
|
|
761
773
|
|
|
762
|
-
// Check
|
|
763
|
-
if(!PyList_Check(times_list)) return FSys_POPULATE_INVALID_TIMES;
|
|
764
|
-
if(!PyList_Check(values_list)) return FSys_POPULATE_INVALID_VALUES;
|
|
774
|
+
// Check and convert times list
|
|
765
775
|
n = PyList_Size(times_list);
|
|
766
|
-
|
|
767
|
-
if (n < 2) return FSys_POPULATE_NOT_ENOUGH_DATA;
|
|
768
|
-
|
|
769
|
-
// Convert and check times list
|
|
770
|
-
sys->times = (double*)malloc((size_t)n*sizeof(double));
|
|
776
|
+
sys->times = (double*)malloc((size_t)n * sizeof(double));
|
|
771
777
|
for(i=0; i<n; i++) {
|
|
772
778
|
// GetItem and convert --> Borrowed reference so ok not to decref!
|
|
773
779
|
sys->times[i] = PyFloat_AsDouble(PyList_GetItem(times_list, i));
|
|
774
780
|
}
|
|
781
|
+
Py_DECREF(times_list); // Finished with the times_list
|
|
782
|
+
|
|
775
783
|
if (PyErr_Occurred()) {
|
|
776
784
|
free(sys->times); sys->times = NULL;
|
|
777
785
|
return FSys_POPULATE_INVALID_TIMES_DATA;
|
|
@@ -783,12 +791,24 @@ FSys_Populate(FSys sys, PyObject* times_list, PyObject* values_list)
|
|
|
783
791
|
}
|
|
784
792
|
}
|
|
785
793
|
|
|
786
|
-
//
|
|
787
|
-
|
|
794
|
+
// Check and convert values list
|
|
795
|
+
values_list = PyObject_CallMethod(protocol, (char*)"values", NULL); // Returns a new reference
|
|
796
|
+
if(values_list == NULL) {
|
|
797
|
+
free(sys->times); sys->times = NULL;
|
|
798
|
+
return FSys_POPULATE_INVALID_PROTOCOL;
|
|
799
|
+
}
|
|
800
|
+
if(!PyList_Check(values_list) || PyList_Size(values_list) != n) {
|
|
801
|
+
free(sys->times); sys->times = NULL;
|
|
802
|
+
Py_DECREF(values_list);
|
|
803
|
+
return FSys_POPULATE_INVALID_VALUES;
|
|
804
|
+
}
|
|
805
|
+
sys->values = (double*)malloc((size_t)n * sizeof(double));
|
|
788
806
|
for(i=0; i<n; i++) {
|
|
789
807
|
// GetItem and convert --> Borrowed reference so ok not to decref!
|
|
790
808
|
sys->values[i] = PyFloat_AsDouble(PyList_GetItem(values_list, i));
|
|
791
809
|
}
|
|
810
|
+
Py_DECREF(values_list); // Finished with the values list
|
|
811
|
+
|
|
792
812
|
if (PyErr_Occurred()) {
|
|
793
813
|
free(sys->times); sys->times = NULL;
|
|
794
814
|
free(sys->values); sys->values = NULL;
|
|
@@ -832,7 +852,7 @@ FSys_GetLevel(FSys sys, double time, FSys_Flag* flag)
|
|
|
832
852
|
}
|
|
833
853
|
|
|
834
854
|
// Find the highest index `i` of sorted array `times` such that
|
|
835
|
-
// `times[i] <= time`, or `-1` if no such
|
|
855
|
+
// `times[i] <= time`, or `-1` if no such index can be found.
|
|
836
856
|
// A guess can be given, which will be used to speed things up
|
|
837
857
|
|
|
838
858
|
// Get left point, check value
|
myokit/_sim/rhs.c
CHANGED
|
@@ -49,9 +49,9 @@ tab = ' '
|
|
|
49
49
|
|
|
50
50
|
# Process bindings, remove unsupported bindings, get map of bound variables to
|
|
51
51
|
# internal names
|
|
52
|
-
bound_variables =
|
|
52
|
+
bound_variables = myokit._prepare_bindings(model, {
|
|
53
53
|
'time' : 'engine_time',
|
|
54
|
-
|
|
54
|
+
})
|
|
55
55
|
|
|
56
56
|
# Get equations
|
|
57
57
|
equations = model.solvable_order()
|
|
@@ -135,15 +135,12 @@ log_extract(PyObject* data, const char* name, const int position, double* var)
|
|
|
135
135
|
PyObject* key;
|
|
136
136
|
PyObject* list;
|
|
137
137
|
PyObject* item;
|
|
138
|
-
char errstr[1000];
|
|
139
138
|
|
|
140
139
|
// Get sequence from dict
|
|
141
140
|
key = PyUnicode_FromString(name);
|
|
142
141
|
if (!PyDict_Contains(data, key)) {
|
|
143
142
|
Py_DECREF(key);
|
|
144
|
-
|
|
145
|
-
sprintf(errstr, "Variable %s not found in log.", name);
|
|
146
|
-
PyErr_SetString(PyExc_Exception, errstr);
|
|
143
|
+
PyErr_Format(PyExc_Exception, "Variable %s not found in log.", name);
|
|
147
144
|
return 0;
|
|
148
145
|
}
|
|
149
146
|
list = PyDict_GetItem(data, key); // Borrowed ref, don't decref
|
|
@@ -154,9 +151,7 @@ log_extract(PyObject* data, const char* name, const int position, double* var)
|
|
|
154
151
|
item = PySequence_GetItem(list, position); // New reference, decref
|
|
155
152
|
if (item == NULL) {
|
|
156
153
|
Py_DECREF(key);
|
|
157
|
-
|
|
158
|
-
sprintf(errstr, "No item found at position %i of log for %s.", position, name);
|
|
159
|
-
PyErr_SetString(PyExc_Exception, errstr);
|
|
154
|
+
PyErr_Format(PyExc_Exception, "No item found at position %i of log for %s.", position, name);
|
|
160
155
|
return 0;
|
|
161
156
|
}
|
|
162
157
|
Py_DECREF(key);
|
|
@@ -164,9 +159,7 @@ log_extract(PyObject* data, const char* name, const int position, double* var)
|
|
|
164
159
|
// Get double from float
|
|
165
160
|
if (!PyFloat_Check(item)) {
|
|
166
161
|
Py_XDECREF(item);
|
|
167
|
-
|
|
168
|
-
sprintf(errstr, "Log for %s can only contain floats (error at index %i).", name, position);
|
|
169
|
-
PyErr_SetString(PyExc_Exception, errstr);
|
|
162
|
+
PyErr_Format(PyExc_Exception, "Log for %s can only contain floats (error at index %i).", name, position);
|
|
170
163
|
return 0;
|
|
171
164
|
}
|
|
172
165
|
|
|
@@ -250,7 +243,7 @@ bench(PyObject* self, PyObject* args, void (*fnc)(void))
|
|
|
250
243
|
return 0;
|
|
251
244
|
}
|
|
252
245
|
if (start < 0) {
|
|
253
|
-
PyErr_SetString(PyExc_Exception, "Invalid log position selection: Negative list
|
|
246
|
+
PyErr_SetString(PyExc_Exception, "Invalid log position selection: Negative list index given.");
|
|
254
247
|
return 0;
|
|
255
248
|
}
|
|
256
249
|
|
myokit/_sim/rhs.py
CHANGED
|
@@ -4,20 +4,11 @@
|
|
|
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 os
|
|
11
|
-
import timeit
|
|
12
|
-
import myokit
|
|
13
8
|
import platform
|
|
9
|
+
import timeit
|
|
14
10
|
|
|
15
|
-
|
|
16
|
-
try:
|
|
17
|
-
basestring
|
|
18
|
-
except NameError: # pragma: no cover
|
|
19
|
-
basestring = str
|
|
20
|
-
|
|
11
|
+
import myokit
|
|
21
12
|
|
|
22
13
|
# Location of C source file
|
|
23
14
|
SOURCE_FILE = 'rhs.c'
|
|
@@ -33,7 +24,7 @@ class RhsBenchmarker(myokit.CModule):
|
|
|
33
24
|
be selected.
|
|
34
25
|
|
|
35
26
|
By default, the given list of variables are the only variables included in
|
|
36
|
-
a partial simulation. This
|
|
27
|
+
a partial simulation. This behavior can be inverted by setting
|
|
37
28
|
``exclude_selected=True``. With this setting, all variables except those in
|
|
38
29
|
the given list will be tested.
|
|
39
30
|
|
|
@@ -42,7 +33,7 @@ class RhsBenchmarker(myokit.CModule):
|
|
|
42
33
|
_index = 0 # Unique id for the generated module
|
|
43
34
|
|
|
44
35
|
def __init__(self, model, variables=None, exclude_selected=False):
|
|
45
|
-
super(
|
|
36
|
+
super().__init__()
|
|
46
37
|
|
|
47
38
|
# Require a valid model
|
|
48
39
|
model.validate()
|
|
@@ -201,7 +192,7 @@ class RhsBenchmarker(myokit.CModule):
|
|
|
201
192
|
else:
|
|
202
193
|
self._variables = set()
|
|
203
194
|
for var in variables:
|
|
204
|
-
if isinstance(var,
|
|
195
|
+
if isinstance(var, str):
|
|
205
196
|
# String? Then get variable from model
|
|
206
197
|
var = self._model.get(var)
|
|
207
198
|
else:
|
myokit/_sim/sundials.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 os
|
|
11
8
|
|
|
12
9
|
import myokit
|
|
@@ -32,7 +29,7 @@ class Sundials(myokit.CModule):
|
|
|
32
29
|
_version = None
|
|
33
30
|
|
|
34
31
|
def __init__(self):
|
|
35
|
-
super(
|
|
32
|
+
super().__init__()
|
|
36
33
|
# Create and cache back-end
|
|
37
34
|
Sundials._index += 1
|
|
38
35
|
|
myokit/_system.py
CHANGED
|
@@ -4,13 +4,10 @@
|
|
|
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
|
|
9
|
-
|
|
7
|
+
import importlib
|
|
10
8
|
import os
|
|
11
|
-
import sys
|
|
12
9
|
import platform
|
|
13
|
-
import
|
|
10
|
+
import sys
|
|
14
11
|
|
|
15
12
|
import myokit
|
|
16
13
|
|
|
@@ -28,7 +25,7 @@ def system(live_printing=False):
|
|
|
28
25
|
out = []
|
|
29
26
|
else:
|
|
30
27
|
# Create fake list interface that just prints
|
|
31
|
-
class Out
|
|
28
|
+
class Out:
|
|
32
29
|
def append(self, x):
|
|
33
30
|
print(x)
|
|
34
31
|
|
|
@@ -68,25 +65,22 @@ def system(live_printing=False):
|
|
|
68
65
|
out.append('== GUI ==')
|
|
69
66
|
|
|
70
67
|
try: # pragma: no cover
|
|
71
|
-
from
|
|
72
|
-
out.append('
|
|
68
|
+
from PyQt6.QtCore import QT_VERSION_STR
|
|
69
|
+
out.append('PyQt6: ' + QT_VERSION_STR)
|
|
73
70
|
out.append(' Sip: ' + _module_version('sip'))
|
|
74
71
|
del QT_VERSION_STR
|
|
75
72
|
except ImportError:
|
|
76
|
-
out.append('
|
|
73
|
+
out.append('PyQt6: Not found')
|
|
77
74
|
|
|
78
75
|
try: # pragma: no cover
|
|
79
|
-
from
|
|
80
|
-
out.append('
|
|
76
|
+
from PyQt5.QtCore import QT_VERSION_STR
|
|
77
|
+
out.append('PyQt5: ' + QT_VERSION_STR)
|
|
81
78
|
out.append(' Sip: ' + _module_version('sip'))
|
|
82
79
|
del QT_VERSION_STR
|
|
83
80
|
except ImportError:
|
|
84
|
-
out.append('
|
|
85
|
-
except RuntimeError: # pragma: no cover
|
|
86
|
-
# Happens if PyQt5 was also found
|
|
87
|
-
out.append('PyQt4: OK')
|
|
81
|
+
out.append('PyQt5: Not found')
|
|
88
82
|
|
|
89
|
-
out.append('
|
|
83
|
+
out.append('PySide6: ' + _module_version('PySide6'))
|
|
90
84
|
out.append('PySide2: ' + _module_version('PySide2'))
|
|
91
85
|
out.append('')
|
|
92
86
|
|
myokit/_unit.py
CHANGED
|
@@ -5,21 +5,12 @@
|
|
|
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 math
|
|
12
9
|
|
|
13
10
|
import myokit
|
|
14
11
|
|
|
15
|
-
# Strings in Python 2 and 3
|
|
16
|
-
try:
|
|
17
|
-
basestring
|
|
18
|
-
except NameError: # pragma: no python 2 cover
|
|
19
|
-
basestring = str
|
|
20
|
-
|
|
21
12
|
|
|
22
|
-
class Unit
|
|
13
|
+
class Unit:
|
|
23
14
|
"""
|
|
24
15
|
Represents a unit.
|
|
25
16
|
|
|
@@ -516,13 +507,13 @@ class Unit(object):
|
|
|
516
507
|
``True`` if this units name should be used to display this unit in.
|
|
517
508
|
This should be set for all common units (m, kg, nm, Hz) but not for
|
|
518
509
|
more obscure units (furlong, parsec). Having ``output`` set to
|
|
519
|
-
``False`` will cause one-way
|
|
510
|
+
``False`` will cause one-way behavior: Myokit will recognise the
|
|
520
511
|
unit name but never use it in output.
|
|
521
512
|
Setting this to ``True`` will also register the given name as a
|
|
522
513
|
preferred representation format.
|
|
523
514
|
|
|
524
515
|
"""
|
|
525
|
-
if not isinstance(name,
|
|
516
|
+
if not isinstance(name, str):
|
|
526
517
|
raise TypeError('Given name must be a string.')
|
|
527
518
|
if not isinstance(unit, Unit):
|
|
528
519
|
raise TypeError('Given unit must be myokit.Unit')
|
|
@@ -679,7 +670,7 @@ class Unit(object):
|
|
|
679
670
|
self._m - other._m)
|
|
680
671
|
|
|
681
672
|
|
|
682
|
-
class Quantity
|
|
673
|
+
class Quantity:
|
|
683
674
|
"""
|
|
684
675
|
Represents a quantity with a :class:`unit <myokit.Unit>`. Can be used to
|
|
685
676
|
perform unit-safe arithmetic.
|
myokit/float.py
CHANGED
myokit/formats/__init__.py
CHANGED
|
@@ -4,15 +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
|
-
import myokit
|
|
11
7
|
import os
|
|
12
8
|
import sys
|
|
13
9
|
import traceback
|
|
14
10
|
import warnings
|
|
15
11
|
|
|
12
|
+
import myokit
|
|
13
|
+
|
|
16
14
|
# Constants
|
|
17
15
|
DIR_FORMATS = os.path.join(myokit.DIR_MYOKIT, 'formats')
|
|
18
16
|
|
|
@@ -23,12 +21,12 @@ _EWRITERS = None
|
|
|
23
21
|
|
|
24
22
|
|
|
25
23
|
# Classes & methods
|
|
26
|
-
class Exporter
|
|
24
|
+
class Exporter:
|
|
27
25
|
"""
|
|
28
26
|
Abstract base class for exporters.
|
|
29
27
|
"""
|
|
30
28
|
def __init__(self):
|
|
31
|
-
super(
|
|
29
|
+
super().__init__()
|
|
32
30
|
|
|
33
31
|
def post_export_info(self):
|
|
34
32
|
"""
|
|
@@ -106,7 +104,7 @@ def exporters():
|
|
|
106
104
|
return sorted(_EXPORTERS.keys())
|
|
107
105
|
|
|
108
106
|
|
|
109
|
-
class ExpressionWriter
|
|
107
|
+
class ExpressionWriter:
|
|
110
108
|
"""
|
|
111
109
|
Base class for expression writers, that take myokit expressions as input
|
|
112
110
|
and convert them to text or other formats.
|
|
@@ -322,12 +320,12 @@ def ewriters():
|
|
|
322
320
|
return sorted(_EWRITERS.keys())
|
|
323
321
|
|
|
324
322
|
|
|
325
|
-
class Importer
|
|
323
|
+
class Importer:
|
|
326
324
|
"""
|
|
327
325
|
Abstract base class for importers.
|
|
328
326
|
"""
|
|
329
327
|
def __init__(self):
|
|
330
|
-
super(
|
|
328
|
+
super().__init__()
|
|
331
329
|
|
|
332
330
|
def component(self, path, model):
|
|
333
331
|
"""
|
|
@@ -411,7 +409,7 @@ class TemplatedRunnableExporter(Exporter):
|
|
|
411
409
|
protocol) into a runnable chunk of code.
|
|
412
410
|
"""
|
|
413
411
|
def __init__(self):
|
|
414
|
-
super(
|
|
412
|
+
super().__init__()
|
|
415
413
|
|
|
416
414
|
def runnable(self, path, model, protocol=None, *args):
|
|
417
415
|
"""
|
myokit/formats/ansic/__init__.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
|
from ._exporter import AnsiCExporter, AnsiCCableExporter, AnsiCEulerExporter
|
|
11
8
|
from ._ewriter import AnsiCExpressionWriter
|
|
12
9
|
|
myokit/formats/ansic/_ewriter.py
CHANGED
|
@@ -4,10 +4,8 @@
|
|
|
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
|
|
8
|
+
|
|
11
9
|
from myokit.formats.python import PythonExpressionWriter
|
|
12
10
|
|
|
13
11
|
|
|
@@ -17,7 +15,7 @@ class AnsiCExpressionWriter(PythonExpressionWriter):
|
|
|
17
15
|
equations for variables in a C-style syntax.
|
|
18
16
|
"""
|
|
19
17
|
def __init__(self):
|
|
20
|
-
super(
|
|
18
|
+
super().__init__()
|
|
21
19
|
self._function_prefix = ''
|
|
22
20
|
self._fcond = None
|
|
23
21
|
|
|
@@ -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 os
|
|
11
8
|
|
|
12
9
|
import myokit.formats
|
|
@@ -121,7 +118,7 @@ class AnsiCCableExporter(myokit.formats.TemplatedRunnableExporter):
|
|
|
121
118
|
``pace``
|
|
122
119
|
The value of the pacing variable, implemented using the given protocol.
|
|
123
120
|
``diffusion_current``
|
|
124
|
-
The current flowing from each cell to its
|
|
121
|
+
The current flowing from each cell to its neighbors. This will be
|
|
125
122
|
positive if the cell is acting as a source, negative when it's acting
|
|
126
123
|
as a sink.
|
|
127
124
|
|
|
@@ -23,11 +23,11 @@ model.create_unique_names()
|
|
|
23
23
|
w = ansic.AnsiCExpressionWriter()
|
|
24
24
|
|
|
25
25
|
# Process bindings, remove unsupported bindings
|
|
26
|
-
bound_variables =
|
|
26
|
+
bound_variables = myokit._prepare_bindings(model, {
|
|
27
27
|
'time' : 't',
|
|
28
28
|
'pace' : 'pace',
|
|
29
29
|
'diffusion_current' : 'current'
|
|
30
|
-
|
|
30
|
+
}).keys()
|
|
31
31
|
|
|
32
32
|
if model.binding('diffusion_current') is None:
|
|
33
33
|
raise Exception('This exporter requires a variable to be bound to'
|
|
@@ -155,8 +155,8 @@ static void
|
|
|
155
155
|
Cell_set_initial_state(Cell *cell)
|
|
156
156
|
{
|
|
157
157
|
<?
|
|
158
|
-
for
|
|
159
|
-
print(tab +
|
|
158
|
+
for var, init in zip(model.states(), model.initial_values(True)):
|
|
159
|
+
print(tab + v(var) + ' = ' + myokit.float.str(init) + ';')
|
|
160
160
|
?>}
|
|
161
161
|
|
|
162
162
|
/*
|
|
@@ -29,10 +29,10 @@ model.create_unique_names()
|
|
|
29
29
|
|
|
30
30
|
# Process bindings, remove unsupported bindings, get map of bound variables to
|
|
31
31
|
# internal names
|
|
32
|
-
bound_variables =
|
|
32
|
+
bound_variables = myokit._prepare_bindings(model, {
|
|
33
33
|
'time' : 'time',
|
|
34
34
|
'pace' : 'pace',
|
|
35
|
-
|
|
35
|
+
})
|
|
36
36
|
|
|
37
37
|
# Get equations
|
|
38
38
|
equations = model.solvable_order()
|
|
@@ -95,7 +95,7 @@ def v(var):
|
|
|
95
95
|
if var in bound_variables:
|
|
96
96
|
return bound_variables[var]
|
|
97
97
|
if var.is_state():
|
|
98
|
-
return pre + 'state[' + str(var.
|
|
98
|
+
return pre + 'state[' + str(var.index()) + ']'
|
|
99
99
|
elif var.is_constant():
|
|
100
100
|
return pre + 'C_' + var.uname()
|
|
101
101
|
else:
|
|
@@ -126,7 +126,7 @@ typedef double Real;
|
|
|
126
126
|
#define N_STATE <?= model.count_states() ?>
|
|
127
127
|
<?
|
|
128
128
|
for var in model.states():
|
|
129
|
-
print('#define S_' + var.uname() + ' state[' + str(var.
|
|
129
|
+
print('#define S_' + var.uname() + ' state[' + str(var.index()) + ']')
|
|
130
130
|
?>
|
|
131
131
|
|
|
132
132
|
/* Define constants, calculated constants */
|
|
@@ -220,7 +220,7 @@ int main()
|
|
|
220
220
|
Real state[N_STATE];
|
|
221
221
|
<?
|
|
222
222
|
for var in model.states():
|
|
223
|
-
print(tab + v(var) + ' = ' + myokit.float.str(var.
|
|
223
|
+
print(tab + v(var) + ' = ' + myokit.float.str(var.initial_value(True)) + ';')
|
|
224
224
|
|
|
225
225
|
?>
|
|
226
226
|
|
|
@@ -22,11 +22,11 @@ model.create_unique_names()
|
|
|
22
22
|
# Define lhs function
|
|
23
23
|
def v(var):
|
|
24
24
|
if isinstance(var, myokit.Derivative):
|
|
25
|
-
return 'NV_Ith_S(ydot, ' + str(var.var().
|
|
25
|
+
return 'NV_Ith_S(ydot, ' + str(var.var().index()) + ')'
|
|
26
26
|
elif isinstance(var, myokit.Name):
|
|
27
27
|
var = var.var()
|
|
28
28
|
if var.is_state():
|
|
29
|
-
return 'NV_Ith_S(y, ' + str(var.
|
|
29
|
+
return 'NV_Ith_S(y, ' + str(var.index()) + ')'
|
|
30
30
|
elif var.is_constant():
|
|
31
31
|
return 'AC_' + var.uname()
|
|
32
32
|
else:
|
|
@@ -38,10 +38,10 @@ w.set_lhs_function(v)
|
|
|
38
38
|
|
|
39
39
|
# Process bindings, remove unsupported bindings, get map of bound variables to
|
|
40
40
|
# internal names
|
|
41
|
-
bound_variables =
|
|
41
|
+
bound_variables = myokit._prepare_bindings(model, {
|
|
42
42
|
'time' : 't',
|
|
43
43
|
'pace' : 'pace',
|
|
44
|
-
|
|
44
|
+
})
|
|
45
45
|
|
|
46
46
|
# Tab
|
|
47
47
|
tab = ' '
|
|
@@ -131,8 +131,8 @@ static void
|
|
|
131
131
|
default_initial_values(N_Vector y)
|
|
132
132
|
{
|
|
133
133
|
<?
|
|
134
|
-
for
|
|
135
|
-
print(tab +
|
|
134
|
+
for var, init in zip(model.states(), model.initial_values(True)):
|
|
135
|
+
print(tab + v(var) + ' = ' + myokit.float.str(init) + ';')
|
|
136
136
|
?>
|
|
137
137
|
}
|
|
138
138
|
|
myokit/formats/axon/__init__.py
CHANGED
|
@@ -4,13 +4,11 @@
|
|
|
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
|
from ._abf import AbfFile, Sweep, Channel # noqa
|
|
11
8
|
from ._atf import AtfFile, load_atf, save_atf # noqa
|
|
12
9
|
from ._importer import AbfImporter
|
|
13
10
|
|
|
11
|
+
|
|
14
12
|
# Importers
|
|
15
13
|
_importers = {
|
|
16
14
|
'abf': AbfImporter,
|