00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "ModelNeuron/IZNeuron.H"
00037
00038
00039
00040
00041 void IZNeuronFunc::integrate()
00042 {
00043
00044
00045 double temp = itsk * (itsV - itsVr) * (itsV - itsVth) - itsU + itsI;
00046
00047
00048 itsV += (temp / itsCm);
00049
00050
00051 itsU += itsa * (itsb * (itsV-itsVr) - itsU);
00052
00053
00054 if (itsV > itsVp)
00055 {
00056 itsSpike = true;
00057 reset();
00058 }
00059 else
00060 itsSpike = false;
00061 }
00062
00063
00064 void IZNeuronFunc::initialize() {
00065 itsSpike = false;
00066 itsV = itsVr;
00067 itsI = 0.0;
00068 itsU = 0.0;
00069 }
00070
00071
00072 void IZNeuronFunc::reset()
00073 {
00074 itsV = itsc;
00075 itsU += itsd;
00076 }
00077
00078
00079 void IZNeuronFunc::setup(const std::string& name, const bool use_random)
00080 {
00081 if (name.compare("RS") == 0)
00082 {
00083 itsa = 0.01;
00084 itsb = 5.0;
00085 itsc = -60.0;
00086 itsd = 400.0;
00087 itsk = 3.0;
00088 itsCm = 100.0;
00089 itsVr = -60.0;
00090 itsVth = -50.0;
00091 itsVp = 50.0;
00092 }
00093 else if (name.compare("FS") == 0)
00094 {
00095 itsa = 0.15;
00096 itsb = 8.0;
00097 itsc = -55.0;
00098 itsd = 200.0;
00099 itsk = 1.0;
00100 itsCm = 20.0;
00101 itsVr = -55.0;
00102 itsVth = -40.0;
00103 itsVp = 25.0;
00104 }
00105 else if (name.compare("EB") == 0)
00106 {
00107 itsa = 0.01;
00108 itsb = 17.0;
00109 itsc = -42.0;
00110 itsd = 1.5;
00111 itsk = 1.4;
00112 itsCm = 20.0;
00113 itsVr = -55.0;
00114 itsVth = -50.0;
00115 itsVp = 25.0;
00116 }
00117
00118 if (use_random)
00119 {
00120
00121 }
00122 }
00123
00124
00125
00126
00127 IZNeuron::IZNeuron(const double& a, const double& b,
00128 const double& c, const double& d, const double& k,
00129 const double& Cm, const double& V_rest,
00130 const double& V_thresh, const double& V_peak,
00131 const std::string& name, const std::string& units) :
00132 SimUnit(SimTime::MSECS(1.0), SimUnit::STRICT, name, units),
00133 itsI(0.0), itsN(a,b,c,d,k,Cm,V_rest,V_thresh,V_peak),
00134 ampa(SimTime::MSECS(1.0)), nmda(SimTime::MSECS(1.0)),
00135 gabaa(SimTime::MSECS(1.0)), gabab(SimTime::MSECS(1.0))
00136 {
00137 }
00138
00139
00140 void IZNeuron::setV(const double& v)
00141 {
00142 itsN.setV(v);
00143 }
00144
00145
00146 const double IZNeuron::getDisplayOutput() const
00147 {
00148 return getV();
00149 }
00150
00151
00152 const uint IZNeuron::numSubs() const
00153 {
00154 return 4;
00155 }
00156
00157
00158 const SimUnit& IZNeuron::getSub(const uint i) const
00159 {
00160 switch (i)
00161 {
00162 case 0:
00163 return ampa;
00164 case 1:
00165 return nmda;
00166 case 2:
00167 return gabaa;
00168 case 3:
00169 return gabab;
00170 default:
00171 LFATAL("Sub module position out of range.");
00172 return ampa;
00173 }
00174 }
00175
00176
00177 SimUnit& IZNeuron::editSub(const uint i)
00178 {
00179 switch (i)
00180 {
00181 case 0:
00182 return ampa;
00183 case 1:
00184 return nmda;
00185 case 2:
00186 return gabaa;
00187 case 3:
00188 return gabab;
00189 default:
00190 LFATAL("Sub module position out of range.");
00191 return ampa;
00192 }
00193 }
00194
00195
00196 const double IZNeuron::getV() const
00197 {
00198 return itsN.getV();
00199 }
00200
00201
00202 const double IZNeuron::getI() const
00203 {
00204 return itsN.getCurrent();
00205 }
00206
00207
00208 void IZNeuron::setI(const double& current)
00209 {
00210 itsI = current;
00211 }
00212
00213
00214 const IZNeuron& IZNeuron::setup(const std::string& name, const bool use_random)
00215 {
00216 itsN.setup(name, false);
00217 setName(name + getName());
00218 return *this;
00219 }
00220
00221
00222 const double IZNeuron::doIntegrate(const SimTime& dt,
00223 const double& exc, const double& inh)
00224 {
00225
00226 const double inh1 = inh * -1.0;
00227 ampa.input(exc);
00228 nmda.input(exc);
00229 gabaa.input(inh1);
00230 gabab.input(inh1);
00231
00232
00233 ampa.setV(getV());
00234 nmda.setV(getV());
00235 gabaa.setV(getV());
00236 gabab.setV(getV());
00237
00238
00239 ampa.evolve(getTime());
00240 nmda.evolve(getTime());
00241 gabaa.evolve(getTime());
00242 gabab.evolve(getTime());
00243
00244 const double synCurr = ampa.getOutput() + nmda.getOutput() +
00245 gabaa.getOutput() + gabab.getOutput();
00246
00247 const double inp = itsI - synCurr;
00248 itsN.setCurrent(inp);
00249 itsN.integrate();
00250
00251 return (double)itsN.getSpike();
00252 }
00253
00254
00255 void IZNeuron::doInit()
00256 {
00257 itsI = 0.0;
00258 itsN.initialize();
00259 ampa.initialize();
00260 nmda.initialize();
00261 gabaa.initialize();
00262 gabab.initialize();
00263 }
00264
00265
00266 IZNeuron* IZNeuron::doClone() const
00267 { return new IZNeuron(*this); };
00268
00269
00270
00271
00272
00273
00274 IZNeuronSyn::IZNeuronSyn(const double& a, const double& b,
00275 const double& c, const double& d, const double& k,
00276 const double& Cm, const double& V_rest,
00277 const double& V_thresh, const double& V_peak,
00278 const std::string& name, const std::string& units) :
00279 SimUnit(SimTime::MSECS(1.0), SimUnit::STRICT, name, units),
00280 itsI(0.0), itsN(a, b, c, d, k, Cm, V_rest, V_thresh, V_peak), itsS()
00281 {
00282 }
00283
00284 // ######################################################################
00285 IZNeuronSyn::IZNeuronSyn(const IZNeuronSyn& rhs) :
00286 SimUnit(rhs), itsI(rhs.itsI), itsN(rhs.itsN), itsS()
00287 {
00288 map::const_iterator i(rhs.itsS.begin()), end(rhs.itsS.begin());
00289 while (i != end)
00290 {
00291 itsS[i->first] = pair(i->second.first,
00292 i->second.second->clone());
00293 ++i;
00294 }
00295 }
00296
00297 // ######################################################################
00298 IZNeuronSyn& IZNeuronSyn::operator=(const IZNeuronSyn& rhs)
00299 {
00300 if (this != &rhs)
00301 {
00302 SimUnit::operator=(rhs);
00303
00304 itsI = rhs.itsI;
00305 itsN = rhs.itsN;
00306 map::const_iterator i(rhs.itsS.begin()), end(rhs.itsS.begin());
00307 while (i != end)
00308 {
00309 itsS[i->first] = pair(i->second.first,
00310 i->second.second->clone());
00311 ++i;
00312 }
00313 }
00314 return *this;
00315 }
00316
00317 // ######################################################################
00318 IZNeuronSyn::~IZNeuronSyn()
00319 {
00320 cleanup();
00321 }
00322
00323 // ######################################################################
00324 void IZNeuronSyn::setV(const double& v)
00325 {
00326 itsN.setV(v);
00327 }
00328
00329 // ######################################################################
00330 const double IZNeuronSyn::getDisplayOutput() const
00331 {
00332 return getV();
00333 }
00334
00335 // ######################################################################
00336 const uint IZNeuronSyn::numSubs() const
00337 {
00338 return (uint)itsS.size();
00339 }
00340
00341 // ######################################################################
00342 const SimUnit& IZNeuronSyn::getSub(const uint pos) const
00343 {
00344 if (pos >= (uint)itsS.size() )
00345 LFATAL("You have not added %d synapses", pos);
00346 map::const_iterator i(itsS.begin());
00347 for (uint j = 0; j < pos; ++j)
00348 ++i;
00349 SimUnit* tmp = i->second.second;
00350 return *tmp;
00351 }
00352
00353 // ######################################################################
00354 SimUnit& IZNeuronSyn::editSub(const uint pos)
00355 {
00356 if (pos >= (uint)itsS.size() )
00357 LFATAL("You have not added %d synapses", pos);
00358 map::iterator i(itsS.begin());
00359 for (uint j = 0; j < pos; ++j)
00360 ++i;
00361 SimUnit* tmp = i->second.second;
00362 return *tmp;
00363 }
00364
00365 // ######################################################################
00366 const double IZNeuronSyn::getV() const
00367 {
00368 return itsN.getV();
00369 }
00370
00371 // ######################################################################
00372 const double IZNeuronSyn::getI() const
00373 {
00374 return itsN.getCurrent();
00375 }
00376
00377 // ######################################################################
00378 void IZNeuronSyn::setI(const double& current)
00379 {
00380 itsI = current;
00381 }
00382
00383 // ######################################################################
00384 const IZNeuronSyn& IZNeuronSyn::setup(const std::string& name,
00385 const bool use_random)
00386 {
00387 itsN.setup(name, false);
00388 setName(name + getName());
00389 return *this;
00390 }
00391
00392 // ######################################################################
00393 template <class S, class I>
00394 void IZNeuronSyn::addSynapse(const Synapse<S, I>& synapse, const double& ratio)
00395 {
00396 //make sure we dont already have it
00397 map::const_iterator i(itsS.find(S::id));
00398 if (i != itsS.end())
00399 LFATAL("Synapse %s of type already added", synapse.getName().c_str());
00400 else
00401 itsS[S::id] = pair(ratio, synapse.clone());
00402 }
00403
00404 // ######################################################################
00405 void IZNeuronSyn::inputSynapse(const double& input,
00406 const Receptor::Type receptor)
00407 {
00408 map::const_iterator i(itsS.find(receptor));
00409 if (i != itsS.end())
00410 {
00411 i->second.second->input(i->second.first * input);
00412 ++i;
00413 }
00414 }
00415
00416 // ######################################################################
00417 void IZNeuronSyn::cleanup()
00418 {
00419 map::iterator i(itsS.begin()), end(itsS.begin());
00420 while (i != end)
00421 {
00422 delete i->second.second;
00423 i->second.second = NULL;
00424 ++i;
00425 }
00426 }
00427
00428 // ######################################################################
00429 const double IZNeuronSyn::doIntegrate(const SimTime& dt,
00430 const double& exc, const double& inh)
00431 {
00432 double synCurr = 0.0;
00433 map::const_iterator i(itsS.begin()), end(itsS.end());
00434 while (i != end)
00435 {
00436 i->second.second->setV(getV());//set starting voltage
00437 i->second.second->evolve(getTime());//evolve our synapse to current time
00438 synCurr += i->second.second->getOutput(); //add synaptic currents
00439 ++i;
00440 }
00441
00442 const double inp = itsI - synCurr;
00443 itsN.setCurrent(inp); //set the current level
00444 itsN.integrate(); //integrate
00445
00446 return (double)itsN.getSpike(); //return any spikes
00447 }
00448
00449 // ######################################################################
00450 void IZNeuronSyn::doInit()
00451 {
00452 map::const_iterator i(itsS.begin()), end(itsS.end());
00453 while (i != end)
00454 (i++)->second.second->initialize();
00455
00456 itsN.initialize();
00457 }
00458
00459 // ######################################################################
00460 IZNeuronSyn* IZNeuronSyn::doClone() const
00461 { return new IZNeuronSyn(*this); };
00462
00463 // ######################################################################
00464 // specific instantiation for addSynapse
00465 // ######################################################################
00466 template
00467 void IZNeuronSyn::addSynapse(Synapse<Receptor::AMPA, LowPassExpEuler> const&,
00468 double const&);
00469 template
00470 void IZNeuronSyn::addSynapse(Synapse<Receptor::NMDA, LowPassExpEuler> const&,
00471 double const&);
00472 template
00473 void IZNeuronSyn::addSynapse(Synapse<Receptor::GABAA, LowPassExpEuler> const&,
00474 double const&);
00475 template
00476 void IZNeuronSyn::addSynapse(Synapse<Receptor::GABAB, LowPassExpEuler> const&,
00477 double const&);
00478
00479 */
00480
00481
00482
00483
00484