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.
Files changed (229) hide show
  1. myokit/__init__.py +9 -36
  2. myokit/__main__.py +76 -142
  3. myokit/_aux.py +62 -16
  4. myokit/_bin/example.mmt +1 -2
  5. myokit/_bin/install-win/menu.json +7 -7
  6. myokit/_config.py +22 -31
  7. myokit/_datablock.py +30 -74
  8. myokit/_datalog.py +49 -72
  9. myokit/_err.py +25 -24
  10. myokit/_expressions.py +50 -68
  11. myokit/_io.py +15 -27
  12. myokit/_model_api.py +453 -249
  13. myokit/_myokit_version.py +1 -5
  14. myokit/_parsing.py +38 -44
  15. myokit/_progress.py +5 -8
  16. myokit/_protocol.py +99 -9
  17. myokit/_sim/__init__.py +7 -24
  18. myokit/_sim/cable.c +6 -8
  19. myokit/_sim/cable.py +6 -8
  20. myokit/_sim/cmodel.h +125 -70
  21. myokit/_sim/cmodel.py +12 -14
  22. myokit/_sim/compiler.py +1 -4
  23. myokit/_sim/cvodessim.c +196 -118
  24. myokit/_sim/cvodessim.py +130 -103
  25. myokit/_sim/differential.hpp +4 -4
  26. myokit/_sim/fiber_tissue.c +4 -8
  27. myokit/_sim/fiber_tissue.py +11 -13
  28. myokit/_sim/jacobian.cpp +2 -2
  29. myokit/_sim/jacobian.py +11 -8
  30. myokit/_sim/mcl.h +53 -55
  31. myokit/_sim/opencl.py +21 -27
  32. myokit/_sim/openclsim.c +3 -7
  33. myokit/_sim/openclsim.cl +3 -3
  34. myokit/_sim/openclsim.py +49 -40
  35. myokit/_sim/pacing.h +36 -16
  36. myokit/_sim/rhs.c +6 -13
  37. myokit/_sim/rhs.py +5 -14
  38. myokit/_sim/sundials.py +1 -4
  39. myokit/_system.py +10 -16
  40. myokit/_unit.py +4 -13
  41. myokit/float.py +0 -3
  42. myokit/formats/__init__.py +8 -10
  43. myokit/formats/ansic/__init__.py +0 -3
  44. myokit/formats/ansic/_ewriter.py +2 -4
  45. myokit/formats/ansic/_exporter.py +1 -4
  46. myokit/formats/ansic/template/cable.c +4 -4
  47. myokit/formats/ansic/template/euler.c +5 -5
  48. myokit/formats/ansic/template/sim.c +6 -6
  49. myokit/formats/axon/__init__.py +1 -3
  50. myokit/formats/axon/_abf.py +12 -17
  51. myokit/formats/axon/_atf.py +5 -6
  52. myokit/formats/axon/_importer.py +0 -3
  53. myokit/formats/cellml/__init__.py +0 -3
  54. myokit/formats/cellml/_ewriter.py +3 -6
  55. myokit/formats/cellml/_exporter.py +3 -6
  56. myokit/formats/cellml/_importer.py +1 -4
  57. myokit/formats/cellml/v1/__init__.py +0 -4
  58. myokit/formats/cellml/v1/_api.py +8 -11
  59. myokit/formats/cellml/v1/_parser.py +2 -5
  60. myokit/formats/cellml/v1/_writer.py +2 -11
  61. myokit/formats/cellml/v2/__init__.py +0 -3
  62. myokit/formats/cellml/v2/_api.py +8 -17
  63. myokit/formats/cellml/v2/_parser.py +2 -5
  64. myokit/formats/cellml/v2/_writer.py +1 -4
  65. myokit/formats/channelml/__init__.py +0 -3
  66. myokit/formats/channelml/_importer.py +11 -21
  67. myokit/formats/cpp/__init__.py +1 -3
  68. myokit/formats/cpp/_ewriter.py +0 -3
  69. myokit/formats/cuda/__init__.py +0 -3
  70. myokit/formats/cuda/_ewriter.py +2 -4
  71. myokit/formats/cuda/_exporter.py +0 -3
  72. myokit/formats/cuda/template/kernel.cu +8 -5
  73. myokit/formats/easyml/__init__.py +0 -3
  74. myokit/formats/easyml/_ewriter.py +9 -11
  75. myokit/formats/easyml/_exporter.py +2 -5
  76. myokit/formats/html/__init__.py +0 -3
  77. myokit/formats/html/_exporter.py +0 -3
  78. myokit/formats/html/_flatten.py +5 -21
  79. myokit/formats/latex/__init__.py +0 -3
  80. myokit/formats/latex/_ewriter.py +1 -4
  81. myokit/formats/latex/_exporter.py +4 -6
  82. myokit/formats/mathml/__init__.py +0 -3
  83. myokit/formats/mathml/_ewriter.py +2 -11
  84. myokit/formats/mathml/_parser.py +4 -6
  85. myokit/formats/matlab/__init__.py +0 -3
  86. myokit/formats/matlab/_ewriter.py +1 -4
  87. myokit/formats/matlab/_exporter.py +2 -5
  88. myokit/formats/matlab/template/main.m +3 -2
  89. myokit/formats/opencl/__init__.py +0 -3
  90. myokit/formats/opencl/_ewriter.py +2 -4
  91. myokit/formats/opencl/_exporter.py +2 -5
  92. myokit/formats/opencl/template/cable.c +10 -10
  93. myokit/formats/opencl/template/kernel.cl +1 -1
  94. myokit/formats/opencl/template/minilog.py +1 -1
  95. myokit/formats/python/__init__.py +0 -3
  96. myokit/formats/python/_ewriter.py +2 -5
  97. myokit/formats/python/_exporter.py +0 -3
  98. myokit/formats/python/template/sim.py +14 -14
  99. myokit/formats/sbml/__init__.py +0 -3
  100. myokit/formats/sbml/_api.py +50 -44
  101. myokit/formats/sbml/_importer.py +1 -4
  102. myokit/formats/sbml/_parser.py +2 -5
  103. myokit/formats/stan/__init__.py +0 -3
  104. myokit/formats/stan/_ewriter.py +2 -4
  105. myokit/formats/stan/_exporter.py +2 -5
  106. myokit/formats/stan/template/cell.stan +3 -3
  107. myokit/formats/sympy/__init__.py +0 -3
  108. myokit/formats/sympy/_ereader.py +1 -4
  109. myokit/formats/sympy/_ewriter.py +2 -5
  110. myokit/formats/wcp/__init__.py +0 -3
  111. myokit/formats/wcp/_wcp.py +2 -8
  112. myokit/formats/xml/__init__.py +0 -3
  113. myokit/formats/xml/_exporter.py +0 -3
  114. myokit/formats/xml/_split.py +0 -3
  115. myokit/gui/__init__.py +80 -246
  116. myokit/gui/datablock_viewer.py +103 -86
  117. myokit/gui/datalog_viewer.py +214 -66
  118. myokit/gui/explorer.py +15 -21
  119. myokit/gui/ide.py +171 -144
  120. myokit/gui/progress.py +9 -9
  121. myokit/gui/source.py +406 -375
  122. myokit/gui/vargrapher.py +2 -12
  123. myokit/lib/deps.py +12 -13
  124. myokit/lib/guess.py +3 -4
  125. myokit/lib/hh.py +20 -18
  126. myokit/lib/markov.py +21 -20
  127. myokit/lib/multi.py +1 -3
  128. myokit/lib/plots.py +20 -9
  129. myokit/pacing.py +0 -3
  130. myokit/pype.py +7 -18
  131. myokit/tests/__init__.py +3 -6
  132. myokit/tests/ansic_event_based_pacing.py +1 -4
  133. myokit/tests/ansic_fixed_form_pacing.py +3 -6
  134. myokit/tests/data/beeler-1977-model-compare-b.mmt +2 -2
  135. myokit/tests/data/clancy-1999-fitting.mmt +1 -0
  136. myokit/tests/test_aux.py +13 -28
  137. myokit/tests/test_cellml_v1_api.py +4 -19
  138. myokit/tests/test_cellml_v1_parser.py +0 -15
  139. myokit/tests/test_cellml_v1_writer.py +0 -9
  140. myokit/tests/test_cellml_v2_api.py +4 -19
  141. myokit/tests/test_cellml_v2_parser.py +0 -15
  142. myokit/tests/test_cellml_v2_writer.py +0 -9
  143. myokit/tests/test_cmodel.py +16 -22
  144. myokit/tests/test_compiler_detection.py +1 -11
  145. myokit/tests/test_component.py +108 -56
  146. myokit/tests/test_config.py +34 -67
  147. myokit/tests/test_datablock.py +1 -9
  148. myokit/tests/test_datalog.py +19 -24
  149. myokit/tests/test_dependency_checking.py +8 -23
  150. myokit/tests/test_expressions.py +0 -9
  151. myokit/tests/test_float.py +1 -5
  152. myokit/tests/test_formats.py +0 -9
  153. myokit/tests/test_formats_axon.py +1 -9
  154. myokit/tests/test_formats_cellml.py +0 -15
  155. myokit/tests/test_formats_channelml.py +0 -15
  156. myokit/tests/test_formats_easyml.py +0 -14
  157. myokit/tests/test_formats_exporters.py +1 -16
  158. myokit/tests/test_formats_expression_writers.py +1 -17
  159. myokit/tests/test_formats_html.py +0 -3
  160. myokit/tests/test_formats_importers.py +1 -16
  161. myokit/tests/test_formats_mathml_content.py +0 -9
  162. myokit/tests/test_formats_mathml_presentation.py +0 -9
  163. myokit/tests/test_formats_opencl.py +0 -10
  164. myokit/tests/test_formats_sbml.py +0 -15
  165. myokit/tests/test_formats_sympy.py +0 -9
  166. myokit/tests/test_formats_wcp.py +1 -3
  167. myokit/tests/test_io.py +27 -27
  168. myokit/tests/test_jacobian_calculator.py +6 -14
  169. myokit/tests/test_jacobian_tracer.py +0 -9
  170. myokit/tests/test_lib_deps.py +0 -9
  171. myokit/tests/test_lib_guess.py +0 -9
  172. myokit/tests/test_lib_hh.py +18 -12
  173. myokit/tests/test_lib_markov.py +21 -13
  174. myokit/tests/test_lib_multi.py +0 -9
  175. myokit/tests/test_lib_plots.py +13 -8
  176. myokit/tests/test_meta.py +0 -3
  177. myokit/tests/test_model.py +390 -96
  178. myokit/tests/test_model_building.py +44 -96
  179. myokit/tests/test_opencl_info.py +5 -14
  180. myokit/tests/test_pacing_factory.py +0 -3
  181. myokit/tests/test_pacing_system_c.py +1 -23
  182. myokit/tests/test_pacing_system_py.py +0 -9
  183. myokit/tests/test_parsing.py +139 -56
  184. myokit/tests/test_progress_reporters.py +0 -3
  185. myokit/tests/test_protocol.py +0 -9
  186. myokit/tests/test_protocol_floating_point.py +1 -10
  187. myokit/tests/test_protocol_time_series.py +82 -0
  188. myokit/tests/test_pype.py +0 -9
  189. myokit/tests/test_quantity.py +0 -9
  190. myokit/tests/test_rhs_benchmarker.py +1 -9
  191. myokit/tests/test_sbml_api.py +27 -42
  192. myokit/tests/test_sbml_parser.py +4 -19
  193. myokit/tests/test_simulation_1d.py +45 -25
  194. myokit/tests/test_simulation_cvodes.py +321 -55
  195. myokit/tests/test_simulation_cvodes_from_disk.py +0 -3
  196. myokit/tests/test_simulation_fiber_tissue.py +39 -12
  197. myokit/tests/test_simulation_log_interval.py +1 -431
  198. myokit/tests/test_simulation_opencl.py +69 -48
  199. myokit/tests/test_simulation_opencl_log_interval.py +1 -3
  200. myokit/tests/test_simulation_opencl_vs_cvode.py +1 -10
  201. myokit/tests/test_simulation_opencl_vs_sim1d.py +1 -10
  202. myokit/tests/test_system_info.py +1 -11
  203. myokit/tests/test_tools.py +0 -9
  204. myokit/tests/test_unit.py +1 -10
  205. myokit/tests/test_user_functions.py +0 -10
  206. myokit/tests/test_variable.py +231 -27
  207. myokit/tools.py +5 -21
  208. myokit/units.py +5 -3
  209. {myokit-1.33.9.dist-info → myokit-1.35.0.dist-info}/METADATA +12 -15
  210. myokit-1.35.0.dist-info/RECORD +391 -0
  211. {myokit-1.33.9.dist-info → myokit-1.35.0.dist-info}/WHEEL +1 -1
  212. {myokit-1.33.9.dist-info → myokit-1.35.0.dist-info}/entry_points.txt +0 -1
  213. myokit/_exec_new.py +0 -15
  214. myokit/_exec_old.py +0 -15
  215. myokit/_sim/cvodesim.c +0 -1551
  216. myokit/_sim/cvodesim.py +0 -674
  217. myokit/_sim/icsim.cpp +0 -563
  218. myokit/_sim/icsim.py +0 -363
  219. myokit/_sim/psim.cpp +0 -656
  220. myokit/_sim/psim.py +0 -493
  221. myokit/lib/common.py +0 -1094
  222. myokit/tests/test_lib_common.py +0 -130
  223. myokit/tests/test_simulation_cvode.py +0 -612
  224. myokit/tests/test_simulation_ic.py +0 -108
  225. myokit/tests/test_simulation_p.py +0 -223
  226. myokit-1.33.9.dist-info/RECORD +0 -403
  227. /myokit/formats/opencl/template/{test → test.sh} +0 -0
  228. {myokit-1.33.9.dist-info → myokit-1.35.0.dist-info}/LICENSE.txt +0 -0
  229. {myokit-1.33.9.dist-info → myokit-1.35.0.dist-info}/top_level.txt +0 -0
