00001 #ifndef _GENERICGLUTAMATESYNAPSE_H_
00002 #define _GENERICGLUTAMATESYNAPSE_H_
00003
00004 #include "SimObject.h"
00005 #include "SimNetwork.h"
00006 #include "InputTargetTypes.h"
00007 #include "PCSIMException.h"
00008
00009 #include "ExponentialDecaySpikeResponse.h"
00010 #include "DoubleExponentialSpikeResponse.h"
00011 #include "AlphaFunctionSpikeResponse.h"
00012
00013 #include <cmath>
00014
00016
00019 template<class Response>
00020 class GenericGlutamateSynapse : public Response
00021 {
00022 public:
00023 GenericGlutamateSynapse()
00024 {
00025 this->ampa_psr=0.0;
00026 this->nmda_psr=0.0;
00027
00028 this->fract_NMDA = 0.5;
00029 this->scale_NMDA = 1.0;
00030
00031 this->Erev_NMDA = 0.0;
00032 this->Erev_AMPA = 0.0;
00033
00034 this->Mg_conc = 1.2e-3;
00035
00036 this->has_NMDA = 1;
00037
00038 this->target = &dummyConductanceBasedSynapseTarget;
00039 };
00040
00041 virtual ~GenericGlutamateSynapse()
00042 {
00043 };
00044
00046 float Erev_NMDA;
00047
00049 float Erev_AMPA;
00050
00052 float fract_NMDA;
00053
00055 float scale_NMDA;
00056
00058 float Mg_conc;
00059
00061 int has_NMDA;
00062
00064 virtual int adjust(double dt)
00065 {
00066 if (has_NMDA) {
00067 resp_AMPA.adjust(dt);
00068 return Response::adjust(dt);
00069 }
00070 else
00071 return resp_AMPA.adjust(dt);
00072 }
00073
00075 virtual int init(InitializeInfo *ii)
00076 {
00077 if (has_NMDA) {
00078 resp_AMPA.init(ii);
00079 return Response::init(ii);
00080 }
00081 else
00082 return resp_AMPA.init(ii);
00083 }
00084
00086 virtual int reset(double dt)
00087 {
00088 if (has_NMDA) {
00089 resp_AMPA.reset(dt);
00090 return Response::reset(dt);
00091 }
00092 else
00093 return resp_AMPA.reset(dt);
00094 }
00095
00096 virtual int spikeHit(spikeport_t port, SpikeEvent const& spike)
00097 {
00098 if (has_NMDA) {
00099 resp_AMPA.spikeHit(port, spike);
00100 return Response::spikeHit(port, spike);
00101 }
00102 else
00103 return resp_AMPA.spikeHit(port, spike);
00104 }
00105
00106 virtual int advance(AdvanceInfo const &ai)
00107 {
00108 ampa_psr=(1.0-fract_NMDA)*resp_AMPA.psr;
00109
00110 target->conductanceInput(ampa_psr, Erev_AMPA);
00111
00112 if (has_NMDA) {
00113 double Vm=target->getVm();
00114 double s=1.0/(1.0+exp(-62.0*Vm)*Mg_conc*1000.0/3.57);
00115
00116 nmda_psr=fract_NMDA*s*scale_NMDA*Response::psr;
00117
00118 target->conductanceInput(nmda_psr, Erev_NMDA);
00119
00120 resp_AMPA.advance(ai);
00121 return Response::advance(ai);
00122 }
00123 else
00124 return resp_AMPA.advance(ai);
00125 }
00126
00128 virtual void outgoing(SimObject *receiver, SimObject::ID const& rec, SimObject::ID const& self, SimNetwork & net )
00129 {
00130 ConductanceInputTarget *t = dynamic_cast<ConductanceInputTarget *>(receiver);
00131 if(t) {
00132 target = t;
00133 }
00134 else {
00135 throw(
00136 PCSIM::Exception( "GenericGlutamateSynapse::outgoing", make_string( "Object must be a ConductanceBasedSynapseTarget; which %s is not!\n", typeid(*receiver).name() ) )
00137 );
00138 }
00139 }
00140
00141 virtual double getAnalogOutput(analog_port_id_t p) const
00142 {
00143 if (p == 0)
00144 return ampa_psr;
00145 else if (p == 1)
00146 return nmda_psr;
00147 else if (p == 2)
00148 return resp_AMPA.psr;
00149
00150 return Response::getAnalogOutput(p-3);
00151 };
00152
00153 virtual int psrLength(double dt) const
00154 {
00155 if (has_NMDA)
00156 return Response::psrLength(dt);
00157 else
00158 return resp_AMPA.psrLength(dt);
00159 }
00160
00161 protected:
00163 Response resp_AMPA;
00164
00166 ConductanceInputTarget *target;
00167 double ampa_psr;
00168 double nmda_psr;
00169 };
00170
00171
00172 #endif //_GENERICGLUTAMATESYNAPSE_H_