Experimental methods
This documentation is work in progress. Currently, the extension of Documenter.jl in my package MoST.jl is still experimental. As the package evolves further, this documentation will increase in readability.
InaMo.ExperimentalMethods
This package contains models that capture experimental methods such as voltage and current clamp protocols, which can be used to measure current or voltage behavior of full cells or individual components.
The methods in this package mainly consist of three base modules: CurrentClamp for current clamp experiments, VoltageClamp for voltage clamp experiments and TestPulses for determining pulse protocols for either type of experiment.
Base classes
InaMo.ExperimentalMethods.Interfaces.TestPulses
This model generates a pulse_signal that stays zero for d_hold seconds and then switches to one for a duration of d_pulse, repeating the cycle with another zero period of d_hold seconds and another pulse of d_pulse seconds.
The pulse_signal can be used to facilitate building pulse protocols by simply using the formula x = x_hold + pulse_signal * (x_pulse - x_hold) where x is the resulting pulse signal and x_hold is the value of x during the holding period and x_pulse is the value of x during the pulse.
model TestPulses "generic component to generate a dimensionless pulse signal"
parameter SI.Duration d_hold = 2 "holding period";
parameter SI.Duration d_pulse = 0.050 "pulse period";
output Boolean pulse_start = sample(d_hold, d_hold + d_pulse) "signals start of pulse";
output Boolean pulse_end = sample(d_hold + d_pulse, d_hold + d_pulse) "signals end of pulse";
output Integer pulse_signal(start = 0, fixed = true) "0 during holding period, 1 during pulse";
equation
when pulse_start then
pulse_signal = 1;
elsewhen pulse_end then
pulse_signal = 0;
end when;
annotation(
Documentation(info = "<html>
<p>
This model generates a pulse_signal that stays zero for d_hold seconds
and then switches to one for a duration of d_pulse, repeating the cycle
with another zero period of d_hold seconds and another pulse of d_pulse
seconds.
</p>
<p>
The pulse_signal can be used to facilitate building pulse protocols by
simply using the formula x = x_hold + pulse_signal * (x_pulse - x_hold)
where x is the resulting pulse signal and x_hold is the value of x
during the holding period and x_pulse is the value of x during the pulse.
</p>
</html>"),
Icon(graphics = {Line(origin = {-55.7024, -80.0376}, points = {{-40.2575, -14}, {-20.2575, -14}, {-20.2575, 14}, {-16.2575, 14}, {-16.2575, -14}, {-0.257485, -14}, {-0.257485, 14}, {3.74251, 14}, {3.74251, -14}, {19.7425, -14}, {19.7425, 14}, {23.7425, 14}, {23.7425, -14}, {37.7425, -14}}, color = {0, 0, 255})}));
end TestPulses;
Voltage clamp methods
InaMo.ExperimentalMethods.VoltageClamp.VoltageClamp
Simple voltage clamp model.
The positive pin of this component represents the extracellular electrode while the negative pin represents the intracellular electrode(s).
A positive value for v_stim leads to a positive outward voltage.
model VoltageClamp "general voltage clamp model"
extends InaMo.Currents.Interfaces.TwoPinVertical;
extends InaMo.Icons.CurrentClamp;
Modelica.Electrical.Analog.Sources.SignalVoltage stim(v = v_stim) "stimulation model inducing input voltage into circuit";
Modelica.Electrical.Analog.Basic.Ground g "ground electrode";
SI.Voltage v_stim "input voltage (needs to be defined externally)";
SI.Current i(nominal = 1e-12) = -stim.i "measured membrane current";
equation
connect(p, stim.p);
connect(n, stim.n);
connect(stim.n, g.p);
annotation(
Documentation(info = "<html>
<p>Simple voltage clamp model.</p>
<p>The positive pin of this component represents the extracellular electrode
while the negative pin represents the intracellular electrode(s).</p>
<p>A positive value for v_stim leads to a positive outward voltage.</p>
</html>"),
Icon(graphics = {Text(origin = {57, -68}, extent = {{-27, 18}, {43, -32}}, textString = "V")}));
end VoltageClamp;
InaMo.ExperimentalMethods.VoltageClamp.VCTestPulses
model VCTestPulses "voltage clamp that sends periodic test pulses"
extends VoltageClamp;
extends InaMo.ExperimentalMethods.Interfaces.TestPulses;
parameter SI.Voltage v_hold = -0.090 "voltage during holding period";
discrete input SI.Voltage v_pulse "voltage during pulse (must be defined externally)";
equation
v_stim = pulse_signal * (v_pulse - v_hold) + v_hold;
end VCTestPulses;
InaMo.ExperimentalMethods.VoltageClamp.VCTestPulsesPeak
Ths model extends VCTestPulses with the capability to capture three different types of peak currents:
- "peak": The peak current achieved between pulse_start and pulse_end, i.e. during the pulse
- "tail": The peak current achieved between pulse_end and the next pulse_start, i.e. after the pulse
- "end": The current achieved at pulse_end
The word "peak" in these descriptions refers to the farthest distance to zero achieved during the respective time period. This can either be the global maximum or the global minimum.
Consequently, all three current measures (is_peak, is_tail, and is_end) capture the information of the last pulse cycle. is_end and is_peak are updated at pulse_end and is_tail is updated at pulse_start.
For plotting convenience, the variables vs_peak, vs_tail, and vs_end capture the voltages of the pulse associated with the current measurement in is_peak, is_tail, and is_end respectively. A parametric current-voltage plot then becomes possible by just plotting a pair like (is_peak, vs_peak) without having to process the simulation output.
model VCTestPulsesPeak "voltage clamp with test pulse protocol and peak capture"
extends VCTestPulses;
discrete SI.Current is_peak(start = 0, fixed = true, nominal = 1e-12) "steady step function of peak current during last pulse";
discrete SI.Current is_tail(start = 0, fixed = true, nominal = 1e-12) "steady step function of peak tail current after last pulse";
discrete SI.Current is_end(start = 0, fixed = true, nominal = 1e-12) "steady step function of current at end of last pulse";
discrete SI.Voltage vs_peak(start = 0, fixed = true) "steady step function of pulse associated with is_peak";
discrete SI.Voltage vs_end(start = 0, fixed = true) "steady step function of pulse associated with is_end";
discrete SI.Voltage vs_tail(start = 0, fixed = true) "steady step function of pulse associated with is_tail";
protected
discrete SI.Current peak_i(start = 0, fixed = true, nominal = 1e-12) "peak current during pulse";
discrete SI.Current tail_i(start = 0, fixed = true, nominal = 1e-12) "peak current after pulse";
Boolean peak_indicator(start = false, fixed = true) = der(i) * 1e12 < 0 "forces event at peak (factor of 1e12 is required to detect zero crossing)";
discrete SI.Time tp_last(start = 0, fixed = true) "time stamp of start of last pulse";
discrete SI.Voltage vp_last(start = 0, fixed = true) "voltage of last pulse";
Boolean within_pulse = time - pre(tp_last) < d_pulse "true during pulse";
Boolean after_pulse = time - pre(tp_last) > d_pulse "true after pulse has passed";
function absmax "returns input whose absolute value is larger, preserving the sign"
input Real a "first input";
input Real b "second input";
output Real m "a if abs(a) > abs(b), otherwise b";
algorithm
m := if abs(a) > abs(b) then a else b;
end absmax;
equation
when pulse_start then
peak_i = i;
elsewhen change(peak_indicator) and within_pulse or pulse_end then
peak_i = absmax(i, pre(peak_i));
end when;
when pulse_end then
tail_i = i;
elsewhen change(peak_indicator) and after_pulse or pulse_end then
tail_i = absmax(i, pre(tail_i));
end when;
when pulse_start then
is_tail = pre(tail_i);
vs_tail = pre(vp_last);
tp_last = time;
vp_last = v_pulse;
end when;
when pulse_end then
is_end = pre(i);
is_peak = pre(peak_i);
vs_end = vp_last;
vs_peak = vs_end;
end when;
annotation(
Documentation(info = "<html>
<p>Ths model extends VCTestPulses with the capability to capture three
different types of peak currents:</p>
<ul>
<li>"peak": The peak current achieved between pulse_start and
pulse_end, i.e. <i>during</i> the pulse</li>
<li>"tail": The peak current achieved between pulse_end and the
next pulse_start, i.e. <i>after</i> the pulse</li>
<li>"end": The current achieved at pulse_end</li>
</ul>
<p>The word "peak" in these descriptions refers to the farthest
distance to zero achieved during the respective time period.
This can either be the global maximum or the global minimum.</p>
<p>Consequently, all three current measures (is_peak, is_tail, and is_end)
capture the information of the last pulse cycle.
is_end and is_peak are updated at pulse_end and is_tail is updated at
pulse_start.</p>
<p>For plotting convenience, the variables vs_peak, vs_tail, and vs_end
capture the voltages of the pulse associated with the current measurement
in is_peak, is_tail, and is_end respectively.
A parametric current-voltage plot then becomes possible by just plotting
a pair like (is_peak, vs_peak) without having to process the simulation
output.</p>
</html>"));
end VCTestPulsesPeak;
Current clamp methods
InaMo.ExperimentalMethods.CurrentClamp.CurrentClamp
Simple current clamp model.
The positive pin of this component represents the extracellular electrode while the negative pin represents the intracellular electrode(s).
A positive value for i_stim leads to a positive outward current.
To measure the voltage in the circuit, the variable v can be used, which is introduced through the base class TwoPinVertical.
model CurrentClamp "current clamp that defines input current to measure voltage response"
extends InaMo.Currents.Interfaces.TwoPinVertical;
extends InaMo.Icons.CurrentClamp;
Modelica.Electrical.Analog.Sources.SignalCurrent stim(i = i_stim) "stimulation model inducing input current into circuit";
Modelica.Electrical.Analog.Basic.Ground g "ground electrode";
SI.Current i_stim "input current (needs to be defined externally)";
equation
connect(p, stim.p);
connect(n, stim.n);
connect(stim.n, g.p);
annotation(
Documentation(info = "<html>
<p>Simple current clamp model.</p>
<p>The positive pin of this component represents the extracellular electrode
while the negative pin represents the intracellular electrode(s).</p>
<p>A positive value for i_stim leads to a positive outward current.</p>
<p>To measure the voltage in the circuit, the variable v can be used, which
is introduced through the base class TwoPinVertical.</p>
</html>"),
Icon(graphics = {Text(origin = {57, -68}, extent = {{-27, 18}, {43, -32}}, textString = "I")}));
end CurrentClamp;
InaMo.ExperimentalMethods.CurrentClamp.CCTestPulses
model CCTestPulses "current clamp that sends periodic test pulses"
extends CurrentClamp;
extends InaMo.ExperimentalMethods.Interfaces.TestPulses;
parameter SI.Current i_hold = 0 "current during holding period";
// FIXME cannot be discrete in OpenModelica, but should be
input SI.Current i_pulse "current during pulse (must be defined externally)";
equation
i_stim = pulse_signal * (i_pulse - i_hold) + i_hold;
end CCTestPulses;