00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "STDP1Neuron.h"
00025 #include "SimulationClock.h"
00026 #include "Debug.h"
00027 #include "STDP1Synapse.h"
00028
00029
00030 #include <cmath>
00031 #include <iostream>
00032 using namespace std;
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #define MONITOR_MEMBRANE_POTENTIAL
00044
00045
00046
00047 #define MONITOR_CALCIUM_CONC
00048
00049
00050
00051 double STDP1Neuron::threshold = 0.0;
00052 double STDP1Neuron::refractoryPeriod_millisec = 0.0;
00053 double STDP1Neuron::membraneTimeConstant_millisec = 0.0;
00054 double STDP1Neuron::refractoryParam_m = 0.0;
00055 double STDP1Neuron::refractoryParam_n = 0.0;
00056 bool STDP1Neuron::learningMode = false;
00057 double STDP1Neuron::calciumIncreaseAmnt = 0.0;
00058 double STDP1Neuron::calciumDecayRate = 0.0;
00059 double STDP1Neuron::minPostsynapticPotential = 0.0;
00060
00061
00062
00063 extern "C" {
00064 Neuron* getClass(){
00065 return new STDP1Neuron;
00066 }
00067 }
00068
00069
00070
00071 STDP1Neuron::STDP1Neuron() : Neuron() {
00072
00073 pspTotal = 0;
00074 membranePotential = 0;
00075 currentTime = 0.0;
00076 lastUpdateTime = 0.0;
00077 timeSinceLastFire = 0.0;
00078 oldLearningMode = false;
00079 calciumConc = 0.0;
00080 finalStateUpdateTime = -1.0;
00081
00082
00083 int count = 0;
00084 #ifdef MONITOR_MEMBRANE_POTENTIAL
00085 count++;
00086 #endif//MONITOR_MEMBRANE_POTENTIAL
00087 #ifdef MONITOR_CALCIUM_CONC
00088 count++;
00089 #endif//MONITOR_CALCIUM_CONC
00090
00091 monitorData.dataArray = new double[count];
00092 monitorData.length = count;
00093 }
00094
00095
00096
00097 STDP1Neuron::~STDP1Neuron(){
00098 #ifdef MEMORY_DEBUG
00099 cout<<"DELETING STDP1 NEURON"<<endl;
00100 #endif//MEMORY_DEBUG
00101
00102 delete [] monitorData.dataArray;
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 void STDP1Neuron::calculateFinalState(){
00115 #ifdef NEURON_MODEL_DEBUG
00116 cout<<"STDP1Neuron ["<<neuronID<<"]: Calculating final state."<<endl;
00117 #endif//NEURON_METHOD_DEBUG
00118
00119
00120 update();
00121
00122
00123 calculateMembranePotential();
00124
00125
00126
00127
00128
00129
00130
00131 if(learningMode){
00132 for(vector<void*>::iterator iter = preSynapseVector.begin(); iter != preSynapseVector.end(); ++iter){
00133 ((STDP1Synapse*)*iter)->updateWeight(membranePotential, calciumConc);
00134 }
00135 }
00136
00137
00138 if(membranePotential > threshold){
00139
00140 fireNeuron();
00141
00142
00143 pspTotal = 0;
00144 membranePotential = 0;
00145
00146
00147 calciumConc += calciumIncreaseAmnt;
00148 }
00149
00150
00151
00152 finalStateUpdateTime = simulationClock->getSimulationTime();
00153 }
00154
00155
00156
00157
00158 void STDP1Neuron::changePostSynapticPotential(double amount, unsigned int preSynapticNeuronID){
00159
00160
00161 update();
00162
00163
00164
00165 pspTotal += amount;
00166
00167
00168 if(pspTotal < minPostsynapticPotential)
00169 pspTotal = minPostsynapticPotential;
00170
00171 #ifdef NEURON_MODEL_DEBUG
00172 cout<<"STDP1Neuron ["<<neuronID<<"]: Changing post synaptic potential at time "<<simulationClock->getSimulationTime()<<" with timestep "<<simulationClock->getTimeStep()<<". pspTotal = "<<pspTotal<<endl;
00173 #endif//NEURON_METHOD_DEBUG
00174 }
00175
00176
00177
00178
00179 const string* STDP1Neuron::getDescription(){
00180 string* tempstr = new string("STDP1 Neuron");
00181 return tempstr;
00182 }
00183
00184
00185
00186
00187 MonitorData* STDP1Neuron::getMonitoringData(){
00188
00189
00190 if(finalStateUpdateTime != simulationClock->getSimulationTime())
00191 calculateFinalState();
00192
00193 #ifdef MONITOR_MEMBRANE_POTENTIAL
00194 monitorData.dataArray[0] = membranePotential;
00195 #endif//MONITOR_MEMBRANE_POTENTIAL
00196
00197 #ifdef MONITOR_CALCIUM_CONC
00198 monitorData.dataArray[1] = calciumConc;
00199 #endif//MONITOR_CALCIUM_CONC
00200
00201 return &monitorData;
00202 }
00203
00204
00205
00206 string STDP1Neuron::getMonitoringInfo(){
00207 string xmlString = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
00208 xmlString += "<monitor_info>";
00209
00210 #ifdef MONITOR_MEMBRANE_POTENTIAL
00211 xmlString += "<data><description>Membrane Potential</description><range_high>2</range_high><range_low>-8</range_low></data>";
00212 #endif//MONITOR_MEMBRANE_POTENTIAL
00213
00214 #ifdef MONITOR_CALCIUM_CONC
00215 xmlString += "<data><description>Calcium Concentration</description><range_high>50</range_high><range_low>0</range_low></data>";
00216 #endif//MONITOR_CALCIUM_CONC
00217
00218 xmlString += "</monitor_info>";
00219 return xmlString;
00220 }
00221
00222
00223
00224
00225 void STDP1Neuron::parametersChanged(){
00226 #ifdef NEURON_METHOD_DEBUG
00227 cout<<"STDP1Neuron ["<<neuronID<<"]: Parameters changed."<<endl;
00228 #endif//NEURON_METHOD_DEBUG
00229
00230
00231 if(learningMode == true && oldLearningMode == false){
00232 calciumConc = 0.0;
00233 }
00234 oldLearningMode = learningMode;
00235 }
00236
00237
00238
00239 bool STDP1Neuron::setParameters(map<string, double> paramMap){
00240 #ifdef NEURON_METHOD_DEBUG
00241 cout<<"STDP1Neuron ["<<neuronID<<"]: Setting parameters"<<endl;
00242 #endif//NEURON_METHOD_DEBUG
00243
00244 if(paramMap.count(string("Threshold")))
00245 threshold = paramMap[string("Threshold")];
00246 else{
00247 cerr<<"STDP1Neuron ["<<neuronID<<"]: CANNOT FIND \"Threshold\" IN PARAMETER MAP."<<endl;
00248 return false;
00249 }
00250
00251 if(paramMap.count(string("RefractoryPeriod")))
00252 refractoryPeriod_millisec = paramMap[string("RefractoryPeriod")];
00253 else{
00254 cerr<<"STDP1Neuron ["<<neuronID<<"]: CANNOT FIND \"RefractoryPeriod\" IN PARAMETER MAP"<<endl;
00255 return false;
00256 }
00257
00258 if(paramMap.count(string("MembraneTimeConstant")))
00259 membraneTimeConstant_millisec = paramMap[string("MembraneTimeConstant")];
00260 else{
00261 cerr<<"STDP1Neuron ["<<neuronID<<"]: CANNOT FIND \"MembraneTimeConstant\" IN PARAMETER MAP"<<endl;
00262 return false;
00263 }
00264
00265 if(paramMap.count(string("RefractoryParamM")))
00266 refractoryParam_m = paramMap[string("RefractoryParamM")];
00267 else{
00268 cerr<<"STDP1Neuron ["<<neuronID<<"]: CANNOT FIND \"RefractoryParamM\" IN PARAMETER MAP"<<endl;
00269 return false;
00270 }
00271
00272 if(paramMap.count(string("RefractoryParamN")))
00273 refractoryParam_n = paramMap[string("RefractoryParamN")];
00274 else{
00275 cerr<<"STDP1Neuron ["<<neuronID<<"]: CANNOT FIND \"RefractoryParamN\" IN PARAMETER MAP"<<endl;
00276 return false;
00277 }
00278
00279 if(paramMap.count(string("CalciumIncreaseAmnt")))
00280 calciumIncreaseAmnt = paramMap[string("CalciumIncreaseAmnt")];
00281 else{
00282 cerr<<"STDP1Neuron ["<<neuronID<<"]: CANNOT FIND \"CalciumIncreaseAmnt\" IN PARAMETER MAP"<<endl;
00283 return false;
00284 }
00285
00286 if(paramMap.count(string("CalciumDecayRate")))
00287 calciumDecayRate = paramMap[string("CalciumDecayRate")];
00288 else{
00289 cerr<<"STDP1Neuron ["<<neuronID<<"]: CANNOT FIND \"CalciumDecayRate\" IN PARAMETER MAP"<<endl;
00290 return false;
00291 }
00292
00293 if(paramMap.count(string("MinPostsynapticPotential")))
00294 minPostsynapticPotential = paramMap[string("MinPostsynapticPotential")];
00295 else{
00296 cerr<<"STDP1Neuron ["<<neuronID<<"]: CANNOT FIND \"MinPostsynapticPotential\" IN PARAMETER MAP"<<endl;
00297 return false;
00298 }
00299
00300 if(paramMap.count(string("Learning"))){
00301 if(paramMap[string("Learning")] == 1.0)
00302 learningMode = true;
00303 else if(paramMap[string("Learning")] == 0.0)
00304 learningMode = false;
00305 else{
00306 cerr<<"STDP1Neuron ["<<neuronID<<"]: \"Learning\" HAS INCORRECT VALUE IN PARAMETER MAP: "<<paramMap[string("Learning")]<<endl;
00307 return false;
00308 }
00309 }
00310 else{
00311 cerr<<"STDP1Neuron ["<<neuronID<<"]: CANNOT FIND Learning IN PARAMETER MAP"<<endl;
00312 return false;
00313 }
00314
00315 #ifdef NEURON_PARAMETERS_DEBUG
00316 printParameters();
00317 #endif//NEURON_PARAMETERS_DEBUG
00318
00319
00320 return true;
00321 }
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 void STDP1Neuron::calculateMembranePotential(){
00335 #ifdef NEURON_METHOD_DEBUG
00336 cout<<"STDP1Neuron ["<<neuronID<<"]:Calculating membrane potential."<<endl;
00337 #endif//NEURON_METHOD_DEBUG
00338
00339
00340
00341 if(timeSinceLastFire <= refractoryPeriod_millisec){
00342 #ifdef NEURON_MODEL_DEBUG
00343 cout<<"Time "<<currentTime<<" In refractory period: NeuronID = "<<neuronID<<"; timeSinceLastFire = "<<timeSinceLastFire<<endl;
00344 #endif//NEURON_MODEL_DEBUG
00345
00346
00347 pspTotal = 0;
00348 membranePotential = 0;
00349
00350 return;
00351 }
00352
00353
00354
00355 membranePotential = pspTotal - exp ( refractoryParam_n - pow(timeSinceLastFire, refractoryParam_m));
00356
00357
00358
00359 #ifdef NEURON_MODEL_DEBUG
00360 cout<<"Time "<<currentTime<<" Calculating membrane potential: NeuronID = "<<neuronID<<"; timeSinceLastFire = "<<timeSinceLastFire<<" pspTotal = " <<pspTotal<<" membranePotential = "<<membranePotential<<"; refractory period = "<<refractoryPeriod_millisec<<"; param N = "<<refractoryParam_n<<" param M = "<<refractoryParam_m<<"; threshold = "<<threshold;
00361 cout<<" Last update time "<<lastUpdateTime<<" current time "<<currentTime<<endl;
00362 #endif//NEURON_MODEL_DEBUG
00363 }
00364
00365
00366
00367 void STDP1Neuron::printParameters(){
00368 cout<<"============================ STDP1 PARAMETERS =================================="<<endl;
00369 cout<<"Threshold = "<<threshold<<endl;
00370 cout<<"Refractory period = "<<refractoryPeriod_millisec<<endl;
00371 cout<<"Membrane time constant = "<<membraneTimeConstant_millisec<<endl;
00372 cout<<"Refractory parameter M = "<<refractoryParam_m<<endl;
00373 cout<<"Refractory parameter N = "<<refractoryParam_n<<endl;
00374 cout<<"CalciumIncreaseAmnt = "<<calciumIncreaseAmnt<<endl;
00375 cout<<"CalciumDecayRate = "<<calciumDecayRate<<endl;
00376 cout<<"Learning mode = "<<learningMode<<endl;
00377 cout<<"================================================================================="<<endl;
00378 }
00379
00380
00381
00382
00383
00384 void STDP1Neuron::update(){
00385 #ifdef NEURON_METHOD_DEBUG
00386 cout<<"STDP1Neuron ["<<neuronID<<"]: Updating."<<endl;
00387 #endif//NEURON_METHOD_DEBUG
00388
00389
00390 currentTime = simulationClock->getSimulationTime();
00391
00392 if(lastUpdateTime == currentTime)
00393 return;
00394
00395
00396
00397 timeSinceLastFire = currentTime - neuronFireTime;
00398
00399 #ifdef NEURON_MODEL_DEFBUG
00400 if(timeSinceLastFire < 0.0){
00401 cerr<<"STDP1Neuron ["<<neuronID<<"]: TIME SINCE LAST NEURON FIRE SHOULD NOT BE LESS THAN ZERO"<<endl;
00402 return;
00403 }
00404 #endif//NEURON_MODEL_DEBUG
00405
00406
00407
00408
00409
00410 pspTotal = pspTotal * exp( (lastUpdateTime - currentTime) / membraneTimeConstant_millisec );
00411
00412
00413 calciumConc *= exp( (lastUpdateTime - currentTime) / calciumDecayRate );
00414
00415
00416 lastUpdateTime = currentTime;
00417 }
00418
00419