myokit 1.37.2__tar.gz → 1.37.4__tar.gz

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 (417) hide show
  1. {myokit-1.37.2/myokit.egg-info → myokit-1.37.4}/PKG-INFO +2 -2
  2. {myokit-1.37.2 → myokit-1.37.4}/README.md +1 -1
  3. {myokit-1.37.2 → myokit-1.37.4}/myokit/_myokit_version.py +1 -1
  4. {myokit-1.37.2 → myokit-1.37.4}/myokit/_unit.py +48 -40
  5. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/heka/_patchmaster.py +84 -10
  6. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/sbml/_api.py +11 -8
  7. {myokit-1.37.2 → myokit-1.37.4}/myokit/gui/datalog_viewer.py +61 -8
  8. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_quantity.py +2 -2
  9. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_sbml_export.py +21 -0
  10. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_unit.py +28 -7
  11. {myokit-1.37.2 → myokit-1.37.4/myokit.egg-info}/PKG-INFO +2 -2
  12. {myokit-1.37.2 → myokit-1.37.4}/myokit.egg-info/SOURCES.txt +1 -0
  13. myokit-1.37.4/pyproject.toml +3 -0
  14. {myokit-1.37.2 → myokit-1.37.4}/LICENSE.txt +0 -0
  15. {myokit-1.37.2 → myokit-1.37.4}/MANIFEST.in +0 -0
  16. {myokit-1.37.2 → myokit-1.37.4}/myokit/__init__.py +0 -0
  17. {myokit-1.37.2 → myokit-1.37.4}/myokit/__main__.py +0 -0
  18. {myokit-1.37.2 → myokit-1.37.4}/myokit/_aux.py +0 -0
  19. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/example.mmt +0 -0
  20. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/find.png +0 -0
  21. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/icon-datablock-viewer-128.xpm +0 -0
  22. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/icon-datablock-viewer-16.xpm +0 -0
  23. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/icon-datablock-viewer-24.xpm +0 -0
  24. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/icon-datablock-viewer-256.xpm +0 -0
  25. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/icon-datablock-viewer-32.xpm +0 -0
  26. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/icon-datablock-viewer-48.xpm +0 -0
  27. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/icon-datablock-viewer-64.xpm +0 -0
  28. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/icon-datablock-viewer-96.xpm +0 -0
  29. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/icon-datablock-viewer.ico +0 -0
  30. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/icon-datablock-viewer.png +0 -0
  31. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/icon-ide-128.xpm +0 -0
  32. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/icon-ide-16.xpm +0 -0
  33. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/icon-ide-24.xpm +0 -0
  34. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/icon-ide-256.xpm +0 -0
  35. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/icon-ide-32.xpm +0 -0
  36. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/icon-ide-48.xpm +0 -0
  37. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/icon-ide-64.xpm +0 -0
  38. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/icon-ide-96.xpm +0 -0
  39. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/icon-ide.ico +0 -0
  40. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/icon-ide.png +0 -0
  41. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/new.png +0 -0
  42. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/open.png +0 -0
  43. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/redo.png +0 -0
  44. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/run.png +0 -0
  45. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/save.png +0 -0
  46. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/gui/undo.png +0 -0
  47. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/install-lin/myokit-datablock-viewer.desktop +0 -0
  48. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/install-lin/myokit-datalog-viewer.desktop +0 -0
  49. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/install-lin/myokit-ide.desktop +0 -0
  50. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/install-lin/myokit.lang +0 -0
  51. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/install-lin/x-abf.xml +0 -0
  52. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/install-lin/x-cellml.xml +0 -0
  53. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/install-lin/x-myokit.xml +0 -0
  54. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/install-lin/x-wcp.xml +0 -0
  55. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/install-win/menu.json +0 -0
  56. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/sundials-win-vs/LICENSE +0 -0
  57. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/sundials-win-vs/include/cvodes/cvodes.h +0 -0
  58. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/sundials-win-vs/include/cvodes/cvodes_direct.h +0 -0
  59. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/sundials-win-vs/include/cvodes/cvodes_ls.h +0 -0
  60. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/sundials-win-vs/include/nvector/nvector_serial.h +0 -0
  61. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/sundials-win-vs/include/sundials/sundials_config.h +0 -0
  62. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/sundials-win-vs/include/sundials/sundials_dense.h +0 -0
  63. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/sundials-win-vs/include/sundials/sundials_direct.h +0 -0
  64. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/sundials-win-vs/include/sundials/sundials_export.h +0 -0
  65. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/sundials-win-vs/include/sundials/sundials_iterative.h +0 -0
  66. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/sundials-win-vs/include/sundials/sundials_linearsolver.h +0 -0
  67. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/sundials-win-vs/include/sundials/sundials_matrix.h +0 -0
  68. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/sundials-win-vs/include/sundials/sundials_nonlinearsolver.h +0 -0
  69. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/sundials-win-vs/include/sundials/sundials_nvector.h +0 -0
  70. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/sundials-win-vs/include/sundials/sundials_types.h +0 -0
  71. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/sundials-win-vs/include/sundials/sundials_version.h +0 -0
  72. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/sundials-win-vs/include/sunlinsol/sunlinsol_dense.h +0 -0
  73. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/sundials-win-vs/include/sunmatrix/sunmatrix_dense.h +0 -0
  74. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/sundials-win-vs/lib/sundials_cvodes.dll +0 -0
  75. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/sundials-win-vs/lib/sundials_cvodes.lib +0 -0
  76. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/sundials-win-vs/lib/sundials_nvecserial.dll +0 -0
  77. {myokit-1.37.2 → myokit-1.37.4}/myokit/_bin/sundials-win-vs/lib/sundials_nvecserial.lib +0 -0
  78. {myokit-1.37.2 → myokit-1.37.4}/myokit/_config.py +0 -0
  79. {myokit-1.37.2 → myokit-1.37.4}/myokit/_datablock.py +0 -0
  80. {myokit-1.37.2 → myokit-1.37.4}/myokit/_datalog.py +0 -0
  81. {myokit-1.37.2 → myokit-1.37.4}/myokit/_err.py +0 -0
  82. {myokit-1.37.2 → myokit-1.37.4}/myokit/_expressions.py +0 -0
  83. {myokit-1.37.2 → myokit-1.37.4}/myokit/_io.py +0 -0
  84. {myokit-1.37.2 → myokit-1.37.4}/myokit/_model_api.py +0 -0
  85. {myokit-1.37.2 → myokit-1.37.4}/myokit/_parsing.py +0 -0
  86. {myokit-1.37.2 → myokit-1.37.4}/myokit/_progress.py +0 -0
  87. {myokit-1.37.2 → myokit-1.37.4}/myokit/_protocol.py +0 -0
  88. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/__init__.py +0 -0
  89. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/cable.c +0 -0
  90. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/cable.py +0 -0
  91. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/cmodel.h +0 -0
  92. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/cmodel.py +0 -0
  93. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/compiler.c +0 -0
  94. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/compiler.py +0 -0
  95. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/cvodessim.c +0 -0
  96. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/cvodessim.py +0 -0
  97. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/differential.hpp +0 -0
  98. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/fiber_tissue.c +0 -0
  99. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/fiber_tissue.py +0 -0
  100. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/jacobian.cpp +0 -0
  101. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/jacobian.py +0 -0
  102. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/mcl.h +0 -0
  103. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/opencl.c +0 -0
  104. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/opencl.py +0 -0
  105. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/openclsim.c +0 -0
  106. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/openclsim.cl +0 -0
  107. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/openclsim.py +0 -0
  108. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/pacing.h +0 -0
  109. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/rhs.c +0 -0
  110. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/rhs.py +0 -0
  111. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/sundials.c +0 -0
  112. {myokit-1.37.2 → myokit-1.37.4}/myokit/_sim/sundials.py +0 -0
  113. {myokit-1.37.2 → myokit-1.37.4}/myokit/_system.py +0 -0
  114. {myokit-1.37.2 → myokit-1.37.4}/myokit/float.py +0 -0
  115. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/__init__.py +0 -0
  116. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/ansic/__init__.py +0 -0
  117. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/ansic/_ewriter.py +0 -0
  118. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/ansic/_exporter.py +0 -0
  119. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/ansic/template/cable.c +0 -0
  120. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/ansic/template/euler.c +0 -0
  121. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/ansic/template/sim.c +0 -0
  122. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/axon/__init__.py +0 -0
  123. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/axon/_abf.py +0 -0
  124. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/axon/_atf.py +0 -0
  125. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/axon/_importer.py +0 -0
  126. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/cellml/__init__.py +0 -0
  127. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/cellml/_ewriter.py +0 -0
  128. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/cellml/_exporter.py +0 -0
  129. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/cellml/_importer.py +0 -0
  130. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/cellml/v1/__init__.py +0 -0
  131. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/cellml/v1/_api.py +0 -0
  132. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/cellml/v1/_parser.py +0 -0
  133. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/cellml/v1/_writer.py +0 -0
  134. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/cellml/v2/__init__.py +0 -0
  135. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/cellml/v2/_api.py +0 -0
  136. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/cellml/v2/_parser.py +0 -0
  137. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/cellml/v2/_writer.py +0 -0
  138. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/channelml/__init__.py +0 -0
  139. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/channelml/_importer.py +0 -0
  140. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/cpp/__init__.py +0 -0
  141. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/cpp/_ewriter.py +0 -0
  142. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/cuda/__init__.py +0 -0
  143. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/cuda/_ewriter.py +0 -0
  144. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/cuda/_exporter.py +0 -0
  145. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/cuda/template/kernel.cu +0 -0
  146. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/diffsl/__init__.py +0 -0
  147. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/diffsl/_ewriter.py +0 -0
  148. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/diffsl/_exporter.py +0 -0
  149. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/easyml/__init__.py +0 -0
  150. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/easyml/_ewriter.py +0 -0
  151. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/easyml/_exporter.py +0 -0
  152. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/heka/__init__.py +0 -0
  153. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/heka/_importer.py +0 -0
  154. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/html/__init__.py +0 -0
  155. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/html/_exporter.py +0 -0
  156. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/html/_flatten.py +0 -0
  157. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/latex/__init__.py +0 -0
  158. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/latex/_ewriter.py +0 -0
  159. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/latex/_exporter.py +0 -0
  160. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/mathml/__init__.py +0 -0
  161. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/mathml/_ewriter.py +0 -0
  162. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/mathml/_parser.py +0 -0
  163. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/matlab/__init__.py +0 -0
  164. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/matlab/_ewriter.py +0 -0
  165. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/matlab/_exporter.py +0 -0
  166. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/matlab/template/constants.m +0 -0
  167. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/matlab/template/ifthenelse.m +0 -0
  168. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/matlab/template/main.m +0 -0
  169. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/matlab/template/model.m +0 -0
  170. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/matlab/template/model_wrapper.m +0 -0
  171. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/opencl/__init__.py +0 -0
  172. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/opencl/_ewriter.py +0 -0
  173. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/opencl/_exporter.py +0 -0
  174. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/opencl/template/cable.c +0 -0
  175. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/opencl/template/kernel.cl +0 -0
  176. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/opencl/template/minilog.py +0 -0
  177. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/opencl/template/plot.py +0 -0
  178. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/opencl/template/test.sh +0 -0
  179. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/python/__init__.py +0 -0
  180. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/python/_ewriter.py +0 -0
  181. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/python/_exporter.py +0 -0
  182. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/python/template/sim.py +0 -0
  183. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/sbml/__init__.py +0 -0
  184. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/sbml/_exporter.py +0 -0
  185. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/sbml/_importer.py +0 -0
  186. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/sbml/_parser.py +0 -0
  187. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/sbml/_writer.py +0 -0
  188. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/stan/__init__.py +0 -0
  189. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/stan/_ewriter.py +0 -0
  190. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/stan/_exporter.py +0 -0
  191. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/stan/template/cell.stan +0 -0
  192. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/stan/template/run.py +0 -0
  193. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/sympy/__init__.py +0 -0
  194. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/sympy/_ereader.py +0 -0
  195. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/sympy/_ewriter.py +0 -0
  196. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/wcp/__init__.py +0 -0
  197. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/wcp/_wcp.py +0 -0
  198. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/xml/__init__.py +0 -0
  199. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/xml/_exporter.py +0 -0
  200. {myokit-1.37.2 → myokit-1.37.4}/myokit/formats/xml/_split.py +0 -0
  201. {myokit-1.37.2 → myokit-1.37.4}/myokit/gui/__init__.py +0 -0
  202. {myokit-1.37.2 → myokit-1.37.4}/myokit/gui/datablock_viewer.py +0 -0
  203. {myokit-1.37.2 → myokit-1.37.4}/myokit/gui/explorer.py +0 -0
  204. {myokit-1.37.2 → myokit-1.37.4}/myokit/gui/ide.py +0 -0
  205. {myokit-1.37.2 → myokit-1.37.4}/myokit/gui/progress.py +0 -0
  206. {myokit-1.37.2 → myokit-1.37.4}/myokit/gui/source.py +0 -0
  207. {myokit-1.37.2 → myokit-1.37.4}/myokit/gui/vargrapher.py +0 -0
  208. {myokit-1.37.2 → myokit-1.37.4}/myokit/lib/__init__.py +0 -0
  209. {myokit-1.37.2 → myokit-1.37.4}/myokit/lib/deps.py +0 -0
  210. {myokit-1.37.2 → myokit-1.37.4}/myokit/lib/guess.py +0 -0
  211. {myokit-1.37.2 → myokit-1.37.4}/myokit/lib/hh.py +0 -0
  212. {myokit-1.37.2 → myokit-1.37.4}/myokit/lib/markov.py +0 -0
  213. {myokit-1.37.2 → myokit-1.37.4}/myokit/lib/multi.py +0 -0
  214. {myokit-1.37.2 → myokit-1.37.4}/myokit/lib/plots.py +0 -0
  215. {myokit-1.37.2 → myokit-1.37.4}/myokit/pacing.py +0 -0
  216. {myokit-1.37.2 → myokit-1.37.4}/myokit/pype.py +0 -0
  217. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/__init__.py +0 -0
  218. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/ansic_event_based_pacing.py +0 -0
  219. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/ansic_time_series_pacing.py +0 -0
  220. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/beeler-1977-model-compare-a.mmt +0 -0
  221. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/beeler-1977-model-compare-b.mmt +0 -0
  222. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/beeler-1977-model.mmt +0 -0
  223. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/beeler-1977-protocol.mmt +0 -0
  224. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/beeler-1977-script.mmt +0 -0
  225. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/beeler-1977-units.mmt +0 -0
  226. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/clancy-1999-fitting.mmt +0 -0
  227. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/conditional.mmt +0 -0
  228. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/cv1d.mmt +0 -0
  229. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/cv1d.zip +0 -0
  230. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/decker-2009.mmt +0 -0
  231. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/decker.model +0 -0
  232. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/dn-1985-normalised.mmt +0 -0
  233. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/dom-markov.mmt +0 -0
  234. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/abf-protocol.pro +0 -0
  235. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/abf-v1.abf +0 -0
  236. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/abf-v2.abf +0 -0
  237. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/cellml/LICENSE +0 -0
  238. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/cellml/br-1977-dot.cellml +0 -0
  239. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/cellml/br-1977.cellml +0 -0
  240. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/cellml/corrias.cellml +0 -0
  241. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/cellml/decker-2009.cellml +0 -0
  242. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/cellml/documentation.cellml +0 -0
  243. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/cellml/invalid-file.cellml +0 -0
  244. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/cellml/lr-1991-exported-1.cellml +0 -0
  245. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/cellml/lr-1991-exported-2.cellml +0 -0
  246. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/channelml/ch-00-valid-file.channelml +0 -0
  247. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/channelml/ch-01-wrong-root.channelml +0 -0
  248. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/channelml/ch-02-no-channel-type.channelml +0 -0
  249. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/channelml/ch-03-overlapping-name.channelml +0 -0
  250. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/channelml/ch-04-no-cvr.channelml +0 -0
  251. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/channelml/ch-05-two-cvrs.channelml +0 -0
  252. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/channelml/ch-06-no-q10.channelml +0 -0
  253. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/channelml/ch-07-three-transitions.channelml +0 -0
  254. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/channelml/ch-08-no-closed-to-open.channelml +0 -0
  255. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/channelml/ch-09-no-open-to-closed.channelml +0 -0
  256. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/channelml/ch-10-tco-bad-expression.channelml +0 -0
  257. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/channelml/ch-11-toc-bad-expression.channelml +0 -0
  258. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/channelml/ch-12-no-steady-state.channelml +0 -0
  259. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/channelml/ch-13-no-time-course.channelml +0 -0
  260. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/channelml/ch-14-inf-bad-expression.channelml +0 -0
  261. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/channelml/ch-15-tau-bad-expression.channelml +0 -0
  262. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/channelml/ch-16-no-gates.channelml +0 -0
  263. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/channelml/ch-17-invalid-name.channelml +0 -0
  264. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/channelml/ch-18-c-style-if.channelml +0 -0
  265. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/sbml/00004-sbml-l2v1-modified.xml +0 -0
  266. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/sbml/00004-sbml-l3v2-modified.xml +0 -0
  267. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/sbml/HodgkinHuxley.xml +0 -0
  268. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/sbml/LICENSE +0 -0
  269. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/sbml/model/00001-sbml-l3v2.xml +0 -0
  270. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/sbml/model/00004-sbml-l3v2.xml +0 -0
  271. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/sbml/model/01103-sbml-l3v2.xml +0 -0
  272. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/sbml/result/00001-results.csv +0 -0
  273. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/sbml/result/00004-results.csv +0 -0
  274. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/sbml/result/01103-results.csv +0 -0
  275. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/wcp-file-empty.wcp +0 -0
  276. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/formats/wcp-file.wcp +0 -0
  277. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/bad1d-1-not-enough-files.zip +0 -0
  278. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/bad1d-2-no-header.zip +0 -0
  279. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/bad1d-3-no-data.zip +0 -0
  280. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/bad1d-4-not-a-zip.zip +0 -0
  281. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/bad1d-5-bad-data-type.zip +0 -0
  282. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/bad1d-6-time-too-short.zip +0 -0
  283. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/bad1d-7-0d-too-short.zip +0 -0
  284. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/bad1d-8-1d-too-short.zip +0 -0
  285. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/bad2d-1-not-enough-files.zip +0 -0
  286. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/bad2d-2-no-header.zip +0 -0
  287. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/bad2d-3-no-data.zip +0 -0
  288. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/bad2d-4-not-a-zip.zip +0 -0
  289. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/bad2d-5-bad-data-type.zip +0 -0
  290. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/bad2d-6-time-too-short.zip +0 -0
  291. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/bad2d-7-0d-too-short.zip +0 -0
  292. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/bad2d-8-2d-too-short.zip +0 -0
  293. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/badlog-1-no-data.zip +0 -0
  294. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/badlog-2-no-structure.zip +0 -0
  295. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/badlog-3-not-a-zip.zip +0 -0
  296. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/badlog-4-invalid-n-fields.zip +0 -0
  297. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/badlog-5-invalid-data-size.zip +0 -0
  298. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/badlog-6-bad-data-type.zip +0 -0
  299. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/badlog-7-not-enough-data.zip +0 -0
  300. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/block1d.mmt +0 -0
  301. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/block2d.mmt +0 -0
  302. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/block2d.zip +0 -0
  303. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/datalog-1-empty.csv +0 -0
  304. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/datalog-10-just-spaces.csv +0 -0
  305. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/datalog-11-just-a-semicolon.csv +0 -0
  306. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/datalog-12-bad-header.csv +0 -0
  307. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/datalog-13-header-with-empty-1.csv +0 -0
  308. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/datalog-14-header-with-empty-2.csv +0 -0
  309. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/datalog-15-header-with-empty-3.csv +0 -0
  310. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/datalog-16-wrong-columns-in-data.csv +0 -0
  311. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/datalog-17-non-float-data.csv +0 -0
  312. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/datalog-18-duplicate-keys.csv +0 -0
  313. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/datalog-2-windows.csv +0 -0
  314. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/datalog-3-old-mac.csv +0 -0
  315. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/datalog-4-empty-lines.csv +0 -0
  316. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/datalog-5-semicolons.csv +0 -0
  317. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/datalog-6-open-string.csv +0 -0
  318. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/datalog-7-empty-lines-2.csv +0 -0
  319. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/datalog-8-unquoted-header.csv +0 -0
  320. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/datalog-9-double-quoted-header.csv +0 -0
  321. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/datalog.csv +0 -0
  322. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/io/goodlog.zip +0 -0
  323. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/lr-1991-dep.mmt +0 -0
  324. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/lr-1991-fitting.mmt +0 -0
  325. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/lr-1991-testing.mmt +0 -0
  326. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/lr-1991.mmt +0 -0
  327. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/multi/beeler-1977-protocol.mmt +0 -0
  328. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/multi/beeler-1977-script.mmt +0 -0
  329. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/multi/beeler-no-name.mmt +0 -0
  330. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/multi/lr-1991.mmt +0 -0
  331. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/multi/not-a-model.csv +0 -0
  332. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/multi/subdir/beeler-no-name.mmt +0 -0
  333. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/data/noble-1962.mmt +0 -0
  334. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_aux.py +0 -0
  335. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_cellml_v1_api.py +0 -0
  336. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_cellml_v1_parser.py +0 -0
  337. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_cellml_v1_writer.py +0 -0
  338. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_cellml_v2_api.py +0 -0
  339. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_cellml_v2_parser.py +0 -0
  340. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_cellml_v2_writer.py +0 -0
  341. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_cmodel.py +0 -0
  342. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_compiler_detection.py +0 -0
  343. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_component.py +0 -0
  344. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_config.py +0 -0
  345. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_datablock.py +0 -0
  346. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_datalog.py +0 -0
  347. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_dependency_checking.py +0 -0
  348. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_expressions.py +0 -0
  349. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_float.py +0 -0
  350. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_formats.py +0 -0
  351. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_formats_ansic.py +0 -0
  352. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_formats_axon.py +0 -0
  353. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_formats_cellml.py +0 -0
  354. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_formats_channelml.py +0 -0
  355. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_formats_cpp.py +0 -0
  356. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_formats_cuda.py +0 -0
  357. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_formats_diffsl.py +0 -0
  358. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_formats_easyml.py +0 -0
  359. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_formats_exporters_run.py +0 -0
  360. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_formats_html.py +0 -0
  361. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_formats_latex.py +0 -0
  362. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_formats_mathml_content.py +0 -0
  363. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_formats_mathml_presentation.py +0 -0
  364. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_formats_matlab.py +0 -0
  365. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_formats_opencl.py +0 -0
  366. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_formats_python.py +0 -0
  367. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_formats_sbml.py +0 -0
  368. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_formats_stan.py +0 -0
  369. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_formats_sympy.py +0 -0
  370. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_formats_wcp.py +0 -0
  371. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_io.py +0 -0
  372. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_jacobian_calculator.py +0 -0
  373. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_jacobian_tracer.py +0 -0
  374. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_lib_deps.py +0 -0
  375. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_lib_guess.py +0 -0
  376. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_lib_hh.py +0 -0
  377. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_lib_markov.py +0 -0
  378. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_lib_multi.py +0 -0
  379. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_lib_plots.py +0 -0
  380. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_meta.py +0 -0
  381. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_model.py +0 -0
  382. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_model_building.py +0 -0
  383. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_opencl_info.py +0 -0
  384. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_pacing_factory.py +0 -0
  385. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_pacing_system_c.py +0 -0
  386. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_pacing_system_py.py +0 -0
  387. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_parsing.py +0 -0
  388. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_progress_reporters.py +0 -0
  389. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_protocol.py +0 -0
  390. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_protocol_floating_point.py +0 -0
  391. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_protocol_time_series.py +0 -0
  392. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_pype.py +0 -0
  393. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_rhs_benchmarker.py +0 -0
  394. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_sbml_api.py +0 -0
  395. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_sbml_parser.py +0 -0
  396. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_simulation_1d.py +0 -0
  397. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_simulation_cvodes.py +0 -0
  398. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_simulation_cvodes_from_disk.py +0 -0
  399. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_simulation_fiber_tissue.py +0 -0
  400. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_simulation_log_interval.py +0 -0
  401. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_simulation_opencl.py +0 -0
  402. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_simulation_opencl_log_interval.py +0 -0
  403. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_simulation_opencl_vs_cvode.py +0 -0
  404. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_simulation_opencl_vs_sim1d.py +0 -0
  405. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_system_info.py +0 -0
  406. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_tools.py +0 -0
  407. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_user_functions.py +0 -0
  408. {myokit-1.37.2 → myokit-1.37.4}/myokit/tests/test_variable.py +0 -0
  409. {myokit-1.37.2 → myokit-1.37.4}/myokit/tools.py +0 -0
  410. {myokit-1.37.2 → myokit-1.37.4}/myokit/units.py +0 -0
  411. {myokit-1.37.2 → myokit-1.37.4}/myokit.egg-info/dependency_links.txt +0 -0
  412. {myokit-1.37.2 → myokit-1.37.4}/myokit.egg-info/entry_points.txt +0 -0
  413. {myokit-1.37.2 → myokit-1.37.4}/myokit.egg-info/not-zip-safe +0 -0
  414. {myokit-1.37.2 → myokit-1.37.4}/myokit.egg-info/requires.txt +0 -0
  415. {myokit-1.37.2 → myokit-1.37.4}/myokit.egg-info/top_level.txt +0 -0
  416. {myokit-1.37.2 → myokit-1.37.4}/setup.cfg +0 -0
  417. {myokit-1.37.2 → myokit-1.37.4}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: myokit
