# Pacing protocols¶

class myokit.Protocol

Represents a pacing protocol as a sequence of events.

Every event represents a time span during which the stimulus is non-zero. All events specify a stimulus level, a starting time and a duration. The stimulus level is given as a dimensionless number where 0 is no stimulus and 1 is a “full” stimulus. No range is specified: 2 would indicate “twice the normal stimulus”.

Periodic events can be created by specifying their period. A period of 0 is used for non-periodic events. The number of times a periodic event occurs can be set using the multiplier value. For any non-zero value, the event will occur exactly this many times.

If an event starts while another event is already active, the new event will determine the pacing value and the old event will be deactivated.

Scheduling two events to occur at the same time will result in an error, as the resulting behavior would be undefined. When events are scheduled with the same starting time an error will be raised immediately. If the clash only happens when an event re-occurs, an error will be raised when using the protocol (for example during a simulation).

An event with start time a and duration b will be active during the interval [a, b). In other words, time a will be the first time it is active and time b will be the first time after a at which it is not.

add(e)

(Re-)schedules an event.

add_step(level, duration)

Appends an event to the end of this protocol. This method can be used to easily create voltage-step protocols.

level
The stimulus level. 1 Represents a full-sized stimulus. Only non-zero levels should be set.
duration
The length of the stimulus.

A call to p.append(level, duration) is equivalent to p.schedule(level, p.characteristic_time(), duration, 0, 0).

characteristic_time()

Returns the characteristic time associated with this protocol.

The characteristic time is defined as the maximum characteristic time of all events in the protocol. For a sequence of events, this is simply the protocol duration.

Examples:

>>> import myokit
>>> # A sequence of events
>>> p = myokit.Protocol()
>>> p.schedule(1, 0, 100)
>>> p.schedule(1, 100, 100)
>>> p.characteristic_time()
200.0

>>> # A finitely reoccurring event
>>> p = myokit.Protocol()
>>> p.schedule(1, 100, 0.5, 1000, 3)
>>> p.characteristic_time()
3100.0

>>> # An indefinitely reoccurring event, method returns period
>>> p = myokit.Protocol()
>>> p.schedule(1, 100, 0.5, 1000, 0)
>>> p.characteristic_time()
1000.0

clone()

Returns a deep clone of this protocol.

code()

Returns the mmt code representing this protocol and its events.

create_log_for_interval(a, b, for_drawing=False)

Creates a myokit.DataLog containing the entries time and pace representing the value of the pacing stimulus at each point.

The time points in the log will be on the interval [a, b], such that every time at which the pacing value changes is present in the log.

If for_drawing is set to True each time value between a and b will be listed twice, so that a vertical line can be drawn from the old to the new pacing value.

create_log_for_times(times)

Creates a myokit.DataLog containing the entries time and pace representing the value of the pacing stimulus at each point.

The time entries times must be an non-descreasing series of non-negative points.

events()

Returns a list of all events in this protocol.

guess_duration()

Deprecated

This method now returns the value given by characteristic_time().

head()

Returns the first event in this protocol.

If the protocol is empty, None will be returned.

in_words()

Returns a description of this protocol in words.

is_infinite()

Returns True if (and only if) this protocol contains indefinitely recurring events.

is_sequence(exception=False)

Checks if this protocol is a sequence of non-periodic steps.

The following checks are performed:

1. The protocol does not contain any periodic events
2. The protocol does not contain any overlapping events

If exception is set to True, the method will raise an Exception instead of returning False. This allows you to obtain specific information about the check that failed

is_unbroken_sequence(exception=False)

Checks if this protocol is an unbroken sequence of steps. Returns True only for an unbroken sequence.

The following checks are performed:

1. The protocol does not contain any periodic events
2. The protocol does not contain any overlapping events
3. Each new event starts where the last ended

If exception is set to True, the method will raise an Exception instead of returning False. This allows you to obtain specific information about the check that failed

levels()

Returns the levels of the events scheduled in this protocol.

For unbroken sequences of events this will produce a list of the levels visited by the protocol. For sequences with gaps or protocols with periodic events the relationship between actual levels and this method’s output is more complicated.

pop()

Removes and returns the event at the head of the queue.

range()

Returns the minimum and maximum levels set in this protocol. Will return 0, 0 for empty protocols.

schedule(level, start, duration, period=0, multiplier=0)

Schedules a new event.

level
The stimulus level. 1 Represents a full-sized stimulus. Only non-zero levels should be set.
start
The time this event first occurs.
duration
The length of the stimulus.
period (optional)
This event’s period, or 0 if it is a one-off event.
multiplier (optional)
For periodic events, this indicates the number of times this event occurs. Non-periodic events or periodic events that continue indefinitely can use 0 here.
tail()

