// Na Ion Channel Dynamics (Baker 2003)
//
// Copyright 2007 John L Baker. All rights reserved.
//
// This software is provided AS IS under the terms of the Open Source
// MIT License. See http://www.opensource.org/licenses/mit-license.php.
//
// File: ionchan_na_baker_2003.cpp
//
// Release: 1.0.0
// Author: John Baker
// Updated: 14 July 2006
//
// Description:
//
// This header file contains the classes used to implement variations
// on the sodium (Na) channel. See header file for references and notes.
#include "ionchan_na_baker_2003.h"
using namespace std;
using namespace BNSF;
using namespace UOM;
using namespace BAKER_2003;
// ==============================================
// Na channel class bodies
// ==============================================
// ----------------------------------------------
// Class static values
// ----------------------------------------------
AlphaBetaEntry* Na_h_gate::_abTable = NULL;
AlphaBetaEntry* Soma_Na_s_gate::_abTable = NULL;
AlphaBetaEntry* Proximal_Na_s_gate::_abTable = NULL;
AlphaBetaEntry* Distal_Na_s_gate::_abTable = NULL;
AlphaBetaEntry* Proximal_Na_m_gate::_abTable = NULL;
AlphaBetaEntry* Distal_Na_m_gate::_abTable = NULL;
AlphaBetaEntry* Soma_Na_m_gate::_abTable = NULL;
AlphaBetaEntry* Axon_Na_m_gate::_abTable = NULL;
AlphaBetaEntry* Axon_Na_h_gate::_abTable = NULL;
AlphaBetaEntry* Persistent_Na_m_gate::_abTable = NULL;
AlphaBetaEntry* Persistent_Na_h_gate::_abTable = NULL;
// Reversal potentials from Gasparini & Magee
// Blended reversal is average of distal and proximal.
const Number Proximal_Na_channel::_Vrev = 55.8*mV;
const Number Distal_Na_channel::_Vrev = 54.4*mV;
const Number Blended_Na_channel::_Vrev = 54.9*mV;
// Reversal pontential for other Na channels
const Number Soma_Na_channel::_Vrev = 55*mV;
const Number Axon_Na_channel::_Vrev = 55*mV;
const Number Persistent_Na_channel::_Vrev = 55*mV;
// ----------------------------------------------
// Abstract_Na_h_gate body
// ----------------------------------------------
// Constructor
Abstract_Na_h_gate::Abstract_Na_h_gate(IonChannel* mg)
{
_mgate = mg;
// Set initial parameter values.
// Subclasses can override via constructor
// or wait for simulationStarted event below.
_inactRate = 0;
_tauZero = 0;
}
Abstract_Na_h_gate::~Abstract_Na_h_gate() {}
// Save values for fast path code
void Abstract_Na_h_gate::simulationStarted()
{
// Set parameters using subclass overrides if any.
_inactRate = inactRate();
_tauZero = tauZero();
// Let superclass take over the rest of the logic
EnergyBarrierTabGate::simulationStarted();
}
// Fast path computation of derivatives.
void Abstract_Na_h_gate::computeDerivatives()
{
// Get alpha and beta values
Number a=alpha();
Number b=beta();
// Get the current activation state from the mgate
Number m = mgate()->value();
// Now get the adjusted xinf and tau values
Number tau = 1/(a+b+_inactRate*m*m*m);
Number xinf = tau*a;
// Apply xinf and tau to get derivative
// loadAlphaBetaTable prevents tau=0 case from occurring
derivValue(0) = (xinf-stateValue(0))/(tau+_tauZero);
}
// Fast path computation of local state update via implicit rule.
void Abstract_Na_h_gate::localStateUpdate(SimTime h, CNStepType stepType)
{
// Get alpha and beta values
Number a=alpha();
Number b=beta();
// Get the current activation state from the mgate
Number m = mgate()->value();
// Now get the adjusted xinf and tau values
Number tau = 1/(a+b+_inactRate*m*m*m);
Number xinf = tau*a;
Number x = stateValue(0);
// Perform the update (semi-implicit trapezoid rule)
if (stepType==CNStartingHalfStep) {
stateValue(0) += h/(tau+_tauZero+h)*(xinf-x);
}
else {
stateValue(0) += h/(tau+_tauZero+h/2)*(xinf-x);
}
}
// ----------------------------------------------
// Abstract_Na_s_gate body
// ----------------------------------------------
// Constructor and destructor
Abstract_Na_s_gate::Abstract_Na_s_gate(bool isDisabled, Number dval)
{
using namespace UOM;
// Initialize values
_gateDisabled = isDisabled;
_disabledValue = dval;
// Set a default value (value is not critical)
_disabledTau = 2*msec;
}
Abstract_Na_s_gate::~Abstract_Na_s_gate() {}
// Override compute derivatives to test gate status.
// Fall back to the Hodgkin-Huxley alpha-beta formulas.
void Abstract_Na_s_gate::computeDerivatives()
{
HHIonChannel::computeDerivatives();
}
// Override localStateUpdate to handle gate status
// Fall back to the Hodgkin-Huxley alpha-beta formulas.
void Abstract_Na_s_gate::localStateUpdate(SimTime h, CNStepType stepType)
{
HHIonChannel::localStateUpdate(h, stepType);
}
// Return an HH alpha value, adjusted if needed by gate status
Number Abstract_Na_s_gate::alpha()
{
return gateDisabled()
? disabledValue()/disabledTau()
: EnergyBarrierTabGate::alpha();
}
// Return an HH beta value, adjusted if needed by gate status
Number Abstract_Na_s_gate::beta()
{
return gateDisabled()
? (1-disabledValue())/disabledTau()
: EnergyBarrierTabGate::beta();
}
// ----------------------------------------------
// Blended_Na_s_gate body
// ----------------------------------------------
Blended_Na_s_gate::Blended_Na_s_gate(
Number bratio, // blend ratio
bool isDisabled, // set gateDisabled on or off
Number dval) // disabled value
: BlendedIonGate(
new Proximal_Na_s_gate,
new Distal_Na_s_gate,
bratio)
{
_gateDisabled = isDisabled;
_disabledValue = dval;
}
Blended_Na_s_gate::~Blended_Na_s_gate() {}
void Blended_Na_s_gate::gateDisabled(bool flag)
{
// Pass-thru to underlying gates
sgate1()->gateDisabled(flag);
sgate2()->gateDisabled(flag);
}
void Blended_Na_s_gate::disabledValue(Number s)
{
// Pass-thru to underlying gates
sgate1()->disabledValue(s);
sgate2()->disabledValue(s);
}
// ----------------------------------------------
// Proximal_Na_channel body
// ----------------------------------------------
Proximal_Na_channel::Proximal_Na_channel(
Number gSpVal, // specific conductance
bool sGateDisabled, // s gate disabled flag
Number sGateValue) // s gate value if disabled
{
IonChannel* mgate;
gSpecific(gSpVal);
add( mgate = new Proximal_Na_m_gate );
add( new Na_h_gate(mgate) );
add( _sGate = new Proximal_Na_s_gate(sGateDisabled) );
}
// ----------------------------------------------
// Distal_Na_channel body
// ----------------------------------------------
Distal_Na_channel::Distal_Na_channel(
Number gSpVal, // specific conductance
bool sGateDisabled, // s gate disabled flag
Number sGateValue) // s gate value if disabled
{
IonChannel* mgate;
gSpecific(gSpVal);
add( mgate = new Distal_Na_m_gate );
add( new Na_h_gate(mgate) );
add( _sGate = new Distal_Na_s_gate(sGateDisabled,sGateValue) );
}
// ----------------------------------------------
// Blended_Na_channel (Proximal blended with Distal)
// ----------------------------------------------
Blended_Na_channel::Blended_Na_channel(
Number gSpVal, // specific conductance
Number bratio, // blend ratio
bool sGateDisabled, // s gate disabled flag
Number sGateValue) // s gate value if disabled
{
IonChannel* mgate;
gSpecific(gSpVal);
add( mgate = new Blended_Na_m_gate(bratio));
add( new Na_h_gate(mgate));
add( _blendedSGate = new Blended_Na_s_gate(bratio,sGateDisabled,sGateValue) );
}
// ----------------------------------------------
// Soma_Na_channel body
// ----------------------------------------------
Soma_Na_channel::Soma_Na_channel(
Number gSpVal, // specific conductance
bool sGateDisabled, // s gate disabled flag
Number sGateValue) // s gate value if disabled
{
IonChannel* mgate;
gSpecific(gSpVal);
add( mgate = new Soma_Na_m_gate );
add( new Na_h_gate(mgate) );
add( _sGate = new Proximal_Na_s_gate(sGateDisabled, sGateValue) );
}
// ----------------------------------------------
// Axon_Na_channel body
// ----------------------------------------------
Axon_Na_channel::Axon_Na_channel(Number gSpVal)
{
gSpecific(gSpVal);
add( new Axon_Na_m_gate );
add( new Axon_Na_h_gate );
}
// ----------------------------------------------
// Persistent_Na_channel body
// ----------------------------------------------
Persistent_Na_channel::Persistent_Na_channel(Number gSpVal)
{
gSpecific(gSpVal);
add( new Persistent_Na_m_gate );
add( new Persistent_Na_h_gate );
}