3
- Version: 1.37.2
3
+ Version: 1.37.4
4
4
  Summary: A modeling and simulation tool for cardiac cellular electrophysiology
5
5
  Home-page: http://myokit.org
6
6
  Author: Michael Clerx
@@ -123,7 +123,7 @@ A high-level plan for Myokit's future is provided in the [roadmap](./ROADMAP.md)
123
123
  ### Meet the team!
124
124
 
125
125
  Myokit's development is driven by a [team](https://github.com/orgs/myokit/people) at the Universities of Nottingham, Oxford, and Macao, led by Michael Clerx (Nottingham).
126
- It is guided by an external advisory board composed of Jordi Heijman (Maastricht University), Trine Krogh-Madsen (Weill Cornell Medicine), and David Gavaghan (Oxford).
126
+ It is guided by an external advisory group composed of Jordi Heijman (Maastricht University), Trine Krogh-Madsen (Weill Cornell Medicine), and David Gavaghan (Oxford).
127
127
 
128
128
 
129
129
  ## Citing Myokit
@@ -76,7 +76,7 @@ A high-level plan for Myokit's future is provided in the [roadmap](./ROADMAP.md)
76
76
  ### Meet the team!
77
77
 
78
78
  Myokit's development is driven by a [team](https://github.com/orgs/myokit/people) at the Universities of Nottingham, Oxford, and Macao, led by Michael Clerx (Nottingham).