myokit/_datalog.py CHANGED
@@ -4,22 +4,16 @@
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
  import re
12
9
  import sys
13
10
  import array
11
+
14
12
  import numpy as np
13
+
15
14
  from collections import OrderedDict
16
- import myokit
17
15
 
18
- # Strings in Python 2 and 3
19
- try:
20
- basestring
21
- except NameError: # pragma: no python 2 cover
22
- basestring = str
16
+ import myokit
23
17
 
24
18
 
25
19
  # Function to split keys into dimension-key,qname-key pairs
@@ -95,18 +89,17 @@ class DataLog(OrderedDict):
95
89
  ``time``
96
90
  The log key to use for the time variable. When cloning a log, adding
97
91
  the ``time`` argument will overwrite the cloned value.
92
+
98
93
  """
94
+
99
95
  def __init__(self, other=None, time=None):
100
- """
101
- Creates a new DataLog.
102
- """
103
96
  if other is None:
104
97
  # Create new
105
- super(DataLog, self).__init__()
98
+ super().__init__()
106
99
  self._time = None
107
100
  else:
108
101
  # Clone
109
- super(DataLog, self).__init__(other)
102
+ super().__init__(other)
110
103
  try:
111
104
  self._time = str(other._time)
112
105
  except Exception:
@@ -119,7 +112,7 @@ class DataLog(OrderedDict):
119
112
  Calculates one or more Action Potential Durations (APDs) in a single
120
113
  cell's membrane potential.
121
114
 
122
- *Note 1: More accuracte apd measurements can be created using the*
115
+ *Note 1: More accuracte APD measurements can be obtained using the*
123
116
  :class:`Simulation` *object's APD tracking functionality. See*
124
117
  :meth:`Simulation.run()` *for details.*
125
118
 
@@ -130,10 +123,6 @@ class DataLog(OrderedDict):
130
123
  The membrane potential data should be listed in the log under the key
131
124
  given by ``v``.
132
125
 
133
- The APD is measured as the time that the membrane potential exceeds a
134
- certain, fixed, threshold. It does *not* calculate dynamic thresholds
135
- like "90% of max(V) - min(V)".
136
-
137
126
  The returned value is a list of tuples (AP_start, APD).
138
127
  """
