CARLsim  5.0.0
CARLsim: a GPU-accelerated SNN simulator
group_monitor_core.cpp
Go to the documentation of this file.
1 /* * Copyright (c) 2016 Regents of the University of California. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions
5 * are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * 3. The names of its contributors may not be used to endorse or promote
15 * products derived from this software without specific prior written
16 * permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * *********************************************************************************************** *
31 * CARLsim
32 * created by: (MDR) Micah Richert, (JN) Jayram M. Nageswaran
33 * maintained by:
34 * (MA) Mike Avery <averym@uci.edu>
35 * (MB) Michael Beyeler <mbeyeler@uci.edu>,
36 * (KDC) Kristofor Carlson <kdcarlso@uci.edu>
37 * (TSC) Ting-Shuo Chou <tingshuc@uci.edu>
38 * (HK) Hirak J Kashyap <kashyaph@uci.edu>
39 *
40 * CARLsim v1.0: JM, MDR
41 * CARLsim v2.0/v2.1/v2.2: JM, MDR, MA, MB, KDC
42 * CARLsim3: MB, KDC, TSC
43 * CARLsim4: TSC, HK
44 * CARLsim5: HK, JX, KC
45 *
46 * CARLsim available from http://socsci.uci.edu/~jkrichma/CARLsim/
47 * Ver 12/31/2016
48 */
49 #include <group_monitor_core.h>
50 
51 #include <snn.h> // CARLsim private implementation
52 #include <snn_definitions.h> // KERNEL_ERROR, KERNEL_INFO, ...
53 
54 #include <algorithm> // std::sort
55 
56 // we aren't using namespace std so pay attention!
57 GroupMonitorCore::GroupMonitorCore(SNN* snn, int monitorId, int grpId) {
58  snn_ = snn;
59  grpId_= grpId;
60  monitorId_ = monitorId;
61 
62  groupFileId_ = NULL;
63  recordSet_ = false;
64  grpMonLastUpdated_ = 0;
65 
66  persistentData_ = false;
67 
68  needToWriteFileHeader_ = true;
69  groupFileSignature_ = 206661989;
70  groupFileVersion_ = 0.2f;
71 
72  // defer all unsafe operations to init function
73  init();
74 }
75 
76 void GroupMonitorCore::init() {
77  nNeurons_ = snn_->getGroupNumNeurons(grpId_);
78  assert(nNeurons_> 0);
79 
80  clear();
81 
82  // use KERNEL_{ERROR|WARNING|etc} typesetting (const FILE*)
83  fpInf_ = snn_->getLogFpInf();
84  fpErr_ = snn_->getLogFpErr();
85  fpDeb_ = snn_->getLogFpDeb();
86  fpLog_ = snn_->getLogFpLog();
87 }
88 
90  if (groupFileId_ != NULL) {
91  fclose(groupFileId_);
92  groupFileId_ = NULL;
93  }
94 }
95 
96 // +++++ PUBLIC METHODS: +++++++++++++++++++++++++++++++++++++++++++++++//
97 
99  assert(!isRecording());
100  recordSet_ = false;
101  startTime_ = -1;
102  startTimeLast_ = -1;
103  stopTime_ = -1;
104  accumTime_ = 0;
105  totalTime_ = -1;
106 
107  timeVector_.clear();
108  dataVector_.clear();
109 }
110 
111 void GroupMonitorCore::pushData(int time, float data) {
112  assert(isRecording());
113 
114  timeVector_.push_back(time);
115  dataVector_.push_back(data);
116 }
117 
118 std::vector<float> GroupMonitorCore::getDataVector(){
119  return dataVector_;
120 }
121 
123  return timeVector_;
124 }
125 
127  std::vector<int> peakTimeVector;
128 
129  int size = dataVector_.size() - 1;
130  for (int i = 1; i < size; i++) {
131  if (dataVector_[i-1] < dataVector_[i] && dataVector_[i] > dataVector_[i+1])
132  peakTimeVector.push_back(timeVector_[i]);
133  }
134 
135  return peakTimeVector;
136 }
137 
139  std::vector<int> sortedPeakTimeVector;
140 
141  int size = dataVector_.size() - 1;
142  for (int i = 1; i < size; i++) {
143  if (dataVector_[i-1] < dataVector_[i] && dataVector_[i] > dataVector_[i+1])
144  sortedPeakTimeVector.push_back(timeVector_[i]);
145  }
146 
147  std::sort(sortedPeakTimeVector.begin(), sortedPeakTimeVector.end());
148  std::reverse(sortedPeakTimeVector.begin(), sortedPeakTimeVector.end());
149 
150  return sortedPeakTimeVector;
151 }
152 
154  std::vector<float> peakValueVector;
155 
156  int size = dataVector_.size() - 1;
157  for (int i = 1; i < size; i++) {
158  if (dataVector_[i-1] < dataVector_[i] && dataVector_[i] > dataVector_[i+1])
159  peakValueVector.push_back(dataVector_[i]);
160  }
161 
162  return peakValueVector;
163 }
164 
166  std::vector<float> sortedPeakValueVector;
167 
168  int size = dataVector_.size() - 1;
169  for (int i = 1; i < size; i++) {
170  if (dataVector_[i-1] < dataVector_[i] && dataVector_[i] > dataVector_[i+1])
171  sortedPeakValueVector.push_back(dataVector_[i]);
172  }
173 
174  std::sort(sortedPeakValueVector.begin(), sortedPeakValueVector.end());
175  std::reverse(sortedPeakValueVector.begin(), sortedPeakValueVector.end());
176 
177  return sortedPeakValueVector;
178 }
179 
181  if (!persistentData_) {
182  // if persistent mode is off (default behavior), automatically call clear() here
183  clear();
184  }
185 
186  // call updateGroupMonitor to make sure group data file and the data vector are up-to-date
187  // Caution: must be called before recordSet_ is set to true!
188  snn_->updateGroupMonitor(grpId_);
189 
190  recordSet_ = true;
191  int currentTime = snn_->getSimTimeSec()*1000+snn_->getSimTimeMs();
192 
193  if (persistentData_) {
194  // persistent mode on: accumulate all times
195  // change start time only if this is the first time running it
196  startTime_ = (startTime_<0) ? currentTime : startTime_;
197  startTimeLast_ = currentTime;
198  accumTime_ = (totalTime_>0) ? totalTime_ : 0;
199  } else {
200  // persistent mode off: we only care about the last probe
201  startTime_ = currentTime;
202  startTimeLast_ = currentTime;
203  accumTime_ = 0;
204  }
205 }
206 
208  assert(isRecording());
209  assert(startTime_>-1 && startTimeLast_>-1 && accumTime_>-1);
210 
211  // call updateGroupMonitor to make sure group data file and the data vector are up-to-date
212  // Caution: must be called before recordSet_ is set to false!
213  snn_->updateGroupMonitor(grpId_);
214 
215  recordSet_ = false;
216  stopTime_ = snn_->getSimTimeSec()*1000+snn_->getSimTimeMs();
217 
218  // total time is the amount of time of the last probe plus all accumulated time from previous probes
219  totalTime_ = stopTime_-startTimeLast_ + accumTime_;
220  assert(totalTime_>=0);
221 }
222 
223 void GroupMonitorCore::setGroupFileId(FILE* groupFileId) {
224  assert(!isRecording());
225 
226  // \TODO consider the case where this function is called more than once
227  if (groupFileId_ != NULL)
228  KERNEL_ERROR("GroupMonitorCore: setGroupFileId() has already been called.");
229 
230  groupFileId_ = groupFileId;
231 
232  if (groupFileId_ == NULL)
233  needToWriteFileHeader_ = false;
234  else {
235  // for now: file pointer has changed, so we need to write header (again)
236  needToWriteFileHeader_ = true;
237  writeGroupFileHeader();
238  }
239 }
240 
241 // write the header section of the group data file
242 // this should be done once per file, and should be the very first entries in the file
243 void GroupMonitorCore::writeGroupFileHeader() {
244  if (!needToWriteFileHeader_)
245  return;
246 
247  // write file signature
248  if (!fwrite(&groupFileSignature_, sizeof(int), 1, groupFileId_))
249  KERNEL_ERROR("GroupMonitorCore: writeSpikeFileHeader has fwrite error");
250 
251  // write version number
252  if (!fwrite(&groupFileVersion_, sizeof(float), 1, groupFileId_))
253  KERNEL_ERROR("GroupMonitorCore: writeGroupFileHeader has fwrite error");
254 
255  // write grid dimensions
256  Grid3D grid = snn_->getGroupGrid3D(grpId_);
257  int tmpInt = grid.numX;
258  if (!fwrite(&tmpInt,sizeof(int), 1, groupFileId_))
259  KERNEL_ERROR("GroupMonitorCore: writeGroupFileHeader has fwrite error");
260 
261  tmpInt = grid.numY;
262  if (!fwrite(&tmpInt,sizeof(int),1,groupFileId_))
263  KERNEL_ERROR("GroupMonitorCore: writeGroupFileHeader has fwrite error");
264 
265  tmpInt = grid.numZ;
266  if (!fwrite(&tmpInt,sizeof(int),1,groupFileId_))
267  KERNEL_ERROR("GroupMonitorCore: writeGroupFileHeader has fwrite error");
268 
269 
270  needToWriteFileHeader_ = false;
271 }
SNN::getSimTimeSec
int getSimTimeSec()
Definition: snn.h:582
SNN::getGroupNumNeurons
int getGroupNumNeurons(int gGrpId)
Definition: snn.h:559
group_monitor_core.h
SNN::updateGroupMonitor
void updateGroupMonitor(int grpId=ALL)
access group status (currently the concentration of neuromodulator)
Definition: snn_manager.cpp:6280
GroupMonitorCore::startRecording
void startRecording()
starts recording group data
Definition: group_monitor_core.cpp:180
Grid3D::numX
int numX
Definition: carlsim_datastructures.h:548
GroupMonitorCore::getPeakTimeVector
std::vector< int > getPeakTimeVector()
get the timestamps for peak values
Definition: group_monitor_core.cpp:126
GroupMonitorCore::clear
void clear()
deletes the data vector
Definition: group_monitor_core.cpp:98
GroupMonitorCore::getSortedPeakValueVector
std::vector< float > getSortedPeakValueVector()
get the sorted peak values of group data
Definition: group_monitor_core.cpp:165
GroupMonitorCore::getDataVector
std::vector< float > getDataVector()
get the group data
Definition: group_monitor_core.cpp:118
GroupMonitorCore::stopRecording
void stopRecording()
stops recording group data
Definition: group_monitor_core.cpp:207
GroupMonitorCore::~GroupMonitorCore
~GroupMonitorCore()
destructor, cleans up all the memory upon object deletion
Definition: group_monitor_core.cpp:89
GroupMonitorCore::isRecording
bool isRecording()
returns recording status
Definition: group_monitor_core.h:100
snn_definitions.h
KERNEL_ERROR
#define KERNEL_ERROR(formatc,...)
Definition: snn_definitions.h:110
Grid3D::numY
int numY
Definition: carlsim_datastructures.h:548
GroupMonitorCore::getSortedPeakTimeVector
std::vector< int > getSortedPeakTimeVector()
get the sorted timestamps for peak values
Definition: group_monitor_core.cpp:138
SNN::getLogFpErr
const FILE * getLogFpErr()
returns file pointer to error log
Definition: snn.h:516
SNN::getSimTimeMs
int getSimTimeMs()
Definition: snn.h:583
SNN::getLogFpInf
const FILE * getLogFpInf()
function writes population weights from gIDpre to gIDpost to file fname in binary.
Definition: snn.h:514
Grid3D
A struct to arrange neurons on a 3D grid (a primitive cubic Bravais lattice with cubic side length 1)
Definition: carlsim_datastructures.h:490
SNN::getLogFpDeb
const FILE * getLogFpDeb()
returns file pointer to debug log
Definition: snn.h:518
GroupMonitorCore::GroupMonitorCore
GroupMonitorCore(SNN *snn, int monitorId, int grpId)
constructor (called by CARLsim::setGroupMonitor)
Definition: group_monitor_core.cpp:57
GroupMonitorCore::setGroupFileId
void setGroupFileId(FILE *groupFileId)
sets pointer to group data file
Definition: group_monitor_core.cpp:223
snn.h
SNN
Contains all of CARLsim's core functionality.
Definition: snn.h:115
GroupMonitorCore::getTimeVector
std::vector< int > getTimeVector()
get the timestamps for group data
Definition: group_monitor_core.cpp:122
GroupMonitorCore::getPeakValueVector
std::vector< float > getPeakValueVector()
get the peak values of group data
Definition: group_monitor_core.cpp:153
Grid3D::numZ
int numZ
Definition: carlsim_datastructures.h:548
SNN::getGroupGrid3D
Grid3D getGroupGrid3D(int grpId)
Definition: snn_manager.cpp:1846
SNN::getLogFpLog
const FILE * getLogFpLog()
returns file pointer to log file
Definition: snn.h:520
GroupMonitorCore::pushData
void pushData(int time, float data)
inserts group data (time, value) into the vectors
Definition: group_monitor_core.cpp:111