79
- It is guided by an external advisory board composed of Jordi Heijman (Maastricht University), Trine Krogh-Madsen (Weill Cornell Medicine), and David Gavaghan (Oxford).
79
+ It is guided by an external advisory group composed of Jordi Heijman (Maastricht University), Trine Krogh-Madsen (Weill Cornell Medicine), and David Gavaghan (Oxford).
80
80
 
81
81
 
82
82
  ## Citing Myokit
@@ -14,7 +14,7 @@ __release__ = True
14
14
  # incompatibility
15
15
  # - Changes to revision indicate bugfixes, tiny new features
16
16
  # - There is no significance to odd/even numbers
17
- __version_tuple__ = 1, 37, 2
17
+ __version_tuple__ = 1, 37, 4
18
18
 
19
19
  # String version of the version number
20
20
  __version__ = '.'.join([str(x) for x in __version_tuple__])
@@ -487,56 +487,55 @@ class Unit:
487
487
  return self.__rtruediv__(other)
488
488
 
489
489
  @staticmethod
490
- def register(name, unit, quantifiable=False, output=False):
490
+ def register(name, unit, quantifiable=False,
491
+ preferred_representation=False):
491
492
  """
492
- Registers a unit name with the Unit class. Registered units will be
493
- recognised by the parse() method.
493
+ Registers a unit name with the :class:`Unit` class so that it will be
494
+ recognised when parsing.
494
495
 
495
496
  Arguments:
496
497
 
497
498
  ``name``
498
- The unit name. A variable will be created using this name.
499
+ The unit name. This must be a valid myokit name, i.e.
500
+ ``myokit.check_name(name)`` should not raise any errors.
499
501
  ``unit``
500
502
  A valid unit object
501
503
  ``quantifiable``
502
504
  ``True`` if this unit should be registered with the unit class as a
503
- quantifiable unit. Typically this should only be done for the
504
- unquantified symbol notation of SI or SI derived units. For example
505
- m, g, Hz, N but not meter, kg, hertz or forthnight.
506
- ``output``
507
- ``True`` if this units name should be used to display this unit in.
508
- This should be set for all common units (m, kg, nm, Hz) but not for
509
- more obscure units (furlong, parsec). Having ``output`` set to
510
- ``False`` will cause one-way behavior: Myokit will recognise the
511
- unit name but never use it in output.
512
- Setting this to ``True`` will also register the given name as a
513
- preferred representation format.
514
-
515
- """
516
- if not isinstance(name, str):
517
- raise TypeError('Given name must be a string.')
505
+ _quantifiable_ unit, i.e. a unit that can be preceded by an SI
506
+ prefix such as "m" or "G". Typically this should only be done
507
+ for the unquantified symbol notation of SI or SI derived units. For
508
+ example "m", "g", or "Hz" but not "km", "meter", or "bushel".
509
+ ``preferred_representation``
510
+ Set to ``True`` to also register ``name`` as the preferred
511
+ representation for ``unit``.
512
+
513
+ """
514
+ name = myokit.check_name(name)
518
515
  if not isinstance(unit, Unit):
519
516
  raise TypeError('Given unit must be myokit.Unit')
520
517
  Unit._units[name] = unit
521
518
  if quantifiable:
522
519
  # Overwrite existing entries without warning
523
520
  Unit._quantifiable.add(name)
524
- if output:
521
+ if preferred_representation:
525
522
  # Overwrite existing entries without warning
526
523
  Unit._preferred_representations[unit] = name
527
524
 
528
525
  @staticmethod
529
526
  def register_preferred_representation(rep, unit):
530
527
  """