139
128
  def crossings(x, y, t):
@@ -221,10 +210,10 @@ class DataLog(OrderedDict):
221
210
  return log
222
211
 
223
212
  def __contains__(self, key):
224
- return super(DataLog, self).__contains__(self._parse_key(key))
213
+ return super().__contains__(self._parse_key(key))
225
214
 
226
215
  def __delitem__(self, key):
227
- return super(DataLog, self).__delitem__(self._parse_key(key))
216
+ return super().__delitem__(self._parse_key(key))
228
217
 
229
218
  def extend(self, other):
230
219
  """
@@ -240,9 +229,11 @@ class DataLog(OrderedDict):
240
229
  'Cannot extend DataLog with data from an earlier time.')
241
230
  if set(self.keys()) != set(other.keys()):
242
231
  raise ValueError('Both logs must have the same keys.')
232
+
243
233
  # Create new log
244
234
  log = DataLog()
245
235
  log._time = self._time
236
+
246
237
  # Add data
247
238
  for k, v1 in self.items():
248
239
  v2 = other[k]
@@ -252,6 +243,7 @@ class DataLog(OrderedDict):
252
243
  else:
253
244
  log[k] = list(v1) # Copies v1 data
254
245
  log[k].extend(v2) # Copies v2 data
246
+
255
247
  # Return
256
248
  return log
257
249
 
@@ -269,7 +261,7 @@ class DataLog(OrderedDict):
269
261
 
270
262
  def find_after(self, time):
271
263
  """
