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.
Files changed (65) hide show
  1. myokit/__init__.py +6 -19
  2. myokit/_aux.py +4 -0
  3. myokit/_datablock.py +55 -65
  4. myokit/_datalog.py +42 -7
  5. myokit/_err.py +26 -3
  6. myokit/_expressions.py +241 -127
  7. myokit/_model_api.py +19 -13
  8. myokit/_myokit_version.py +1 -1
  9. myokit/_sim/jacobian.py +3 -3
  10. myokit/_sim/openclsim.py +5 -5
  11. myokit/_sim/rhs.py +1 -1
  12. myokit/formats/__init__.py +4 -9
  13. myokit/formats/ansic/_ewriter.py +4 -20
  14. myokit/formats/axon/_abf.py +11 -4
  15. myokit/formats/diffsl/__init__.py +60 -0
  16. myokit/formats/diffsl/_ewriter.py +145 -0
  17. myokit/formats/diffsl/_exporter.py +435 -0
  18. myokit/formats/heka/_patchmaster.py +345 -115
  19. myokit/formats/opencl/_ewriter.py +3 -42
  20. myokit/formats/opencl/template/minilog.py +1 -1
  21. myokit/formats/sympy/_ereader.py +2 -1
  22. myokit/formats/wcp/_wcp.py +3 -3
  23. myokit/gui/datalog_viewer.py +28 -9
  24. myokit/lib/markov.py +2 -2
  25. myokit/lib/plots.py +4 -4
  26. myokit/tests/data/formats/wcp-file-empty.wcp +0 -0
  27. myokit/tests/data/io/bad1d-2-no-header.zip +0 -0
  28. myokit/tests/data/io/bad1d-3-no-data.zip +0 -0
  29. myokit/tests/data/io/bad1d-4-not-a-zip.zip +1 -105
  30. myokit/tests/data/io/bad1d-5-bad-data-type.zip +0 -0
  31. myokit/tests/data/io/bad1d-6-time-too-short.zip +0 -0
  32. myokit/tests/data/io/bad1d-7-0d-too-short.zip +0 -0
  33. myokit/tests/data/io/bad1d-8-1d-too-short.zip +0 -0
  34. myokit/tests/data/io/bad2d-2-no-header.zip +0 -0
  35. myokit/tests/data/io/bad2d-3-no-data.zip +0 -0
  36. myokit/tests/data/io/bad2d-4-not-a-zip.zip +1 -105
  37. myokit/tests/data/io/bad2d-5-bad-data-type.zip +0 -0
  38. myokit/tests/data/io/bad2d-8-2d-too-short.zip +0 -0
  39. myokit/tests/data/io/block1d.mmt +187 -0
  40. myokit/tests/data/io/datalog-18-duplicate-keys.csv +4 -0
  41. myokit/tests/test_aux.py +4 -0
  42. myokit/tests/test_datablock.py +16 -16
  43. myokit/tests/test_datalog.py +24 -1
  44. myokit/tests/test_expressions.py +532 -251
  45. myokit/tests/test_formats_ansic.py +6 -18
  46. myokit/tests/test_formats_cpp.py +0 -5
  47. myokit/tests/test_formats_cuda.py +7 -15
  48. myokit/tests/test_formats_diffsl.py +728 -0
  49. myokit/tests/test_formats_easyml.py +4 -9
  50. myokit/tests/test_formats_exporters_run.py +3 -0
  51. myokit/tests/test_formats_latex.py +10 -11
  52. myokit/tests/test_formats_matlab.py +0 -8
  53. myokit/tests/test_formats_opencl.py +0 -29
  54. myokit/tests/test_formats_python.py +2 -19
  55. myokit/tests/test_formats_stan.py +0 -13
  56. myokit/tests/test_formats_sympy.py +3 -3
  57. myokit/tests/test_formats_wcp.py +15 -0
  58. myokit/tests/test_model.py +20 -20
  59. myokit/tests/test_parsing.py +19 -0
  60. {myokit-1.36.1.dist-info → myokit-1.37.1.dist-info}/METADATA +1 -1
  61. {myokit-1.36.1.dist-info → myokit-1.37.1.dist-info}/RECORD +65 -58
  62. {myokit-1.36.1.dist-info → myokit-1.37.1.dist-info}/LICENSE.txt +0 -0
  63. {myokit-1.36.1.dist-info → myokit-1.37.1.dist-info}/WHEEL +0 -0
  64. {myokit-1.36.1.dist-info → myokit-1.37.1.dist-info}/entry_points.txt +0 -0
  65. {myokit-1.36.1.dist-info → myokit-1.37.1.dist-info}/top_level.txt +0 -0
@@ -167,11 +167,11 @@ class DataBlock1dTest(unittest.TestCase):
167
167
  d = myokit.DataLog()
168
168
  d.set_time_key('time')
169
169
  d['time'] = time
170
- d['x', 0] = np.array(down, copy=True)
171
- d['x', 1] = np.array(down, copy=True)
172
- d['x', 2] = np.array(down, copy=True)
173
- d['x', 3] = np.array(down, copy=True)
174
- d['x', 4] = np.array(down, copy=True)
170
+ d['x', 0] = np.copy(down)
171
+ d['x', 1] = np.copy(down)
172
+ d['x', 2] = np.copy(down)
173
+ d['x', 3] = np.copy(down)
174
+ d['x', 4] = np.copy(down)
175
175
  d['x', 1][10:] = 40
176
176
  b = myokit.DataBlock1d.from_log(d)
177
177
  self.assertEqual(b.cv('x'), 0)