531
- Registers a preferred representation for the given unit without
532
- registering it as a new type. This method can be used to register
533
- common representations such as "umol/L" and "km/h".
528
+ Sets the preferred representation for the a unit, in terms of already
529
+ defined units.
530
+
531
+ This method can be used to register common representations such as
532
+ "umol/L" and "km/h". The given representation should be parseable by
533
+ Myokit, with the result equalling ``unit``.
534
534
 
535
535
  Arguments:
536
536
 
537
537
  ``rep``
538
- A string, containing the preferred name for this unit. This should
539
- be something that Myokit can parse.
538
+ A string containing the preferred representation for this unit.
540
539
  ``unit``
541
540
  The unit to register a notation for.
542
541
 
@@ -545,9 +544,14 @@ class Unit:
545
544
  # Overwrite existing entries without warning
546
545
  if not isinstance(unit, myokit.Unit):
547
546
  raise ValueError(
548
- 'Second argument to register_preferred_representation must be'
549
- ' a myokit.Unit')
550
- Unit._preferred_representations[unit] = str(rep)
547
+ 'The second argument to register_preferred_representation must'
548
+ ' be a myokit.Unit')
549
+ rep = str(rep)
550
+ if not myokit.parse_unit(rep) == unit:
551
+ raise ValueError(
552
+ f'The representation [{rep}] does not equal {unit._str(True)}'
553
+ ' when parsed.')
554
+ Unit._preferred_representations[unit] = rep
551
555
 