272
- Returns the lowest indice ``i`` such that
264
+ Returns the lowest index ``i`` such that
273
265
 
274
266
  times[i] >= time
275
267
 
@@ -288,7 +280,7 @@ class DataLog(OrderedDict):
288
280
 
289
281
  # Find t
290
282
  def find(lo, hi):
291
- # lo = first indice, hi = last indice + 1
283
+ # lo = first index, hi = last index + 1
292
284
  if (lo + 1 == hi):
293
285
  return lo + 1
294
286
  m = int((lo + hi) / 2)
@@ -330,7 +322,7 @@ class DataLog(OrderedDict):
330
322
  return out
331
323
 
332
324
  def __getitem__(self, key):
333
- return super(DataLog, self).__getitem__(self._parse_key(key))
325
+ return super().__getitem__(self._parse_key(key))
334
326
 
335
327
  def has_nan(self):
336
328
  """
@@ -442,7 +434,7 @@ class DataLog(OrderedDict):
442
434
 
443
435
  def itrim_left(self, i):
444
436
  """
445
- Returns a copy of this log, with all entries before indice ``i``
437
+ Returns a copy of this log, with all entries before index ``i``
446
438
  removed (similar to performing ``x = x[i:]`` on a list).
447
439
  """
448
440
  log = DataLog()
@@ -456,7 +448,7 @@ class DataLog(OrderedDict):
456
448
 
457
449
  def itrim_right(self, i):
458
450
  """
