// Synapse Dynamics for Glutamate Synapses
//
// 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: synapse_glu_baker_2003.cpp
//
// Release: 1.0.0
// Author: John Baker
// Updated: 14 July 2006
//
// Description:
//
// This header file contains the classes used to implement
// glutamate synapse conductances.
//
// See header file for references.
#include "synapse_glu_baker_2003.h"
#include "plasticity_glu_baker_2003.h"
using namespace std;
using namespace BNSF;
using namespace UOM;
using namespace BAKER_2003;
// ================================================================
// AMPA synaptic conductance static values
// ================================================================
const Number AMPA_SynapticResp::_Vrev = 0*mV;
DualExpSynapticCondClassCache AMPA_SynapticResp::_CC;
// Constructors and destructor
AMPA_SynapticResp ::AMPA_SynapticResp (Number gVal)
: DualExpSynapticCond(gVal) {}
AMPA_SynapticResp ::~AMPA_SynapticResp () {}
// =================================================
// NMDA Synaptic Conductance Class Body
// =================================================
// Static variables
const Number NMDA_SynapticResp::_Vrev = 0*mV;
NMDAVmTableEntry* NMDA_SynapticResp::_NMDAVmTable = NULL;
// Constructors and destructor
NMDA_SynapticResp::NMDA_SynapticResp(Number gVal)
: DualExpSynapticCond(gVal) {}
NMDA_SynapticResp::~NMDA_SynapticResp() {}
// Load the Mg gate table when the simulation starts
void NMDA_SynapticResp::simulationStarted()
{
// Let superclass do any of its initializations
DualExpSynapticCond::simulationStarted();
// Load the effective potential table on the first call
if (*pNMDAVmTable()==NULL)
loadNMDAVmTable();
}
// Delete the effective potential table when the simulation ends
void NMDA_SynapticResp::simulationEnded()
{
// Delete the table
delete[] *pNMDAVmTable();
*pNMDAVmTable() = NULL;
// Let superclass do its own cleanup
DualExpSynapticCond::simulationEnded();
}
// Load the effective potential array
void NMDA_SynapticResp::loadNMDAVmTable()
{
NMDAVmTableEntry* tbl;
int k;
Number v;
Number CaXin = defaultPeakCaXin();
Number CaXout = defaultCaXout();
Number dVm = 1e-2*VStepForIndex;
// Delete any previously allocated table
if (*pNMDAVmTable()!=NULL) {
delete[] *pNMDAVmTable();
}
// Allocate a new table and remember where it is
*pNMDAVmTable() = tbl = new NMDAVmTableEntry[VTableSize];
// Go through the voltages one step at a time
for (k=0,v=VMinForIndex; k<VTableSize; k++, v+=VStepForIndex ) {
// Get the (instantaneous) Mg++ gate value
tbl[k].MgGate = MgGateValueForTable(v);
}
}
// Set ACh concentration level and modulation
void NMDA_SynapticResp::AChLevel(Number ach)
{
// Save param value
_AChLevel = ach;
// Get a new modulation value
_AChMod = 1+AChA1()*ach/( ach+AChKd1() );
_AChMod *= 1+AChA2()*ach/( ach+AChKd2() );
// Set the new conductance modulation value
gModulator( _AChMod );
}
// Apply an ACh neuromodulation rule
void NMDA_SynapticResp::setModParams(TokenId id, int nv, Number* values)
{
using namespace UOM;
static const TokenId AChMod = token("AChModulator");
// Skip any other forms of modulation and check num of params
if (id!=AChMod) return;
if (nv<1) {
FatalError("(NMDA_SynapticResp::setModParams::setModParams) "
"Too few params");
}
// Set the new concentration value
AChLevel( values[0] );
}
// Get conductance including the Mg++ gate value and Ca++ effective conductance
Number NMDA_SynapticResp::conductance()
{
NMDAVmTableEntry* ent = *pNMDAVmTable()+container()->VmIndex();
Number mgGate = VTableInterp(container()->VmRem()/VStepForIndex,
(ent-1)->MgGate,ent->MgGate,
(ent+1)->MgGate,(ent+2)->MgGate);
return g()*s2()*mgGate;
}
// Get current flow assuming Ohm's law behavior
Number NMDA_SynapticResp::Iion()
{
NMDAVmTableEntry* ent = *pNMDAVmTable()+container()->VmIndex();
Number mgGate = VTableInterp(container()->VmRem()/VStepForIndex,
(ent-1)->MgGate,ent->MgGate,
(ent+1)->MgGate,(ent+2)->MgGate);
// As a fastpath, include conductance calculation inline.
return g()*s2()*mgGate*(Vm()-Vrev());
}
// Get the decay time constant based on rated Vm value.
SimTime NMDA_SynapticResp::tau2()
{
Number tauAtV0 = ratedTau2() /
maxval(nhdMin(),nhdAtV0()+nhdSlope()*ratedVm());
Number tauAtVm = tauAtV0 *
maxval(nhdMin(),nhdAtV0()+nhdSlope()*nominalVm());
return tauAtVm;
}
// Return the Mg++ plug state for a given voltage
Number NMDA_SynapticResp::MgGateValueForTable(Number vm)
{
return 1/(1+MgExtConc()/MgKdAtV0()*exp(-MgVmMult()*vm));
}
// ================================================================
// Combined NR2A and NR2B static values
// ================================================================
DualExpSynapticCondClassCache NR2A_SynapticResp::_CC;
DualExpSynapticCondClassCache NR2B_SynapticResp::_CC;
// ================================================================
// AC_Glu_SynapticResp class body
// ================================================================
// Constructor
AC_Glu_SynapticResp::AC_Glu_SynapticResp (
Number gAMPAR, // AMPAR conductance
Number gNMDAR ) // NMDAR conductance
{
add(_ampa = new AMPA_SynapticResp(gAMPAR));
add(_nmda = new NR2A_SynapticResp(gNMDAR));
// Set the presynaptic rule
ampa()->presynapticRule(new CA3_AC_PairedPulseRule);
// Set the postsynaptic rule passing associated NMDAR
ampa()->postsynapticRule(new CA3_AC_STDPRule(nmda()) );
}
// ================================================================
// PP_Glu_SynapticResp class body
// ================================================================
// Constructor
PP_Glu_SynapticResp::PP_Glu_SynapticResp (
Number gAMPAR, // AMPAR conductance
Number gNMDAR ) // NMDAR conductance
{
add(_ampa = new AMPA_SynapticResp(gAMPAR));
add(_nmda = new NR2A_SynapticResp(gNMDAR));
// Presynaptic properties of PP are not well
// determined. MEC-PP shows PPD while LEC-PP
// shows PPF. For simplicity, a random
// release rule is used.
ampa()->presynapticRule(new RandomReleaseRule);
// Set the postsynaptic rule. There is no
// evidence for this in PP synapses, but it
// it is the best available data and something
// like this probably applies for MEC PP.
// LEC PP is more of an unknown and opiod
// dependencies have been found experimentally.
ampa()->postsynapticRule(new CA3_PP_STDPRule(nmda()) );
}
// ================================================================
// MF_AMPA_SynapticResp class body
// ================================================================
const Number MF_AMPA_SynapticResp::_Vrev = 0*mV;
DualExpSynapticCondClassCache MF_AMPA_SynapticResp::_CC;
MF_AMPA_SynapticResp::MF_AMPA_SynapticResp (Number gVal)
{
// Set the peak achievable conductance per synapse
gMax(gVal);
// Set the presynaptic rule for MF PPF
presynapticRule(new CA3_MF_PairedPulseRule);
}
MF_AMPA_SynapticResp::~MF_AMPA_SynapticResp () {}
// ================================================================
// MF_Glu_SynapticResp class body
// ================================================================
// Constructor
MF_Glu_SynapticResp::MF_Glu_SynapticResp (
Number gAMPAR, // AMPAR conductance
Number gNMDAR ) // NMDAR conductance
{
add(_ampa = new MF_AMPA_SynapticResp(gAMPAR));
add(_nmda = new NR2A_SynapticResp(gNMDAR));
}