def test_simulate(self): """Tests whether the simulate method works as expected. Tests implicitly also whether the _set_parameters method works properly. """ # Test Case I: Linear Growth Model # define parameters and times parameters = [1, 2] times = np.arange(25) # expected # init model in myokit model, protocol, _ = myokit.load(self.file_linear_growth_model) # set inital state of model model.set_state([parameters[0]]) # set linear growth constant model.set_value('central_compartment.lambda', parameters[1]) # instantiate and run simulation simulation = myokit.Simulation(model, protocol) myokit_result = simulation.run(duration=times[-1] + 1, log=['central_compartment.drug'], log_times=times) expected_result = myokit_result.get('central_compartment.drug') # assert that Model.simulate returns the same result. model_result = self.linear_model.simulate(parameters, times) assert np.array_equal(expected_result, model_result) # Test case II: One Compartment Model (checks whether access of # correct output works) # define parameters and times parameters = [0, 2, 4] times = np.arange(25) # expected # init model in myokit model, protocol, _ = myokit.load(self.file_one_comp_model) # set inital state of model model.set_state([parameters[0]]) # set clearance and volume model.set_value('central_compartment.CL', parameters[1]) model.set_value('central_compartment.V', parameters[2]) # instantiate and run simulation simulation = myokit.Simulation(model, protocol) state_name = 'central_compartment.drug_concentration' myokit_result = simulation.run(duration=times[-1] + 1, log=[state_name], log_times=times) expected_result = myokit_result.get(state_name) # assert that Model.simulate returns the same result. model_result = self.one_comp_model.simulate(parameters, times) assert np.array_equal(expected_result, model_result)
def simulation(name='plain'): # Load model and protocol m, p, _ = myokit.load('example') sens = ( ('ina.m', 'dot(ina.m)', 'ina.INa'), ('ina.gNa', 'init(ina.m)') ) if name == 'plain': s = myokit.Simulation(m, p) def c(): s.run(100) elif name == 'sens': s = myokit.Simulation(m, p, sens) def c(): s.run(100) elif name == 'realtime': # Realtime tracking # Note: This doesn't show much: Python re-uses strings etc. so can # delete some decrefs without seeing it here! v = m.get('engine').add_variable('realtime') v.set_rhs(0) v.set_binding('realtime') s = myokit.Simulation(m, p) def c(): s.run(100) elif name == 'apd': # APD measuring # Note: Can remove some decrefs without seeing results here... s = myokit.Simulation(m, p) def c(): s.run(1000, apd_variable='membrane.V', apd_threshold=-1) elif name == 'log_times': # Point-list logging s = myokit.Simulation(m, p, sens) def c(): s.reset() s.run(1000, log_times=[0, 100, 500]) else: raise ValueError(f'Unknown test: simulation {name}') print(f'Testing simulation: {name}') test(c)
def __init__(self, mmtfile: str) -> None: """Initialises the model class. Arguments: mmtfile {str} -- Path to the mmtfile defining the model and the protocol. """ # load model and protocol model, protocol, _ = myokit.load(mmtfile) # get dose events from protocol self.mmt_dose_events = self._get_mmt_dose_events(protocol) # get state, parameter and output names self.state_names = [state.qname() for state in model.states()] self.state_dimension = model.count_states() self.output_names = [] self.output_dimension = None self.parameter_names = self._get_parameter_names(model) self.number_parameters_to_fit = model.count_variables(inter=False, bound=False ) # instantiate the simulation self.simulation = myokit.Simulation(model, protocol) self.model = model
def test_pickling(self): # Test pickling a simulation # Test with myokit.Protocol m, p, _ = myokit.load('example') s1 = myokit.Simulation(m, p) s1.pre(123) s_bytes = pickle.dumps(s1) s2 = pickle.loads(s_bytes) self.assertEqual(s1.time(), s2.time()) self.assertEqual(s1.state(), s2.state()) self.assertEqual(s1.default_state(), s2.default_state()) s1.run(123, log=myokit.LOG_NONE) s2.run(123, log=myokit.LOG_NONE) self.assertEqual(s1.time(), s2.time()) self.assertEqual(s1.state(), s2.state()) # Test simulation properties s1.set_tolerance(1e-8, 1e-8) s1.set_min_step_size(1e-2) s1.set_max_step_size(0.1) s2 = pickle.loads(pickle.dumps(s1)) s1.run(23, log=myokit.LOG_NONE) s2.run(23, log=myokit.LOG_NONE) self.assertEqual(s1.time(), s2.time()) self.assertEqual(s1.state(), s2.state()) # Test changed constants s1.set_constant('membrane.C', 1.1) s2 = pickle.loads(pickle.dumps(s1)) s1.run(17, log=myokit.LOG_NONE) s2.run(17, log=myokit.LOG_NONE) self.assertEqual(s1.time(), s2.time()) self.assertEqual(s1.state(), s2.state())
def __init__(self, protocol, temperature, sine_wave=False): # Load model model = myokit.load_model(model_file) # Set reversal potential model.get('nernst.EK').set_rhs(erev(temperature)) # Add sine-wave equation to model if sine_wave: model.get('membrane.V').set_rhs( 'if(engine.time >= 3000.1 and engine.time < 6500.1,' + ' - 30' + ' + 54 * sin(0.007 * (engine.time - 2500.1))' + ' + 26 * sin(0.037 * (engine.time - 2500.1))' + ' + 10 * sin(0.190 * (engine.time - 2500.1))' + ', engine.pace)') # Create simulation self.simulation = myokit.Simulation(model) # Add protocol if isinstance(protocol, myokit.Protocol): self.simulation.set_protocol(protocol) else: # Apply data-clamp times, voltage = protocol self.simulation.set_fixed_form_protocol(times, voltage) # Set max step size self.simulation.set_max_step_size(0.1) # Set solver tolerances to values used by Kylie self.simulation.set_tolerance(1e-8, 1e-8)
def setUpClass(cls): # Test simulation creation. m, p, x = myokit.load(os.path.join(DIR_DATA, 'lr-1991.mmt')) cls.model = m cls.protocol = p cls.sim = myokit.Simulation(cls.model, cls.protocol)
def test_simultaneous_event_error(self): # Test raising of errors on rescheduled periodic events p = myokit.Protocol() p.schedule(1, 0, 1, 1000) p.schedule(1, 3000, 1) s = AnsicEventBasedPacing(p) t = s.next_time() self.assertEqual(t, 1) s.advance(t) t = s.next_time() self.assertEqual(t, 1000) s.advance(t) t = s.next_time() self.assertEqual(t, 1001) s.advance(t) t = s.next_time() self.assertEqual(t, 2000) self.assertRaises(myokit.SimultaneousProtocolEventError, s.advance, t) # Test raising of errors in simulation p = myokit.Protocol() p.schedule(1, 0, 1, 10) p.schedule(1, 30, 1) m = myokit.load_model('example') s = myokit.Simulation(m, p) self.assertRaises(myokit.SimultaneousProtocolEventError, s.run, 40)
def test_progress_reporter(self): # Test running with a progress reporter. # Test if it works sim = myokit.Simulation(self.model, self.protocol) with myokit.tools.capture() 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 ratio(self): """ Returns the ratios of the peak conductances (p1 / p2) for step 1 and step 2. The returned value is a :class:`myokit.DataLog` with entries corresponding to the given variable names. """ # Times to wait twaits = np.exp( np.linspace(np.log(self._tmin), np.log(self._tmax), self._nt)) # Variables to log log_vars = [x.qname() for x in self._vars] # Run simulations self._vvar.set_rhs(self._vhold) # Make V a constant s = myokit.Simulation(self._model) log = myokit.DataLog() gvars = [x.qname() for x in self._vars] for g in gvars: log[g] = [] log[self._tvar.qname()] = list(twaits) for twait in twaits: s.set_constant(self._vvar, self._vhold) s.run(self._thold, log=myokit.LOG_NONE) s.set_constant(self._vvar, self._vstep) d1 = s.run(self._tstep1, log=log_vars) s.set_constant(self._vvar, self._vhold) s.run(twait, log=myokit.LOG_NONE) s.set_constant(self._vvar, self._vstep) d2 = s.run(self._tstep2, log=log_vars) for g in gvars: ratio = np.max(d1[g]) ratio = np.nan if ratio == 0 else np.max(d2[g]) / ratio log[g].append(ratio) return log
def __init__(self, model, regimen): super(PintsModel, self).__init__() # Instantiate simulation and sensitivity simulation self._simulation = myokit.Simulation(model, regimen) self._psimulation = myokit.PSimulation(model, regimen) # Create iterator over state and parameter variables self._state_names = np.array( [state.name() for state in model.states()]) self._param_names = np.array( [param.name() for param in model.parameters()]) # Create mask for inferable initial conditions and parameters self._infer_init_states = np.ones(shape=model.count_states(), dtype=bool) self._infer_params = np.ones(shape=model.count_variables(const=True), dtype=bool) # Number inferable initial state values self._n_infer_init_states = model.count_states() # Create container for initial values self._initial_states = np.zeros(shape=model.count_states()) # Create total number of inferable parameters self._n_parameters = model.count_states() + model.count_variables( const=True) # Define which variables are logged upon simulation self._logged_vars = self._state_names
def test_current_arrows(self): # Test the current arrows plot. # Select matplotlib backend that doesn't require a screen import matplotlib matplotlib.use('template') import matplotlib.pyplot as plt # Run simulation, get currents m, p, x = myokit.load(os.path.join(DIR_DATA, 'lr-1991.mmt')) # Add dummy current, that never carries much charge and should be # ignored c = m.add_component('dummy') x = c.add_variable('IDummy') x.set_rhs('0 * membrane.V') s = myokit.Simulation(m, p) currents = ['ina.INa', 'ik1.IK1', 'ica.ICa', 'dummy.IDummy'] d = s.run(600, log=['engine.time', 'membrane.V'] + currents) fig = plt.figure() plots.current_arrows(d, 'membrane.V', currents) plt.close(fig) plt.show() # Massive peak at final point d = d.npview() d['dummy.IDummy'][-1] = 100 fig = plt.figure() plots.current_arrows(d, 'membrane.V', currents) plt.close(fig) plt.show()
def load_protocol_values(protocol, variant=False): """ Returns a (capacitance filtered) tuple ``(times, voltages)`` for the selected ``protocol``. """ p = load_myokit_protocol(protocol, variant) if protocol == 6: log = load_ap_protocol().npview() t, v = log['time'], log['voltage'] elif protocol == 7: m = load_myokit_model() m.get('membrane.V').set_rhs( 'if(engine.time >= 3000.1 and engine.time < 6500.1,' + ' - 30' + ' + 54 * sin(0.007 * (engine.time - 2500.1))' + ' + 26 * sin(0.037 * (engine.time - 2500.1))' + ' + 10 * sin(0.190 * (engine.time - 2500.1))' + ', engine.pace)') p = load_myokit_protocol(protocol) s = myokit.Simulation(m, p) tmax = p.characteristic_time() t = np.arange(0, tmax, 0.1) v = s.run(tmax + 0.1, log=['membrane.V'], log_times=t) v = np.array(v['membrane.V']) else: t = np.arange(0, p.characteristic_time(), 0.1) v = np.array(p.value_at_times(t)) return capacitance(p, 0.1, t, v)
def simulate_aps(scales, model_file, beats=2, cl=1000, prepace=100, stimulate=True): """ Generate APs using the given scalings. """ # Load model model = myokit.load_model(model_file) # Apply scalings for var in scales: scale = scales[var] v = model.get(var) v.set_rhs(myokit.Multiply(myokit.Number(scale), v.rhs())) # Simulate with modified model sim = myokit.Simulation(model) # Add stimulus if stimulate: protocol = myokit.pacing.blocktrain(period=cl, duration=1, offset=50) sim.set_protocol(protocol) # Pre-pace for some beats sim.pre(prepace * cl) # Log some beats and return log = ['engine.time', 'membrane.V'] log = ['environment.time', 'membrane.V'] log = ['membrane.V'] return sim.run(beats * cl, log=log, log_interval=DT).npview()
def test_simulate(self): """Tests whether the simulate method works as expected. Tests implicitly also whether the _set_parameters method works properly. """ # Test case I: 1-compartment model parameters = [0, 2, 4] # different from initialised parameters times = np.arange(25) # expected model, protocol, _ = myokit.load(self.file_name) model.set_state([parameters[0]]) model.set_value('central_compartment.CL', parameters[1]) model.set_value('central_compartment.V', parameters[2]) simulation = myokit.Simulation(model, protocol) myokit_result = simulation.run( duration=times[-1] + 1, log=['central_compartment.drug_concentration'], log_times=times) expected_result = myokit_result.get( 'central_compartment.drug_concentration') # assert that Model.simulate returns the same result. model_result = self.one_comp_model.simulate(parameters, times) assert np.array_equal(expected_result, model_result)
def test_against_cvode(self): # Validate against a cvode sim. # Get a model fname = os.path.join(DIR_DATA, 'lr-1991-fitting.mmt') model = myokit.load_model(fname) model.get('membrane.V').set_binding('pace') # Create a protocol vs = [-30, -20, -10] p = myokit.pacing.steptrain(vsteps=vs, vhold=-120, tpre=8, tstep=2, tpost=0) t = p.characteristic_time() # Run an analytical simulation dt = 0.01 m = hh.HHModel.from_component(model.get('ina')) s1 = hh.AnalyticalSimulation(m, p) d1 = s1.run(t, log_interval=dt).npview() s2 = myokit.Simulation(model, p) s2.set_tolerance(1e-8, 1e-8) d2 = s2.run(t, log_interval=dt).npview() # Test protocol output is the same e = np.abs(d1['membrane.V'] - d2['membrane.V']) self.assertEqual(np.max(e), 0) # Test current output is very similar e = np.abs(d1['ina.INa'] - d2['ina.INa']) self.assertLess(np.max(e), 2e-4)
def test_against_cvode_v_independent(self): # Test with v-independent states model = myokit.parse_model(MODEL) model.get('membrane.V').set_rhs(-80) model.get('membrane.V').demote() model.binding('pace').set_binding(None) model.get('membrane.V').set_binding('pace') # Create a protocol vs = [-30, -20, -10] p = myokit.pacing.steptrain(vsteps=vs, vhold=-120, tpre=8, tstep=2, tpost=0) t = p.characteristic_time() # Run an analytical simulation dt = 0.01 m = hh.HHModel.from_component(model.get('binding')) s1 = hh.AnalyticalSimulation(m, p) d1 = s1.run(t, log_interval=dt).npview() s2 = myokit.Simulation(model, p) s2.set_tolerance(1e-8, 1e-8) d2 = s2.run(t, log_interval=dt).npview() # Test protocol output is the same e = np.abs(d1['membrane.V'] - d2['membrane.V']) self.assertEqual(np.max(e), 0) # Test current output is very similar e = np.abs(d1['binding.I'] - d2['binding.I']) self.assertLess(np.max(e), 2e-4)
def setUpClass(self): """ Test simulation creation. """ m, p, x = myokit.load(os.path.join(myotest.DIR_DATA, 'lr-1991.mmt')) self.model = m self.protocol = p self.sim = myokit.Simulation(self.model, self.protocol)
def test_pacing_values_at_event_transitions(self): # Tests the value of the pacing signal at event transitions # Create a simple model m = myokit.Model() c = m.add_component('c') t = c.add_variable('t') t.set_rhs(0) t.set_binding('time') v = c.add_variable('v') v.set_rhs('0') v.set_binding('pace') x = c.add_variable('x') x.set_rhs(0.1) x.promote(0) # Create step protocol p = myokit.Protocol() p.schedule(0, 0, 2) p.schedule(1, 2, 2) p.schedule(2, 4, 4) p.schedule(3, 8, 2) # Simulate with dynamic logging s = myokit.Simulation(m, p) d = s.run(p.characteristic_time()) time = list(d.time()) value = list(d['c.v']) if False: for i, t in enumerate(d.time()): t = str(np.round(t, 5)) print(t + ' ' * (10 - len(t)) + str(d['c.v'][i])) # Values should be # t 0 1 2 3 4 5 6 7 8 9 10 # p 0 0 1 1 2 2 2 2 3 3 0 self.assertEqual(value[time.index(0.0)], 0) self.assertEqual(value[time.index(0.0) + 1], 0) self.assertEqual(value[time.index(2.0) - 1], 0) self.assertEqual(value[time.index(2.0)], 1) self.assertEqual(value[time.index(2.0) + 1], 1) self.assertEqual(value[time.index(4.0) - 1], 1) self.assertEqual(value[time.index(4.0)], 2) self.assertEqual(value[time.index(4.0) + 1], 2) self.assertEqual(value[time.index(8.0) - 1], 2) self.assertEqual(value[time.index(8.0)], 3) self.assertEqual(value[time.index(8.0) + 1], 3) self.assertEqual(value[time.index(10.0) - 1], 3) self.assertEqual(value[time.index(10.0)], 0) # Simulate with fixed logging s.reset() d = s.run(p.characteristic_time() + 1, log_times=d.time()) time2 = list(d.time()) value2 = list(d['c.v']) self.assertEqual(time, time2) self.assertEqual(value, value2)
class SBMLTestSuiteExamplesTest(unittest.TestCase): """ Tests whether forward simulation of test cases from the SBML test suite coincides with the provided time-series data. Test Suite examples were taken from http://sbml.org/Facilities/Database/. """ @classmethod def setUpClass(cls): cls.importer = myokit.formats.importer('sbml') def get_sbml_file(self, case): return os.path.join(DIR_FORMATS, 'sbml', 'model', case + '-sbml-l3v2.xml') def get_results(self, case): path = os.path.join(DIR_FORMATS, 'sbml', 'result', case + '-results.csv') data = np.genfromtxt(path, delimiter=',') # Eliminate title row data = data[1:, :] return data def test_case_00001(self): # # From the SBML Test Suite settings: # # start: 0 # duration: 5 # steps: 50 # variables: S1, S2 # absolute: 1.000000e-007 # relative: 0.0001 # amount: S1, S2 # concentration: case = '00001' model = self.importer.model(self.get_sbml_file(case)) results = self.get_results(case) times = results[:, 0] s1 = results[:, 1] s2 = results[:, 2] sim = myokit.Simulation(model) output = sim.run( duration=times[-1] + 1, log=['compartment.S1_amount', 'compartment.S2_amount'], log_times=times) s1_sim = np.array(output['compartment.S1_amount']) np.testing.assert_almost_equal(s1_sim, s1, decimal=6) s2_sim = np.array(output['compartment.S2_amount']) np.testing.assert_almost_equal(s2_sim, s2, decimal=6)
def steady_state(m, pcl): p = myokit.pacing.blocktrain(pcl, 0.5, offset=0, level=1.0, limit=0) s = myokit.Simulation(m, p) ''' d = s.run(pcl) value = max(d['membrane.V']) max_AP_time = d['membrane.V'].index(value) for i in range(max_AP_time + 1, len(d['membrane.V'])): if d['membrane.V'][i] <= value: value = d['membrane.V'][i] else: end_repo = i time_AP = round(d['engine.time'][i],0) + 1 break #pl.figure() #pl.plot(d['engine.time'],d['membrane.V']) #pl.show() s.reset() print end_repo ''' variation = np.zeros((40, 300)) l = 0 for i in range(10, 50): s.reset() d = s.run(i) variation[l][0] = (d['membrane.V'][-1]) for j in range(1, 20): d = s.run(pcl) variation[l][j] = (d['membrane.V'][-1]) l += 1 a = np.std(variation, axis=1) time_AP = np.nonzero(a == max(a))[0][0] + 10 print time_AP # Run simulation maxi = 600 volt = np.zeros(maxi) s.reset() # One run at d = s.run(time_AP) volt[0] = (d['membrane.V'][-1]) for i in range(1, maxi - 1): # Run a simulation of PCL length on top, so same point of AP is listed last d = s.run(pcl) # Append the list with the last recorded membrane potential volt[i] = (d['membrane.V'][-1]) if np.all([ volt[i - 10:i] >= volt[i] - volt[i] * 0.0001, volt[i - 10:i] <= volt[i] + volt[i] * 0.0001 ]) and i >= 10: steady = i break volt = volt[0:steady + 1] return (steady, volt)
def test_myokit_import(): """Test that Myokit can be loaded. Uses the Myokit builtin example. """ m, p, x = myokit.load('example') s = myokit.Simulation(m, p) assert isinstance(s, myokit.Simulation) assert True
def test_interpolation_and_pacing(self): # Test if interpolation results in correct pacing values. # When logging with discontinuous steps, in the adaptive time # CVODE sim, the value of pace must be # 1. The old value *before* the time of the event # 2. The new value *at and after* the time of the event # 3. Back to zero *at and after* the end of the event # (Unless it ends sooner due to a new event arriving) # Load model m = myokit.load_model('example') # Voltage-clamp V (but don't bind it directly) v = m.label('membrane_potential') v.demote() v.set_rhs('-80 + 10 * engine.pace') # Create protocol p = myokit.Protocol() p.schedule(level=1, start=0, duration=5, period=10) # Create simulation s = myokit.Simulation(m, p) # Test if this would result in multiple interpolation steps for logging # i.e. test if the step before each transition was at least 2 log steps # long e = s.run(30).npview() t = e.time() for x in [5, 10, 15, 20, 25]: i = e.find_after(x) if not t[i] - t[i - 1] > 0.2: raise Exception('Issue with test: use longer intervals!') del(e, t, x, i) # Now test if correct interpolated values are returned by periodic # logging. d = s.run(30, log_interval=0.1).npview() # Test bound variable p = d['engine.pace'] self.assertTrue(np.all(p[0:50] == 1)) self.assertTrue(np.all(p[50:100] == 0)) self.assertTrue(np.all(p[100:150] == 1)) self.assertTrue(np.all(p[150:200] == 0)) self.assertTrue(np.all(p[200:250] == 1)) self.assertTrue(np.all(p[250:300] == 0)) # Test variable dependent on bound variable p = d['membrane.V'] self.assertTrue(np.all(p[0:50] == -70)) self.assertTrue(np.all(p[50:100] == -80)) self.assertTrue(np.all(p[100:150] == -70)) self.assertTrue(np.all(p[150:200] == -80)) self.assertTrue(np.all(p[200:250] == -70)) self.assertTrue(np.all(p[250:300] == -80))
def test_timeout_progress_reporter(self): m, p, x = myokit.load('example') s = myokit.Simulation(m, p) t = myokit.Timeout(0.1) with self.assertRaises(myokit.SimulationCancelledError): s.run(100000, progress=t) t = myokit.Timeout(3600) s.run(100, progress=t)
def test_simulation_error_2(self): # Test for simulation error detection: failure occurred too often. # Cvode error (test failure occurred too many times) m = self.model.clone() v = m.get('membrane.V') v.set_rhs(myokit.Multiply(v.rhs(), myokit.Number(1e18))) s = myokit.Simulation(m, self.protocol) with self.assertRaises(myokit.SimulationError) as e: s.run(5000) self.assertIn('CV_ERR_FAILURE', str(e.exception))
def test_simulation_error_2(self): # Test for simulation error detection: failure occurred too often. # Cvode error (test failure occurred too many times) m = self.model.clone() v = m.get('membrane.V') v.set_rhs(myokit.Multiply(v.rhs(), myokit.Number(1e18))) s = myokit.Simulation(m, self.protocol) with WarningCollector(): self.assertRaisesRegex(myokit.SimulationError, 'numerical error', s.run, 5000)
def test_cvode_floating_point_protocol_1(self): # Tests the protocol handling in a CVODE simulation, which uses the # pacing.h file shared by all C/C++ simulation code. # Create model without states m = myokit.Model() c = m.add_component('c') t = c.add_variable('t') t.set_rhs(0) t.set_binding('time') v = c.add_variable('v') v.set_rhs('0') v.set_binding('pace') # Create tricky protocol p = myokit.Protocol() p.schedule(-80, 0, 1.2345) p.schedule(-70, 1.2345, 2.3454) p.schedule(-60, 3.5799, 1.4201) # Run & test s = myokit.Simulation(m, p) d = s.run(p.characteristic_time()) self.assertEqual(list(d['c.v']), [-80, -70, -60, 0]) # Test starting/stopping at difficult points p = myokit.Protocol() p.schedule(-80, 0, 1.2345) p.schedule(-70, 1.2345, 2.3454) # Interval end s = myokit.Simulation(m, p) d = s.run(3.5799) self.assertEqual(list(d['c.t']), [0, 1.2345, 3.5799]) self.assertEqual(list(d['c.v']), [-80, -70, 0]) # Interval start d = s.run(6.4201) self.assertEqual(list(d['c.t']), [3.5799, 10]) self.assertEqual(list(d['c.v']), [0, 0])
def test_last_evaluations_and_steps(self): # Test :meth:`Simulation.last_number_of_evaluations()` and # :meth:`Simulation.last_number_of_steps()` s = myokit.Simulation(self.model, self.protocol) self.assertEqual(s.last_number_of_evaluations(), 0) self.assertEqual(s.last_number_of_steps(), 0) s.run(1) self.assertTrue(s.last_number_of_evaluations() > 0) self.assertTrue(s.last_number_of_steps() > 0) self.assertNotEqual(s.last_number_of_evaluations(), s.last_number_of_steps())
def test_cvode_floating_point_protocol_3(self): # Tests the protocol handling in a CVODE simulation, which uses the # pacing.h file shared by all C/C++ simulation code. m = myokit.Model() c = m.add_component('c') t = c.add_variable('t') t.set_rhs(0) t.set_binding('time') v = c.add_variable('v') v.set_rhs('0') v.set_binding('pace') p = myokit.Protocol() p.schedule(-80, 0, 22159.6) p.schedule(-70, 22159.6, 1340.6) p.schedule(-60, 23500.2, 6499.8) # Test without state variables, dynamic logging s = myokit.Simulation(m, p) d = s.run(40000) self.assertEqual(list(d['c.t']), [0, 22159.6, 23500.2, 30000, 40000]) self.assertEqual(list(d['c.v']), [-80, -70, -60, 0, 0]) # Test without state variables, fixed log times s.reset() d = s.run(40001, log_times=d['c.t']) self.assertEqual(list(d['c.t']), [0, 22159.6, 23500.2, 30000, 40000]) self.assertEqual(list(d['c.v']), [-80, -70, -60, 0, 0]) x = c.add_variable('x') x.set_rhs('cos(t)') x.promote(0) # Test with state variables, fixed log times s = myokit.Simulation(m, p) d = s.run(40001, log_times=d['c.t']) self.assertEqual(list(d['c.t']), [0, 22159.6, 23500.2, 30000, 40000]) self.assertEqual(list(d['c.v']), [-80, -70, -60, 0, 0])
def test_fields(self): # Test using fields # Load model and protocol m = myokit.load_model(os.path.join(DIR_DATA, 'beeler-1977-model.mmt')) p = myokit.pacing.blocktrain(duration=2, offset=1, period=1000) # Create simulations t = 6.5 dt = 0.1 lv = ['engine.time', 'membrane.V'] sa = myokit.Simulation(m, p) sa.set_constant('membrane.C', 0.9) d0 = sa.run(t, log=lv, log_interval=dt).npview() sa.reset() sa.set_constant('membrane.C', 1.1) d1 = sa.run(t, log=lv, log_interval=dt).npview() sa.reset() sa.set_constant('membrane.C', 1.2) d2 = sa.run(t, log=lv, log_interval=dt).npview() sb = myokit.SimulationOpenCL(m, p, ncells=3, diffusion=False) sb.set_field('membrane.C', [0.9, 1.1, 1.2]) sb.set_step_size(0.001) dx = sb.run(t, log=lv, log_interval=dt).npview() e0 = np.max(np.abs(d0['membrane.V'] - dx['membrane.V', 0])) e1 = np.max(np.abs(d1['membrane.V'] - dx['membrane.V', 1])) e2 = np.max(np.abs(d2['membrane.V'] - dx['membrane.V', 2])) if debug: import matplotlib.pyplot as plt print('Field') print(e0, e1, e2) plt.figure(figsize=(9, 6)) plt.suptitle('Field') plt.subplot(1, 2, 1) plt.plot(d0.time(), d0['membrane.V'], lw=2, alpha=0.5) plt.plot(d1.time(), d1['membrane.V'], lw=2, alpha=0.5) plt.plot(d2.time(), d2['membrane.V'], lw=2, alpha=0.5) plt.plot(dx.time(), dx['membrane.V', 0], '--') plt.plot(dx.time(), dx['membrane.V', 1], '--') plt.plot(dx.time(), dx['membrane.V', 2], '--') plt.subplot(1, 2, 2) plt.plot(d0.time(), d0['membrane.V'] - dx['membrane.V', 0]) plt.plot(d0.time(), d1['membrane.V'] - dx['membrane.V', 1]) plt.plot(d0.time(), d2['membrane.V'] - dx['membrane.V', 2]) plt.show() self.assertLess(e0, 0.5) self.assertLess(e1, 0.5) self.assertLess(e2, 0.5)
def _run(self): """ Runs the simulation, saves the current traces. """ log = self._vars + [self._tvar] d = [] s = myokit.Simulation(self._model) for v in self._steps: s.reset() s.set_constant(self._vvar, v) s.pre(self._tstep) s.set_constant(self._vvar, self._vhold) d.append(s.run(self._thold, log=log)) self._logs = d