459
- Returns a copy of this log, with all entries starting from indice ``i``
451
+ Returns a copy of this log, with all entries starting from index ``i``
460
452
  removed (similar to performing ``x = x[:i]`` on a list).
461
453
  """
462
454
  log = DataLog()
@@ -519,17 +511,10 @@ class DataLog(OrderedDict):
519
511
  'This method requires the ``zlib`` module to be installed.')
520
512
 
521
513
  # Get size of single and double types on this machine
522
- try:
523
- dsize = {
524
- 'd': len(array.array('d', [1]).tobytes()),
525
- 'f': len(array.array('f', [1]).tobytes()),
526
- }
527
- except (AttributeError, TypeError): # pragma: no python 3 cover
528
- # List dtype as str for Python 2.7.10 (see #225)
529
- dsize = {
530
- b'd': len(array.array(b'd', [1]).tostring()),
531
- b'f': len(array.array(b'f', [1]).tostring()),
532
- }
514
+ dsize = {
515
+ 'd': len(array.array('d', [1]).tobytes()),
516
+ 'f': len(array.array('f', [1]).tobytes()),
517
+ }
533
518
 
534
519
  # Read data
535
520
  try:
@@ -565,7 +550,7 @@ class DataLog(OrderedDict):
565
550
  head = iter(head.splitlines())
566
551
  n = int(next(head))
567
552
  data_size = int(next(head))
568
- data_type = str(next(head)) # Cast to str for Python 2.7.10 (see #225)
553
+ data_type = next(head)
569
554
  time = next(head)
570
555
  if time:
571
556
  # Note, this field doesn't have to be present in the log!
@@ -606,10 +591,7 @@ class DataLog(OrderedDict):
606
591
 
607
592
  # Read data
608
593
  ar = array.array(data_type)
609
- try:
610
- ar.frombytes(body[start:end])
611
- except AttributeError: # pragma: no python 3 cover
612
- ar.fromstring(body[start:end])
594
+ ar.frombytes(body[start:end])
613
595
  if sys.byteorder == 'big': # pragma: no cover
614
596
  ar.byteswap()
615
597
  log[field] = ar
@@ -640,8 +622,7 @@ class DataLog(OrderedDict):
640
622
  filename = os.path.expanduser(filename)
641
623
 
642
624
  # Typecode dependent on precision
643
- # Typecode must be str for Python 2.7.10 (see #225)
644
- typecode = str('d' if precision == myokit.DOUBLE_PRECISION else 'f')
625
+ typecode = 'd' if precision == myokit.DOUBLE_PRECISION else 'f'
645
626
 
646
627
  # Error raising function
647
628
  def e(line, char, msg):
@@ -649,16 +630,9 @@ class DataLog(OrderedDict):
649
630
  'Syntax error on line ' + str(line) + ', character '
650
631
  + str(1 + char) + ': ' + msg)
651
632
 
652
- def uopen(filename):
653
- # Open a filename in 'universal newline' mode, python 2 and 3
654
- try:
655
- return open(filename, 'r', newline=None)
656
- except TypeError: # pragma: no python 3 cover
657
- return open(filename, 'U')
658
-
659
633
  quote = '"'
660
634
  delim = ','
661
- with uopen(filename) as f:
635
+ with open(filename, 'r', newline=None) as f:
662
636
  # Read header
663
637
  keys = [] # The log keys, in order of appearance
664
638
 
@@ -828,11 +802,16 @@ class DataLog(OrderedDict):
828
802
  key = '.'.join(parts)
829
803
  return str(key)
830
804
 
831
- def regularize(self, dt, tmin=None, tmax=None):
805
+ def regularize(self, dt, tmin=None, tmax=None): # pragma: no cover
832
806
  """
