API :: Formats

This page is about importing from and exporting to formats other than mmt. If you are interested in the mmt format, please look at the section Reading and writing.

One of the main goals of myokit is to provide export of Simulations to other formats (for example C or matlab). To provide a uniform interface to these functions the Exporter class is defined. Import from other formats is provided through the Importer interface.

Exporters to exchange or presentation formats will typically export a bare model definition, while exporters to programming languages mostly create a full Simulation including pacing, a simulation engine and even some post processing.

The goal of an Importer is to produce a (model, protocol, script) tuple containing the three main parts of an mmt file. However, most importers will only provide a model definition so the remaining entries in the tuple will be None.

The methods used to import and export programmatically are described below, and and some example code is given.

The following formats are currently supported:

Example

To find out which kinds of import/export are available, the methods exporters() and importers() are defined. These functions return a list of names that can be passed to exporter() or importer() to obtain the class name of the requested im- or exporter. This is returned as a type object, from which instances can then be constructed:

import myokit
from myokit import formats

# Load a (model, protocol, script) tuple
m, p, s = myokit.load('example.mmt')

# Create a simulation
s = myokit.Simulation(m, p)

# Create an Ansi-C exporter
e = formats.exporter('ansic')

# Get some info about this exporter
print e.info()

# Export to the directory /home/michael/test
# If this directory does not exist, the exporter will attempt to create it.
e.export_simulation(s, '/home/michael/test')

Importing

myokit.formats.importer(name)

Creates and returns an instance of the importer specified by name.

myokit.formats.importers()

Returns a list of available importers by name.

class myokit.formats.Importer

Abstract base class for importers.

component(path, model)

Imports a component from the given path and adds it to the given model.

The importer may pose restraints on the used model. For example, the model may be required to contain a variable labelled “membrane_potential”. For details, check the documentation of the individual importers.

The created myokit.Component is returned. A myokit.ImportError will be raised if any errors occur.

model(path)

Imports a model from the given path.

The created myokit.Model is returned. A myokit.ImportError will be raised if any errors occur.

protocol(path)

Imports a protocol from the given path.

The created myokit.Protocol is returned. A myokit.ImportError will be raised if any errors occur.

supports_component()

Returns a bool indicating if component import is supported.

supports_model()

Returns a bool indicating if model import is supported.

supports_protocol()

Returns a bool indicating if protocol import is supported.

Exporting

myokit.formats.exporter(name)

Creates and returns an instance of the exporter specified by name.

myokit.formats.exporters()

Returns a list of available exporters by name.

class myokit.formats.Exporter

Abstract base class for exporters.

An exporter is a class that can produce model code or runnable code from a Myokit model or a model & protocol combination (runnable).

_test_writable_dir(path)

Ensures the given path is writable, or raises a myokit.ExportError if it can’t be used.

model(path, model)

Exports a myokit.Model.

The output will be stored in the file path. A myokit.ExportError will be raised if any errors occur.

post_export_info()

Optional method that returns a string containing information about this exporter, to be shown after the export is completed.

runnable(path, model, protocol=None, *args)

Exports a myokit.Model and optionally a myokit.Protocol to something that can be run or compiled.

The output will be stored in the directory path. A myokit.ExportError will be raised if any errors occur.

supports_model()

Returns True if this exporter supports model export.

supports_runnable()

Returns True if this exporter supports export of a model and optional protocol to a runnable piece of code.

class myokit.formats.TemplatedRunnableExporter

Abstract class, extends: Exporter

Abstract base class for exporters that turn a model (and optionally a protocol) into a runnable chunk of code.

_dict()

Returns a dict (filename : template_file_name) containing all the templates used by this exporter.

This should be implemented by each subclass.

_dir(formats_dir)

Returns the path to this exporter’s data files (as a string).

This should be implemented by each subclass. The root directory all format extensions are stored in in passed in as ``formats_dir``.

_vars(model, protocol)

Returns a dict containing all variables the templates will need.

Will be called with the arguments model and protocol, followed by any extra arguments passed to runnable().

This should be implemented by each subclass.

runnable(path, model, protocol=None, *args)

Exports a myokit.Model and optionally a myokit.Protocol to something that can be run or compiled.

