Guessing variable meanings

The module myokit.lib.guess contains functions that can guess the meaning of model variables. In general, it’s better to use annotation (e.g. labels and binds) for this sort of thing.

In addition, the module contains methods that can manipulate models using these guesses or other heuristics.

myokit.lib.guess.add_embedded_protocol(model, protocol, add_oxmeta_annotations=True)

Attempts to convert a myokit.Protocol to a (discontinuous) expression and embed it in the given :class`myokit.Model`.

Returns True if the model was succesfully updated.

This method is designed for protocols that contain a single, indefinitely recurring event (e.g. cell pacing protocols), and doesn’t handle other forms of protocol.

If add_oxmeta_annotations is set to True, the method will add the relevant oxmeta annotations to any newly created variables

myokit.lib.guess.membrane_capacitance(model)

Guess which model variable (if any) represents the membrane capacitance.

The following strategy is used:

  1. If a variable is found with the annotation oxmeta: membrane_capacitance, this variable is returned.

  2. If not, a list of candidates is drawn up from all constants in the model.

  3. 1.5 points are awarded for being referenced by the membrane potential.

  4. A point is awarded for having a unit compatible with F, F/m^2, or m^2. A point is subtracted for having a unit other than None that’s incompatible with any of the above.

  5. A point is awarded for having the name C, Cm, C_m, Acap or A_cap, or having a name including the string ‘capacitance’ (where the checks are made case-insensitively).

If no suitable candidates are found the method returns None, otherwise the highest ranking candidate is returned.

myokit.lib.guess.membrane_currents(model)

Gueses which model variables represent ionic currents through the outer membrane and returns them.

This method assumes that all currents follow the same sign convention.

Currents defined as sums of currents (or multiples of fluxes) are not expanded.

myokit.lib.guess.membrane_potential(model)

Gueses which model variable (if any) represents the membrane potential and returns it.

Three strategies can be attempted.

First, variables annotated as membrane potential will be returned, regardless of name, units, etc. In order of priority this method will search for (1) the label membrane_potential, (2) the meta data property oxmeta: membrane_voltage.

If no annotated variables are found, the following strategy is used:

  1. A list of candidates is compiled, consisting of all non-nested variables.

  2. Candidates with a unit compatible with voltage get +1 points

  3. Candidates that define a unit (not None) incompatible with voltage are discarded

  4. Candidates in a component with a common name for membrane potential variables get +1 point. Similarly candidates in a common component for membrane potential get +1 point, with an additional +0.5 point if both conditions are met.

  5. State variables get +1 point.

  6. The candidate that is used in the most equations gets +0.1 point.

  7. Candidates with a score < 1 are discarded.

  8. The highest scoring candidate is returned (with no particular tie-breaking rules).

If all strategies fail the method returns None.

myokit.lib.guess.remove_embedded_protocol(model)

Searches the given model for a hardcoded periodic stimulus current and, if one is found, removes it and returns a myokit.Protocol instead.

For this method to work, stimulus_current_info() should return at least a current variable, a period and duration variable, and either an amplitude variable or an amplitude expression.

Returns a myokit.Protocol if succesful, or None if not.

myokit.lib.guess.stimulus_current(model)

Guesses which model variable (if any) represents the stimulus current and returns it.

Three strategies are tried to find the stimulus current.

Firstly, annotated variables are searched for. If found, these are returned without further checking of names, units etc. Supported annotations (in order of priority) are (1) the label stimulus_current, (2) the meta data property oxmeta: membrane_stimulus_current.

If no annotated variables are found, the following strategy is followed:

  1. A list of candidate variables that depend (in)directly on time or pace is compiled. Variables that depend (in)directly on states are discounted.

  2. Each candidate is assign an initial score 1 - 1 / (1 + d), where d is the distance (in the variable graph) to time or pace. As a result, if we define t_beat = engine.time % 1000 then this gets a lower score than I = if(t_beat > 100...).

  3. Candidates that have a unit compatible with current get +1 point.

  4. Candidates that define a unit (not None) incompatible with current are discarded.

  5. Candidates whose name (case-insensitively) matches a known common stimulus current variable name get +2 points.

  6. Remaining candidates are ranked, and the highest scoring candidate is returned. If there is more than one highest scoring candidate an arbitrary one is selected.

If no candiates are found with this approach, a third strategy is tried:

  1. All constants are scanned for variables with a known common name and a current unit (or None). The first such variable is returned.

If all strategies fail, None is returned.

myokit.lib.guess.stimulus_current_info(model)

Guesses the stimulus current variable and related variables representing the stimulus amplitude, duration, period, and offset.

Returns a dict with entries current, amplitude, duration, period, offset, and amplitude_expression, any of which may be None.

The field amplitude_expression will be used if no variable representing the stimulus amplitude can be detected, but a literal expression for it can be found, e.g. from i_stim = -5 [pA].

The method starts by guessing the stimulus current, and looking for annotations:

  1. The stimulus current is guessed using stimulus_current(). If no stimulus current is found the method terminates and returns a dict of None objects.

  2. Any variables annotated with oxmeta stimulus terms are found.

If all fields (except amplitude_expression) are filled now, the method returns. If not, the following strategy is used:

  1. The (direct and indirect) dependencies of the stimulus current are gathered in a list of candidate variables. Whenever a variable is used (e.g. as stimulus duration) it is removed from the list of candidates.

  2. The list is scanned for variables that don’t declare a unit, or that declare a unit compatible with time. The first such variable containing the string duration (if any) is set as the duration variable, and the first containing either offset or start is used for the stimulus offset.

  3. The first candidate that has period in its name and has no units, time units, or is dimensionless, is used for the stimulus period.

The stimulus amplitude is determined as follows:

  1. All remaining candidates are assigned a score 1 / (1 + d) where d is the distance to the stimulus current variable (for a score in the range (0, 0.5]).

  2. Any candidates with unit other than None or the unit of the stimulus current are rejected.

  3. Candidates in the same unit as the stimulus current are given +1 points.

  4. Candidates with a name containing amplitude or current are given +1 points.

  5. If there are one or more candidates, the best is set as stimulus amplitude and the method returns.

If the stimulus amplitude variable has not been determined, the following strategy is used to find a stimulus current _expression_:

  1. If the expression for the stimulus current is a constant, this is set as the amplitude expression.

  2. Otherwise, if the expression is a conditional (an if or a piecewise), then the first piece that isn’t a literal which evaluates to zero is returned.

At this point the method returns, with any undetermined fields left set to None.