833
807
  Returns a copy of this DataLog with data points at regularly spaced
834
808
  times.
835
809
 
810
+ This method is deprecated and will be removed in future versions of
811
+ Myokit.
812
+
813
+ This method requires ``SciPy`` to be installed.
814
+
836
815
  *Note: While regularize() can be used post-simulation to create fixed
837
816
  time-step data from variable time-step data, it is usually better to
838
817
  re-run a simulation with fixed time step logging. See*
@@ -856,17 +835,21 @@ class DataLog(OrderedDict):
856
835
 
857
836
  As a result of the cubic spline interpolation, the function may perform
858
837
  poorly on large data sets.
859
-
860
- This method requires ``SciPy`` to be installed.
861
838
  """
862
- self.validate()
839
+ # Deprecated since 2023-06-06
840
+ import warnings
841
+ warnings.warn(
842
+ 'The method `regularize` is deprecated and will be removed in'
843
+ ' future versions of Myokit.')
844
+
863
845
  from scipy.interpolate import UnivariateSpline as Spline
846
+ self.validate()
864
847
 
865
848
  # Check time variable
866
849
  time = self.time()
867
850
  n = len(time)
868
851
 
869
- # Get left indice for splines
852
+ # Get left index for splines
870
853
  imin = 0
871
854
  if tmin is None:
872
855
  tmin = time[0]
@@ -875,7 +858,7 @@ class DataLog(OrderedDict):
875
858
  # left so that the spline has 4 points
876
859
  imin = max(0, np.searchsorted(time, tmin) - 2)
877
860
 
878
- # Get right indice for splines
861
+ # Get right index for splines
879
862
  imax = n
880
863
  if tmax is None:
881
864
  tmax = time[-1]
@@ -929,8 +912,7 @@ class DataLog(OrderedDict):
929
912
  'This method requires the `zlib` module to be installed.')
930
913
 
931
914
  # Data type
932
- # dtype must be str for Python 2.7.10 (see #225)
933
- dtype = str('d' if precision == myokit.DOUBLE_PRECISION else 'f')
915
+ dtype = 'd' if precision == myokit.DOUBLE_PRECISION else 'f'
934
916
 
935
917
  # Create data strings
936
918
  head_str = []
@@ -952,10 +934,7 @@ class DataLog(OrderedDict):
952
934
  ar = array.array(dtype, v)
953
935
  if sys.byteorder == 'big': # pragma: no cover
954
936
  ar.byteswap()
955
- try:
956
- body_str.append(ar.tobytes())
957
- except AttributeError: # pragma: no python 3 cover
958
- body_str.append(ar.tostring())
937
+ body_str.append(ar.tobytes())
959
938
  head_str = '\n'.join(head_str)
960
939
  body_str = b''.join(body_str)
961
940
 
@@ -999,7 +978,7 @@ class DataLog(OrderedDict):
999
978
  If a precision argument (for example ``myokit.DOUBLE_PRECISION``)
1000
979
  is given, the output will be stored in such a way that this amount
1001
980
  of precision is guaranteed to be present in the string. If the
1002
- precision argument is set to ``None`` python's default formatting
981
+ precision argument is set to ``None`` Python's default formatting
1003
982
  is used, which may lead to smaller files.
1004
983
  ``order``
1005
984
  To specify the ordering of the log's arguments, pass in a sequence
@@ -1100,7 +1079,7 @@ class DataLog(OrderedDict):
1100
1079
  self._time = None if key is None else str(key)
1101
1080
 
1102
1081
  def __setitem__(self, key, value):
1103
- return super(DataLog, self).__setitem__(
1082
+ return super().__setitem__(
1104
1083
  self._parse_key(key), value)
1105
1084
 
1106
1085
  def split(self, value):
@@ -1129,7 +1108,7 @@ class DataLog(OrderedDict):
1129
1108
 
1130
1109
  By default, the returned intervals are *closed*, so both the left and
1131
1110
  right endpoint are included (if present in the data). This may involve
1132
- the duplication of some data points. To disable this behaviour and
1111
+ the duplication of some data points. To disable this behavior and
1133
1112
  return half-closed endpoints (containing only the left point), set
1134
1113
  ``closed_intervals`` to ``False``.
1135
1114
  """
