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
@@ -5,24 +5,14 @@
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 os
12
- import platform
13
9
  import unittest
14
10
 
15
11
  import numpy as np
16
12
 
17
13
  import myokit
18
14
 
19
- from myokit.tests import DIR_DATA, WarningCollector
20
-
21
- # Unit testing in Python 2 and 3
22
- try:
23
- unittest.TestCase.assertRaisesRegex
24
- except AttributeError:
25
- unittest.TestCase.assertRaisesRegex = unittest.TestCase.assertRaisesRegexp
15
+ from myokit.tests import DIR_DATA
26
16
 
27
17
  # Extra output
28
18
  debug = False
@@ -410,313 +400,6 @@ class SimulationTest(PeriodicTest):
410
400
  self.assertNotEqual(e['membrane.V'][0], e['membrane.V'][1])
411
401
 
412
402
 
413
- @unittest.skipIf(platform.system() != 'Linux', 'Legacy CVODE tests')
414
- class LegacySimulationTest(PeriodicTest):
415
- """
416
- Tests myokit.LegacySimulation (which has dynamic, periodic and point-list
417
- logging) for consistent log entry timing.
418
- """
419
- def test_dynamic(self):
420
- # Test dynamic logging.
421
-
422
- emax = 1e-6 # Used for equality testing
423
- if debug:
424
- print('= Simulation :: Dynamic logging =')
425
- # Load model & protocol
426
- m, p, x = myokit.load(os.path.join(DIR_DATA, 'lr-1991.mmt'))
427
- # Create simulation
428
- s = myokit.LegacySimulation(m, p)
429
-
430
- #
431
- # Test 1: Simple 5 ms simulation, log_interval 0.5 ms
432
- #
433
- d = s.run(50, log=['engine.time'])
434
- t = d['engine.time']
435
- if debug:
436
- print(t[:2])
437
- print(t[-2:])
438
- print('- ' * 10)
439
- # Test first point not double
440
- self.assertGreater(t[1], t[0])
441
- # Test last point not double
442
- self.assertGreater(t[-1], t[-2])
443
- # Test first point is 0
444
- self.assertTrue(np.abs(t[0] - 0) < emax)
445
- # Test last point is 50
446
- self.assertTrue(np.abs(t[-1] - 50) < emax)
447
-
448
- #
449
- # Test 2: Very short simulation
450
- #
451
- s.reset()
452
- d = s.run(1, log=['engine.time'])
453
- t = d['engine.time']
454
- if debug:
455
- print(t[:2])
456
- print(t[-2:])
457
- print('- ' * 10)
458
- # Test first point not double
459
- self.assertGreater(t[1], t[0])
460
- # Test last point not double
461
- self.assertGreater(t[-1], t[-2])
462
- # Test first point is 0
463
- self.assertTrue(np.abs(t[0] - 0) < emax)
464
- # Test last point is 50
465
- self.assertTrue(np.abs(t[-1] - 1) < emax)
466
-
467
- #
468
- # Test 3: Stop and start a simulation
469
- #
470
- s.reset()
471
- d = s.run(2, log=['engine.time'])
472
- t = d['engine.time']
473
- n = len(d['engine.time'])
474
- if debug:
475
- print(d['engine.time'][:2])
476
- # Test first point not double
477
- self.assertGreater(t[1], t[0])
478
- # Test last point not double
479
- self.assertGreater(t[-1], t[-2])
480
- # Test first point is 0
481
- self.assertTrue(np.abs(t[0] - 0) < emax)
482
- # Test last point is 2
483
- self.assertTrue(np.abs(t[-1] - 2) < emax)
484
- d = s.run(13, log=d)
485
- t = d['engine.time']
486
- if debug:
487
- print(t[n - 2:n + 2])
488
- # Test last point not double
489
- self.assertGreater(t[-1], t[-2])
490
- # Test last point is 2+13
491
- self.assertTrue(np.abs(t[-1] - 15) < emax)
492
- # Test intermediary points are different
493
- self.assertGreater(t[n], t[n - 1])
494
- n = len(d['engine.time'])
495
- d = s.run(15, log=d)
496
- t = d['engine.time']
497
- if debug:
498
- print(t[n - 2:n + 2])
499
- # Test last point not double
500
- self.assertGreater(t[-1], t[-2])
501
- # Test last point is 2 + 13 + 15
502
- self.assertTrue(np.abs(t[-1] - 30) < emax)
503
- # Test intermediary points are different
504
- self.assertGreater(t[n], t[n - 1])
505
- n = len(d['engine.time'])
506
- d = s.run(20, log=d)
507
- t = d['engine.time']
508
- if debug:
509
- print(t[n - 2:n + 2])
510
- print(t[-2:])
511
- print('- ' * 10)
512
- # Test last point not double
513
- self.assertGreater(t[-1], t[-2])
514
- # Test last point is 2 + 13 + 15 + 20
515
- self.assertTrue(np.abs(t[-1] - 50) < emax)
516
- # Test intermediary points are different
517
- self.assertGreater(t[n], t[n - 1])
518
-
519
- def test_periodic(self):
520
- # Test periodic logging
521
-
522
- m, p, x = myokit.load(os.path.join(DIR_DATA, 'lr-1991.mmt'))
523
- s = myokit.LegacySimulation(m, p)
524
- self.periodic(s)
525
-
526
- def test_interpolation_and_pacing(self):
527
- # Test if interpolation results in correct pacing values.
528
-
529
- # When logging with discontinuous steps, in the adaptive time
530
- # CVODE sim, the value of pace must be
531
- # 1. The old value *before* the time of the event
532
- # 2. The new value *at and after* the time of the event
533
- # 3. Back to zero *at and after* the end of the event
534
- # (Unless it ends sooner due to a new event arriving)
535
- # Load model
536
- m = myokit.load_model('example')
537
-
538
- # Voltage-clamp V (but don't bind it directly)
539
- v = m.label('membrane_potential')
540
- v.demote()
541
- v.set_rhs('-80 + 10 * engine.pace')
542
-
543
- # Create protocol
544
- p = myokit.Protocol()
545
- p.schedule(level=1, start=0, duration=5, period=10)
546
-
547
- # Create simulation
548
- s = myokit.LegacySimulation(m, p)
549
-
550
- # Test if this would result in multiple interpolation steps for logging
551
- # i.e. test if the step before each transition was at least 2 log steps
552
- # long
553
- e = s.run(30).npview()
554
- t = e.time()
555
- for x in [5, 10, 15, 20, 25]:
556
- i = e.find_after(x)
557
- if not t[i] - t[i - 1] > 0.2:
558
- raise Exception('Issue with test: use longer intervals!')
559
- del e, t, x, i
560
-
561
- # Now test if correct interpolated values are returned by periodic
562
- # logging.
563
- d = s.run(30, log_interval=0.1).npview()
564
-
565
- # Test bound variable
566
- p = d['engine.pace']
567
- self.assertTrue(np.all(p[0:50] == 1))
568
- self.assertTrue(np.all(p[50:100] == 0))
569
- self.assertTrue(np.all(p[100:150] == 1))
570
- self.assertTrue(np.all(p[150:200] == 0))
571
- self.assertTrue(np.all(p[200:250] == 1))
572
- self.assertTrue(np.all(p[250:300] == 0))
573
-
574
- # Test variable dependent on bound variable
575
- p = d['membrane.V']
576
- self.assertTrue(np.all(p[0:50] == -70))
577
- self.assertTrue(np.all(p[50:100] == -80))
578
- self.assertTrue(np.all(p[100:150] == -70))
579
- self.assertTrue(np.all(p[150:200] == -80))
580
- self.assertTrue(np.all(p[200:250] == -70))
581
- self.assertTrue(np.all(p[250:300] == -80))
582
-
583
- def test_point_list(self):
584
- # Test logging with a preset list of points.
585
-
586
- # Load model
587
- m, p, x = myokit.load(os.path.join(DIR_DATA, 'lr-1991.mmt'))
588
- # Create simulation
589
- s = myokit.LegacySimulation(m, p)
590
-
591
- # Don't allow decreasing values
592
- times = [1, 2, 1]
593
- self.assertRaisesRegex(
594
- ValueError, 'non-decreasing', s.run, 5, log_times=times)
595
-
596
- # Can't use together with a log interval
597
- self.assertRaisesRegex(
598
- ValueError, 'simultaneously', s.run, 5, log_interval=1,
599
- log_times=[1, 2, 3])
600
-
601
- # Get some odd times
602
- times = np.linspace(0, 90, 999)
603
-
604
- # Test!
605
- s.reset()
606
- d = s.run(100, log_times=times).npview()
607
- self.assertTrue(np.all(d.time() == times))
608
-
609
- # Reset and run again
610
- s.reset()
611
- d = s.run(100, log_times=times).npview()
612
- self.assertTrue(np.all(d.time() == times))
613
-
614
- # Run in parts
615
- s.reset()
616
- d = s.run(50, log_times=times)
617
- self.assertEqual(len(d.time()), np.where(times >= 50)[0][0])
618
- d = s.run(50, log=d, log_times=times).npview()
619
- self.assertTrue(np.all(d.time() == times))
620
-
621
- # Pre-pacing
622
- s.reset()
623
- s.pre(50)
624
- s.run(100, log_times=times)
625
- self.assertTrue(np.all(d.time() == times))
626
-
627
- # Partial logging
628
- s.reset()
629
- s.run(10)
630
- d = s.run(10, log_times=times)
631
- imin = np.where(times >= 10)[0][0]
632
- imax = np.where(times >= 20)[0][0]
633
- self.assertEqual(len(d.time()), imax - imin)
634
- self.assertTrue(np.all(d.time() == times[imin:imax]))
635
- s.run(20)
636
- d = s.run(15, log_times=times)
637
- imin = np.where(times >= 40)[0][0]
638
- imax = np.where(times >= 55)[0][0]
639
- self.assertEqual(len(d.time()), imax - imin)
640
- self.assertTrue(np.all(d.time() == times[imin:imax]))
641
-
642
- # Get some regular times
643
- times = [0, 1, 2, 3, 4, 5]
644
- s.reset()
645
- d = s.run(6, log_times=times).npview()
646
- self.assertEqual(len(d.time()), len(times))
647
- self.assertTrue(np.all(d.time() == times))
648
-
649
- # Repeated points
650
- times = [0, 0, 0, 5, 5, 5]
651
- s.reset()
652
- d = s.run(6, log_times=times).npview()
653
- self.assertEqual(len(d.time()), len(times))
654
- self.assertTrue(np.all(d.time() == times))
655
-
656
- # End points not included, unless also visited!
657
- s.reset()
658
- s.run(5)
659
- d = s.run(5, log_times=times).npview()
660
- self.assertEqual(len(d.time()), 3)
661
- self.assertTrue(np.all(d.time() == times[3:]))
662
- d = s.run(5, log_times=times).npview()
663
- self.assertEqual(len(d.time()), 0)
664
-
665
- # Empty list is same as none
666
- s.reset()
667
- d = s.run(1, log_times=[])
668
- self.assertNotEqual(len(d.time()), 0)
669
-
670
- def test_point_list_2(self):
671
- # Test how the point-list logging performs when some of the logging
672
- # points overlap with protocol change points.
673
-
674
- # Load model
675
- m = myokit.load_model(os.path.join(DIR_DATA, 'lr-1991.mmt'))
676
- # Voltage clamp
677
- m.binding('pace').set_binding(None)
678
- v = m.get('membrane.V')
679
- v.demote()
680
- v.set_rhs(0)
681
- v.set_binding('pace')
682
- #TODO: Implement chaining like this?
683
- #m.get('membrane.V').demote().set_rhs(0).set_binding('pace')
684
- # Create step protocol
685
- dt = 0.1
686
- steps = [
687
- [-80, 250.1],
688
- [-120, 50],
689
- [-80, 200],
690
- [40, 1000],
691
- [-120, 500],
692
- [-80, 1000],
693
- [-30, 3500],
694
- [-120, 500],
695
- [-80, 1000],
696
- ]
697
- p = myokit.Protocol()
698
- for f, t in steps:
699
- p.add_step(f, t)
700
- # Create set of times that overlap with change points
701
- times = np.arange(80000) * dt
702
- # Create simulation
703
- s = myokit.LegacySimulation(m, p)
704
- # Run
705
- d = s.run(8000, log_times=times).npview()
706
- # Check if logging points show correct pacing value
707
- # In an earlier implementation, rounding errors and a difference in the
708
- # implementation of passing logpoints and passing protocol points could
709
- # cause the log point to be just before the protocol change.
710
- # In this case, a change at t=120.0 would only be picked up at t=120.1
711
- # (but not consistently!)
712
- # The below code checks for this
713
- offset = 0
714
- for v, t in steps[:-1]:
715
- offset += t
716
- e = d.trim(offset - dt, offset + 2 * dt)
717
- self.assertNotEqual(e['membrane.V'][0], e['membrane.V'][1])
718
-
719
-
720
403
  class Simulation1dTest(PeriodicTest):
