Model
¶
The central object in Myokit is the Model
. In most scenario’s, models
are created by parsing a file in
mmt syntax. Once parsed, a model can be
validated
to ensure its integrity. In models with
unsound semantics (for example a cyclical reference between variables) the
validate()
method will raise an IntegrityError
.
For models with a limited number of state variables, validation is fast. In
these cases, the validate()
method is run after parsing as an additional
check. For larger models, validation is costly and avoided until a simulation
is run or another analysis method is used.
Once created and validated, a model can be asked to
compute the solvable order of its equations
which can then be used by an exporter to generate runnable simulation or
analysis code.
myokit.Model
¶
-
class
myokit.
Model
(name=None)¶ Represents an electrophysiological cell model, structured in components.
Components can be added to the model using
add_component()
. Access to a model’s component is provided through theget()
method andcomponents()
.Minimal dictionary support is provided: A component named “x” can be obtained from a model
m
usingm["x"]
. The number of components inm
is given bylen(m)
and the presence of “x” inm
can be tested usingif "x" in m:
.Variables stored inside components can be accessed using
get()
orvalues()
. Values defined through their derivative make up the model state and can be accessed usingstates()
. States have initial values accessible throughinits()
.A model’s validity can be checked using
is_valid()
, which returns the latest validation status andvalidate()
, which (re)validates the model. Warnings can be obtained usingwarnings()
The optional constructor argument
name
can be used to set a meta property “name”.Meta-data properties can be accessed via the property
meta
, for examplemodel.meta['key']= 'value'
.-
add_component
(name)¶ Adds a component with the given name to this model.
This method resets the model’s validation status.
-
add_component_allow_renaming
(name)¶ Attempts to add a component with the given name to this model, but uses a different name if this causes any conflicts.
The new component’s name will be modified by appending _1, _2, etc. until the conflict is resolved.
This method can be used when symbolically manipulating a model in situations where the exact names are unimportant.
Returns the newly created component.
-
add_function
(name, arguments, template)¶ Adds a user function to this model.
-
binding
(binding)¶ Returns the variable with the binding label
binding
. If no such variable is found,None
is returned.
-
bindings
()¶ Returns an iterator over all (binding label : variable) mappings in this model.
-
check_units
(mode=1)¶ Checks the units used in this model. Models can specify units in two ways:
- By setting a Variable unit. This is done using the
in
keyword inmmt
syntax or through the methodmyokit.Variable.set_unit()
. This specifies the unit the variable’s value should be in. - By adding units to the literals in variables’ right hand
expressions. This is done using square brackets in
mmt
syntax (for example5 [m] / 10 [s]
) or by adding a unit when creating a Number object, for exampleNumber(2, myokit.parse_unit('mV')
.
Per variable, the unit check proceeds in two steps:
- The unit resulting from the variable’s RHS is evaluated. This may
trigger an
myokit.IncompatibleUnitExpression
if any inompatibilities are found in the expression (see below). - The calculated unit is compared with the variable unit. An
IncompatibleUnitError
will be triggered if the two units don’t match.
Two unit-checking modes are available.
In strict mode (
mode=myokit.UNIT_STRICT
), all unspecified units in expressions are treated as “dimensionless”. For example, the expression5 * V
whereV
is in[mV]
will be treated as dimensionless times millivolt (or[1] * [mV] in mmt syntax), resulting in the unit ``[mV]
. The expression5 + V
will be interpreted as dimensionless plus millivolt, and will raise an error. In strict mode, functions such assin
andexp
will check that their argument is dimensionless (sosin(3 [m])
is never allowed, only e.g.sin(3 [m] / 1 [m])
).In tolerant mode, unspecified units will be treated as whatever makes the expression work. So
? + [mV]
wil be interpreted as[mV] + [mV]
. In addition, functions that require dimensionless input in strict mode won’t perform this check in tolerant mode.A note about references:
In both modes, when a reference is encountered, for example when checking the expression
5 * y
, the system will look up the variable y’s unit, and will not look at y’s rhs. Consider the following buggy model:x = 5 [mV] # RHS unit, no variable unit y = 3 [A] + x # RHS unit, no variable unitWhen checking the expression
y = 3 + x
the variablex
will be treated as unspecified, because no variable unit is set forx
using thein
keyword. In strict mode, this will lead to an error when checkingx = 5 [mV]
becausex
is dimensionless while5 [mV]
has units[mV]
. In tolerant mode, no error will be raised. When tolerantly evaluatingy = 3[A] + x
it will be assumed thatx
is also in[A]
, because no variable unit is given that says otherwise, despite the RHS ofx
having unitsmV
.- By setting a Variable unit. This is done using the
-
clone
()¶ Returns a deep clone of this model.
-
code
(line_numbers=False)¶ Returns this model in
mmt
syntax.Line numbers can be added by setting
line_numbers=True
.
-
component_cycles
()¶ Finds cyclical references between components and returns them. For example, if
a.p
depends onb.q
whileb.x
depends ona.y
, a cyclea > b > a
will be returned.For a faster way to check if there are any interdependent components (without returning the exact cycles found), use
has_interdependent_components()
.
-
components
(sort=False)¶ Returns an iterator over this model’s component objects.
-
count_components
()¶ Returns the number of components in this model.
-
count_equations
(const=None, inter=None, state=None, bound=None, deep=False)¶ Returns the number of equations matching the given criteria. See
equations()
for an explanation of the arguments.
-
count_states
()¶ Returns the number of state variables in this model.
-
count_variables
(const=None, inter=None, state=None, bound=None, deep=False)¶ Returns the number of variables matching the given criteria. See
variables()
for an explanation of the arguments.
-
create_unique_names
()¶ Create a globally unique name for each Component and Variable.
Ideally, the global name equals the variable or component’s basic name. If a name is disputed the following strategy will be used:
- For variables, the parent name will be added as a prefix to all variables claiming the disputed name.
- If problems persist, a suffix
_i
will be added, wherei
is the first integer which doesn’t result in clashing names.
-
equations
(const=None, inter=None, state=None, bound=None, deep=False)¶ Creates and returns a filtered iterator over the equations of this object’s variables.
The returned values can be filtered using the following arguments:
const=True|False|None
Set to
True
to return only constants’ equations.False
to exclude all constants and any other value to ignore this check.For a definition of “constant variable” see
variables()
.inter=True|False|None
Set to
True
to return only intermediary variables’ equations,False
to exclude all intermediary variables and any other value to ignore this check.For a definition of “intermediary variable” see
variables()
.state=True|False|None
- Set to
True
to return only state variables’ equations,False
to exclude all state variables and any other value to ignore this check. bound=True|False|None
- Set to
True
to return only bound variables’ equations,False
to exclude all bound variables and any other value to ignore this check. deep=True|False
(by default it’sFalse
)- Set to
True
to include the equations of nested variables meeting all other criteria.
-
eval_state_derivatives
(state=None, inputs=None, precision=64, ignore_errors=False)¶ Evaluates and returns the values of all state variable derivatives. The values are returned in a list sorted in the same order as the state variables.
If given, the state values given by
state
will be used as starting point. Herestate
can be any object accepted as input by :meth:map_to_state()
.To set the values of external inputs, a dictionary mapping binding labels to values can be passed in as
inputs
.To assist in finding the origins of numerical errors, the equations can be evaluated using 32 bit floating point. To do this, set
precision=myokit.SINGLE_PRECISION
.By default, the evaluation routine raises
myokit.NumericalError
exceptions for invalid operations. To returnNaN
instead, setignore_errors=True
.
-
expressions_for
(variable)¶ Returns a tuple
(eqs, args)
whereeqs
is a list of Equation objects in solvable order containing the minimal set of equations needed to evaluate the givenvariable
andargs
is a list of the state variables and bound variables these expressions require as input.
-
format_state
(state=None, state2=None)¶ Converts the given list of floating point numbers to a string where each line has the format
<full_qualified_name> = <float_value>
. If no state is given the one returned bystate()
is used.An optional second state can be added for display as
state2
.
-
format_state_derivatives
(state=None, derivatives=None)¶ Like
format_state()
but displays the derivatives along with each state’s value.
-
format_warnings
()¶ Formats all warnings generated during the last call to
validate()
and returns a string containing the result.
-
get
(name, class_filter=None)¶ Searches for a component or variable with the given
qname
and returns it.To return only objects of a certain class, pass it in as
class_filter
.
-
get_function
(name, nargs)¶ Returns the user function with name
name
andnargs
arguments.
-
has_component
(name)¶ Returns
True
if this model has a component with the givenname
.
-
has_equations
(const=None, inter=None, state=None, bound=None, deep=False)¶ Returns True if there are any equations that can be returned by calling :meth:
equations
with the same arguments.
-
has_interdependent_components
()¶ Returns
True
if this model contains mutually dependent components. That is, if there exists any component A whose variables depend on variables from component B, while variables in component B depend on variables in component A.To see the variables causing the interdependence, use
component_cycles()
.
-
has_variable
(name)¶ Returns True if the given name corresponds to a variable in this object. Accepts both single names
x
and qualified namesx.y
as input.This function performs the same search as
variable
, so in most cases it will be more efficient to callvariable()
in a try-catch block rather than checking for existence explicitly.
-
has_variables
(const=None, inter=None, state=None, bound=None, deep=False)¶ Returns True if there are any variables that can be returned by calling :meth:
variables
with the same arguments.
-
has_warnings
()¶ Returns True if this model has any warnings.
-
inits
()¶ Returns an iterator over the
Equation
objects defining this model’s current state.
-
is_valid
()¶ Returns
True
if this model is valid,False
if it is invalid andNone
if the validation status has not been determined withvalidate()
.Valid models may still have one or more warnings.
-
item_at_text_position
(line, char)¶ Finds the component, variable, or expression at the position
(line, char)
, and returns a tuple(token, object)
with a parser token and the found object, orNone
if nothing is found.Both
line
andchar
should be given as integers. The first line is line 1, while the first character is char 0.
-
label
(label)¶ Returns the variable with the given label. If no variable is labelled as
label
it returnsNone
.
-
labels
()¶ Returns an iterator over all (label : variable) mappings in this model.
-
load_state
(filename)¶ Sets the model state using data from a file formatted in any style accepted by
myokit.parse_state()
.
-
map_component_dependencies
(omit_states=True, omit_constants=False)¶ Scans all equations and creates a map of inter-component dependencies.
The result is an ordered dictionary with the following structure:
{ comp1 : [dep1, dep2, dep3, ...], comp2 : [dep1, dep2, dep3, ...], ... }
where
comp1, comp2, ...
are Components anddep1, dep2, ...
are the components they depend upon.Only direct dependencies are listed: If
A
depends onB
andB
depends onC
then the returned value forA
is[B]
, not[B,C]
.By default, dependencies on state variables’ current values are omitted. This behaviour can be changed by setting
omit_states
toFalse
.To omit all dependencies on constants, set
omit_constants
toTrue
.
-
map_component_io
(omit_states=False, omit_derivatives=False, omit_constants=False, rl_states=None)¶ Scans all equations and creates a list of input and output variables for each component.
Input variables are taken to be any foreign variables the component needs to perform its calculations, plus the current values of its own state variables if it needs them.
Output variables are taken to be any values calculated by this component but used outside it. This includes the derivatives of the state variables it calculates. State variables are never given as outputs, as it is assumed these are updated by an ODE solver.
The output can be customized using the following arguments:
omit_states
- Set to
True
to omit state values from the input lists. This can be useful in cases where the state is stored in a vector. omit_derivatives
- Set to
True
to omit derivatives from the input and output lists. This can be useful if derivatives are stored in a vector. omit_constants
- Set to
True
to omit constants from the input and output lists. This can be useful if constants are stored globally, e.g. as C macros. rl_states
- A map
{state_variable : {inf_variable, tau_variable}
can be passed in to enable mapping for Rush-Larsen schemes. In this case, all variables listed asinf
ortau_variable
will be included in component output lists, and the derivatives of eachstate_variable
in the mapping will only be added to the output list if there are other variables that depend on it.
The result is a tuple containing two
OrderedDict
objects, each of the following structure:{ comp1: [lhs1, lhs2, ...], comp2: [lhs1, lhs2, ...], ... }
The first dict contains the inputs to every component, the second dict contains every components output values. The values in the lists are :class:
LhsExpression
objects referring to either a variable or its derivative.
-
map_deep_dependencies
(collapse=False, omit_states=True, filter_encompassed=False)¶ Scans the list of equations stored in this model and creates a map relating each equation’s left hand side to a list of other
LhsExpressions
it depends on, either directly or through an intermediate variable.The method
map_shallow_dependencies()
performs a similar check, but only returns direct dependencies. This method expands the full dependency tree.The result is an
OrderedDict
with the following structure:{ lhs1 : [dep1, dep2, dep3, ...], ... }
where
lhs1
is aLhsExpression
anddep1
,dep2
anddep3
are theLhsExpression
objects it depends upon.If the system is not solvable: that is, if it contains cyclical references, a
myokit.IntegrityError
is raised.If the optional parameter
collapse
is set toTrue
nested variables will not be listed separatly. Instead, their dependencies will be added to the dependency lists of their parents.By default, dependencies on state variables’ current values are omitted. This behaviour can be changed by setting
omit_states
toFalse
.In case of a dependency such as:
a = f(b) b = g(c)
The set returned for
a
will includeb
andc
. So whilea
here depends on bothb
andc
,b
’s sole dependency onc
meansa
can be calculated if justc
is known. To filter out the dependency onb
, setfilter_encompassed
toTrue
. Note that this will also filter out all dependencies on constants, since a constant’s dependencies (an empty set) can be said to be included in all other sets.
-
map_shallow_dependencies
(collapse=False, omit_states=True, omit_constants=False)¶ Scans the list of equations stored in this model and creates a map relating each equation’s left hand side to a list of other
LhsExpressions
it depends on directly.In contrast to the method
map_deep_dependencies()
, that performs a deep search for all nested dependencies, this method only returns direct dependencies. I.E. LhsExpressions named specifically in the equation’s right hand side.The result is an
OrderedDict
with the following structure:{ lhs1 : [dep1, dep2, dep3, ...], ... }
where
lhs1
is aLhsExpression
anddep1
,dep2
anddep3
are theLhsExpression
objects it depends upon.In special cases, the obtained result can differ from the mathematical concept of a dependency: if
x = 0 * y
the function will return a dependency ofx
ony
. Similarly, forx = if(cond, a, b)
the function will report a dependency ofx
oncond
,a
andb
.If the optional parameter
collapse
is set toTrue
nested variables will not be listed separatly. Instead, their dependencies will be added to the dependency lists of their parents.By default, dependencies on state variables’ current values are omitted. This behaviour can be changed by setting
omit_states
toFalse
. Dependencies on constants are included by default, but this can be changed by settingomit_constants
toTrue
.
-
map_to_state
(state)¶ This utility function accepts a number of different input types and returns a list of floats in the same order as the model’s state variables.
The following types of input are meaningfully handled:
- A dictionary mapping state variable names or objects to floats
- A dictionary mapping state variable names or objects to lists. The
last value in every list will be used. This allows the dictionary
returned by
myokit.Simulation.run()
to be used directly. - A formatted string declaring each variable’s value using the syntax
component.var_name = 1.234
or simply containing a comma or space delimited list of floats. - A list of scalars. In this case, the list length will be checked and all values converted to float. No re-ordering takes place.
-
merge_interdependent_components
()¶ Deprecated alias of
resolve_interdependent_components()
.
-
name
()¶ Returns the model meta property
name
, orNone
if it isn’t set.
-
prepare_bindings
(labels)¶ Takes a mapping of binding labels to internal references as input and returns a mapping of variables to internal references. All variables appearing in the map will have their right hand side set to zero. All bindings not mapped to any internal reference will be deleted.
The argument
mapping
should take the form:labels = { 'binding_label_1' : internal_name_1, 'binding_label_2' : internal_name_2, ... }
The returned dictionary will have the form:
variables = { variable_x : internal_name_1, variable_y : internal_name_2, ... }
Unsupported bindings (i.e. bindings not appearing in
labels
) will be ignored.
-
remove_component
(component)¶ Removes a component from the model.
This will reset the model’s validation status.
-
reorder_state
(order)¶ Changes the order of this model’s state variables. The argument
order
must be a list of state variables or their qnames.This method does not affect the model’s validation status.
-
reserve_unique_names
(*unames)¶ Reserves one or more names that won’t be used in unique names (unames).
This function can be used to add keywords to a model before exporting. After reserving one or more keywords, use
create_unique_names()
to reset the model’s unames.Adding new names does _not_ clear the previously reserved names.
-
resolve_interdependent_components
()¶ Checks if the model contains components that each depend on the other. If so, variables from these components will be moved to a new component called “remaining” until the issue is resolved.
-
save_state
(filename)¶ Saves the model state to a file.
-
set_name
(name=None)¶ Changes the value of the meta-property “name”.
-
set_state
(state)¶ Changes this model’s state. Accepts any type of input handled by
map_to_state()
.
-
set_value
(qname, value)¶ Changes a variable’s defining expression to the given number or
myokit.Expression
.For state variables, this updates the expression for their derivative. For all other variables, the expression for their value is updated.
This will reset the model’s validation status.
-
show_evaluation_of
(var)¶ Returns a string representing the evaluation of a single variable.
The variable’s equation and value are displayed, along with the value and formula of any nested variables and the values of all dependencies.
-
show_expressions_for
(var)¶ Returns a string containing the expressions needed to evaluate the given variable from the state variables.
-
show_line
(var)¶ Deprecated alias of
show_line_of()
.
-
show_line_of
(var)¶ Returns a string containing the type of variable
var
is and the line it was defined on.
-
solvable_order
()¶ Returns all equations in a solvable order. The resulting output has the following structure:
OrderedDict { 'comp1' : EquationList([eq1, eq2, eq3, ...]), 'comp2' : EquationList([eq1, eq2, eq3, ...]), ..., '*remaining*' : EquationList([eq1, eq2, eq3]) }
The
OrderedDict
contains each component’s name as a key and maps it to a list of equations that can be solved for this component, stored in an :class:EquationList
object which extends thelist
type with a number of special iterators.The order of the components is such that the components with the fewest dependencies are listed first, in an effort to ensure as many equations as possible can be solved on a per-component basis.
The final entry in the
OrderedDict
is a list of all remaining equations that could not be solved on a per-component basis. For models that contain fully separable components (that is, if the model contains only components that depend on each other non-cyclically) this list will be empty.
-
solvable_subset
(*args)¶ This method is deprecated and will be removed in future versions of Myokit.
Returns all equations dependent on one or more
LhsExpression
objects in a solvable order. The resulting equations are stored in anEquationList
.The returned equations can be used to recalculate the model expressions, given new values for the variables in
args
.The input arguments can be given as
LhsExpression
objects or string names of variables.
-
state
()¶ Returns the current state of the model as a list of floating point numbers.
-
suggest_variable
(name)¶ Returns a tuple
(found, suggested, msg)
.If the requested variable is found, only the
found
part of the tuple is set. If not, the second and third argument are set. Heresuggested
will take the form of a suggested variable with a similar name, whilemsg
will be a suggested error message.
-
time
()¶ Returns this model’s time variable.
The time variable is identified by it’s binding to the external source “time”. For a valid model, this method always returns a unique variable. If no time variable has been declared
None
is returned.
-
time_unit
(mode=1)¶ Returns the units used by this model’s time variable.
If no time unit is set and
mode
ismyokit.UNIT_TOLERANT
(default), thenNone
is returned. Withmode
set tomyokit.UNIT_STRICT
the returned value in this case ismyokit.units.dimensionless
.
-
user_functions
()¶ Returns a dictionary mapping this model’s user function names to their
Expression
objects.
-
validate
(remove_unused_variables=False)¶ Attempts to check model validity, raises errors if it isn’t.
Small issues (e.g. unused variables) will generate warnings, which can be retrieved using
Model.warnings()
orModel.format_warnings()
. Any previously set warnings will be erased whenever validate() is run.If
remove_unused_variables
is set to True, any unused variables will be removed from this model during validation.
-
value
(qname)¶ Returns the value of a variable.
-
var
(name)¶ Searches for the given variable and returns it if found. Accepts both single names
x
and qualified namesx.y
as input.
-
variables
(const=None, inter=None, state=None, bound=None, deep=False, sort=False)¶ Creates and returns a filtered iterator over the contained variables.
The returned values can be filtered using the following arguments:
const=True|False|None
Constants are defined as variables that do not depend on state variables or derivatives. In other words, any variable whose value can be determined before starting an ODE solving routine.
Set to
True
to return only constants,False
to exclude all constants and any other value to ignore this check.inter=True|False|None
Intermediary variables are those variables that are not constant but are not part of the state. In other words, intermediary variables are the variables that need to be calculated at every step of an ODE solving routine before calculating the ODE derivatives and updating the state.
Set to
True
to return only intermediary variables,False
to exclude all intermediary variables and any other value to ignore this check.state=True|False|None
- Set to True to return only state variables, False to exclude all state variables and any other value to ignore this check.
bound=True|False|None
- Set to True to return only variables bound to an external value, False to exclude all bound variables and any other value to forgo this check.
deep=True|False
(by default it’sFalse
)- Set to True to return nested variables meeting all other criteria.
sort=True|False
(by default it’sFalse
)- Set to True to return the variables in a consistent order. (Note that this does _not_ mean alphabetical sorting of all variables, just that the order is consistent between calls!)
-
warnings
()¶ Returns a list containing the warnings generated in this model.
-
myokit.ModelPart
¶
-
class
myokit.
ModelPart
(parent, name)¶ Base class for model parts.
-
code
()¶ Returns this object in
mmt
syntax.
-
is_ancestor
(obj)¶ Returns
True
if this object is an ancestor of the givenModelPart`
object
.
-
model
()¶ Returns the
myokit.Model
this object belongs to (if set).
-
name
()¶ Returns this object’s name.
-
parent
(kind=None)¶ Returns this object’s parent.
If the optional variable
kind
is set, the method will scan until an instance of the requested type is found.
-
qname
(hide=None)¶ Returns this object’s fully qualified name. That is, an object named
y
with a parent namedx
will return the stringx.y
. Ify
has a childz
its qname will bex.y.z
.If the optional argument
hide
is set to this object’s parent the parent qualifier will be omitted.
-
uname
()¶ Returns a globally unique name for this object.
-
Name validation¶
-
myokit.
check_name
(name)¶ Tests if the given name is a valid myokit name and raises a
myokit.InvalidNameError
if it isn’t.