The output will be stored in the directory path.

supports_runnable()

Returns True if this exporter supports export of a model and optional protocol to a runnable piece of code.

Expression writers

A number of export classes use ExpressionWriter objects to convert myokit expressions to string representations in the appropriate language. The base class for expression writers is described below:

myokit.formats.ewriter(name)

Creates and returns an instance of the expression writer specified by name.

myokit.formats.ewriters()

Returns a list of available expression writers by name.

class myokit.formats.ExpressionWriter

Base class for expression writers.

Expression writers take myokit.Expression objects and produce code in some language other than Myokit.

When implementing an expression writer, there are a few important edge cases to consider:

  1. Simplifications must not be made at this stage. For example, if the user writes “+1” instead of “1”, the code should output “+1”. If simplifications are desired, these should be made at an earlier stage, when everything is still in symbolic form.

  2. Powers (exponentiation) can be left or right-associative. In Myokit and, for example, in Matlab, the expression a^b^c is interpreted as (a^b)^c. By in Python (and e.g. in many spreadsheet applications) a**b**c is interpreted as a**(b**c), necessitating a different bracket-adding logic than used in Myokit.

  3. Binary operators are sometimes implemented as n-ary operators. In Myokit, 0 == 0 == 0 is a sequence of two binary operators, interpreted as (0 == 0) == 0. Because (0 == 0) evaluates to 1, this expression returns 0 (1 does not equal 0). In Python, the expression 0 == 0 == 0 is a ternary (n-ary) operator, interpreted as all_equal(0, 0, 0), which evaluates to 1. For languages that use this convention, extra brackets must be added.

  4. Myokit does not have increment or decrement operators -- and ++, so the expression --x is interpreted as -(-x). This is the same in Python. But in C-based languages, this is interpreted as a decrement operator so care must be taken to add extra brackets.

_build_op_map()

Returns a mapping from Myokit operators to lambda functions on expressions.

eq(q)

Converts a myokit.Equation to a string.

ex(e)

Converts a myokit.Expression to a string.

set_lhs_function(f)
Sets a naming function, will be called to get the variable name from a

myokit.LhsExpression object.

The argument f should be a function that takes an LhsExpression as input and returns a string.

Registering external formats

The importers, exporters, and expression writers that are packed with Myokit are automatically detected at start-up. To register classes defined outside of the myokit module, use the functions below. After registering, you can obtain e.g. an Exporter via myokit.formats.exporter(my_external_exporter).

myokit.formats.register_external_importer(name, importer_class)

Registers an external Importer for use with Myokit.

Arguments:

name

A short descriptive string name.

importer_class

The class to register (must be a myokit.Importer). Importers can be unregistered by passing in None.

myokit.formats.register_external_exporter(name, exporter_class)

Registers an external Exporter for use with Myokit.

Arguments:

name

A short descriptive string name.

exporter_class

The class to register (must be a myokit.Exporter). Exporters can be unregistered by passing in None.

myokit.formats.register_external_ewriter(name, ewriter_class)

Registers an external ExpressionWriter for use with Myokit.

Arguments:

name

A short descriptive string name.

ewriter_class

The class to register (must be a myokit.ExpressionWriter). Expression writers can be unregistered by passing in None.

Default expression writers

Finally, Myokit contains two default expression writers, which are used internally to write expressions in Python format with or without NumPy support.

myokit.python_writer()

Returns a globally shared python expression writer.

LhsExpressions are converted as follows:

  1. Derivatives are indicated as “_d_” + var.uname()

  2. Other names are indicated as var.uname()

This convention ensures a unique mapping of a model’s lhs expressions to acceptable python variable names.

myokit.numpy_writer()

Returns a globally shared numpy expression writer.

LhsExpressions are converted as follows:

  1. Derivatives are indicated as “_d_” + var.uname()

  2. Other names are indicated as var.uname()

This convention ensures a unique mapping of a model’s lhs expressions to acceptable python variable names.

Data formats

In addition to model and protocol formats, Myokit can read some electrophysiology formats. Support for advanced features is usually not implemented, but basic access is provided to ABF, WCP and HEKA files. Classes for these three formats share a common API, and make use of the :class`SweepSource` class shown below.

