def test_with_event_at_t_1(self): # Test with event starting at t=1 p = myokit.Protocol() p.schedule(2, 1, 1, 10, 0) s = myokit.PacingSystem(p) self.assertEqual(s.time(), 0) self.assertEqual(s.next_time(), 1) self.assertEqual(s.pace(), 0) p = myokit.Protocol() s = myokit.PacingSystem(p) self.assertEqual(s.time(), 0) self.assertEqual(s.next_time(), float('inf')) self.assertEqual(s.pace(), 0)
def pre(self, duration): """ Performs an unlogged simulation for ``duration`` time units and uses the final state as the new default state. After the simulation: - The simulation time is **not** affected - The current state and the default state are updated to the final state reached in the simulation. Calls to :meth:`reset` after using :meth:`pre` will set the current state to this new default state. """ # Check arguments duration = float(duration) if duration < 0: raise ValueError('Duration must be non-negative.') # Run # This isn't much faster, but this way the simulation's interface is # similar to the standard simulation one. old_time = self._time self.run(duration, log_interval=2 * duration) # Update default state self._default_state = np.array(self._state, copy=True) # Reset time, reset protocol self._time = old_time if self._protocol: self._pacing = myokit.PacingSystem(self._protocol) self._membrane_potential = self._pacing.advance(self._time)
def __init__(self, model, protocol=None): super(AnalyticalSimulation, self).__init__() # Check model if not isinstance(model, HHModel): raise ValueError('First parameter must be a `HHModel`.') self._model = model # Check protocol if protocol is None: self._protocol = None elif not isinstance(protocol, myokit.Protocol): raise ValueError('Protocol must be a myokit.Protocol object') else: self._protocol = protocol.clone() # Time variable self._time = 0 # Check if we have a current variable self._has_current = self._model.current() is not None # Set state self._state = np.array(self._model.default_state(), copy=True, dtype=float) # Set default state self._default_state = np.array(self._state, copy=True) # Get membrane potential self._membrane_potential = self._model.default_membrane_potential() # Get parameters self._parameters = np.array(self._model.default_parameters(), copy=True, dtype=float) # Mapping from parameter names to index in parameter array self._parameter_map = {} for i, p in enumerate(self._model.parameters()): self._parameter_map[p] = i # Get function self._function = self._model.function() # If protocol was given, create pacing system, update vm self._pacing = None if self._protocol: self._pacing = myokit.PacingSystem(self._protocol) self._membrane_potential = self._pacing.advance(self._time) # Keys for logging self._time_key = self._model._model.time().qname() self._vm_key = self._model._membrane_potential self._log_keys = [self._time_key, self._vm_key] + self._model.states() if self._has_current: self._log_keys.append(self._model.current())
def reset(self): """ Resets the simulation: - The time variable is set to zero. - The state is set to the default state. """ self._time = 0 self._state = np.array(self._default_state, copy=True) if self._protocol: self._pacing = myokit.PacingSystem(self._protocol) self._membrane_potential = self._pacing.advance(self._time)
def test_constant(self): # Test the creation of a constant protocol. level = 0.5 p = myokit.pacing.constant(level) s = myokit.PacingSystem(p) self.assertEqual(len(p.events()), 1) self.assertEqual(s.pace(), level) s.advance(100) self.assertEqual(s.pace(), level) for i in range(10): s.advance(s.next_time()) self.assertEqual(s.pace(), level)
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 = myokit.PacingSystem(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) with self.assertRaises(myokit.SimultaneousProtocolEventError) as e: s.advance(t) m = str(e.exception) self.assertEqual(float(m[2 + m.index('t='):-1]), 3000)
def test_with_event_at_t_0(self): # Test with event starting at t=0 p = myokit.Protocol() # schedule(level, start, duration, period, multiplier) p.schedule(2, 0, 1, 10, 0) s = myokit.PacingSystem(p) self.assertEqual(s.time(), 0) self.assertEqual(s.next_time(), 1) self.assertEqual(s.pace(), 2) s.advance(0) self.assertEqual(s.time(), 0) self.assertEqual(s.next_time(), 1) self.assertEqual(s.pace(), 2) s.advance(0) s.advance(0) s.advance(0) self.assertEqual(s.time(), 0) self.assertEqual(s.next_time(), 1) self.assertEqual(s.pace(), 2) s.advance(0.5) self.assertEqual(s.time(), 0.5) self.assertEqual(s.next_time(), 1) self.assertEqual(s.pace(), 2) s.advance(1) self.assertEqual(s.time(), 1) self.assertEqual(s.next_time(), 10) self.assertEqual(s.pace(), 0) s.advance(2) self.assertEqual(s.time(), 2) self.assertEqual(s.next_time(), 10) self.assertEqual(s.pace(), 0) s.advance(10) self.assertEqual(s.time(), 10) self.assertEqual(s.next_time(), 11) self.assertEqual(s.pace(), 2) self.assertRaisesRegex(ValueError, 'cannot be before', s.advance, 0)
def pacing_system(self): """ Tests if the pacing systems works correctly. """ # Test basics p = myokit.Protocol() p.schedule(2, 0, 1, 10, 0) s = myokit.PacingSystem(p) self.assertEqual(s.time(), 0) self.assertEqual(s.next_time(), 1) self.assertEqual(s.pace(), 2) s.advance(0) self.assertEqual(s.time(), 0) self.assertEqual(s.next_time(), 1) self.assertEqual(s.pace(), 2) s.advance(0) s.advance(0) s.advance(0) self.assertEqual(s.time(), 0) self.assertEqual(s.next_time(), 1) self.assertEqual(s.pace(), 2) s.advance(0.5) self.assertEqual(s.time(), 0.5) self.assertEqual(s.next_time(), 1) self.assertEqual(s.pace(), 2) s.advance(1) self.assertEqual(s.time(), 1) self.assertEqual(s.next_time(), 10) self.assertEqual(s.pace(), 0) s.advance(2) self.assertEqual(s.time(), 2) self.assertEqual(s.next_time(), 10) self.assertEqual(s.pace(), 0) s.advance(10) self.assertEqual(s.time(), 10) self.assertEqual(s.next_time(), 11) self.assertEqual(s.pace(), 2) p = myokit.Protocol() p.schedule(2, 1, 1, 10, 0) s = myokit.PacingSystem(p) self.assertEqual(s.time(), 0) self.assertEqual(s.next_time(), 1) self.assertEqual(s.pace(), 0) p = myokit.Protocol() s = myokit.PacingSystem(p) self.assertEqual(s.time(), 0) self.assertEqual(s.next_time(), float('inf')) self.assertEqual(s.pace(), 0) # Test basic use + log creation methods p = myokit.Protocol() p.schedule(1, 10, 1, 1000, 0) d = p.create_log_for_interval(0, 3000) self.assertEqual(d.time(), [0, 10, 11, 1010, 1011, 2010, 2011, 3000]) d = p.create_log_for_interval(0, 2000, for_drawing=True) self.assertEqual(d.time(), [0, 10, 10, 11, 11, 1010, 1010, 1011, 1011, 2000]) p = myokit.Protocol() p.schedule(1, 0, 1, 1000, 0) d = p.create_log_for_interval(0, 3000) self.assertEqual(d.time(), [0, 1, 1000, 1001, 2000, 2001, 3000]) d = p.create_log_for_interval(0, 2000, for_drawing=True) self.assertEqual(d.time(), [0, 1, 1, 1000, 1000, 1001, 1001, 2000]) if False: import matplotlib.pyplot as pl pl.figure() pl.plot(d.time(), d['pace']) pl.show() # Test raising of errors on rescheduled events p = myokit.Protocol() p.schedule(1, 0, 1, 1000) p.schedule(1, 3000, 1) s = myokit.PacingSystem(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) try: s.advance(t) except myokit.SimultaneousProtocolEventError as e: m = e.message self.assertEqual(float(m[2 + m.index('t='):-1]), 3000)