552
556
  def __repr__(self):
553
557
  """
@@ -616,7 +620,8 @@ class Unit:
616
620
 
617
621
  def __str__(self):
618
622
 
619
- # Strategy 1: Try simple look-up (using float.eq comparison)
623
+ # Strategy 1: Try simple look-up (using hash based on _str() followed
624
+ # by check of exponents in __eq__ for comparison
620
625
  try:
621
626
  return '[' + Unit._preferred_representations[self] + ']'
622
627
  except KeyError:
@@ -629,8 +634,8 @@ class Unit:
629
634
  rep = '[' + test + ']'
630
635
  break
631
636
 
632
- # Strategy 3: Try finding a representation for the exponent and adding
633
- # a multiplier to that.
637
+ # Strategy 3: Try finding a representation for the exponent (without a
638
+ # multiplier) and adding a multiplier to that.
634
639
  if rep is None:
635
640
 
636
641
  # Because kilos are defined with a multiplier of 1000, the
@@ -640,17 +645,20 @@ class Unit:
640
645
  u = Unit(list(self._x), m)
641
646
  rep = Unit._preferred_representations.get(u, None)
642
647
 
643
- # Add multiplier part
648
+ # Add multiplier part:
644
649
  if rep is not None:
645
- m = myokit.float.cround(self._m - m)
646
- m = 10**m
647
- if m >= 1:
648
- m = myokit.float.cround(m)
649
- if m < 1e6:
650
- m = str(m)
650
+ if '(' in rep:
651
+ rep = None
651
652
  else:
652
- m = '{:<1.0e}'.format(m)
653
- rep = '[' + rep + ' (' + m + ')]'
653
+ m = myokit.float.cround(self._m - m)
654
+ m = 10**m
655
+ if m >= 1:
656
+ m = myokit.float.cround(m)
657
+ if m < 1e6:
658
+ m = str(m)
659
+ else:
660
+ m = '{:<1.0e}'.format(m)
661
+ rep = '[' + rep + ' (' + m + ')]'
654
662
 
655
663
  # Strategy 4: Build a new representation
656
664
  if rep is None:
@@ -3,8 +3,6 @@
3
3
  #
4
4
  # Specifically, it targets the 2x90.2 format.
5
5
  #
6
- # It has not been extensively tested.
7
- #
8
6
  # Notes:
9
7
  # - HEKA publishes a lot of information about its file format on its FTP
10
8
  # server: server.hekahome.de
@@ -25,6 +23,8 @@
25
23
  # numbers of steps are given; the manual mentions two types of log
26
24
  # interpretation but there is no obvious field to select one; a "toggle"
27
25
  # mode is mentioned in the manual but again is not easy to find in the file.
26
+ # - Series resistance prediction percentage is not stored in the Patchmaster
27
+ # file.
28
28
  #
29
29
  # This file is part of Myokit.
30
30
  # See http://myokit.org for copyright, sharing, and licensing details.
@@ -236,6 +236,9 @@ class PatchMasterFile:
236
236
  def __iter__(self):
237
237
  return iter(self._pulsed_tree)
238
238
 
239
+ def __len__(self):
240
+ return len(self._pulsed_tree)
241
+
239
242
  def amplifier_tree(self):
240
243
  """
241
244
  Returns this file's amplifier tree (an :class:`AmplifierFile` object),
@@ -626,7 +629,7 @@ class Series(TreeNode, myokit.formats.SweepSource):
626
629
  1. In the individual :class:`Trace` objects. This is somewhat
