Gates

Overview

Gates are the most basic building block for describing dynamics in Conductor.jl. A gate integrates zero or more inputs into a single unitless weighting value. If desired, we can explicitly define the symbolic expression that models the output of a gate:

using Conductor, ModelingToolkit
# Voltage-dependent sigmoid activation
Vₘ = ParentScope(MembranePotential())
@named sigmoid = Gate(inv(1 + exp(-Vₘ)))

# output
Gate{SimpleGate}(SimpleGate, sigmoid(t), Symbolics.Equation[sigmoid(t) ~ 1 / (1 + exp(-Vₘ(t)))], Dict{Symbol, Any}())

The dynamics of a Gate{SimpleGate} are just an algebraic equation:

Alternatively, we can take advantage of customized constructors, which let us describe gate dynamics in a more canonical, domain-friendly form. For instance, in the classic Hodgkin-Huxley formalism, gates are analogous to the "gating particles" used to describe the kinetics of voltage-gated ion channels. In the scientific literature, ionic channel kinetics are often described in terms of forward ($\alpha$) and reverse ($\beta$) reaction rates:

# Sodium channel inactivation kinetics, defined by forward and reverse rxn rates
@named h = Gate(
    AlphaBeta,
    # the α (forward) reaction rate
    0.07*exp(-(Vₘ+65.0)/20.0),
    # the β (reverse) reaction rate
    1.0/(1.0 + exp(-(Vₘ + 35.0)/10.0))
)

# output
Gate{AlphaBeta}(AlphaBeta, h(t), Symbolics.Equation[Differential(t)(h(t)) ~ (-h(t)) / (1.0 + exp(0.1(-35.0 - Vₘ(t)))) + 0.07(1 - h(t))*exp(0.05(-65.0 - Vₘ(t)))], Dict{Symbol, Any}(:ss => (0.07exp(0.05(-65.0 - Vₘ(t)))) / (1.0 / (1.0 + exp(0.1(-35.0 - Vₘ(t)))) + 0.07exp(0.05(-65.0 - Vₘ(t))))))

Gate{AlphaBeta} will automatically setup the differential form, equivalent to:

\[\frac{dh}{dt} = \alpha_h (1-h)-\beta_h h\]

Advanced Gates & Customization

Conductor.jl provides a handful of ready-made Gate types for convenience. But gates may also be user-customized. The following must be implemented for each gate:

  • Create a trait label: struct MyNewGate <: GateVarForm end
  • Define the following methods:
    • Conductor.Gate(::Type{MyNewGate}, ...)
      • This should return with a call to Gate{MyNewGate}(output::Num; kwargs...)
    • Conductor.output(gate::Gate{MyNewGate})::Num
    • ModelingToolkit.get_eqs(gate::Gate{MyNewGate}, compartment::AbstractCompartmentSystem)::Vector{Equation}
Note

Keyword arguments passed to Gate{<:GateVarType}(output::Num; kwargs...) are stored as a dictionary and can be accessed via get, getproperty or (equivalently) dot syntax (e.g. mygate.x)

Conductor.GateVarFormType
abstract type GateVarForm

Abstract supertype for extending the behavior of Gate.

Stub subtypes of GateVarForm are used as traits when writing new methods that call Gate objects.

Example

struct MyNewGate <: Conductor.GateVarForm end

function Conductor.get_eqs(g::Gate{MyNewGate}, comp::CompartmentSystem)
    # a function that returns a vector of equations defining gate dynamics
end
source
Conductor.GateType
struct Gate{T<:Conductor.GateVarForm} <: Conductor.AbstractGatingVariable

Low-level constructor for Gate.

A gate has a single symbolic output and stores properties (passed as a variable length list of keyword arguments). Gate properties are accessible via get and getproperty.

Example

julia> @variables t X(t)
2-element Vector{Num}:
    t
 X(t)

julia> g = Gate{MyGateType}(MyGateType, X, Equation[], prop1 = "foo", prop2 = 62)
Gate{MyGateType}(MyGateType, X(t), Symbolics.Equation[], Dict{Symbol, Any}(:prop2 => 62, :prop1 => "foo"))

julia> (g.prop1, g.prop2)
("foo", 62)
source
Gate(
    form::Type{AlphaBeta},
    α,
    β;
    name,
    kwargs...
) -> Gate{AlphaBeta}

Accepts expressions for forward (α) and reverse (β) reaction rates as descriptors for its kinetics.

See also: get_eqs.

source
Gate(
    form::Type{SteadyStateTau},
    x∞,
    τₓ;
    name,
    kwargs...
) -> Gate{SteadyStateTau}

Accepts expressions for its steady-state activation, x∞(Vₘ), and the time constant, τₓ(Vₘ), as descriptors for its kinetics.

See also: get_eqs.

source
Gate(
    form::Type{SimpleGate},
    rhs::Symbolics.Num;
    default,
    name,
    kwargs...
) -> Gate{SimpleGate}

Accepts any symbolic expression as an explicit definition of the gate dynamics.

source
Gate(
    form::Type{Conductor.ParameterGate},
    val;
    name,
    kwargs...
) -> Gate{Conductor.ParameterGate}

A static parameter gate with initial value, val.

source