Returns the last event in this protocol. Note that recurring events can be rescheduled, so that the event returned by this method is not necessarily the last event that would occur when running the protocol.

If the protocol is empty, None will be returned.

class myokit.ProtocolEvent(level, start, duration, period=0, multiplier=0)

Describes an event occurring as part of a protocol.

characteristic_time()

Returns a characteristic time associated with this event.

The time is calculated as follows:

Singular events
characteristic_time = start + duration
Finitely recurring events
characteristic_time = start + multiplier * period
Indefinitely recurring events, where start + duration < period
characteristic_time = period
Indefinitely recurring events, where start + duration >= period
characteristic_time = start + period

Roughly, this means that for finite events the full duration is returned, while indefinitely recurring events return the time until the first period is completed.

clone()

Returns a clone of this event.

Note that links to other events are not included in the copy!

code()

Returns a consistently formatted string representing an event.

duration()

Returns this even’t duration.

in_words()

Returns a description of this event.

level()

Returns this event’s pacing level.

multiplier()

Returns the number of times this event recurs. Zero is returned for singular events and indefinitely recurring events.

next()

If this event is part of a myokit.Protocol, this returns the next scheduled event.

period()

Returns this event’s period (or zero if the event is singular).

start()

Returns the time this event starts.

stop()

Returns the time this event ends, i.e. start() + duration().

class myokit.PacingSystem(protocol)

This class uses a myokit.Protocol to update the value of a pacing variable over time.

A pacing system is created by passing in a protocol:

import myokit p = myokit.load_protocol(‘example’) s = myokit.PacingSystem(p)

The given protocol will be cloned internally before use.

Initially, all pacing systems are at time 0. Time can be updated (but never moved back!) by calling advance(new_time)(). The current time can be obtained with time(). The value of the pacing variable is obtained from pace(). The next time the pacing variable will change can be obtained from next_time().

A pacing system can be used to calculate the values of the pacing variable at different times:

>>> import myokit
>>> s = myokit.PacingSystem(p)
>>> import numpy as np
>>> time = np.linspace(0, 1000, 10001)
>>> pace = np.array([s.advance(t) for t in time])

advance(new_time, max_time=None)

Advances the time in the pacing system to new_time. If max_time is set, the system will never go beyond max_time.

Returns the current value of the pacing variable.

next_time()

Returns the next time the pacing system will halt at.

pace()

Returns the current value of the pacing variable.

time()

Returns the current time in the pacing system.

## Protocol factory¶

The myokit.pacing module provides a factory methods to facilitate the creation of Protocol objects directly from python. This module is imported as part of the main myokit package.

### Periodic pacing¶

myokit.pacing.bpm2bcl(bpm, m=0.001)

Converts a beats-per-minute number to a basic cycle length in ms. For example a bpm of 60 equals a bcl of 1000ms.

>>> import myokit
>>> print(myokit.pacing.bpm2bcl(60))
1000.0


To use a different unit scaling, change the optional parameter m. For example, with m set to 1 the returned units are seconds:

>>> print(myokit.pacing.bpm2bcl(120, 1))
0.5

myokit.pacing.blocktrain(period, duration, offset=0, level=1.0, limit=0)

Creates an train of block pulses.

Each pulse lasts duration time units and a pulse is initiated every period time units.

An optional offset to the first pulse can be specified using offset and the level of each pulse can be set using level. To limit the number of pulses generated set limit to a non-zero value.

### Step protocols¶

myokit.pacing.constant(level)

Creates a very simple protocol where the pacing variable is held constant at a given level specified by the argument level.

myokit.pacing.steptrain(vsteps, vhold, tpre, tstep, tpost=0)

Creates a series of increasing or decreasing steps away from the fixed holding potential vhold, towards the voltages listed in vsteps.

1. For the first tpre time units, the pacing variable is held at the value given by vhold.
2. For the next tstep time units, the pacing variable is held at a value from vsteps
3. For the next tpost time units, the pacing variable is held at vhold again.

These three steps are repeated for each value in the vsteps.

myokit.pacing.steptrain_linear(vstart, vend, dv, vhold, tpre, tstep, tpost=0)

Creates a series of increasing or decreasing steps away from a holding value (typically a holding potential). This type of protocol is commonly used to measure activation or inactivation in ion channel models.

1. For the first tpre time units, the pacing variable is held at the value given by vhold.
2. For the next tstep time units, the pacing variable is held at a value ranging from vstart to vend, with increments dv.
3. For the next tpost time units, the pacing variable is held at the value vhold again.

These three steps are repeated for each value in the range from vstart up to (but not including) vend, with an increment specified as dv.