@@ -1415,7 +1394,7 @@ class DataLog(OrderedDict):
1415
1394
  return infos
1416
1395
 
1417
1396
 
1418
- class LoggedVariableInfo(object):
1397
+ class LoggedVariableInfo:
1419
1398
  """
1420
1399
  Contains information about the log entries for each variable. These objects
1421
1400
  should only be created by :meth:`DataLog.variable_info()`.
@@ -1622,9 +1601,7 @@ def prepare_log(
1622
1601
  be specified using the ``precision`` argument.
1623
1602
  """
1624
1603
  # Typecode dependent on precision
1625
- # Note: Cast to str() here makes it work with older versions of 2.7.x,
1626
- # where unicode isn't accepted (Python 3 of course doesn't accept bytes)
1627
- typecode = str('d' if precision == myokit.DOUBLE_PRECISION else 'f')
1604
+ typecode = 'd' if precision == myokit.DOUBLE_PRECISION else 'f'
1628
1605
 
1629
1606
  # Get all options for dimensionality
1630
1607
  if dims is None:
@@ -1867,7 +1844,7 @@ def prepare_log(
1867
1844
  'Argument `log` has unexpected type. Expecting None, integer flag,'
1868
1845
  ' sequence of names, dict or DataLog.')
1869
1846
 
1870
- if isinstance(log, basestring):
1847
+ if isinstance(log, str):
1871
1848
  raise ValueError(
1872
1849
  'String passed in as `log` argument, should be list'
1873
1850
  ' or other sequence containing strings.')
myokit/_err.py CHANGED
@@ -4,8 +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
7
 
10
8
 
11
9
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -24,7 +22,7 @@ class MyokitError(Exception):
24
22
  *Extends:* ``Exception``
25
23
  """
26
24
  def __init__(self, message):
27
- super(MyokitError, self).__init__(message)
25
+ super().__init__(message)
28
26
 
29
27
 
30
28
  class IntegrityError(MyokitError):
@@ -37,7 +35,7 @@ class IntegrityError(MyokitError):
37
35
  *Extends:* :class:`myokit.MyokitError`
38
36
  """
39
37
  def __init__(self, message, token=None):
40
- super(IntegrityError, self).__init__(message)
38
+ super().__init__(message)
41
39
  self._token = token
42
40
 
43
41
  def token(self):
@@ -77,7 +75,7 @@ class CyclicalDependencyError(IntegrityError):
77
75
  # Set token: First item in cycle is model's defining lhs
78
76
  tok = cycle[0].var()._token
79
77
  # Raise
80
- super(CyclicalDependencyError, self).__init__(msg, tok)
78
+ super().__init__(msg, tok)
81
79
 
82
80
 
83
81
  class DataBlockReadError(MyokitError):
@@ -167,10 +165,21 @@ class IllegalReferenceError(IntegrityError):
167
165
  *Extends:* :class:`myokit.IntegrityError`
