CARLsim  6.1.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 * CARLsim6: LN, JX, KC, KW
46 *
47 * CARLsim available from http://socsci.uci.edu/~jkrichma/CARLsim/
48 * Ver 12/31/2016
49 */
50 #include <group_monitor_core.h>
51 
52 #include <snn.h> // CARLsim private implementation
53 #include <snn_definitions.h> // KERNEL_ERROR, KERNEL_INFO, ...
54 
55 #include <algorithm> // std::sort
56 
57 // we aren't using namespace std so pay attention!
58 GroupMonitorCore::GroupMonitorCore(SNN* snn, int monitorId, int grpId, int mode) {
59  snn_ = snn;
60  grpId_= grpId;
61  monitorId_ = monitorId;
62  mode_ = mode;
63 
64  groupFileId_ = NULL;
65  recordSet_ = false;
66  grpMonLastUpdated_ = 0;
67 
68  persistentData_ = false;
69 
70  needToWriteFileHeader_ = true;
71  groupFileSignature_ = 206661989;
72  groupFileVersion_ = 0.2f;
73 
74  // defer all unsafe operations to init function
75  init();
76 }
77 
78 void GroupMonitorCore::init() {
79  nNeurons_ = snn_->getGroupNumNeurons(grpId_);
80  assert(nNeurons_> 0);
81 
82 
83 
84  clear();
85 
86  // use KERNEL_{ERROR|WARNING|etc} typesetting (const FILE*)
87  fpInf_ = snn_->getLogFpInf();
88  fpErr_ = snn_->getLogFpErr();
89  fpDeb_ = snn_->getLogFpDeb();
90  fpLog_ = snn_->getLogFpLog();
91 }
92 
94  if (groupFileId_ != NULL) {
95  fclose(groupFileId_);
96  groupFileId_ = NULL;
97  }
98 }
99 
100 // +++++ PUBLIC METHODS: +++++++++++++++++++++++++++++++++++++++++++++++//
101 
103  assert(!isRecording());
104  recordSet_ = false;
105  startTime_ = -1;
106  startTimeLast_ = -1;
107  stopTime_ = -1;
108  accumTime_ = 0;
109  totalTime_ = -1;
110 
111  timeVector_.clear();
112  dataVector_.clear();
113 }
114 
115 void GroupMonitorCore::pushData(int time, float data) {
116  assert(isRecording());
117 
118  timeVector_.push_back(time);
119  dataVector_.push_back(data);
120 }
121 
122 void GroupMonitorCore::pushData(int time, float _DA, float _5HT, float _ACh, float _NE) {
123  assert(isRecording());
124 
125  timeVector_.push_back(time);
126  data4Vector_[0].push_back(_DA);
127  data4Vector_[1].push_back(_5HT);
128  data4Vector_[2].push_back(_ACh);
129  data4Vector_[3].push_back(_NE);
130 }
131 
132 std::vector<float> GroupMonitorCore::getDataVector(){
133  return dataVector_;
134 }
135 
136 std::vector<float> GroupMonitorCore::getDataVector(transmitter_t transmitter){
137  return data4Vector_[transmitter];
138 }
139 
141  return timeVector_;
142 }
143 
145  std::vector<int> peakTimeVector;
146 
147  int size = dataVector_.size() - 1;
148  for (int i = 1; i < size; i++) {
149  if (dataVector_[i-1] < dataVector_[i] && dataVector_[i] > dataVector_[i+1])
150  peakTimeVector.push_back(timeVector_[i]);
151  }
152 
153  return peakTimeVector;
154 }
155 
157  std::vector<int> sortedPeakTimeVector;
158 
159  int size = dataVector_.size() - 1;
160  for (int i = 1; i < size; i++) {
161  if (dataVector_[i-1] < dataVector_[i] && dataVector_[i] > dataVector_[i+1])
162  sortedPeakTimeVector.push_back(timeVector_[i]);
163  }
164 
165  std::sort(sortedPeakTimeVector.begin(), sortedPeakTimeVector.end());
166  std::reverse(sortedPeakTimeVector.begin(), sortedPeakTimeVector.end());
167 
168  return sortedPeakTimeVector;
169 }
170 
172  std::vector<float> peakValueVector;
173 
174  int size = dataVector_.size() - 1;
175  for (int i = 1; i < size; i++) {
176  if (dataVector_[i-1] < dataVector_[i] && dataVector_[i] > dataVector_[i+1])
177  peakValueVector.push_back(dataVector_[i]);
178  }
179 
180  return peakValueVector;
181 }
182 
184  std::vector<float> sortedPeakValueVector;
185 
186  int size = dataVector_.size() - 1;
187  for (int i = 1; i < size; i++) {
188  if (dataVector_[i-1] < dataVector_[i] && dataVector_[i] > dataVector_[i+1])
189  sortedPeakValueVector.push_back(dataVector_[i]);
190  }
191 
192  std::sort(sortedPeakValueVector.begin(), sortedPeakValueVector.end());
193  std::reverse(sortedPeakValueVector.begin(), sortedPeakValueVector.end());
194 
195  return sortedPeakValueVector;
196 }
197 
199  if (!persistentData_) {
200  // if persistent mode is off (default behavior), automatically call clear() here
201  clear();
202  }
203 
204  // call updateGroupMonitor to make sure group data file and the data vector are up-to-date
205  // Caution: must be called before recordSet_ is set to true!
206  snn_->updateGroupMonitor(grpId_);
207 
208  recordSet_ = true;
209  int currentTime = snn_->getSimTimeSec()*1000+snn_->getSimTimeMs();
210 
211  if (persistentData_) {
212  // persistent mode on: accumulate all times
213  // change start time only if this is the first time running it
214  startTime_ = (startTime_<0) ? currentTime : startTime_;
215  startTimeLast_ = currentTime;
216  accumTime_ = (totalTime_>0) ? totalTime_ : 0;
217  } else {
218  // persistent mode off: we only care about the last probe
219  startTime_ = currentTime;
220  startTimeLast_ = currentTime;
221  accumTime_ = 0;
222  }
223 }
224 
226  assert(isRecording());
227  assert(startTime_>-1 && startTimeLast_>-1 && accumTime_>-1);
228 
229  // call updateGroupMonitor to make sure group data file and the data vector are up-to-date
230  // Caution: must be called before recordSet_ is set to false!
231  snn_->updateGroupMonitor(grpId_);
232 
233  recordSet_ = false;
234  stopTime_ = snn_->getSimTimeSec()*1000+snn_->getSimTimeMs();
235 
236  // total time is the amount of time of the last probe plus all accumulated time from previous probes
237  totalTime_ = stopTime_-startTimeLast_ + accumTime_;
238  assert(totalTime_>=0);
239 }
240 
241 void GroupMonitorCore::setGroupFileId(FILE* groupFileId) {
242  assert(!isRecording());
243 
244  // \TODO consider the case where this function is called more than once
245  if (groupFileId_ != NULL)
246  KERNEL_ERROR("GroupMonitorCore: setGroupFileId() has already been called.");
247 
248  groupFileId_ = groupFileId;
249 
250  if (groupFileId_ == NULL)
251  needToWriteFileHeader_ = false;
252  else {
253  // for now: file pointer has changed, so we need to write header (again)
254  needToWriteFileHeader_ = true;
255  writeGroupFileHeader();
256  }
257 }
258 
259 // write the header section of the group data file
260 // this should be done once per file, and should be the very first entries in the file
261 void GroupMonitorCore::writeGroupFileHeader() {
262  if (!needToWriteFileHeader_)
263  return;
264 
265  // write file signature
266  if (!fwrite(&groupFileSignature_, sizeof(int), 1, groupFileId_))
267  KERNEL_ERROR("GroupMonitorCore: writeSpikeFileHeader has fwrite error");
268 
269  // write version number
270  if (!fwrite(&groupFileVersion_, sizeof(float), 1, groupFileId_))
271  KERNEL_ERROR("GroupMonitorCore: writeGroupFileHeader has fwrite error");
272 
273  // write grid dimensions
274  Grid3D grid = snn_->getGroupGrid3D(grpId_);
275  int tmpInt = grid.numX;
276  if (!fwrite(&tmpInt,sizeof(int), 1, groupFileId_))
277  KERNEL_ERROR("GroupMonitorCore: writeGroupFileHeader has fwrite error");
278  //printf("group file header tmpInt/grid.numX: %d\n", tmpInt);
279 
280  tmpInt = grid.numY;
281  if (!fwrite(&tmpInt,sizeof(int),1,groupFileId_))
282  KERNEL_ERROR("GroupMonitorCore: writeGroupFileHeader has fwrite error");
283  //printf("group file header tmpInt/grid.numY: %d\n", tmpInt);
284 
285  tmpInt = grid.numZ;
286  if (!fwrite(&tmpInt,sizeof(int),1,groupFileId_))
287  KERNEL_ERROR("GroupMonitorCore: writeGroupFileHeader has fwrite error");
288  //printf("group file header tmpInt/grid.numZ: %d\n", tmpInt);
289 
290  // the header is written once at the beginning, so the actual size is not known
292  //tmpInt = timeVector_.size();
293  //if (!fwrite(&tmpInt,sizeof(int),1,groupFileId_))
294  // KERNEL_ERROR("ConnectionMonitor: writeConnectFileHeader has fwrite error");
295  //printf("group file header tmpInt/timeVector_.size(): %d \n", tmpInt);
296 
297  // LN: issue: how to handle remainting Neurotransmitter 5HT, ACL and NOR ?
298  // Var 1: handle each transmitter seprately
299  // Var 2: make a new array t x 4 (-) backward comp -> irrelevant, du it is not yet implemented
300 
301  // V2 feat: compression => store only data <> base concentration
302  // V2 feat: bit mask from header: e.g. ACH | DA => stores and retrieves DA, ACH in that order
303 
304  // LN: DA or ALL Transmitter
305  tmpInt = mode_;
306  if (!fwrite(&tmpInt,sizeof(int),1,groupFileId_))
307  KERNEL_ERROR("ConnectionMonitor: writeConnectFileHeader has fwrite error");
308  //printf("group file header tmpInt/mode_: %d\n", tmpInt);
309 
310  //printf("header size %d\n", sizeof(int)*5+sizeof(float)*1);
311 
312  needToWriteFileHeader_ = false;
313 }
std::vector< float > getDataVector()
get the group data
std::vector< int > getSortedPeakTimeVector()
get the sorted timestamps for peak values
bool isRecording()
returns recording status
void updateGroupMonitor(int grpId=ALL)
access group status (currently the concentration of neuromodulator)
int getSimTimeSec()
Definition: snn.h:668
~GroupMonitorCore()
destructor, cleans up all the memory upon object deletion
std::vector< int > getTimeVector()
get the timestamps for group data
std::vector< float > getPeakValueVector()
get the peak values of group data
#define KERNEL_ERROR(formatc,...)
void setGroupFileId(FILE *groupFileId)
sets pointer to group data file
void pushData(int time, float data)
inserts group data (time, value) into the vectors , if monitor is in DA_MODE
Grid3D getGroupGrid3D(int grpId)
A struct to arrange neurons on a 3D grid (a primitive cubic Bravais lattice with cubic side length 1)...
const FILE * getLogFpLog()
returns file pointer to log file
Definition: snn.h:602
void startRecording()
starts recording group data
std::vector< float > getSortedPeakValueVector()
get the sorted peak values of group data
void clear()
deletes the data vector
const FILE * getLogFpErr()
returns file pointer to error log
Definition: snn.h:598
Contains all of CARLsim&#39;s core functionality.
Definition: snn.h:138
GroupMonitorCore(SNN *snn, int monitorId, int grpId, int mode=DA_MODE)
constructor (called by CARLsim::setGroupMonitor)
int getSimTimeMs()
Definition: snn.h:669
const FILE * getLogFpDeb()
returns file pointer to debug log
Definition: snn.h:600
void stopRecording()
stops recording group data
std::vector< int > getPeakTimeVector()
get the timestamps for peak values
int getGroupNumNeurons(int gGrpId)
Definition: snn.h:641
const FILE * getLogFpInf()
function writes population weights from gIDpre to gIDpost to file fname in binary.
Definition: snn.h:596