721
404
  """
722
405
  Tests myokit.Simulation1d for consistent log entry timing.
@@ -729,119 +412,6 @@ class Simulation1dTest(PeriodicTest):
729
412
  self.periodic(s)
730
413
 
731
414
 
732
- class PSimulationTest(unittest.TestCase):
733
- """
734
- Tests myokit.PSimulation for consistent log entry timing.
735
- """
736
- def test_periodic(self):
737
- # Test periodic logging.
738
-
739
- m, p, x = myokit.load(os.path.join(DIR_DATA, 'lr-1991.mmt'))
740
- with WarningCollector():
741
- s = myokit.PSimulation(
742
- m, p, variables=['membrane.V'], parameters=['ina.gNa'])
743
- # Set tolerance for equality testing
744
- emax = 1e-2 # Time steps for logging are approximate
745
-
746
- # Test 1: Simple 5 ms simulation, log_interval 0.5 ms
747
- d, e = s.run(5, log=['engine.time'], log_interval=0.5)
748
- d = d.npview()
749
- t = d['engine.time']
750
- q = np.arange(0, 5, 0.5)
751
- if debug:
752
- print(t)
753
- print(q)
754
- print('- ' * 10)
755
- self.assertEqual(len(t), len(q))
756
- self.assertTrue(np.max(np.abs(t - q)) < emax)
757
-
758
- # Test 2: Very short simulation
759
- s.reset()
760
- d, e = s.run(1, log=['engine.time'], log_interval=0.5)
761
- d = d.npview()
762
- t = d['engine.time']
763
- q = np.arange(0, 1, 0.5)
764
- if debug:
765
- print(t)
766
- print(q)
767
- print('- ' * 10)
768
- self.assertEqual(len(t), len(q))
769
- self.assertTrue(np.max(np.abs(t - q)) < emax)
770
-
771
- # Test 3: Stop and start a simulation
772
- s.reset()
773
- d, e = s.run(1, log=['engine.time'], log_interval=0.5)
774
- d, e = s.run(2, log=d, log_interval=0.5)
775
- d, e = s.run(2, log=d, log_interval=0.5)
776
- d = d.npview()
777
- t = d['engine.time']
778
- q = np.arange(0, 5, 0.5)
779
- if debug:
780
- print(t)
781
- print(q)
782
- print('- ' * 10)
783
- self.assertEqual(len(t), len(q))
784
- self.assertTrue(np.max(np.abs(t - q)) < emax)
785
-
786
- # Negative or 0 log interval --> Log every step
787
- s.set_step_size(0.01)
788
- d, dp = s.run(1, log_interval=0)
789
- self.assertEqual(len(d.time()), 101)
790
- d, dp = s.run(1, log_interval=-1)
791
- self.assertEqual(len(d.time()), 101)
792
-
793
-
794
- class ICSimulationTest(unittest.TestCase):
795
- """
796
- Tests myokit.ICSimulation for consistent log entry timing.
797
- """
798
- def test_periodic(self):
799
- # Test periodic logging.
800
-
801
- m, p, x = myokit.load(os.path.join(DIR_DATA, 'lr-1991.mmt'))
802
- with WarningCollector():
803
- s = myokit.ICSimulation(m, p)
804
- # Set tolerance for equality testing
805
- emax = 1e-2 # Time steps for logging are approximate
806
- # Test 1: Simple 5 ms simulation, log_interval 0.5 ms
807
- d, e = s.run(5, log=['engine.time'], log_interval=0.5)
808
- d = d.npview()
809
- t = d['engine.time']
810
- q = np.arange(0, 5, 0.5)
811
- if debug:
812
- print(t)
813
- print(q)
814
- print('- ' * 10)
815
- self.assertEqual(len(t), len(q))
816
- self.assertTrue(np.max(np.abs(t - q)) < emax)
817
- # Test 2: Very short simulation
818
- s.reset()
819
- d, e = s.run(1, log=['engine.time'], log_interval=0.5)
820
- d = d.npview()
821
- t = d['engine.time']
822
- q = np.arange(0, 1, 0.5)
823
- if debug:
824
- print(t)
825
- print(q)
826
- print('- ' * 10)
827
- self.assertEqual(len(t), len(q))
828
- self.assertTrue(np.max(np.abs(t - q)) < emax)
829
- # Test 3: Stop and start a simulation
830
- s.reset()
831
- d, e = s.run(1, log=['engine.time'], log_interval=0.5)
832
- d, e = s.run(2, log=d, log_interval=0.5)
833
- d, e = s.run(2, log=d, log_interval=0.5)
834
- d = d.npview()
835
- t = d['engine.time']
836
- q = np.arange(0, 5, 0.5)
837
- if debug:
838
- print(t)
839
- print(q)
840
- print('- ' * 10)
841
- self.assertEqual(len(t), len(q))
842
- self.assertTrue(np.max(np.abs(t - q)) < emax)
843
-
844
-
845
415
  if __name__ == '__main__':
846
416
  print('Add -v for more debug output')
847
417
  import sys
@@ -8,11 +8,9 @@
8
8
  # This file is part of Myokit.
9
9
  # See http://myokit.org for copyright, sharing, and licensing details.
10
10
  #
11
- from __future__ import absolute_import, division
12
- from __future__ import print_function, unicode_literals
13
-
14
11
  import os
15
12
  import unittest
13
+
16
14
  import numpy as np
17
15
 
18
16
  import myokit
@@ -25,13 +23,6 @@ from myokit.tests import (
25
23
  WarningCollector,
26
24
  )
27
25
 
28
- # Unit testing in Python 2 and 3
29
- try:
30
- unittest.TestCase.assertRaisesRegex
31
- except AttributeError:
32
- unittest.TestCase.assertRaisesRegex = unittest.TestCase.assertRaisesRegexp
33
-
34
-
35
26
  # Show simulation output
36
27
  debug = False
37
28
 
@@ -621,7 +612,7 @@ class SimulationOpenCLTest(unittest.TestCase):
621
612
  self.assertRaisesRegex(
622
613
  RuntimeError, 'method is unavailable', s.is_paced, 0)
623
614
  self.assertRaisesRegex(
624
- RuntimeError, 'method is unavailable', s.neighbours, 0)
615
+ RuntimeError, 'method is unavailable', s.neighbors, 0)
625
616
  self.assertRaisesRegex(
626
617
  RuntimeError, 'method is unavailable', s.set_conductance)
627
618
  self.assertRaisesRegex(
@@ -666,105 +657,135 @@ class SimulationOpenCLTest(unittest.TestCase):
666
657
  self.assertTrue(np.all(d['membrane.V', 0] == d['membrane.V', 1]))
667
658
  self.assertTrue(np.all(d['membrane.V', 0] == d['membrane.V', 2]))
668
659
 
669
- def test_neighbours_0d(self):
670
- # Test listing neighbours in a 0d simulation
671
-
672
- x = self.s0.neighbours(0)
660
+ def test_initial_value_expressions(self):
661
+ # Test if initial value expressions are converted to floats
662
+ m = myokit.parse_model('''
663
+ [[model]]
664
+ c.x = 1 + sqrt(3)
665
+ c.y = 1 / c.p
666
+ c.z = 3
667
+
668
+ [c]
669
+ t = 0 bind time
670
+ dot(x) = 1 label membrane_potential
671
+ dot(y) = 2
672
+ dot(z) = 3
673
+ p = log(3)
674
+ q = 0 bind diffusion_current
675
+ ''')
676
+ s = myokit.SimulationOpenCL(m, ncells=2)
677
+ x = s.state()
678
+ self.assertIsInstance(x[0], float)
679
+ self.assertIsInstance(x[1], float)
680
+ self.assertIsInstance(x[2], float)
681
+ self.assertEqual(x[:3], x[3:])
682
+ self.assertEqual(x, m.initial_values(True) * 2)
683
+ self.assertEqual(x, s.default_state())
684
+
685
+ def test_neighbors_0d(self):
686
+ # Test listing neighbors in a 0d simulation
687
+
688
+ x = self.s0.neighbors(0)
673
689
  self.assertEqual(len(x), 0)
674
690
  self.assertRaisesRegex(
675
- IndexError, 'out of range', self.s0.neighbours, -1)
691
+ IndexError, 'out of range', self.s0.neighbors, -1)
676
692
  self.assertRaisesRegex(
677
- IndexError, 'out of range', self.s0.neighbours, 1)
693
+ IndexError, 'out of range', self.s0.neighbors, 1)
678
694
  self.assertRaisesRegex(
679
- ValueError, '1-dimensional', self.s0.neighbours, 0, 1)
695
+ ValueError, '1-dimensional', self.s0.neighbors, 0, 1)
696
+
697
+ # Test alias
698
+ with WarningCollector() as w:
699
+ self.assertEqual(self.s0.neighbours(0), self.s0.neighbors(0))
700
+ self.assertIn('deprecated', w.text())
680
701
 
681
- def test_neighbours_1d(self):
682
- # Test listing neighbours in a 1d simulation
702
+ def test_neighbors_1d(self):
703
+ # Test listing neighbors in a 1d simulation
683
704
 
684
705
  # Left edge
685
- x = self.s1.neighbours(0)
706
+ x = self.s1.neighbors(0)
686
707
  self.assertEqual(len(x), 1)
687
708
  self.assertIn(1, x)
688
709
  # Middle
689
- x = self.s1.neighbours(1)
710
+ x = self.s1.neighbors(1)
690
711
  self.assertEqual(len(x), 2)
691
712
  self.assertIn(0, x)
692
713
  self.assertIn(2, x)
693
714
  # Right edge
694
- x = self.s1.neighbours(9)
715
+ x = self.s1.neighbors(9)
695
716
  self.assertEqual(len(x), 1)
696
717
  self.assertIn(8, x)
697
718
 
698
719
  # Out of range
699
720
  self.assertRaisesRegex(
700
- IndexError, 'out of range', self.s1.neighbours, -1)
721
+ IndexError, 'out of range', self.s1.neighbors, -1)
701
722
  self.assertRaisesRegex(
702
- IndexError, 'out of range', self.s1.neighbours, 10)
723
+ IndexError, 'out of range', self.s1.neighbors, 10)
703
724
  self.assertRaisesRegex(
704
- ValueError, '1-dimensional', self.s1.neighbours, 0, 1)
725
+ ValueError, '1-dimensional', self.s1.neighbors, 0, 1)
705
726
 
706
- def test_neighbours_1d_connections(self):
707
- # Test listing neighbours in a 1d simulation with arbitrary geometry
727
+ def test_neighbors_1d_connections(self):
728
+ # Test listing neighbors in a 1d simulation with arbitrary geometry
708
729
 
709
730
  try:
710
731
  g = 1
711
732
  self.s1.set_connections(
712
733
  [(0, 1, g), (0, 2, g), (3, 0, g), (3, 2, g)])
713
- x = self.s1.neighbours(0)
734
+ x = self.s1.neighbors(0)
714
735
  self.assertEqual(len(x), 3)
715
736
  self.assertIn(1, x)
716
737
  self.assertIn(2, x)
717
738
  self.assertIn(3, x)
718
- x = self.s1.neighbours(1)
739
+ x = self.s1.neighbors(1)
719
740
  self.assertEqual(len(x), 1)
720
741
  self.assertIn(0, x)
721
- x = self.s1.neighbours(2)
742
+ x = self.s1.neighbors(2)
722
743
  self.assertEqual(len(x), 2)
723
744
  self.assertIn(0, x)
724
745
  self.assertIn(3, x)
725
- x = self.s1.neighbours(3)
746
+ x = self.s1.neighbors(3)
726
747
  self.assertEqual(len(x), 2)
727
748
  self.assertIn(0, x)
728
749
  self.assertIn(2, x)
729
- x = self.s1.neighbours(4)
750
+ x = self.s1.neighbors(4)
730
751
  self.assertEqual(len(x), 0)
731
752
  finally:
732
753
  # Restore defaults
733
754
  self.s1.set_conductance()
734
755
 
735
- def test_neighbours_2d(self):
736
- # Test listing neighbours in a 2d simulation
756
+ def test_neighbors_2d(self):
757
+ # Test listing neighbors in a 2d simulation
737
758
 
738
759
  # Corners
739
- x = self.s2.neighbours(0, 0)
760
+ x = self.s2.neighbors(0, 0)
740
761
  self.assertEqual(len(x), 2)
741
762
  self.assertIn((1, 0), x)
742
763
  self.assertIn((0, 1), x)
743
- x = self.s2.neighbours(3, 2)
764
+ x = self.s2.neighbors(3, 2)
744
765
  self.assertEqual(len(x), 2)
745
766
  self.assertIn((3, 1), x)
746
767
  self.assertIn((2, 2), x)
747
768
 
748
769
  # Edges
749
- x = self.s2.neighbours(1, 0)
770
+ x = self.s2.neighbors(1, 0)
750
771
  self.assertEqual(len(x), 3)
751
772
  self.assertIn((0, 0), x)
752
773
  self.assertIn((2, 0), x)
753
774
  self.assertIn((1, 1), x)
754
- x = self.s2.neighbours(3, 1)
775
+ x = self.s2.neighbors(3, 1)
755
776
  self.assertEqual(len(x), 3)
756
777
  self.assertIn((2, 1), x)
757
778
  self.assertIn((3, 0), x)
758
779
  self.assertIn((3, 2), x)
759
780
 
760
781
  # Middle
761
- x = self.s2.neighbours(1, 1)
782
+ x = self.s2.neighbors(1, 1)
762
783
  self.assertEqual(len(x), 4)
763
784
  self.assertIn((0, 1), x)
764
785
  self.assertIn((2, 1), x)
765
786
  self.assertIn((1, 0), x)
766
787
  self.assertIn((1, 2), x)
767
- x = self.s2.neighbours(2, 1)
788
+ x = self.s2.neighbors(2, 1)
768
789
  self.assertEqual(len(x), 4)
769
790
  self.assertIn((1, 1), x)
770
791
  self.assertIn((3, 1), x)
@@ -773,15 +794,15 @@ class SimulationOpenCLTest(unittest.TestCase):
773
794
 
774
795
  # Out of range
775
796
  self.assertRaisesRegex(
776
- IndexError, 'out of range', self.s2.neighbours, -1, 0)
797
+ IndexError, 'out of range', self.s2.neighbors, -1, 0)
777
798
  self.assertRaisesRegex(
778
- IndexError, 'out of range', self.s2.neighbours, 0, -1)
799
+ IndexError, 'out of range', self.s2.neighbors, 0, -1)
779
800
  self.assertRaisesRegex(
780
- IndexError, 'out of range', self.s2.neighbours, 4, 0)
801
+ IndexError, 'out of range', self.s2.neighbors, 4, 0)
781
802
  self.assertRaisesRegex(
782
- IndexError, 'out of range', self.s2.neighbours, 0, 3)
803
+ IndexError, 'out of range', self.s2.neighbors, 0, 3)
783
804
  self.assertRaisesRegex(
784
- ValueError, '2-dimensional', self.s2.neighbours, 0)
805
+ ValueError, '2-dimensional', self.s2.neighbors, 0)
785
806
 
786
807
  def test_protocol(self):
787
808
  # Tests changing the protocol
@@ -1180,7 +1201,7 @@ class SimulationOpenCLTest(unittest.TestCase):
1180
1201
  m = 8
1181
1202
  n = 10
1182
1203
  self.s1.reset()
1183
- sm = self.m.state()
1204
+ sm = self.m.initial_values(True)
1184
1205
  ss = [self.s1.state(x) for x in range(n)]
1185
1206
  for si in ss:
1186
1207
  self.assertEqual(sm, si)
@@ -1277,7 +1298,7 @@ class SimulationOpenCLTest(unittest.TestCase):
1277
1298
  m = 8
1278
1299
  nx, ny = 4, 3
1279
1300
  self.s2.reset()
1280
- sm = self.m.state()
1301
+ sm = self.m.initial_values(True)
1281
1302
  for i in range(nx):
1282
1303
  for j in range(ny):
1283
1304
  self.assertEqual(sm, self.s2.state(i, j))