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 toGate{MyNewGate}(output::Num; kwargs...)
- This should
Conductor.output(gate::Gate{MyNewGate})::Num
ModelingToolkit.get_eqs(gate::Gate{MyNewGate}, compartment::AbstractCompartmentSystem)::Vector{Equation}
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.GateVarForm
— Typeabstract 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
Conductor.Gate
— Typestruct 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)
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
.
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
.
Gate(
form::Type{SimpleGate},
rhs::Symbolics.Num;
default,
name,
kwargs...
) -> Gate{SimpleGate}
Accepts any symbolic expression as an explicit definition of the gate dynamics.
Gate(
form::Type{Conductor.ParameterGate},
val;
name,
kwargs...
) -> Gate{Conductor.ParameterGate}
A static parameter gate with initial value, val
.