627
630
  counter-intuitive as some of these properties (e.g.
628
631
  :meth:Trace.r_pipette()`) were set before a series was
629
- acquired and do no change between channels or sweeps.
632
+ acquired and do not change between channels or sweeps.
630
633
  2. In the series' :class:`AmplifierState`, which can be accessed via
631
634
  the :meth:`amplifier_state()` method.
632
635
 
@@ -984,6 +987,8 @@ class Series(TreeNode, myokit.formats.SweepSource):
984
987
  log.meta[f'{pre}current_gain_mV_per_pA'] = a.current_gain()
985
988
  log.meta[f'{pre}filter1'] = a.filter1_str()
986
989
  log.meta[f'{pre}filter2'] = a.filter2_str()
990
+ log.meta[f'{pre}filter1_kHz'] = a.filter1().frequency()
991
+ log.meta[f'{pre}filter2_kHz'] = a.filter2()[2]
987
992
  log.meta[f'{pre}stimulus_filter'] = a.stimulus_filter_str()
988
993
  log.meta[f'{pre}ljp_correction_mV'] = a.ljp()
989
994
  log.meta[f'{pre}voltage_offset_mV'] = a.v_off()
@@ -991,6 +996,10 @@ class Series(TreeNode, myokit.formats.SweepSource):
991
996
  if a.c_fast_enabled():
992
997
  log.meta[f'{pre}c_fast_compensation_enabled'] = 'true'
993
998
  log.meta[f'{pre}c_fast_pF'] = a.c_fast()
999
+ cf = a.c_fast_detailed()
1000
+ log.meta[f'{pre}c_fast_amp1_pF'] = cf[0]
1001
+ log.meta[f'{pre}c_fast_amp2_pF'] = cf[1]
1002
+ log.meta[f'{pre}c_fast_tau2_us'] = cf[2]
994
1003
  else:
995
1004
  log.meta[f'{pre}c_fast_compensation_enabled'] = 'false'
996
1005
  log.meta[f'{pre}c_slow_pF'] = a.c_slow()
@@ -1080,6 +1089,9 @@ class Series(TreeNode, myokit.formats.SweepSource):
1080
1089
  # C fast
1081
1090
  if a.c_fast_enabled():
1082
1091
  out.append(f' C fast compensation: {a.c_fast()} pF,')
1092
+ cf = a.c_fast_detailed()
1093
+ out.append(f' C fast (amp1, amp2, tau2): {cf[0]} pF, {cf[1]}'
1094
+ f' pF, {cf[2]} us')
1083
1095
  else:
1084
1096
  out.append(' C fast compensation: not enabled')
1085
1097
  # C slow
@@ -1635,6 +1647,17 @@ class Trace(TreeNode):
1635
1647
  class AmplifierState:
1636
1648
  """
1637
1649
  Describes the state of an amplifier used by PatchMaster.
1650
+
1651
+ This "state" contains lots of valuable meta data about the fast and slow
1652
+ capacitance correction, the series resistance compensation (but not
1653
+ prediction! see below), the filtering, the gain, and voltage offset
1654
+ corrections (zeroing and online LJP).
1655
+
1656
+ A notable omission is information about the series compensation
1657
+ _prediction_ feature. This should have an on/off statement, and a
1658
+ percentage (which can be set separately from the _correction_ percentage in
1659
+ Patchmaster). Unfortunately this is not stored in the format yet (20 feb
1660
+ 2025).
1638
1661
  """
1639
1662
  def __init__(self, handle, reader):
1640
1663
 
@@ -1663,6 +1686,10 @@ class AmplifierState:
1663
1686
  handle.seek(i + 304) # sRsTau = 304; (* LONGREAL *)
1664
1687
  self._rs_tau = reader.read1('d')
1665
1688
 
1689
+ # Prediction is not recorded!
1690
+ self._rs_prediction = PredictionSetting.UNKNOWN if self._rs_enabled \
1691
+ else PredictionSetting.OFF
1692
+
1666
1693
  # Fast capacitance correction
1667
1694
  handle.seek(i + 56) # sCFastAmp1 = 56; (* LONGREAL *)
1668
1695
  self._cf_amp1 = reader.read1('d')
@@ -1697,10 +1724,13 @@ class AmplifierState:
1697
1724
  # 2 is the combined bandwidth of Filter 1 and Filter 2.
1698
1725
  handle.seek(i + 239) # sF2Response = 239; (* BYTE *)
1699
1726
  self._filter2_type = Filter2Type(reader.read1('b'))
1700
- handle.seek(i + 24) # sF2Frequency = 24; (* LONGREAL *)
1701
- self._filter2_freq_solo = reader.read1('d')
1727
+ if self._filter2_type is Filter2Type.BYPASS:
1728
+ self._filter2_freq_solo = 0
1729
+ else:
1730
+ handle.seek(i + 24) # sF2Frequency = 24; (* LONGREAL *)
1731
+ self._filter2_freq_solo = reader.read1('d') * 1e-3
1702
1732
  handle.seek(i + 16) # sF2Bandwidth = 16; (* LONGREAL *)
1703
- self._filter2_freq_both = reader.read1('d')
1733
+ self._filter2_freq_both = reader.read1('d') * 1e-3
1704
1734
 
1705
1735
  # Suspect this indicates external filter 2
1706
1736
  #handle.seek(i + 287) # sF2Source = 287; (* BYTE *)
@@ -1818,11 +1848,13 @@ class AmplifierState:
1818
1848
  """
1819
1849
  Returns a tuple ``(type, f_both, f_solo)`` describing the Filter 2
1820
1850
  settings, where ``type`` is a :class:`Filter2Type`, where ``f_both`` is
1821
- the frequency in Hz of both filters combined, and when ``f_solo`` is
1822
- the frequency of Filter 2 alone.
1851
+ the frequency in kHz of both filters combined, and when ``f_solo`` is
1852
+ the frequency in kHz of Filter 2 alone.
1823
1853
 
1824
1854
  The frequency shown in PatchMaster is that of both filters combined.
1825
1855
  If the "bypass" filter is selected, the frequency settings are unused.
1856
+ In this case, ``f_both`` will be the frequency of filter 1 and
1857
+ ``f_solo`` will be returned as 0.
1826
1858
 
1827
1859
  For more information on Filter 1 and 2, see :class:`Filter1Setting`.
1828
1860
  """
@@ -1840,8 +1872,8 @@ class AmplifierState:
1840
1872
  """
1841
1873
  if self._filter2_type is Filter2Type.BYPASS:
1842
1874
  return str(self._filter2_type)
1843
- fb = round(self._filter2_freq_both * 1e-3, 2)
1844
- fs = round(self._filter2_freq_solo * 1e-3, 2)
1875
+ fb = round(self._filter2_freq_both, 2)
1876
+ fs = round(self._filter2_freq_solo, 2)
1845
1877
  fb = int(fb) if fb == int(fb) else fb
1846
1878
  return f'{self._filter2_type} {fb} kHz combined, {fs} kHz f2-only'
1847
1879
 
@@ -1889,6 +1921,19 @@ class AmplifierState:
1889
1921
  """
1890
1922
  return self._rs_tau * 1e6 if self._rs_enabled else 0
1891
1923
 
1924
+ def r_series_prediction(self):
1925
+ """
1926
+ The percentage "prediction" is not recorded in the file: this method
1927
+ returns ``PredictionSetting.OFF`` if compensation (and therefore
1928
+ prediction) was disabled, and ``UNKNOWN`` if compensation was enabled
1929
+ (so prediction may have been active).
1930
+
1931
+ This serves as a placeholder in case future changes to the format
1932
+ incorporate it, and as a place to document that this feature is missing
1933
+ by design.
1934
+ """
1935
+ return self._rs_prediction
1936
+
1892
1937
  def stimulus_filter(self):
1893
1938
  """
1894
1939
  Returns a :class:`StimulusFilterSetting` descibing the stimulus filter
@@ -1949,6 +1994,17 @@ class Filter1Setting(enum.Enum):
1949
1994
  else:
1950
1995
  return 'HQ 30 kHz'
1951
1996
 
1997
+ def frequency(self):
1998
+ """ Returns the cut-off frequency for this filter setting, in kHz. """
1999
+ if self is Filter1Setting.BESSEL_100K:
2000
+ return 100
2001
+ elif self is Filter1Setting.BESSEL_30K:
2002
+ return 30
2003
+ elif self is Filter1Setting.BESSEL_10K:
2004
+ return 10
2005
+ else:
2006
+ return 30
2007
+
1952
2008
 
1953
2009
  class Filter2Type(enum.Enum):
1954
2010
  """
@@ -2020,6 +2076,24 @@ class StimulusFilterSetting(enum.Enum):
2020
2076
  return 'Bessel 20 us (on)'
2021
2077
 
2022
2078
 
2079
+ class PredictionSetting(enum.Enum):
2080
+ """
2081
+ Very limited information about the series resistance compensation
2082
+ prediction.
2083
+
2084
+ Series resistance compensation includes a "prediction" pathway,
2085
+ configurable via a percentage prediction in Patchmaster. Unfortunately this
2086
+ is not stored in the file format, so that knowledge of this parameters is
2087
+ limited to "off" (when series resistance compensation is disabled) or
2088
+ "unknown" (when series resistance compensation is enabled).
2089
+ """
2090
+ OFF = 0
2091
+ UNKNOWN = 1
2092
+
2093
+ def __str__(self):
2094
+ return 'Off' if self is PredictionSetting.OFF else 'Unknown'
2095
+
2096
+
2023
2097
  #
2024
2098
  # From StimFile_v9.txt
2025
2099
  # (* RootRecord = RECORD *)
@@ -313,15 +313,18 @@ class Model:
313
313
  variable.uname(),
314
314
  variable.is_constant(),
315
315
  )
316
- if variable.is_state() or variable.is_literal():
317
- v.set_value(variable.rhs(), variable.is_state())
318
- else:
319
- # if variable is constant but not literal,
320
- # set via initial value
321
- v.set_initial_value(variable.rhs())
322
316
 
323
- if variable.is_state():
324
- v.set_initial_value(variable.initial_value())
317
+ if variable.is_constant():
318
+ if variable.is_literal():
319
+ v.set_value(variable.rhs())
320
+ else:
321
+ v.set_initial_value(variable.rhs())
322
+ else:
323
+ if variable.is_state():
324
+ v.set_initial_value(variable.initial_value())
325
+ v.set_value(variable.rhs(), True)
326
+ else:
327
+ v.set_value(variable.rhs())
325
328
 
326
329
  unit = variable_unit(variable, time_unit)
327
330
  if unit is not None:
@@ -63,8 +63,8 @@ SETTINGS_FILE = os.path.join(myokit.DIR_USER, 'DataLogViewer.ini')
63
63
  # About
64
64
  ABOUT = '<h1>' + TITLE + '</h1>' + """
65
65
  <p>
66
- The DataLog viewer is a PROTOTYPE utility to examine time series data.
67
- At the moment, exclusively WinWCP, ABF and CSV files.
66
+ The DataLog viewer is a PROTOTYPE utility to examine time series data in
67
+ formats supported by Myokit.
68
68
  </p>
69
69
  <p>
70
70
  System info:
@@ -162,6 +162,8 @@ class DataLogViewer(myokit.gui.MyokitApplication):
162
162
  self._tool_next_file.setEnabled(True)
163
163
  self._tool_prev_file.setEnabled(True)
164
164
  self._tabs.setCurrentIndex(0)
165
+ self._tool_close.setEnabled(True)
166
+ self._tool_close_all.setEnabled(True)
165
167
 
166
168
  def action_about(self):
167
169
  """
@@ -178,15 +180,48 @@ class DataLogViewer(myokit.gui.MyokitApplication):
178
180
  self._tabs.removeTab(index)
179
181
 
180
182
  # Update buttons
181
- if self._tabs.count() < 2:
183
+ n = self._tabs.count()
184
+ if n < 2:
182
185
  self._tool_next_file.setEnabled(False)
183
186
  self._tool_prev_file.setEnabled(False)
187
+ if n < 1:
188
+ self._tool_close.setEnabled(False)
189
+ self._tool_close_all.setEnabled(False)
184
190
 
185
191
  # Delete tab
186
192
  if tab is not None:
187
193
  tab.deleteLater()
188
- gc.collect()
189
194
  del tab
195
+ gc.collect()
196
+
197
+ def action_close_current(self):
198
+ """ Close the current tab. """
199
+ idx = self._tabs.currentIndex()
200
+ if idx >= 0:
201
+ self.action_close(idx)
202
+
203
+ def action_close_all(self):
204
+ """ Called to close all tabs. """
205
+ n = self._tabs.count()
206
+ if n < 1:
207
+ return
208
+
209
+ # Get all tabs, to delete later
210
+ tabs = [self._tabs.widget(i) for i in range(n)]
211
+ # Remove all tabs, without deleting
212
+ self._tabs.clear()
213
+
214
+ # Update buttons
215
+ self._tool_close.setEnabled(False)
216
+ self._tool_close_all.setEnabled(False)
217
+ self._tool_next_file.setEnabled(False)
218
+ self._tool_prev_file.setEnabled(False)
219
+
220
+ # Delete tabs
221
+ for tab in tabs:
222
+ tab.deleteLater()
223
+ del tab, tabs
224
+ gc.collect()
190
225
 
191
226
  def action_first_var(self):
192
227
  """ Select the first variable in the current file. """
@@ -225,6 +260,10 @@ class DataLogViewer(myokit.gui.MyokitApplication):
225
260
  if tab_count_new > tab_count:
226
261
  self._tabs.setCurrentIndex(tab_count)
227
262
 
263
+ # Enable tab closing buttons
264
+ self._tool_close.setEnabled(True)
265
+ self._tool_close_all.setEnabled(True)
266
+
228
267
  # Enable next/previous file menu items
229
268
  if tab_count_new > 1:
230
269
  self._tool_next_file.setEnabled(True)
@@ -285,6 +324,21 @@ class DataLogViewer(myokit.gui.MyokitApplication):
285
324
  self._tool_open.setIcon(QtGui.QIcon.fromTheme('document-open'))
286
325
  self._tool_open.triggered.connect(self.action_open)
287
326
  self._menu_file.addAction(self._tool_open)
327
+ # File > Close
328
+ self._tool_close = QtGui.QAction('&Close tab', self)
329
+ self._tool_close.setShortcut('Ctrl+W')
330
+ self._tool_close.setStatusTip('Close the current tab')
331
+ self._tool_close.setIcon(QtGui.QIcon.fromTheme('document-close'))
332
+ self._tool_close.triggered.connect(self.action_close_current)
333
+ self._tool_close.setEnabled(False)
334
+ self._menu_file.addAction(self._tool_close)
335
+ # File > Close all
336
+ self._tool_close_all = QtGui.QAction('Close &all tabs', self)
337
+ self._tool_close_all.setStatusTip('Close all tabs')
338
+ self._tool_close_all.setIcon(QtGui.QIcon.fromTheme('document-close'))
339
+ self._tool_close_all.triggered.connect(self.action_close_all)
340
+ self._tool_close_all.setEnabled(False)
341
+ self._menu_file.addAction(self._tool_close_all)
288
342
  # File > ----
289
343
  self._menu_file.addSeparator()
290
344
  # File > Quit
@@ -401,9 +455,7 @@ class DataLogViewer(myokit.gui.MyokitApplication):
401
455
  self._path = path
402
456
 
403
457
  def load_file(self, filename):
404
- """
405
- Loads a data file.
406
- """
458
+ """ Loads a data file. """
407
459
  root, ext = os.path.splitext(os.path.basename(filename))
408
460
  try:
409
461
  action = self._load_actions[ext.lower()]
@@ -700,7 +752,8 @@ class SweepSourceTab(GraphTabWidget):
700
752
  widget.setLayout(vbox)
701
753
 
702
754
  # Add tab
703
- self.addTab(widget, name)
755
+ adda = 'D/A' if da else 'A/D'
756
+ self.addTab(widget, f'{adda}: {name}')
704
757
 
705
758
  '''
706
759
  def debug_tab(self, channel_index, da=True):
@@ -107,10 +107,10 @@ class QuantityTest(unittest.TestCase):
107
107
  # Test has does not change in quantity's lifetime
108
108
 
109
109
  try:
110
- u = myokit.units.m**8
110
+ u = myokit.units.m / myokit.units.mol
111
111
  q1 = myokit.Quantity(1, u)
112
112
  h1 = hash(q1)
113
- myokit.Unit.register_preferred_representation('abc', u)
113
+ myokit.Unit.register_preferred_representation('km/kmol', u)
114
114
  q2 = myokit.Quantity(1, u)
115
115
  h2 = hash(q2)
116
116
  self.assertEqual(h1, h2)
@@ -170,6 +170,7 @@ class TestSBMLExport(unittest.TestCase):
170
170
  self.assertIn("<listOfUnitDefinitions>", sbml_str)
171
171
  self.assertIn('<unitDefinition id="m_per_s_times_1e3">', sbml_str)
172
172
 
173
+ def test_list_of_parameters_const_depend(self):
173
174
  # Test setting a constant parameter that depends on another parameter
174
175
  model = Model()
175
176
  p = model.add_parameter("my_parameter")
@@ -193,6 +194,7 @@ class TestSBMLExport(unittest.TestCase):
193
194
  self.assertIn('<initialAssignment symbol="my_parameter2">', sbml_str)
194
195
  self.assertIn("<times/>\n <ci>my_parameter</ci>\n <cn>2.0</cn>", sbml_str) # noqa: E501
195
196
 
197
+ def test_list_of_parameters_var(self):
196
198
  model = Model()
197
199
  p = model.add_parameter("my_parameter", is_constant=False)
198
200
  p.set_initial_value(myokit.Number(1))
@@ -325,3 +327,22 @@ class TestSBMLExport(unittest.TestCase):
325
327
  sbml_str
326
328
  )
327
329
 
330
+ def test_variable_dependent_variables(self):
331
+ m = myokit.Model()
332
+ c = m.add_component('comp')
333
+ t = c.add_variable('time', rhs=myokit.Number(0))
334
+ t.set_unit(myokit.units.second)
335
+ t.set_binding('time')
336
+ v = c.add_variable('var', initial_value=3)
337
+ v.set_rhs(myokit.Number(1))
338
+ v2 = c.add_variable('var2')
339
+ v2.set_rhs(myokit.Name(v))
340
+
341
+ s = sbml.Model.from_myokit_model(m)
342
+ self.assertEqual(s.parameter('var2').is_rate(), False)
343
+ self.assertEqual(s.parameter('var').is_rate(), True)
344
+
345
+ sbml_str = write_string(s).decode("utf8")
346
+ self.assertIn('<initialAssignment symbol="var">', sbml_str)
347
+ self.assertNotIn('<initialAssignment symbol="var2">', sbml_str)
348
+ self.assertIn('<assignmentRule variable="var2">', sbml_str)
@@ -296,24 +296,35 @@ class MyokitUnitTest(unittest.TestCase):
296
296
  self.assertEqual(x.exponents(), [0, 2, 1.5, 0, 0, 0, -1.23])
297
297
 
298
298
  def test_register_errors(self):
299
- # Test errors for Unit.register (rest is already used a lot).
300
- self.assertRaises(TypeError, myokit.Unit.register, 4, myokit.Unit())
299
+ # Test errors for Unit.register (rest of the method is already used
300
+ # throughout other tests).
301
+ self.assertRaises(myokit.InvalidNameError, myokit.Unit.register, 4,
302
+ myokit.Unit())
301
303
  self.assertRaises(TypeError, myokit.Unit.register, 'hi', 4)
302
304
 
303
305
  def test_register_preferred_representation(self):
304
306
  # Test new representations can be registered
305
307
 
306
- u = myokit.units.m**8
307
- self.assertEqual(str(u), '[m^8]')
308
+ u = myokit.units.K / myokit.units.A
308
309
  try:
309
- myokit.Unit.register_preferred_representation(
310
- 'abc', myokit.units.m**8)
311
- self.assertEqual(str(u), '[abc]')
310
+ # Register valid unit
311
+ self.assertEqual(str(u), '[K/A]') # also auto registers!
312
+ myokit.Unit.register_preferred_representation('mK/mA', u)
313
+ self.assertEqual(str(u), '[mK/mA]')
312
314
 
315
+ # Attempt registering something that isn't a unit
313
316
  self.assertRaisesRegex(
314
317
  ValueError, 'must be a myokit.Unit',
315
318
  myokit.Unit.register_preferred_representation, 'x', 123)
316
319
 
320
+ # Attempt registering a representation that doesn't match the unit
321
+ self.assertRaisesRegex(
322
+ ValueError, r'does not equal \[K/A] when parsed',
323
+ myokit.Unit.register_preferred_representation, 'm', u)
324
+ self.assertRaisesRegex(
325
+ ValueError, r'does not equal \[K/A \(2\)] when parsed',
326
+ myokit.Unit.register_preferred_representation, 'K/A', u * 2)
327
+
317
328
  finally:
318
329
  # Bypassing the public API, this is bad test design!
319
330
  if u in myokit.Unit._preferred_representations:
@@ -365,6 +376,16 @@ class MyokitUnitTest(unittest.TestCase):
365
376
  self.assertEqual(str(c), '[V]')
366
377
  self.assertEqual(str(d), '[V]')
367
378
 
379
+ # 1115: Test str() doesn't create representations with more than one
380
+ # multiplier.
381
+ unit1 = myokit.units.mol / (1e3 * myokit.units.g)
382
+ unit2 = 1e-12 * myokit.units.mol / (1e3 * myokit.units.g)
383
+ unit3 = 1e-6 * unit2
384
+ self.assertEqual(str(unit1), '[mol/g (0.001)]')
385
+ self.assertEqual(str(unit2), '[mol/g (1e-15)]')
386
+ # Before fixing 1115, this returned [mol/g (0.001) (1e-12)]
387
+ self.assertEqual(str(unit3), '[mol/g (1e-21)]')
388
+
368
389
  def test_repr(self):
369
390
  # Test :meth:`Unit.repr()`.
370
391
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: myokit
3
- Version: 1.37.2
3
+ Version: 1.37.4
4
4
  Summary: A modeling and simulation tool for cardiac cellular electrophysiology
5
5
  Home-page: http://myokit.org
6
6
  Author: Michael Clerx
@@ -123,7 +123,7 @@ A high-level plan for Myokit's future is provided in the [roadmap](./ROADMAP.md)
123
123
  ### Meet the team!
124
124
 
125
125
  Myokit's development is driven by a [team](https://github.com/orgs/myokit/people) at the Universities of Nottingham, Oxford, and Macao, led by Michael Clerx (Nottingham).
126
- It is guided by an external advisory board composed of Jordi Heijman (Maastricht University), Trine Krogh-Madsen (Weill Cornell Medicine), and David Gavaghan (Oxford).
126
+ It is guided by an external advisory group composed of Jordi Heijman (Maastricht University), Trine Krogh-Madsen (Weill Cornell Medicine), and David Gavaghan (Oxford).
127
127
 
128
128
 
129
129
  ## Citing Myokit