@@ -180,11 +180,11 @@ class DataBlock1dTest(unittest.TestCase):
180
180
  d = myokit.DataLog()
181
181
  d.set_time_key('time')
182
182
  d['time'] = time
183
- d['x', 0] = np.array(down, copy=True)
184
- d['x', 1] = np.array(down, copy=True)
185
- d['x', 2] = np.array(down, copy=True)
186
- d['x', 3] = np.array(down, copy=True)
187
- d['x', 4] = np.array(down, copy=True)
183
+ d['x', 0] = np.copy(down)
184
+ d['x', 1] = np.copy(down)
185
+ d['x', 2] = np.copy(down)
186
+ d['x', 3] = np.copy(down)
187
+ d['x', 4] = np.copy(down)
188
188
  d['x', 1][10:] = 40
189
189
  d['x', 2][10:] = 40
190
190
  d['x', 3][10:] = 40
@@ -397,19 +397,19 @@ class DataBlock1dTest(unittest.TestCase):
397
397
  # Not enough data: detected at time level
398
398
  path = os.path.join(DIR_IO, 'bad1d-6-time-too-short.zip')
399
399
  self.assertRaisesRegex(
400
- myokit.DataBlockReadError, 'larger data',
400
+ myokit.DataBlockReadError, 'more time data',
401
401
  myokit.DataBlock1d.load, path)
402
402
 
403
403
  # Not enoug data: detected at 0d level
404
404
  path = os.path.join(DIR_IO, 'bad1d-7-0d-too-short.zip')
405
405
  self.assertRaisesRegex(
406
- myokit.DataBlockReadError, 'larger data',
406
+ myokit.DataBlockReadError, 'more 0d data',
407
407
  myokit.DataBlock1d.load, path)
408
408
 
409
409
  # Not enough data: detected at 1d level
410
410
  path = os.path.join(DIR_IO, 'bad1d-8-1d-too-short.zip')
411
411
  self.assertRaisesRegex(
412
- myokit.DataBlockReadError, 'larger data',
412
+ myokit.DataBlockReadError, 'more 1d data',
413
413
  myokit.DataBlock1d.load, path)
414
414
 
415
415
  # Test progress reporter
@@ -1324,19 +1324,19 @@ class DataBlock2dTest(unittest.TestCase):
1324
1324
  # Unknown data type in data
1325
1325
  path = os.path.join(DIR_IO, 'bad2d-6-time-too-short.zip')
1326
1326
  self.assertRaisesRegex(
1327
- myokit.DataBlockReadError, 'larger data',
1327
+ myokit.DataBlockReadError, 'more time data',
1328
1328
  myokit.DataBlock2d.load, path)
1329
1329
 
1330
1330
  # Unknown data type in data
1331
1331
  path = os.path.join(DIR_IO, 'bad2d-7-0d-too-short.zip')
1332
1332
  self.assertRaisesRegex(
1333
- myokit.DataBlockReadError, 'larger data',
1333
+ myokit.DataBlockReadError, 'more 0d data',
1334
1334
  myokit.DataBlock2d.load, path)
1335
1335
 
1336
1336
  # Unknown data type in data
1337
1337
  path = os.path.join(DIR_IO, 'bad2d-8-2d-too-short.zip')
1338
1338
  self.assertRaisesRegex(
1339
- myokit.DataBlockReadError, 'larger data',
1339
+ myokit.DataBlockReadError, 'more 2d data',
1340
1340
  myokit.DataBlock2d.load, path)
1341
1341
 
1342
1342
  # Test progress reporter
@@ -683,6 +683,26 @@ class DataLogTest(unittest.TestCase):
683
683
  d = myokit.DataLog.load(path, progress=p)
684
684
  self.assertIsNone(d)
685
685
 
686
+ def test_load_csv_duplicate_keys(self):
687
+ # Test loading a CSV with duplicate key names
688
+
689
+ path = os.path.join(DIR_IO, 'datalog-18-duplicate-keys.csv')
690
+ d = myokit.DataLog.load_csv(path)
691
+ self.assertEqual(len(d), 7)
692
+ self.assertEqual(
693
+ list(d.keys()),
694
+ ['time', 'x-1', 'x-3', 'ys-2-1', 'x-4', 'ys-2-2', 'x-2'])
695
+
696
+ def test_load_csv_ufeff(self):
697
+ # Test ignoring byte order marker (BOM) at start of file
698
+
699
+ with TemporaryDirectory() as td:
700
+ path = td.path('test.csv')
701
+ with open(path, 'w', encoding='utf-8-sig') as f:
702
+ f.write('time,x\n0,2\n1,3\n')
703
+ d = myokit.DataLog.load_csv(path)
704
+ self.assertEqual(list(d.keys()), ['time', 'x'])
705
+
686
706
  def test_load_csv_errors(self):
687
707
  # Test for errors during csv loading.
688
708
 
@@ -2109,9 +2129,12 @@ class DataLogTest(unittest.TestCase):
2109
2129
  self.assertRaises(ValueError, d.split_periodic, 0)
2110
2130
  self.assertRaises(ValueError, d.split_periodic, -1)
2111
2131
 
2112
- # Test larger period than log data
2132
+ # Test larger period than log data: Should return length-1 list
2113
2133
  d['x'] = [4, 5, 6, 7]
2114
2134
  e = d.split_periodic(100)
2135
+ self.assertIsInstance(e, list)
2136
+ self.assertEqual(len(e), 1)
2137
+ e = e[0]
2115
2138
  self.assertEqual(set(d.keys()), set(e.keys()))
2116
2139
  self.assertFalse(d is e)
2117
2140