class myokit.formats.SweepSource

Interface for classes that provide time-series data organised into sweeps (or records or episodes) and channels (or traces).

The SweepSource interface defines methods to get the number of sweeps and channels, the names and units of the channels, and the data stored in channels either as numpy arrays or in a myokit.DataLog.

Each sweep contains the same number of channels, and each channel is represented as a 1d array. In most cases these arrays have the same length for every sweep, but whether this is the case for the current source can be tested with equal_length_sweeps().

Data can be retrieved sweep by sweep:

(time[0], sweep[0]),        n_t data points, n_c channels of n_t points
(time[1], sweep[1]),
(time[2], sweep[2]),
...
(time[n_s], sweep[n_s])

This allows plotting in the common “overlaid” fashion, i.e. plotting every sweep[i] against ``time[0].

For other types of analysis (e.g. parameter estimation) the data can also be returned as single time series:

time                            sum(n_t[i]) data points
sweep[0] + sweep[1] + ...       n_c channels, with sum(n_t[i]) points

Some formats can also contain information from which D/A output signals can be reconstructed. These can be accessed using the da().

channel(channel_id, join_sweeps=False)

Returns the data for a single channel, identified by integer or string channel_id.

With join_sweeps=False, the data is returned as a tuple (times, sweeps) where times and sweeps are 2d numpy arrays indexed so that times[i][j] is the j-th time point for sweep i.

If join_sweeps=True the sweeps are joined together, and a tuple (times, values) is returned times and values are 1d arrays.

channel_count()

Returns the number of channels.

channel_names(index=None)

Returns the names of all channels or the name of a specific channel index.

channel_units(index=None)

Returns the units (as myokit.Unit) of all channels or the units of a specific channel index.

da(output_id, join_sweeps=False)

Like channel(), but returns reconstructed D/A signals.

da_count()

Returns the available number of reconstructed D/A output channels.

This should return 0 if D/A channels are not supported.

da_names(index=None)

Returns the names of all reconstructed D/A output channels or the name of a specific output channel index.

This will raise a NotImplementedError if D/A channels are not supported.

da_protocol(output_id=None, tu='ms', vu='mV', cu='pA', n_digits=9)

Returns a myokit.Protocol representation of the D/A output channel specified by name or integer output_id.

If no explicit output channel is set, a guess will be made.

Time units will be converted to tu, voltage units to vu, and current units to cu. Other unit types will be left unchanged. Units may be specified as myokit.Unit objects or strings.

By default, floating point numbers in the protocol will be rounded to 9 digits after the decimal point. This can be customised using the argument n_digits.

If a D/A output cannot be converted to a myokit.Protocol, a ValueError is raised. A NotImplementedError is raised if D/A channels are not supported at all.

da_units(index=None)

Returns the units (as myokit.Unit) of all reconstructed D/A output channels or the units of a specific output channel index.

This will raise a NotImplementedError if D/A channels are not supported.

equal_length_sweeps()

Returns True only if each sweep in this source has the same length.

log(join_sweeps=False, use_names=False, include_da=True)

Returns a myokit.DataLog containing the data from all channels.

The log will have a single entry time corresponding to the time of the first sweep if join_sweeps is False, or the time of all points when join_sweeps is True.

Names will have a systematic form i_sweep.i_channel.label, for example 0.1.channel for sweep 0 of recorded channel 1, or 3.0.da for sweep 3 of reconstructed D/A output 0. These can also be accessed using the syntax log['channel', 1, 0] and log['da', 0, 3].

To obtain a log with the user-specified names from the source instead, set use_names to True. This will result in names such as 0.IN 1 or 3.Cmd 0.

To exclude D/A signal reconstructions, set include_da to False.

A call with join_sweeps=False on a source where equal_length_sweeps() returns False will raise a ValueError.

meta_str(verbose=False)

Optional method that returns a multi-line string with unstructured meta data about the source and its contents.

Will return None if no such string is available.

sweep_count()

Returns the number of sweeps.

Note that a source with zero recorded channels may still report a non-zero number of sweeps if it can provide D/A outputs.

time_unit()

Returns the time unit used in this source.