63 monitorId_ = monitorId;
67 spkMonLastUpdated_ = 0;
70 persistentData_ =
false;
71 userHasBeenWarned_ =
false;
72 needToWriteFileHeader_ =
true;
73 spikeFileSignature_ = 206661989;
74 spikeFileVersion_ = 0.2f;
80 void SpikeMonitorCore::init() {
87 spkVector_.resize(nNeurons_);
99 if (spikeFileId_!=NULL) {
100 fclose(spikeFileId_);
110 userHasBeenWarned_ =
false;
117 for (
int i=0; i<nNeurons_; i++)
118 spkVector_[i].
clear();
120 needToCalculateFiringRates_ =
true;
121 needToSortFiringRates_ =
true;
122 firingRates_.clear();
123 firingRatesSorted_.clear();
124 firingRates_.assign(nNeurons_,0);
125 firingRatesSorted_.assign(nNeurons_,0);
147 for (
int i=0; i<nNeurons_; i++)
148 std += (rates[i]-meanRate)*(rates[i]-meanRate);
149 std = sqrt(std/(nNeurons_-1));
159 for (
int i=0; i<nNeurons_; i++)
169 calculateFiringRates();
187 return rates.front();
192 assert(neurId>=0 && neurId<nNeurons_);
199 assert(neurId>=0 && neurId<nNeurons_);
202 return spkVector_[neurId].size();
211 return firingRatesSorted_;
216 assert(min>=0.0f && max>=0.0f);
223 std::vector<float>::const_iterator it_begin = firingRatesSorted_.begin();
224 std::vector<float>::const_iterator it_end = firingRatesSorted_.end();
225 for(std::vector<float>::const_iterator it=it_begin; it!=it_end; it++){
226 if((*it) >= min && (*it) <= max)
263 int dispSpkTimPerRow = 7;
265 KERNEL_INFO(
"(t=%.3fs) SpikeMonitor for group %s(%d) has %d spikes in %ld ms (%.2f +/- %.2f Hz)",
274 if (printSpikeTimes && mode_==
AER) {
276 KERNEL_INFO(
"| Neur ID | Rate (Hz) | Spike Times (ms)");
277 KERNEL_INFO(
"|- - - - -|- - - - - -|- - - - - - - - - - - - - - - - -- - - - - - - - - - - - -")
279 for (
int i=0; i<nNeurons_; i++) {
281 #if defined(WIN32) || defined(WIN64) 286 int nSpk = spkVector_[i].size();
287 for (
int j=0; j<nSpk; j++) {
289 #if defined(WIN32) || defined(WIN64) 290 _snprintf(times, 10,
"%8d", spkVector_[i][j]);
292 snprintf(times, 10,
"%8d", spkVector_[i][j]);
294 strcat(buffer, times);
295 if (j%dispSpkTimPerRow == dispSpkTimPerRow-1 && j<nSpk-1) {
297 strcpy(buffer,
"| | | ");
309 spkVector_[neurId].push_back(time);
315 if (!persistentData_) {
324 needToCalculateFiringRates_ =
true;
325 needToSortFiringRates_ =
true;
329 if (persistentData_) {
332 startTime_ = (startTime_<0) ? currentTime : startTime_;
333 startTimeLast_ = currentTime;
334 accumTime_ = (totalTime_>0) ? totalTime_ : 0;
338 startTime_ = currentTime;
339 startTimeLast_ = currentTime;
346 assert(startTime_>-1 && startTimeLast_>-1 && accumTime_>-1);
353 userHasBeenWarned_ =
false;
357 totalTime_ = stopTime_-startTimeLast_ + accumTime_;
358 assert(totalTime_>=0);
365 if (spikeFileId_!=NULL) {
366 fclose(spikeFileId_);
371 spikeFileId_=spikeFileId;
373 if (spikeFileId_==NULL)
374 needToWriteFileHeader_ =
false;
377 needToWriteFileHeader_ =
true;
378 writeSpikeFileHeader();
383 void SpikeMonitorCore::calculateFiringRates() {
385 if (!needToCalculateFiringRates_)
391 firingRates_.assign(nNeurons_,0);
392 firingRatesSorted_.assign(nNeurons_,0);
396 KERNEL_WARN(
"SpikeMonitorCore: calculateFiringRates has 0 totalTime");
401 assert(totalTime_>0);
402 for(
int i=0;i<nNeurons_;i++) {
403 firingRates_[i]=spkVector_[i].size()*1000.0/totalTime_;
406 needToCalculateFiringRates_ =
false;
410 void SpikeMonitorCore::sortFiringRates() {
412 if (!needToSortFiringRates_)
416 calculateFiringRates();
418 firingRatesSorted_=firingRates_;
419 std::sort(firingRatesSorted_.begin(),firingRatesSorted_.end());
421 needToSortFiringRates_ =
false;
426 void SpikeMonitorCore::writeSpikeFileHeader() {
427 if (!needToWriteFileHeader_)
431 if (!fwrite(&spikeFileSignature_,
sizeof(
int),1,spikeFileId_))
432 KERNEL_ERROR(
"SpikeMonitorCore: writeSpikeFileHeader has fwrite error");
435 if (!fwrite(&spikeFileVersion_,
sizeof(
float),1,spikeFileId_))
436 KERNEL_ERROR(
"SpikeMonitorCore: writeSpikeFileHeader has fwrite error");
440 int tmpInt = grid.
numX;
441 if (!fwrite(&tmpInt,
sizeof(
int),1,spikeFileId_))
442 KERNEL_ERROR(
"SpikeMonitorCore: writeSpikeFileHeader has fwrite error");
445 if (!fwrite(&tmpInt,
sizeof(
int),1,spikeFileId_))
446 KERNEL_ERROR(
"SpikeMonitorCore: writeSpikeFileHeader has fwrite error");
449 if (!fwrite(&tmpInt,
sizeof(
int),1,spikeFileId_))
450 KERNEL_ERROR(
"SpikeMonitorCore: writeSpikeFileHeader has fwrite error");
453 needToWriteFileHeader_ =
false;
460 long int bufferSize=0;
461 for(
int i=0; i<spkVector_.size();i++){
462 bufferSize+=spkVector_[i].size()*
sizeof(int);
470 if(userHasBeenWarned_)
475 userHasBeenWarned_=
true;
int getNumNeuronsWithFiringRate(float min, float max)
returns number of neurons whose firing rate was in [min,max] during recording
void clear()
deletes data from the 2D spike vector
std::vector< float > getAllFiringRates()
returns a list of firing rates for all neurons in the group (sorted by neuron ID ascending) ...
int getNumSilentNeurons()
returns number of neurons that didn't spike while recording
float getPercentSilentNeurons()
returns percentage of neurons that didn't spike during recording
std::vector< float > getAllFiringRatesSorted()
returns a list of firing rates for all neurons in the group (sorted by firing rate ascending) ...
long int getRecordingTotalTime()
returns the total recorded time in ms
bool isBufferBig()
returns true if spike buffer is close to maxAllowedBufferSize
#define KERNEL_WARN(formatc,...)
SpikeMonMode getMode()
returns recording mode
float getPercentNeuronsWithFiringRate(float min, float max)
returns percentage of neurons whose firing rate was in [min,max] during recording ...
float getNeuronMeanFiringRate(int neurId)
returns the recorded mean firing rate for a specific neuron
#define KERNEL_ERROR(formatc,...)
int getNeuronNumSpikes(int neurId)
returns the number of recorded spikes of a specific neuron
Grid3D getGroupGrid3D(int grpId)
std::vector< std::vector< int > > getSpikeVector2D()
returns the 2D AER vector
void startRecording()
starts recording AER data
#define KERNEL_INFO(formatc,...)
A struct to arrange neurons on a 3D grid (a primitive cubic Bravais lattice with cubic side length 1)...
void setSpikeFileId(FILE *spikeFileId)
sets pointer to spike file
float getMaxFiringRate()
returns the largest recorded firing rate
std::string getGroupName(int grpId)
void updateSpikeMonitor(int grpId=ALL)
copy required spikes from firing buffer to spike buffer
mode in which spike information is collected in AER format
const FILE * getLogFpLog()
returns file pointer to log file
long int getAccumTime()
returns the total accumulated time
void print(bool printSpikeTimes)
prints the AER vector in human-readable format
int getPopNumSpikes()
returns the total number of recorded spikes in the group
~SpikeMonitorCore()
destructor, cleans up all the memory upon object deletion
#define MAX_SPIKE_MON_BUFFER_SIZE
const FILE * getLogFpErr()
returns file pointer to error log
Contains all of CARLsim's core functionality.
float getMinFiringRate()
returns the smallest recorded firing rate
void pushAER(int time, int neurId)
inserts a (time,neurId) tupel into the 2D spike vector
bool isRecording()
returns recording status
const FILE * getLogFpDeb()
returns file pointer to debug log
float getPopStdFiringRate()
computes the standard deviation of firing rates in the group
int getGroupNumNeurons(int gGrpId)
float getPopMeanFiringRate()
returns the recorded mean firing rate of the group
void stopRecording()
stops recording AER data
SpikeMonitorCore(SNN *snn, int monitorId, int grpId)
constructor (called by CARLsim::setSpikeMonitor)
long int getBufferSize()
returns the approximate size of the spike vector in bytes
const FILE * getLogFpInf()
function writes population weights from gIDpre to gIDpost to file fname in binary.