168
166
  """
169
167
  def __init__(self, reference, owner):
170
- super(IllegalReferenceError, self).__init__(
168
+ super().__init__(
171
169
  'Illegal reference: The referenced variable <' + reference.qname()
172
- + '> is outside the scope of <' + owner.qname() + '>.'
173
- )
170
+ + '> is outside the scope of <' + owner.qname() + '>.')
171
+
172
+
173
+ class IllegalReferenceInInitialValueError(IllegalReferenceError):
174
+ """
175
+ Raised when an illegal reference is made in an initial value.
176
+
177
+ The only way this can occur is if the reference is to a nested variable.
178
+ """
179
+ def __init__(self, reference, owner):
180
+ super(IntegrityError, self).__init__(
181
+ 'Illegal reference made in initial value: The referenced variable'
182
+ ' <' + reference.qname() + '> is nested.')
174
183
 
175
184
 
176
185
  class ImportError(MyokitError):
@@ -192,7 +201,7 @@ class IncompatibleModelError(MyokitError):
192
201
  if model_name:
193
202
  msg += ' <' + str(model_name) + '>'
194
203
  msg += ': ' + str(message)
195
- super(IncompatibleModelError, self).__init__(msg)
204
+ super().__init__(msg)
196
205
 
197
206
 
198
207
  class IncompatibleUnitError(MyokitError):
@@ -202,7 +211,7 @@ class IncompatibleUnitError(MyokitError):
202
211
  *Extends:* :class:`myokit.MyokitError`.
203
212
  """
204
213
  def __init__(self, message, token=None):
205
- super(MyokitError, self).__init__(message)
214
+ super().__init__(message)
206
215
  self._token = token
207
216
 
208
217
  def token(self):
@@ -277,7 +286,7 @@ class MissingRhsError(IntegrityError):
277
286
  def __init__(self, var):
278
287
  msg = 'No rhs set for <' + var.qname() + '>.'
279
288
  tok = var._token
280
- super(MissingRhsError, self).__init__(msg, tok)
289
+ super().__init__(msg, tok)
281
290
 
282
291
 
283
292
  class MissingTimeVariableError(IntegrityError):
@@ -289,15 +298,7 @@ class MissingTimeVariableError(IntegrityError):
289
298
  def __init__(self):
290
299
  msg = 'No variable bound to time. At least one of the model\'s' \
291
300
  ' variables must be bound to "time".'
292
- super(MissingTimeVariableError, self).__init__(msg)
293
-
294
-
295
- class NonLiteralValueError(IntegrityError):
296
- """
297
- Raised when a literal value is required but not given.
298
-
299
- *Extends:* :class:`myokit.IntegrityError`
300
- """
301
+ super().__init__(msg)
301
302
 
302
303
 
303
304
  class NumericalError(MyokitError):
@@ -336,7 +337,7 @@ class ParseError(MyokitError):
336
337
  self.desc = str(desc)
337
338
  self.value += ': ' + self.desc
338
339
  self.cause = cause
339
- super(ParseError, self).__init__(self.value)
340
+ super().__init__(self.value)
340
341
 
341
342
 
342
343
  class ProtocolEventError(MyokitError):
@@ -380,7 +381,7 @@ class SimulationCancelledError(MyokitError):
380
381
  *Extends:* :class:`myokit.MyokitError`
381
382
  """
382
383
  def __init__(self, message='Operation cancelled by user.'):
383
- super(SimulationCancelledError, self).__init__(message)
384
+ super().__init__(message)
384
385
 
385
386
 
386
387
  class SimultaneousProtocolEventError(MyokitError):
@@ -399,7 +400,7 @@ class UnresolvedReferenceError(IntegrityError):
399
400
  *Extends:* :class:`myokit.IntegrityError`
400
401
  """
401
402
  def __init__(self, reference, extra_message=None):
402
- super(UnresolvedReferenceError, self).__init__(
403
+ super().__init__(
403
404
  'Unknown variable: <' + reference + '>.'
404
405
  + ((' ' + extra_message) if extra_message else '')
405
406
  )
@@ -416,7 +417,7 @@ class UnusedVariableError(IntegrityError):
416
417
  def __init__(self, var):
417
418
  msg = 'Unused variable: <' + var.qname() + '>.'
418
419
  tok = var.lhs()._token
419
- super(UnusedVariableError, self).__init__(msg, tok)
420
+ super().__init__(msg, tok)
420
421
 
421
422
 
422
423
  class VariableMappingError(MyokitError):