def test_progress_printer(self): """ Test basic functionality. """ # Zero call with myokit.PyCapture() as c: p = myokit.ProgressPrinter() self.assertTrue(p.update(0)) pattern1 = re.compile( '\[[0-9]{1}\.[0-9]{1} minutes\] [0-9]+(.[0-9])? % done') lines = c.text().splitlines() self.assertTrue(len(lines) > 0) for line in lines: self.assertTrue(pattern1.match(line)) # Normal call with myokit.PyCapture() as c: p = myokit.ProgressPrinter() self.assertTrue(p.update(0.49)) pattern2 = re.compile( '\[[0-9]{1}\.[0-9]{1} minutes] [0-9]+(.[0-9])? % done,' ' estimated [0-9]{1} seconds remaining') lines = c.text().splitlines() self.assertTrue(len(lines) > 0) for line in lines: self.assertTrue(pattern2.match(line)) # Call that will take minutes with myokit.PyCapture() as c: p = myokit.ProgressPrinter() time.sleep(0.1) self.assertTrue(p.update(1e-3)) self.assertIn('minutes remaining', c.text()) # Note: Printer must be created withing PyCapture, otherwise it will # print to stdout (which won't have been redirected yet). # Status every ten percent with myokit.PyCapture() as c: p = myokit.ProgressPrinter(digits=-1) self.assertTrue(p.update(0)) self.assertTrue(p.update(0.08)) self.assertTrue(p.update(0.18)) self.assertTrue(p.update(0.19)) self.assertTrue(p.update(0.199)) self.assertTrue(p.update(1)) lines = c.text().splitlines() self.assertTrue(len(lines), 3) self.assertTrue(pattern1.match(lines[0])) self.assertTrue(pattern2.match(lines[1])) self.assertTrue(pattern2.match(lines[2]))
def test_system_info(self): import matplotlib matplotlib.use('template') self.assertIsInstance(myokit.system(), basestring) with myokit.PyCapture(): myokit.system(live_printing=True)
def test_progress_reporter(self): # Test running with a progress reporter. # Test if it works sim = myokit.Simulation(self.model, self.protocol) with myokit.PyCapture() as c: sim.run(110, progress=myokit.ProgressPrinter()) c = c.text().splitlines() self.assertEqual(len(c), 2) p = re.compile( re.escape('[0.0 minutes] 1.9 % done, estimated ') + '[0-9]+' + re.escape(' seconds remaining')) self.assertIsNotNone(p.match(c[0])) p = re.compile( re.escape('[0.0 minutes] 100.0 % done, estimated ') + '[0-9]+' + re.escape(' seconds remaining')) self.assertIsNotNone(p.match(c[1])) # Not a progress reporter self.assertRaisesRegex(ValueError, 'ProgressReporter', self.sim.run, 5, progress=12) # Cancel from reporter self.assertRaises(myokit.SimulationCancelledError, self.sim.run, 1, progress=CancellingReporter(0))
def test_run(self): # Test run() method. m, p, _ = myokit.load('example') x = '\n'.join([ 'import myokit', 'm = get_model()', # Test magic methods 'p = get_protocol()', 's = myokit.Simulation(m, p)', 's.run(200)', ]) with myokit.PyCapture(): myokit.run(m, p, x) with myokit.PyCapture(): myokit.run(m, p, '[[script]]\n' + x) self.assertRaises(ZeroDivisionError, myokit.run, m, p, 'print(1 / 0)') # Test with stringio x = "print('Hi there')" s = StringIO() with myokit.PyCapture() as c: myokit.run(m, p, x, stderr=s, stdout=s) self.assertEqual(c.text(), '') self.assertEqual(s.getvalue(), 'Hi there\n')
def test_py_capture(self): # Test the PyCapture method. # Test basic use with myokit.PyCapture() as c: print('Hello') self.assertEqual(c.text(), 'Hello\n') sys.stdout.write('Test') self.assertEqual(c.text(), 'Hello\nTest') # Test wrapping with myokit.PyCapture() as c: print('Hello') self.assertEqual(c.text(), 'Hello\n') with myokit.PyCapture() as d: print('Yes') self.assertEqual(d.text(), 'Yes\n') sys.stdout.write('Test') self.assertEqual(c.text(), 'Hello\nTest') # Test disabling / enabling with myokit.PyCapture() as c: print('Hello') self.assertEqual(c.text(), 'Hello\n') with myokit.PyCapture() as d: sys.stdout.write('Yes') d.disable() print('Hmmm') d.enable() print('No') self.assertEqual(d.text(), 'YesNo\n') sys.stdout.write('Test') self.assertEqual(c.text(), 'Hello\nHmmm\nTest') # Test clear() method with myokit.PyCapture() as c: print('Hi') self.assertEqual(c.text(), 'Hi\n') print('Ho') self.assertEqual(c.text(), 'Hi\nHo\n') c.clear() print('Ha') self.assertEqual(c.text(), 'Ha\n') # Bug: Test clear method _without_ calling text() before clear() with myokit.PyCapture() as c: print('Hi') print('Ho') c.clear() print('Ha') self.assertEqual(c.text(), 'Ha\n')
def test_with_progress_reporter(self): # Test running with a progress reporter. m, p, _ = myokit.load(os.path.join(DIR_DATA, 'lr-1991.mmt')) # Test using a progress reporter s = myokit.Simulation1d(m, p, ncells=5) s.set_step_size(0.05) with myokit.PyCapture() as c: s.run(110, progress=myokit.ProgressPrinter()) c = c.text().splitlines() self.assertTrue(len(c) > 0) # Not a progress reporter self.assertRaisesRegex( ValueError, 'ProgressReporter', s.run, 5, progress=12) # Cancel from reporter self.assertRaises( myokit.SimulationCancelledError, s.run, 1, progress=CancellingReporter(0))
def run_simple(self): # Load models mf = os.path.join(myotest.DIR_DATA, 'dn-1985-normalised.mmt') mt = os.path.join(myotest.DIR_DATA, 'lr-1991.mmt') mf = myokit.load_model(mf) mt = myokit.load_model(mt) # Run times run = .1 # Create pacing protocol p = myokit.pacing.blocktrain(1000, 2.0, offset=.01) # Fiber/Tissue sizes nfx = 8 nfy = 4 ntx = 8 nty = 8 # Create simulation s = myokit.FiberTissueSimulation(mf, mt, p, ncells_fiber=(nfx, nfy), ncells_tissue=(ntx, nty), nx_paced=10, g_fiber=(235, 100), g_tissue=(9, 5), g_fiber_tissue=9) s.set_step_size(0.0012) # Set up logging logf = [ 'engine.time', 'membrane.V', 'isi.isiCa', ] logt = [ 'membrane.V', 'ica.Ca_i', 'ica.ICa', ] # Run simulation with myokit.PyCapture(): logf, logt = s.run(run, logf=logf, logt=logt, log_interval=0.01)
def test_process_errors(self): """ Test error handling in the ``process`` method. """ # Process method takes a dict e = myokit.pype.TemplateEngine() self.assertRaisesRegex(ValueError, 'dict', e.process, 'file.txt', []) with myokit.PyCapture(): # Test not-a-file self.assertRaises(IOError, e.process, 'file.txt', {}) # Test simple error self.e("""<?print(1/0) ?>""", {}, 'ZeroDivisionError') # Test closing without opening self.e("""Hello ?>""", {}, 'without opening tag') # Opening without closing is allowed self.e("""<?print('hi')""", {}) # Nested opening self.e( """<?print('hi')<?print('hello')?>""", {}, 'Nested opening tag', ) # Too much inside <?=?> self.e("""<?=if 1 > 2: print('hi')?>""", {}, 'contain a single') # Triple quote should be allowed self.e('''Hello"""string"""yes''', {}) # OSError from inside pype self.e("""Hello<?open('file.txt', 'r')?>yes""", {}, 'No such file')
def test_model_comparison(self): # Test the model comparison class. m1 = os.path.join(DIR_DATA, 'beeler-1977-model.mmt') m2 = os.path.join(DIR_DATA, 'beeler-1977-model-different.mmt') m1 = myokit.load_model(m1) m2 = myokit.load_model(m2) with myokit.PyCapture() as capture: c = myokit.ModelComparison(m1, m2, live=True) differences = [ '[x] Mismatched Meta property in model: "desc"', '[x] Mismatched Meta property in model: "name"', '[2] Missing Meta property in model: "author"', '[1] Missing Meta property in model: "extra"', '[x] Mismatched User function <f(1)>', '[1] Missing User function <g(1)>.', '[x] Mismatched Time variable: [1]<engine.time> [2]<engine.toim>', '[x] Mismatched Initial value for <ina.h>', '[x] Mismatched State at position 5: [1]<isi.d> [2]<isiz.d>', '[x] Mismatched State at position 6: [1]<isi.f> [2]<isiz.f>', '[2] Missing state at position 7', '[x] Mismatched RHS <calcium.Cai>', '[2] Missing Variable <engine.time>', '[1] Missing Variable <engine.toim>', '[x] Mismatched RHS <ina.h.alpha>', '[x] Mismatched RHS <ina.j>', '[2] Missing Variable <ina.j.beta>', '[1] Missing Variable <ina.j.jeta>', '[2] Missing Component <isi>', '[x] Mismatched LHS <ix1.x1>', '[x] Mismatched RHS <ix1.x1>', '[2] Missing Variable <ix1.x1.alpha>', '[2] Missing Variable <ix1.x1.beta>', '[x] Mismatched RHS <membrane.C>', '[x] Mismatched RHS <membrane.i_ion>', '[x] Mismatched unit <membrane.V>', '[1] Missing Component <isiz>', ] live = [ 'Comparing:', ' [1] beeler-1977', ' [2] beeler-1977-with-differences', ] + differences + [ 'Done', ' ' + str(len(differences)) + ' differences found', ] # Show massive diff messages self.maxDiff = None caught_differences = set(capture.text().splitlines()) live = set(live) self.assertEqual(live, caught_differences) differences = set(differences) caught_differences = set(c.text().splitlines()) self.assertEqual(differences, caught_differences) # Test equality method self.assertFalse(c.equal()) self.assertTrue(myokit.ModelComparison(m1, m1).equal()) self.assertTrue(myokit.ModelComparison(m2, m2).equal()) # Test len and iterator interface self.assertEqual(len(c), len(differences)) self.assertEqual(len([x for x in c]), len(differences)) # Test reverse is similar d = myokit.ModelComparison(m2, m1) self.assertEqual(len(c), len(d)) # Test detection of missing time variable # Note: user function disappears when cloning m3 = m1.clone() m3.binding('time').set_binding(None) c = myokit.ModelComparison(m1, m3) self.assertEqual( c.text(), '[2] Missing User function <f(1)>\n' '[2] Missing Time variable <engine.time>') self.assertEqual(len(c), 2) self.assertEqual(len(c), len(myokit.ModelComparison(m3, m1)))
def test_against_cvode(self): # Compare the fiber-tissue simulation output with CVODE output # Load model m = myokit.load_model(os.path.join(DIR_DATA, 'lr-1991.mmt')) # Create pacing protocol p = myokit.pacing.blocktrain(1000, 2.0, offset=0) # Create simulation s1 = myokit.FiberTissueSimulation( m, m, p, ncells_fiber=(1, 1), ncells_tissue=(1, 1), nx_paced=1, g_fiber=(0, 0), g_tissue=(0, 0), g_fiber_tissue=0, precision=myokit.DOUBLE_PRECISION, ) s1.set_step_size(0.01) # Set up logging logvars = ['engine.time', 'engine.pace', 'membrane.V', 'ica.ICa'] logt = myokit.LOG_NONE # Run simulation tmax = 100 dlog = 0.1 with myokit.PyCapture(): d1, logt = s1.run(tmax, logf=logvars, logt=logt, log_interval=dlog) del(logt) d1 = d1.npview() # Run CVODE simulation s2 = myokit.Simulation(m, p) s2.set_tolerance(1e-8, 1e-8) d2 = s2.run(tmax, logvars, log_interval=dlog).npview() # Check implementation of logging point selection e0 = np.max(np.abs(d1.time() - d2.time())) # Check implementation of pacing r1 = d1['engine.pace'] - d2['engine.pace'] e1 = np.sum(r1**2) # Check membrane potential (will have some error!) # Using MRMS from Marsh, Ziaratgahi, Spiteri 2012 r2 = d1['membrane.V', 0, 0] - d2['membrane.V'] r2 /= (1 + np.abs(d2['membrane.V'])) e2 = np.sqrt(np.sum(r2**2) / len(r2)) # Check logging of intermediary variables r3 = d1['ica.ICa', 0, 0] - d2['ica.ICa'] r3 /= (1 + np.abs(d2['ica.ICa'])) e3 = np.sqrt(np.sum(r3**2) / len(r3)) if debug: import matplotlib.pyplot as plt print('Event at t=0') print(d1.time()[:7]) print(d2.time()[:7]) print(d1.time()[-7:]) print(d2.time()[-7:]) print(e0) plt.figure() plt.suptitle('Pacing signals') plt.subplot(2, 1, 1) plt.plot(d1.time(), d1['engine.pace'], label='FiberTissue') plt.plot(d2.time(), d2['engine.pace'], label='CVODE') plt.legend() plt.subplot(2, 1, 2) plt.plot(d1.time(), r1) print(e1) plt.figure() plt.suptitle('Membrane potential') plt.subplot(2, 1, 1) plt.plot(d1.time(), d1['membrane.V', 0, 0], label='FiberTissue') plt.plot(d2.time(), d2['membrane.V'], label='CVODE') plt.legend() plt.subplot(2, 1, 2) plt.plot(d1.time(), r2) print(e2) plt.figure() plt.suptitle('Calcium current') plt.subplot(2, 1, 1) plt.plot(d1.time(), d1['ica.ICa', 0, 0], label='FiberTissue') plt.plot(d2.time(), d2['ica.ICa'], label='CVODE') plt.legend() plt.subplot(2, 1, 2) plt.plot(d1.time(), r2) print(e3) plt.show() self.assertLess(e0, 1e-10) self.assertLess(e1, 1e-14) self.assertLess(e2, 0.05) self.assertLess(e3, 0.01)