CARLsim  6.1.0
CARLsim: a GPU-accelerated SNN simulator
carlsim.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 
51 #include <carlsim.h>
52 #include <user_errors.h>
53 
54 //#include <callback.h>
55 
56 #include <callback_core.h>
57 
58 #include <iostream> // std::cout, std::endl
59 #include <sstream> // std::stringstream
60 #include <algorithm> // std::find, std::transform
61 
62 #include <snn.h>
63 
64 // includes for mkdir
65 #if CREATE_SPIKEDIR_IF_NOT_EXISTS
66  #if defined(WIN32) || defined(WIN64)
67  #else
68  #include <sys/stat.h>
69  #include <errno.h>
70  #include <libgen.h>
71  #endif
72 #endif
73 
74 // NOTE: Conceptual code documentation should go in carlsim.h. Do not include extensive high-level documentation here,
75 // but do document your code.
76 
77 
78 
80 public:
81  // +++++ PUBLIC METHODS: SETUP / TEAR-DOWN ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
82 
83  Impl(CARLsim* sim, const std::string& netName, SimMode prferredSimMode, LoggerMode loggerMode, int randSeed) {
84  netName_ = netName;
85  loggerMode_ = loggerMode;
86  preferredSimMode_ = prferredSimMode;
87  randSeed_ = randSeed;
88  enablePrint_ = false;
89  copyState_ = false;
90 
91  numConnections_ = 0;
92 
93  hasSetHomeoALL_ = false;
94  hasSetHomeoBaseFiringALL_ = false;
95  hasSetSTDPALL_ = false;
96  hasSetSTPALL_ = false;
97  hasSetConductances_ = false;
98  carlsimState_ = CONFIG_STATE;
99 
100  sim_ = sim;
101  snn_ = NULL;
102 
103  CARLsimInit(); // move everything else out of constructor
104  }
105 
106  ~Impl() {
107 
108 
109  // save simulation
110  if (carlsimState_ == SETUP_STATE || carlsimState_ == RUN_STATE)
111  saveSimulation(def_save_fileName_,def_save_synapseInfo_);
112  //\issue: LN20201021: certainly _NOT_ in the desctructor - review this following the user manual regarding open file pointers
113 
114  // deallocate all dynamically allocated structures
115  for (int i=0; i<spkGen_.size(); i++) {
116  if (spkGen_[i]!=NULL)
117  delete spkGen_[i];
118  spkGen_[i]=NULL;
119  }
120  for (int i=0; i<connGen_.size(); i++) {
121  if (connGen_[i]!=NULL)
122  delete connGen_[i];
123  connGen_[i]=NULL;
124  }
125  if (snn_!=NULL)
126  delete snn_;
127  snn_=NULL;
128  }
129 
130 
131 //#ifdef __LN_EXT__
132 //
133 // // LN Extension 20201017
134 // int cudaDeviceCount() {
135 // return snn_->cudaDeviceCount();
136 // }
137 //
138 // // LN Extension 20201017
139 // void cudaDeviceDescription(unsigned ithGPU, const char **desc) {
140 // snn_->cudaDeviceDescription(ithGPU, desc);
141 // }
142 //
143 //#endif
144 
145 
146 
147  // +++++++++ PUBLIC METHODS: SETTING UP A SIMULATION ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
148 
149  // Connects a presynaptic to a postsynaptic group using one of the primitive types
150  short int connect(int grpId1, int grpId2, const std::string& connType, const RangeWeight& wt, float connProb,
151  const RangeDelay& delay, const RadiusRF& radRF, bool synWtType, float mulSynFast, float mulSynSlow)
152  {
153  std::string funcName = "connect(\""+getGroupName(grpId1)+"\",\""+getGroupName(grpId2)+"\")";
154  std::stringstream grpId1str; grpId1str << "Group Id " << grpId1;
155  std::stringstream grpId2str; grpId2str << "Group Id " << grpId2;
156  UserErrors::assertTrue(grpId1!=ALL, UserErrors::ALL_NOT_ALLOWED, funcName, grpId1str.str()); // grpId can't be ALL
157  UserErrors::assertTrue(grpId2!=ALL, UserErrors::ALL_NOT_ALLOWED, funcName, grpId2str.str());
158  UserErrors::assertTrue(!isPoissonGroup(grpId2), UserErrors::WRONG_NEURON_TYPE, funcName, grpId2str.str() +
159  " is PoissonGroup, connect");
160  UserErrors::assertTrue(wt.max>=0.0f, UserErrors::CANNOT_BE_NEGATIVE, funcName, "wt.max");
161  UserErrors::assertTrue(wt.min>=0.0f, UserErrors::CANNOT_BE_NEGATIVE, funcName, "wt.min");
162  UserErrors::assertTrue(wt.init>=0.0f, UserErrors::CANNOT_BE_NEGATIVE, funcName, "wt.init");
163  UserErrors::assertTrue(connProb>=0.0f && connProb<=1.0f, UserErrors::MUST_BE_IN_RANGE, funcName,
164  "Connection Probability connProb", "[0,1]");
165  UserErrors::assertTrue(delay.min>0, UserErrors::MUST_BE_POSITIVE, funcName, "delay.min");
166  UserErrors::assertTrue(connType.compare("one-to-one")!=0
167  || connType.compare("one-to-one")==0 && getGroupNumNeurons(grpId1) == getGroupNumNeurons(grpId2),
168  UserErrors::MUST_BE_IDENTICAL, funcName, "For type \"one-to-one\", number of neurons in pre and post");
169  UserErrors::assertTrue(connType.compare("gaussian")!=0
170  || connType.compare("gaussian")==0 && (radRF.radX>-1 || radRF.radY>-1 || radRF.radZ>-1),
171  UserErrors::CANNOT_BE_NEGATIVE, funcName, "Receptive field radius for type \"gaussian\"");
172  UserErrors::assertTrue(synWtType==SYN_PLASTIC || synWtType==SYN_FIXED && wt.init==wt.max,
173  UserErrors::MUST_BE_IDENTICAL, funcName, "For fixed synapses, initWt and maxWt");
174  UserErrors::assertTrue(mulSynFast>=0.0f, UserErrors::CANNOT_BE_NEGATIVE, funcName, "mulSynFast");
175  UserErrors::assertTrue(mulSynSlow>=0.0f, UserErrors::CANNOT_BE_NEGATIVE, funcName, "mulSynSlow");
176 
178  "CONFIG.");
179  assert(++numConnections_ <= MAX_CONN_PER_SNN);
180 
181  // throw a warning if "one-to-one" is used in combination with a non-zero RF
182  if (connType.compare("one-to-one")==0 && (radRF.radX>0 || radRF.radY>0 || radRF.radZ>0)) {
183  userWarnings_.push_back("RadiusRF>0 will be ignored for connection type \"one-to-one\"");
184  }
185 
186  // TODO: enable support for non-zero min
187  if (fabs(wt.min)>1e-15) {
188  std::cerr << funcName << ": " << wt << ". Non-zero minimum weights are not yet supported.\n" << std::endl;
189  assert(false);
190  }
191 
192  // groups cannot be both chemically (synaptically) and electrically (compartmentally) connected
193  UserErrors::assertTrue(std::find(connComp_[grpId1].begin(), connComp_[grpId1].end(), grpId2) ==
194  connComp_[grpId1].end(), UserErrors::CANNOT_BE_CONN_SYN_AND_COMP, funcName,
195  grpId1str.str() + " and " + grpId2str.str());
196 
197  UserErrors::assertTrue(std::find(connComp_[grpId2].begin(), connComp_[grpId2].end(), grpId1) ==
198  connComp_[grpId2].end(), UserErrors::CANNOT_BE_CONN_SYN_AND_COMP, funcName,
199  grpId1str.str() + " and " + grpId2str.str());
200 
201  // add synaptic connection to 2D matrix
202  connSyn_[grpId1].push_back(grpId2);
203 
204  return snn_->connect(grpId1, grpId2, connType, wt.init, wt.max, connProb, delay.min, delay.max,
205  radRF, mulSynFast, mulSynSlow, synWtType);
206  }
207 
208  // custom connectivity profile
209  short int connect(int grpId1, int grpId2, ConnectionGenerator* conn, bool synWtType) {
210  std::string funcName = "connect(\""+getGroupName(grpId1)+"\",\""+getGroupName(grpId2)+"\")";
211  std::stringstream grpId1str; grpId1str << ". Group Id " << grpId1;
212  std::stringstream grpId2str; grpId2str << ". Group Id " << grpId2;
213  UserErrors::assertTrue(grpId1!=ALL, UserErrors::ALL_NOT_ALLOWED, funcName, grpId1str.str()); // grpId can't be ALL
214  UserErrors::assertTrue(grpId2!=ALL, UserErrors::ALL_NOT_ALLOWED, funcName, grpId2str.str());
215  UserErrors::assertTrue(!isPoissonGroup(grpId2), UserErrors::WRONG_NEURON_TYPE, funcName, grpId2str.str() +
216  " is PoissonGroup, connect");
217  UserErrors::assertTrue(conn!=NULL, UserErrors::CANNOT_BE_NULL, funcName, "ConnectionGenerator* conn");
218 
219  UserErrors::assertTrue(carlsimState_==CONFIG_STATE, UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName, funcName, "CONFIG.");
220  assert(++numConnections_ <= MAX_CONN_PER_SNN);
221 
222  // groups cannot be both chemically (synaptically) and electrically (compartmentally) connected
223  UserErrors::assertTrue(std::find(connComp_[grpId1].begin(), connComp_[grpId1].end(), grpId2) ==
224  connComp_[grpId1].end(), UserErrors::CANNOT_BE_CONN_SYN_AND_COMP, funcName,
225  grpId1str.str() + " and " + grpId2str.str());
226  UserErrors::assertTrue(std::find(connComp_[grpId2].begin(), connComp_[grpId2].end(), grpId1) ==
227  connComp_[grpId2].end(), UserErrors::CANNOT_BE_CONN_SYN_AND_COMP, funcName,
228  grpId1str.str() + " and " + grpId2str.str());
229 
230  // add synaptic connection to 2D matrix
231  connSyn_[grpId1].push_back(grpId2);
232 
233  // TODO: check for sign of weights
234  // ConnectionGeneratorCore* CGC = new ConnectionGeneratorCore(this, conn);
235  ConnectionGeneratorCore* CGC = new ConnectionGeneratorCore(sim_, conn);
236  connGen_.push_back(CGC);
237  return snn_->connect(grpId1, grpId2, CGC, 1.0f, 1.0f, synWtType);
238  }
239 
240  // custom connectivity profile
241  short int connect(int grpId1, int grpId2, ConnectionGenerator* conn, float mulSynFast, float mulSynSlow,
242  bool synWtType)
243  {
244  std::string funcName = "connect(\""+getGroupName(grpId1)+"\",\""+getGroupName(grpId2)+"\")";
245  std::stringstream grpId1str; grpId1str << ". Group Id " << grpId1;
246  std::stringstream grpId2str; grpId2str << ". Group Id " << grpId2;
247  UserErrors::assertTrue(grpId1!=ALL, UserErrors::ALL_NOT_ALLOWED, funcName, grpId1str.str()); // grpId can't be ALL
248  UserErrors::assertTrue(grpId2!=ALL, UserErrors::ALL_NOT_ALLOWED, funcName, grpId2str.str());
249  UserErrors::assertTrue(!isPoissonGroup(grpId2), UserErrors::WRONG_NEURON_TYPE, funcName, grpId2str.str() +
250  " is PoissonGroup, connect");
251  UserErrors::assertTrue(conn!=NULL, UserErrors::CANNOT_BE_NULL, funcName);
252  UserErrors::assertTrue(mulSynFast>=0.0f, UserErrors::CANNOT_BE_NEGATIVE, funcName, "mulSynFast");
253  UserErrors::assertTrue(mulSynSlow>=0.0f, UserErrors::CANNOT_BE_NEGATIVE, funcName, "mulSynSlow");
255  funcName, "CONFIG.");
256  assert(++numConnections_ <= MAX_CONN_PER_SNN);
257 
258  // groups cannot be both chemically (synaptically) and electrically (compartmentally) connected
259  UserErrors::assertTrue(std::find(connComp_[grpId1].begin(), connComp_[grpId1].end(), grpId2) ==
260  connComp_[grpId1].end(), UserErrors::CANNOT_BE_CONN_SYN_AND_COMP, funcName,
261  grpId1str.str() + " and " + grpId2str.str());
262  UserErrors::assertTrue(std::find(connComp_[grpId2].begin(), connComp_[grpId2].end(), grpId1) ==
263  connComp_[grpId2].end(), UserErrors::CANNOT_BE_CONN_SYN_AND_COMP, funcName,
264  grpId1str.str() + " and " + grpId2str.str());
265 
266  // add synaptic connection to 2D matrix
267  connSyn_[grpId1].push_back(grpId2);
268 
269  // ConnectionGeneratorCore* CGC = new ConnectionGeneratorCore(this, conn);
270  ConnectionGeneratorCore* CGC = new ConnectionGeneratorCore(sim_, conn);
271  connGen_.push_back(CGC);
272  return snn_->connect(grpId1, grpId2, CGC, mulSynFast, mulSynSlow, synWtType);
273  }
274 
275  short int connectCompartments(int grpIdLower, int grpIdUpper) {
276  std::stringstream funcName; funcName << "connectCompartments(" << grpIdLower << "," << grpIdUpper << ")";
277 
278  // grpIDs must be valid, cannot be identical
279  std::stringstream grpIdLowerStr; grpIdLowerStr << "Group Id " << grpIdLower;
280  std::stringstream grpIdUpperStr; grpIdUpperStr << "Group Id " << grpIdUpper;
281  UserErrors::assertTrue(grpIdLower >= 0 && grpIdLower<getNumGroups(), UserErrors::MUST_BE_IN_RANGE, funcName.str(),
282  grpIdLowerStr.str(), "[0,getNumGroups()]");
283  UserErrors::assertTrue(grpIdUpper >= 0 && grpIdUpper<getNumGroups(), UserErrors::MUST_BE_IN_RANGE, funcName.str(),
284  grpIdUpperStr.str(), "[0,getNumGroups()]");
285  UserErrors::assertTrue(grpIdLower != grpIdUpper, UserErrors::CANNOT_BE_IDENTICAL, funcName.str(),
286  grpIdLowerStr.str() + " and " + grpIdUpperStr.str());
287 
288  // groups cannot be spike generators
290  grpIdLowerStr.str() + " is PoissonGroup, connectCompartments");
292  grpIdUpperStr.str() + " is PoissonGroup, connectCompartments");
293 
294  // groups must have the same size
296  UserErrors::MUST_BE_IDENTICAL, funcName.str(), "Sizes of " + grpIdLowerStr.str() + " and " +
297  grpIdUpperStr.str());
298 
299  // groups must be located on the same partition
300  UserErrors::assertTrue(groupPrefNetIds_.at(grpIdLower) == groupPrefNetIds_.at(grpIdUpper),
301  UserErrors::MUST_BE_IDENTICAL, funcName.str(), "Preferred partions of " + grpIdLowerStr.str() + " and " +
302  grpIdUpperStr.str());
303 
304  // groups cannot be both chemically (synaptically) and electrically (compartmentally) connected
305  UserErrors::assertTrue(std::find(connSyn_[grpIdLower].begin(), connSyn_[grpIdLower].end(), grpIdUpper) ==
306  connSyn_[grpIdLower].end(), UserErrors::CANNOT_BE_CONN_SYN_AND_COMP, funcName.str(),
307  grpIdLowerStr.str() + " and " + grpIdUpperStr.str());
308  UserErrors::assertTrue(std::find(connSyn_[grpIdUpper].begin(), connSyn_[grpIdUpper].end(), grpIdLower) ==
309  connSyn_[grpIdUpper].end(), UserErrors::CANNOT_BE_CONN_SYN_AND_COMP, funcName.str(),
310  grpIdLowerStr.str() + " and " + grpIdUpperStr.str());
311 
312  // groups cannot be connected twice (order doesn't matter)
313  UserErrors::assertTrue(std::find(connComp_[grpIdLower].begin(), connComp_[grpIdLower].end(), grpIdUpper) ==
314  connComp_[grpIdLower].end(), UserErrors::CANNOT_BE_CONN_TWICE, funcName.str(),
315  grpIdLowerStr.str() + " and " + grpIdUpperStr.str());
316  UserErrors::assertTrue(std::find(connComp_[grpIdUpper].begin(), connComp_[grpIdUpper].end(), grpIdLower) ==
317  connComp_[grpIdUpper].end(), UserErrors::CANNOT_BE_CONN_TWICE, funcName.str(),
318  grpIdLowerStr.str() + " and " + grpIdUpperStr.str());
319 
320  // groups can have at most getMaxNumCompConnections() connections
322  funcName.str(), "Number of compartmental connections for group " + grpIdLowerStr.str(),
323  "[0,getMaxNumCompConnections()");
325  funcName.str(), "Number of compartmental connections for group " + grpIdUpperStr.str(),
326  "[0,getMaxNumCompConnections()");
327 
328  // add compartment connection to 2D matrix (both ways)
329  connComp_[grpIdLower].push_back(grpIdUpper);
330  connComp_[grpIdUpper].push_back(grpIdLower);
331 
332  return snn_->connectCompartments(grpIdLower, grpIdUpper);
333  }
334 
335  // create group of Izhikevich spiking neurons on 1D grid
336  int createGroup(const std::string& grpName, int nNeur, int neurType, int preferredPartition, ComputingBackend preferredBackend) {
337  return createGroup(grpName, Grid3D(nNeur,1,1), neurType, preferredPartition, preferredBackend);
338  }
339 
340  // create group of LIF spiking neurons on 1D grid
341  int createGroupLIF(const std::string& grpName, int nNeur, int neurType, int preferredPartition = ANY, ComputingBackend preferredBackend = CPU_CORES){
342  return createGroupLIF(grpName, Grid3D(nNeur,1,1), neurType, preferredPartition, preferredBackend);
343  }
344 
345  // create a group of Izhikevich spiking neurons on 3D grid
346  int createGroup(const std::string& grpName, const Grid3D& grid, int neurType, int preferredPartition, ComputingBackend preferredBackend) {
347  std::string funcName = "createGroup(\""+grpName+"\")";
349  funcName, "CONFIG.");
350  UserErrors::assertTrue(grid.numX>0, UserErrors::CANNOT_BE_NEGATIVE, funcName, "grid.numX");
351  UserErrors::assertTrue(grid.numY>0, UserErrors::CANNOT_BE_NEGATIVE, funcName, "grid.numY");
352  UserErrors::assertTrue(grid.numZ>0, UserErrors::CANNOT_BE_NEGATIVE, funcName, "grid.numZ");
353 
354  // if user has called any set functions with grpId=ALL, and is now adding another group, previously set properties
355  // will not apply to newly added group
356  if (hasSetSTPALL_)
357  userWarnings_.push_back("Make sure to call setSTP on group "+grpName);
358  if (hasSetSTDPALL_)
359  userWarnings_.push_back("Make sure to call setSTDP on group "+grpName);
360  if (hasSetHomeoALL_)
361  userWarnings_.push_back("Make sure to call setHomeostasis on group "+grpName);
362  if (hasSetHomeoBaseFiringALL_)
363  userWarnings_.push_back("Make sure to call setHomeoBaseFiringRate on group "+grpName);
364 
365  int grpId = snn_->createGroup(grpName.c_str(), grid, neurType, preferredPartition, preferredBackend);
366  grpIds_.push_back(grpId); // keep track of all groups
367 
368  int partitionOffset = 0;
369  if (preferredBackend == CPU_CORES)
370  partitionOffset = MAX_NUM_CUDA_DEVICES;
371  else if (preferredBackend == GPU_CORES)
372  partitionOffset = 0;
373  int prefPartition = preferredPartition + partitionOffset;
374  groupPrefNetIds_.insert(std::pair<int, int>(grpId, prefPartition));
375 
376  // extend 2D connection matrices to number of groups
377  connSyn_.resize(grpIds_.size());
378  connComp_.resize(grpIds_.size());
379 
380  return grpId;
381  }
382 
383  // create a group of LIF spiking neurons on 3D grid
384  int createGroupLIF(const std::string& grpName, const Grid3D& grid, int neurType, int preferredPartition, ComputingBackend preferredBackend) {
385  std::string funcName = "createGroupLIF(\""+grpName+"\")";
387  funcName, "CONFIG.");
388  UserErrors::assertTrue(grid.numX>0, UserErrors::CANNOT_BE_NEGATIVE, funcName, "grid.numX");
389  UserErrors::assertTrue(grid.numY>0, UserErrors::CANNOT_BE_NEGATIVE, funcName, "grid.numY");
390  UserErrors::assertTrue(grid.numZ>0, UserErrors::CANNOT_BE_NEGATIVE, funcName, "grid.numZ");
391 
392  // if user has called any set functions with grpId=ALL, and is now adding another group, previously set properties
393  // will not apply to newly added group
394  if (hasSetSTPALL_)
395  userWarnings_.push_back("Make sure to call setSTP on group "+grpName);
396  if (hasSetSTDPALL_)
397  userWarnings_.push_back("Make sure to call setSTDP on group "+grpName);
398  if (hasSetHomeoALL_)
399  userWarnings_.push_back("Make sure to call setHomeostasis on group "+grpName);
400  if (hasSetHomeoBaseFiringALL_)
401  userWarnings_.push_back("Make sure to call setHomeoBaseFiringRate on group "+grpName);
402 
403  int grpId = snn_->createGroupLIF(grpName.c_str(), grid, neurType, preferredPartition, preferredBackend);
404  grpIds_.push_back(grpId); // keep track of all groups
405 
406  int partitionOffset = 0;
407  if (preferredBackend == CPU_CORES)
408  partitionOffset = MAX_NUM_CUDA_DEVICES;
409  else if (preferredBackend == GPU_CORES)
410  partitionOffset = 0;
411  int prefPartition = preferredPartition + partitionOffset;
412  groupPrefNetIds_.insert(std::pair<int, int>(grpId, prefPartition));
413 
414  // extend 2D connection matrices to number of groups
415  connSyn_.resize(grpIds_.size());
416  connComp_.resize(grpIds_.size());
417 
418  return grpId;
419  }
420 
421  // create group of spike generators on 1D grid
422  int createSpikeGeneratorGroup(const std::string& grpName, int nNeur, int neurType, int preferredPartition, ComputingBackend preferredBackend) {
423  return createSpikeGeneratorGroup(grpName, Grid3D(nNeur,1,1), neurType, preferredPartition, preferredBackend);
424  }
425 
426  // create group of spike generators on 3D grid
427  int createSpikeGeneratorGroup(const std::string& grpName, const Grid3D& grid, int neurType, int preferredPartition, ComputingBackend preferredBackend) {
428  std::string funcName = "createSpikeGeneratorGroup(\""+grpName+"\")";
430  funcName, "CONFIG.");
431  UserErrors::assertTrue(grid.numX>0, UserErrors::CANNOT_BE_NEGATIVE, funcName, "grid.numX");
432  UserErrors::assertTrue(grid.numY>0, UserErrors::CANNOT_BE_NEGATIVE, funcName, "grid.numY");
433  UserErrors::assertTrue(grid.numZ>0, UserErrors::CANNOT_BE_NEGATIVE, funcName, "grid.numZ");
434 
435  int grpId = snn_->createSpikeGeneratorGroup(grpName.c_str(),grid,neurType, preferredPartition, preferredBackend);
436  grpIds_.push_back(grpId); // keep track of all groups
437 
438  // extend 2D connection matrices to number of groups
439  connSyn_.resize(grpIds_.size());
440  connComp_.resize(grpIds_.size());
441 
442  return grpId;
443  }
444 
445  void setCompartmentParameters(int grpId, float couplingUp, float couplingDown) {
446  std::string funcName = "setCompartmentParameters(\"" + getGroupName(grpId) + "\")";
448  "CONFIG.");
449 
450  snn_->setCompartmentParameters(grpId, couplingUp, couplingDown);
451  }
452 
453 #define LN_I_CALC_TYPES__REQUIRED_FOR_NETWORK_LEVEL
454 
455  // set conductance values, use defaults
456  void setConductances(bool isSet) {
457  std::stringstream funcName; funcName << "setConductances(" << isSet << ")";
459  funcName.str(), "CONFIG.");
460  hasSetConductances_ = true;
461 
462  if (isSet) { // enable conductances, use default values
463  snn_->setConductances(true, def_tdAMPA_, 0, def_tdNMDA_, def_tdGABAa_, 0, def_tdGABAb_);
464  }
465  else { // disable conductances
466  snn_->setConductances(false, 0, 0, 0, 0, 0, 0);
467  }
468  }
469 
470  // set conductances values, CUSTOM
471  void setConductances(bool isSet, int tdAMPA, int tdNMDA, int tdGABAa, int tdGABAb) {
472  std::stringstream funcName; funcName << "setConductances(" << isSet << "," << tdAMPA << "," << tdNMDA << ","
473  << tdGABAa << "," << tdGABAb << ")";
474  UserErrors::assertTrue(!isSet || tdAMPA > 0, UserErrors::MUST_BE_POSITIVE, funcName.str(), "tdAMPA");
475  UserErrors::assertTrue(!isSet || tdNMDA > 0, UserErrors::MUST_BE_POSITIVE, funcName.str(), "tdNMDA");
476  UserErrors::assertTrue(!isSet || tdGABAa > 0, UserErrors::MUST_BE_POSITIVE, funcName.str(), "tdGABAa");
477  UserErrors::assertTrue(!isSet || tdGABAb > 0, UserErrors::MUST_BE_POSITIVE, funcName.str(), "trGABAb");
479  funcName.str(), "CONFIG.");
480  hasSetConductances_ = true;
481 
482  if (isSet) { // enable conductances, use custom values
483  snn_->setConductances(true, tdAMPA, 0, tdNMDA, tdGABAa, 0, tdGABAb);
484  }
485  else { // disable conductances
486  snn_->setConductances(false, 0, 0, 0, 0, 0, 0);
487  }
488  }
489 
490  // set conductances values, custom
491  void setConductances(bool isSet, int tdAMPA, int trNMDA, int tdNMDA, int tdGABAa, int trGABAb,
492  int tdGABAb)
493  {
494  std::stringstream funcName; funcName << "setConductances(" << isSet << "," << tdAMPA << "," << trNMDA << "," <<
495  tdNMDA << "," << tdGABAa << "," << trGABAb << "," << tdGABAb << ")";
496  UserErrors::assertTrue(!isSet || tdAMPA > 0, UserErrors::MUST_BE_POSITIVE, funcName.str(), "tdAMPA");
497  UserErrors::assertTrue(!isSet || trNMDA >= 0, UserErrors::CANNOT_BE_NEGATIVE, funcName.str(), "trNMDA");
498  UserErrors::assertTrue(!isSet || tdNMDA > 0, UserErrors::MUST_BE_POSITIVE, funcName.str(), "tdNMDA");
499  UserErrors::assertTrue(!isSet || tdGABAa > 0, UserErrors::MUST_BE_POSITIVE, funcName.str(), "tdGABAa");
500  UserErrors::assertTrue(!isSet || trGABAb >= 0, UserErrors::CANNOT_BE_NEGATIVE, funcName.str(), "trGABAb");
501  UserErrors::assertTrue(!isSet || tdGABAb > 0, UserErrors::MUST_BE_POSITIVE, funcName.str(), "trGABAb");
502  UserErrors::assertTrue(trNMDA != tdNMDA, UserErrors::CANNOT_BE_IDENTICAL, funcName.str(), "trNMDA and tdNMDA");
503  UserErrors::assertTrue(trGABAb != tdGABAb, UserErrors::CANNOT_BE_IDENTICAL, funcName.str(),
504  "trGABAb and tdGABAb");
506  funcName.str(), "CONFIG.");
507  hasSetConductances_ = true;
508 
509  if (isSet) { // enable conductances, use custom values
510  snn_->setConductances(true, tdAMPA, trNMDA, tdNMDA, tdGABAa, trGABAb, tdGABAb);
511  }
512  else { // disable conductances
513  snn_->setConductances(false, 0, 0, 0, 0, 0, 0);
514  }
515  }
516 
517 
518 
519 #ifdef LN_I_CALC_TYPES
520 // LN2021
521 
522  // set conductance values, use defaults
523  void setConductances(int grpId, bool isSet) {
524  std::stringstream funcName; funcName << "setConductances(" << grpId << "," << isSet << ")";
526  funcName.str(), "CONFIG.");
527  hasSetConductances_ = true;
528 
529  if (isSet) { // enable conductances, use default values
530  snn_->setConductances(grpId, true, def_tdAMPA_, 0, def_tdNMDA_, def_tdGABAa_, 0, def_tdGABAb_);
531  }
532  else { // disable conductances
533  snn_->setConductances(grpId, false, 0, 0, 0, 0, 0, 0);
534  }
535  }
536 
537 
538  // set conductances values, CUSTOM
539  void setConductances(int grpId, bool isSet, int tdAMPA, int tdNMDA, int tdGABAa, int tdGABAb) {
540  std::stringstream funcName; funcName << "setConductances(" << grpId << "," << isSet << "," << tdAMPA << "," << tdNMDA << ","
541  << tdGABAa << "," << tdGABAb << ")";
542  UserErrors::assertTrue(!isSet || tdAMPA > 0, UserErrors::MUST_BE_POSITIVE, funcName.str(), "tdAMPA");
543  UserErrors::assertTrue(!isSet || tdNMDA > 0, UserErrors::MUST_BE_POSITIVE, funcName.str(), "tdNMDA");
544  UserErrors::assertTrue(!isSet || tdGABAa > 0, UserErrors::MUST_BE_POSITIVE, funcName.str(), "tdGABAa");
545  UserErrors::assertTrue(!isSet || tdGABAb > 0, UserErrors::MUST_BE_POSITIVE, funcName.str(), "trGABAb");
547  funcName.str(), "CONFIG.");
548  hasSetConductances_ = true;
549 
550  if (isSet) { // enable conductances, use custom values
551  snn_->setConductances(grpId, true, tdAMPA, 0, tdNMDA, tdGABAa, 0, tdGABAb);
552  }
553  else { // disable conductances
554  snn_->setConductances(grpId, false, 0, 0, 0, 0, 0, 0);
555  }
556  }
557 
558  // set conductances values, custom
559  void setConductances(int grpId, bool isSet, int tdAMPA, int trNMDA, int tdNMDA, int tdGABAa, int trGABAb,
560  int tdGABAb)
561  {
562  std::stringstream funcName; funcName << "setConductances(" << grpId << "," << isSet << "," << tdAMPA << "," << trNMDA << "," <<
563  tdNMDA << "," << tdGABAa << "," << trGABAb << "," << tdGABAb << ")";
564  UserErrors::assertTrue(!isSet || tdAMPA > 0, UserErrors::MUST_BE_POSITIVE, funcName.str(), "tdAMPA");
565  UserErrors::assertTrue(!isSet || trNMDA >= 0, UserErrors::CANNOT_BE_NEGATIVE, funcName.str(), "trNMDA");
566  UserErrors::assertTrue(!isSet || tdNMDA > 0, UserErrors::MUST_BE_POSITIVE, funcName.str(), "tdNMDA");
567  UserErrors::assertTrue(!isSet || tdGABAa > 0, UserErrors::MUST_BE_POSITIVE, funcName.str(), "tdGABAa");
568  UserErrors::assertTrue(!isSet || trGABAb >= 0, UserErrors::CANNOT_BE_NEGATIVE, funcName.str(), "trGABAb");
569  UserErrors::assertTrue(!isSet || tdGABAb > 0, UserErrors::MUST_BE_POSITIVE, funcName.str(), "trGABAb");
570  UserErrors::assertTrue(trNMDA != tdNMDA, UserErrors::CANNOT_BE_IDENTICAL, funcName.str(), "trNMDA and tdNMDA");
571  UserErrors::assertTrue(trGABAb != tdGABAb, UserErrors::CANNOT_BE_IDENTICAL, funcName.str(),
572  "trGABAb and tdGABAb");
574  funcName.str(), "CONFIG.");
575  hasSetConductances_ = true;
576 
577  if (isSet) { // enable conductances, use custom values
578  snn_->setConductances(grpId, true, tdAMPA, trNMDA, tdNMDA, tdGABAa, trGABAb, tdGABAb);
579  }
580  else { // disable conductances
581  snn_->setConductances(grpId, false, 0, 0, 0, 0, 0, 0);
582  }
583  }
584 
585 #endif
586 
587 #ifdef LN_I_CALC_TYPES
588  void setACNE12(int grpId) {
589  //_snn->setACNE12(grpId);
590  // TODO LN2021
591  }
592 
593  void setNM4weighted(int grpId, IcalcType icalc, float wDA, float w5HT, float wACh, float wNE, float wNorm, float wBase) {
594  std::stringstream funcName; funcName << "setNM4weighted(" << grpId << "," << icalc << ","
595  << wDA << "," << w5HT << "," << wACh << "," << wNE << "," << wNorm << "," << wBase << ")";
596 // TODO ln
597 // UserErrors::assertTrue(wNorm > 0, UserErrors::MUST_BE_POSITIVE, funcName.str(), "wNorm");
599  funcName.str(), "CONFIG.");
600  hasSetConductances_ = true; // API check
601 
602  if(icalc == alpha1_ADK13) // set Conductance defaults
603  snn_->setConductances(grpId, true, def_tdAMPA_, 0, def_tdNMDA_, def_tdGABAa_, 0, def_tdGABAb_);
604 
605  snn_->setNM4weighted(grpId, icalc, wDA, w5HT, wACh, wNE, wNorm, wBase);
606  }
607 #endif
608 
609  // set default homeostasis params
610  void setHomeostasis(int grpId, bool isSet) {
611  std::string funcName = "setHomeostasis(\""+getGroupName(grpId)+"\")";
612  UserErrors::assertTrue(!isSet || isSet && !isPoissonGroup(grpId), UserErrors::WRONG_NEURON_TYPE, funcName,
613  funcName);
615  funcName, "CONFIG.");
616 
617  hasSetHomeoALL_ = grpId==ALL; // adding groups after this will not have homeostasis set
618 
619  if (isSet) { // enable homeostasis, use default values
620  snn_->setHomeostasis(grpId,true,def_homeo_scale_,def_homeo_avgTimeScale_);
621  if (grpId!=ALL && hasSetHomeoBaseFiringALL_)
622  userWarnings_.push_back("Make sure to call setHomeoBaseFiringRate on group "
623  + getGroupName(grpId));
624  } else { // disable conductances
625  snn_->setHomeostasis(grpId,false,0.0f,0.0f);
626  }
627  }
628 
629  // set custom homeostasis params for group
630  void setHomeostasis(int grpId, bool isSet, float homeoScale, float avgTimeScale) {
631  std::string funcName = "setHomeostasis(\""+getGroupName(grpId)+"\")";
632  UserErrors::assertTrue(!isSet || isSet && !isPoissonGroup(grpId), UserErrors::WRONG_NEURON_TYPE, funcName,
633  funcName);
635  "CONFIG.");
636 
637  hasSetHomeoALL_ = grpId==ALL; // adding groups after this will not have homeostasis set
638 
639  if (isSet) { // enable homeostasis, use default values
640  snn_->setHomeostasis(grpId,true,homeoScale,avgTimeScale);
641  if (grpId!=ALL && hasSetHomeoBaseFiringALL_)
642  userWarnings_.push_back("Make sure to call setHomeoBaseFiringRate on group "
643  + getGroupName(grpId));
644  } else { // disable conductances
645  snn_->setHomeostasis(grpId,false,0.0f,0.0f);
646  }
647  }
648 
649  // set a homeostatic target firing rate (enforced through homeostatic synaptic scaling)
650  void setHomeoBaseFiringRate(int grpId, float baseFiring, float baseFiringSD) {
651  std::string funcName = "setHomeoBaseFiringRate(\""+getGroupName(grpId)+"\")";
654  funcName, " Must call setHomeostasis first.");
656  "CONFIG.");
657 
658  hasSetHomeoBaseFiringALL_ = grpId==ALL; // adding groups after this will not have base firing set
659 
660  snn_->setHomeoBaseFiringRate(grpId, baseFiring, baseFiringSD);
661  }
662 
663  // sets integration method (FORWARD_EULER, RUNGE_KUTTA4, etc.) and integration step
664  void setIntegrationMethod(integrationMethod_t method, int numStepsPerMs) {
665  std::string funcName = "setIntegrationMethod()";
667  "CONFIG.");
668  UserErrors::assertTrue((numStepsPerMs >= 1) && (numStepsPerMs <= 100), UserErrors::MUST_BE_IN_RANGE, funcName,
669  "numStepsPerMs", "[1, 100]");
670 
671  snn_->setIntegrationMethod(method, numStepsPerMs);
672 
673  //std::cout << "numStepsPerMs is (in interface): " + numStepsPerMs << std::endl;
674  }
675 
676  // set neuron parameters for Izhikevich neuron, with standard deviations
677  void setNeuronParameters(int grpId, float izh_a, float izh_a_sd, float izh_b, float izh_b_sd,
678  float izh_c, float izh_c_sd, float izh_d, float izh_d_sd)
679  {
680  std::string funcName = "setNeuronParameters(\""+getGroupName(grpId)+"\")";
683  "CONFIG.");
684 
685  // wrapper identical to core func
686  snn_->setNeuronParameters(grpId, izh_a, izh_a_sd, izh_b, izh_b_sd, izh_c, izh_c_sd, izh_d, izh_d_sd);
687  }
688 
689  // set neuron parameters for Izhikevich neuron
690  void setNeuronParameters(int grpId, float izh_a, float izh_b, float izh_c, float izh_d) {
691  std::string funcName = "setNeuronParameters(\""+getGroupName(grpId)+"\")";
694  funcName, "CONFIG.");
695 
696  // set standard deviations of Izzy params to zero
697  snn_->setNeuronParameters(grpId, izh_a, 0.0f, izh_b, 0.0f, izh_c, 0.0f, izh_d, 0.0f);
698  }
699 
700  void setNeuronParameters(int grpId, float izh_C, float izh_k, float izh_vr, float izh_vt,
701  float izh_a, float izh_b, float izh_vpeak, float izh_c, float izh_d)
702  {
703  std::string funcName = "setNeuronParameters(\"" + getGroupName(grpId) + "\")";
705  UserErrors::assertTrue(carlsimState_ == CONFIG_STATE, UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName, funcName, "CONFIG.");
706  UserErrors::assertTrue(izh_C > 0, UserErrors::CANNOT_BE_NEGATIVE, funcName, "izh_C");
707 
708  // set standard deviations of Izzy params to zero
709  snn_->setNeuronParameters(grpId, izh_C, 0.0f, izh_k, 0.0f, izh_vr, 0.0f, izh_vt, 0.0f,
710  izh_a, 0.0f, izh_b, 0.0f, izh_vpeak, 0.0f, izh_c, 0.0f, izh_d, 0.0f);
711  }
712 
713 
714  void setNeuronParameters(int grpId, float izh_C, float izh_C_sd, float izh_k, float izh_k_sd,
715  float izh_vr, float izh_vr_sd, float izh_vt, float izh_vt_sd,
716  float izh_a, float izh_a_sd, float izh_b, float izh_b_sd,
717  float izh_vpeak, float izh_vpeak_sd, float izh_c, float izh_c_sd,
718  float izh_d, float izh_d_sd)
719  {
720  std::string funcName = "setNeuronParameters(\"" + getGroupName(grpId) + "\")";
722  UserErrors::assertTrue(carlsimState_ == CONFIG_STATE, UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName, funcName, "CONFIG.");
723  UserErrors::assertTrue(izh_C > 0, UserErrors::CANNOT_BE_NEGATIVE, funcName, "izh_C");
724 
725  // wrapper identical to core func
726  snn_->setNeuronParameters(grpId, izh_C, izh_C_sd, izh_k, izh_k_sd, izh_vr, izh_vr_sd, izh_vt, izh_vt_sd,
727  izh_a, izh_a_sd, izh_b, izh_b_sd, izh_vpeak, izh_vpeak_sd, izh_c, izh_c_sd, izh_d, izh_d_sd);
728  }
729 
730  // set neuron parameters for LIF spiking neuron
731  void setNeuronParametersLIF(int grpId, int tau_m, int tau_ref, float vTh, float vReset, const RangeRmem& rMem)
732  {
733  std::string funcName = "setNeuronParametersLIF(\"" + getGroupName(grpId) + "\")";
735  UserErrors::assertTrue(carlsimState_ == CONFIG_STATE, UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName, funcName, "CONFIG.");
736 
737  UserErrors::assertTrue(tau_m >= 0 , UserErrors::CANNOT_BE_NEGATIVE, funcName, "tau_m");
738  UserErrors::assertTrue(tau_ref >= 0 , UserErrors::CANNOT_BE_NEGATIVE, funcName, "tau_ref");
739 
740  UserErrors::assertTrue(vReset < vTh , UserErrors::CANNOT_BE_LARGER, funcName, "vReset");
741 
742  UserErrors::assertTrue(rMem.minRmem >= 0.0f , UserErrors::CANNOT_BE_NEGATIVE, funcName, "rangeRmem.minRmem");
743  UserErrors::assertTrue(rMem.minRmem <= rMem.maxRmem , UserErrors::CANNOT_BE_LARGER, funcName, "rangeRmem.minRmem");
744 
745  // wrapper identical to core func
746  snn_->setNeuronParametersLIF(grpId, tau_m, tau_ref, vTh, vReset,rMem.minRmem, rMem.maxRmem);
747  }
748 
749  // set parameters for each neuronmodulator
750  void setNeuromodulator(int grpId,
751  float baseDP, float tauDP, float releaseDP, bool activeDP,
752  float base5HT, float tau5HT, float release5HT, bool active5HT,
753  float baseACh, float tauACh, float releaseACh, bool activeACh,
754  float baseNE, float tauNE, float releaseNE, bool activeNE)
755  {
756  std::string funcName = "setNeuromodulator(\"" + getGroupName(grpId) + "\")";
757  UserErrors::assertTrue(baseDP >= 0, UserErrors::CANNOT_BE_NEGATIVE, funcName); // LN2021: due to decay
766  funcName, "CONFIG.");
767 
768  snn_->setNeuromodulator(grpId,
769  baseDP, tauDP, releaseDP, activeDP,
770  base5HT, tau5HT, release5HT, active5HT,
771  baseACh, tauACh, releaseACh, activeACh,
772  baseNE, tauNE, releaseNE, activeNE);
773  }
774 
775  // set parameters for each neuronmodulator
776  void setNeuromodulator(int grpId, float baseDP, float tauDP, float base5HT, float tau5HT, float baseACh,
777  float tauACh, float baseNE, float tauNE)
778  {
779  std::string funcName = "setNeuromodulator(\""+getGroupName(grpId)+"\")";
789  funcName, "CONFIG.");
790 
791  snn_->setNeuromodulator(grpId, baseDP, tauDP, base5HT, tau5HT, baseACh, tauACh, baseNE, tauNE);
792  }
793 
794  void setNeuromodulator(int grpId,float tauDP, float tau5HT, float tauACh, float tauNE) {
795  std::string funcName = "setNeuromodulator(\""+getGroupName(grpId)+"\")";
801  funcName, "CONFIG.");
802 
803  snn_->setNeuromodulator(grpId, 1.0f, tauDP, 1.0f, tau5HT, 1.0f, tauACh, 1.0f, tauNE);
804  }
805 
806  // set STDP, default, wrapper function
807  void setSTDP(int preGrpId, int postGrpId, bool isSet) {
808  setESTDP(preGrpId, postGrpId, isSet);
809  }
810 
811  // set STDP, custom, wrapper function
812  void setSTDP(int preGrpId, int postGrpId, bool isSet, STDPType type, float alphaPlus, float tauPlus, float alphaMinus,
813  float tauMinus)
814  {
815  setESTDP(preGrpId, postGrpId, isSet, type, ExpCurve(alphaPlus, tauPlus, alphaMinus, tauMinus));
816  }
817 
818  // set ESTDP, default
819  void setESTDP(int preGrpId, int postGrpId, bool isSet) {
820  std::string funcName = "setESTDP(\""+getGroupName(preGrpId) + ", " + getGroupName(postGrpId) +"\")";
821  UserErrors::assertTrue(!isSet || isSet && !isPoissonGroup(postGrpId), UserErrors::WRONG_NEURON_TYPE, funcName,
822  funcName);
824  funcName, "CONFIG.");
825 
826  hasSetSTDPALL_ = postGrpId==ALL; // adding groups after this will not have conductances set
827 
828  if (isSet) { // enable STDP, use default values and type
829  snn_->setESTDP(preGrpId, postGrpId, true, def_STDP_type_, EXP_CURVE, def_STDP_alphaLTP_, def_STDP_tauLTP_,
830  def_STDP_alphaLTD_, def_STDP_tauLTD_, 0.0f);
831  } else { // disable STDP
832  snn_->setESTDP(preGrpId, postGrpId, false, UNKNOWN_STDP, UNKNOWN_CURVE, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f);
833  }
834  }
835 
836  // set ESTDP by stdp curve
837  void setESTDP(int preGrpId, int postGrpId, bool isSet, STDPType type, ExpCurve curve) {
838  std::string funcName = "setESTDP(\""+getGroupName(preGrpId) + ", " + getGroupName(postGrpId) +"\")";
839  UserErrors::assertTrue(!isSet || isSet && !isPoissonGroup(postGrpId), UserErrors::WRONG_NEURON_TYPE, funcName,
840  funcName);
843  funcName, "CONFIG.");
844 
845  hasSetSTDPALL_ = postGrpId==ALL; // adding groups after this will not have conductances set
846 
847  if (isSet) { // enable STDP, use custom values
848  snn_->setESTDP(preGrpId, postGrpId, true, type, curve.stdpCurve, curve.alphaPlus, curve.tauPlus, curve.alphaMinus,
849  curve.tauMinus, 0.0f);
850  } else { // disable STDP and DA-STDP as well
851  snn_->setESTDP(preGrpId, postGrpId, false, UNKNOWN_STDP, UNKNOWN_CURVE, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f);
852  }
853  }
854 
855 #ifdef LN_I_CALC_TYPES
856  // set ESTDP by stdp curve
857  void setESTDP(int preGrpId, int postGrpId, bool isSet, STDPType type, ExpCurve curve, PkaPlcModulation modulation) {
858  std::string funcName = "setESTDP(\"" + getGroupName(preGrpId) + ", " + getGroupName(postGrpId) + "\")";
859  UserErrors::assertTrue(!isSet || isSet && !isPoissonGroup(postGrpId), UserErrors::WRONG_NEURON_TYPE, funcName,
860  funcName);
861  UserErrors::assertTrue(type == modulation.type, UserErrors::MUST_BE_IN_RANGE, funcName, "Mode");
863  funcName, "CONFIG.");
864 
865  hasSetSTDPALL_ = postGrpId == ALL; // adding groups after this will not have conductances set
866 
867  if (isSet) { // enable STDP, use custom values
868  snn_->setESTDP(preGrpId, postGrpId, true, type,
869  curve.stdpCurve, curve.alphaPlus, curve.tauPlus, curve.alphaMinus, curve.tauMinus,
870  modulation.nm_pka(), modulation.w_pka(), modulation.nm_plc(), modulation.w_plc()
871  );
872  }
873  else { // disable STDP and DA-STDP as well
874  snn_->setESTDP(preGrpId, postGrpId, false, UNKNOWN_STDP, UNKNOWN_CURVE, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f);
875  }
876  }
877 
878  // set connection nm
879  void setConnectionModulation(int preGrpId, int postGrpId, IcalcType icalcType) {
880 
881  snn_->setConnectionModulation(preGrpId, postGrpId, icalcType);
882 
883  }
884 #endif
885 
886  // set ESTDP by stdp curve
887  void setESTDP(int preGrpId, int postGrpId, bool isSet, STDPType type, TimingBasedCurve curve) {
888  std::string funcName = "setESTDP(\""+getGroupName(preGrpId) + ", " + getGroupName(postGrpId) +"\")";
889  UserErrors::assertTrue(!isSet || isSet && !isPoissonGroup(postGrpId), UserErrors::WRONG_NEURON_TYPE, funcName,
890  funcName);
893  funcName, "CONFIG.");
894 
895  hasSetSTDPALL_ = postGrpId==ALL; // adding groups after this will not have conductances set
896 
897  if (isSet) { // enable STDP, use custom values
898  snn_->setESTDP(preGrpId, postGrpId, true, type, curve.stdpCurve, curve.alphaPlus, curve.tauPlus, curve.alphaMinus,
899  curve.tauMinus, curve.gamma);
900  } else { // disable STDP and DA-STDP as well
901  snn_->setESTDP(preGrpId, postGrpId, false, UNKNOWN_STDP, UNKNOWN_CURVE, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f);
902  }
903  }
904 
905  // set ISTDP, default
906  void setISTDP(int preGrpId, int postGrpId, bool isSet) {
907  std::string funcName = "setISTDP(\""+getGroupName(preGrpId) + ", " + getGroupName(postGrpId) +"\")";
908  UserErrors::assertTrue(!isSet || isSet && !isPoissonGroup(postGrpId), UserErrors::WRONG_NEURON_TYPE, funcName,
909  funcName);
911  funcName, "CONFIG.");
912 
913  hasSetSTDPALL_ = postGrpId==ALL; // adding groups after this will not have conductances set
914 
915  if (isSet) { // enable STDP, use default values and types
916  snn_->setISTDP(preGrpId, postGrpId, true, def_STDP_type_, PULSE_CURVE, def_STDP_betaLTP_, def_STDP_betaLTD_,
917  def_STDP_lambda_, def_STDP_delta_);
918  } else { // disable STDP
919  snn_->setISTDP(preGrpId, postGrpId, false, UNKNOWN_STDP, UNKNOWN_CURVE, 0.0f, 0.0f, 1.0f, 1.0f);
920  }
921  }
922 
923  // set ISTDP by stdp curve
924  void setISTDP(int preGrpId, int postGrpId, bool isSet, STDPType type, ExpCurve curve) {
925  std::string funcName = "setISTDP(\""+getGroupName(preGrpId) + ", " + getGroupName(postGrpId) +"\")";
926  UserErrors::assertTrue(!isSet || isSet && !isPoissonGroup(postGrpId), UserErrors::WRONG_NEURON_TYPE, funcName,
927  funcName);
930  funcName, "CONFIG.");
931 
932  hasSetSTDPALL_ = postGrpId==ALL; // adding groups after this will not have conductances set
933 
934  if (isSet) { // enable STDP, use custom values
935  snn_->setISTDP(preGrpId, postGrpId, true, type, curve.stdpCurve, curve.alphaPlus, curve.alphaMinus, curve.tauPlus,
936  curve.tauMinus);
937  } else { // disable STDP and DA-STDP as well
938  snn_->setISTDP(preGrpId, postGrpId, false, UNKNOWN_STDP, UNKNOWN_CURVE, 0.0f, 0.0f, 1.0f, 1.0f);
939  }
940  }
941 
942  // set ISTDP by stdp curve
943  void setISTDP(int preGrpId, int postGrpId, bool isSet, STDPType type, PulseCurve curve) {
944  std::string funcName = "setISTDP(\""+getGroupName(preGrpId) + ", " + getGroupName(postGrpId) +"\")";
945  UserErrors::assertTrue(!isSet || isSet && !isPoissonGroup(postGrpId), UserErrors::WRONG_NEURON_TYPE, funcName,
946  funcName);
949  funcName, "CONFIG.");
950 
951  hasSetSTDPALL_ = postGrpId==ALL; // adding groups after this will not have conductances set
952 
953  if (isSet) { // enable STDP, use custom values
954  snn_->setISTDP(preGrpId, postGrpId, true, type, curve.stdpCurve, curve.betaLTP, curve.betaLTD, curve.lambda, curve.delta);
955  } else { // disable STDP and DA-STDP as well
956  snn_->setISTDP(preGrpId, postGrpId, false, UNKNOWN_STDP, UNKNOWN_CURVE, 0.0f, 0.0f, 1.0f, 1.0f);
957  }
958  }
959 
960  // set STP, default
961  void setSTP(int grpId, bool isSet) {
962  std::string funcName = "setSTP(\""+getGroupName(grpId)+"\")";
964  funcName, "CONFIG.");
965 
966  hasSetSTPALL_ = grpId==ALL; // adding groups after this will not have conductances set
967 
968  if (isSet) { // enable STDP, use default values
970  funcName, "setSTP");
971 
972  if (isExcitatoryGroup(grpId))
973  snn_->setSTP(grpId,true,def_STP_U_exc_,def_STP_tau_u_exc_,def_STP_tau_x_exc_);
974  else if (isInhibitoryGroup(grpId))
975  snn_->setSTP(grpId,true,def_STP_U_inh_,def_STP_tau_u_inh_,def_STP_tau_x_inh_);
976  else {
977  // some error message
978  }
979  } else { // disable STDP
980  snn_->setSTP(grpId,false,0.0f,0.0f,0.0f);
981  }
982  }
983 
984  // set STP, custom
985  void setSTP(int grpId, bool isSet, float STP_U, float STP_tau_u, float STP_tau_x) {
986  std::string funcName = "setSTP(\""+getGroupName(grpId)+"\")";
988  funcName, "CONFIG.");
989 
990  hasSetSTPALL_ = grpId==ALL; // adding groups after this will not have conductances set
991 
992  if (isSet) { // enable STDP, use default values
994  funcName,"setSTP");
995 
996  snn_->setSTP(grpId,true,STP_U,STP_tau_u,STP_tau_x);
997  } else { // disable STDP
998  snn_->setSTP(grpId,false,0.0f,0.0f,0.0f);
999  }
1000  }
1001 
1002 #ifdef LN_I_CALC_TYPES
1003 
1004  // set neuromodulator targeting STP
1005  void setNM4STP(int grpId, float wSTP_U[], float wSTP_tau_u[], float wSTP_tau_x[]) {
1006  std::string funcName = "setNM4STP(\"" + getGroupName(grpId) + "\")";
1008  funcName, "CONFIG.");
1009 
1011  // snn_->groupConfigMap[gGrpId].stpConfig.WithSTP
1012  // -->
1013  // snn_->isGroupWithSTP(grpId);
1014  //if (isSet) {
1015  // UserErrors::assertTrue(isExcitatoryGroup(grpId) || isInhibitoryGroup(grpId), UserErrors::WRONG_NEURON_TYPE,
1016  // funcName, "setSTP");
1017  //}
1018 
1019  snn_->setNM4STP(grpId, wSTP_U, wSTP_tau_u, wSTP_tau_x);
1020 
1021  }
1022 
1023 
1024 #endif
1025 
1026  void setWeightAndWeightChangeUpdate(UpdateInterval wtANDwtChangeUpdateInterval, bool enableWtChangeDecay,
1027  float wtChangeDecay)
1028  {
1029  std::string funcName = "setWeightAndWeightChangeUpdate()";
1030  UserErrors::assertTrue(wtChangeDecay > 0.0f, UserErrors::MUST_BE_POSITIVE, funcName);
1031  UserErrors::assertTrue(wtChangeDecay < 1.0f, UserErrors::CANNOT_BE_LARGER, funcName);
1033  funcName, "CONFIG.");
1034 
1035  snn_->setWeightAndWeightChangeUpdate(wtANDwtChangeUpdateInterval, enableWtChangeDecay, wtChangeDecay);
1036  }
1037 
1038 
1039  // +++++++++ PUBLIC METHODS: RUNNING A SIMULATION +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
1040 
1041  // run network with custom options
1042  int runNetwork(int nSec, int nMsec, bool printRunSummary) {
1043  std::string funcName = "runNetwork()";
1044  UserErrors::assertTrue(carlsimState_ == SETUP_STATE || carlsimState_ == RUN_STATE,
1045  UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName, funcName, "SETUP or RUN.");
1046 
1047  // run some checks before running network for the first time
1048  if (carlsimState_ != RUN_STATE) {
1049  // if user hasn't called setConductances, set to false and disp warning
1050  if (!hasSetConductances_) {
1051  userWarnings_.push_back("setConductances has not been called. Setting simulation mode to CUBA.");
1052  }
1053 
1054  // make sure user didn't provoque any user warnings
1055  handleUserWarnings();
1056  }
1057 
1058  carlsimState_ = RUN_STATE;
1059 
1060  return snn_->runNetwork(nSec, nMsec, printRunSummary);
1061  }
1062 
1063  // setup network with custom options
1064  void setupNetwork() {
1065  std::string funcName = "setupNetwork()";
1067  funcName, "CONFIG.");
1068 
1069  carlsimState_ = SETUP_STATE;
1070  snn_->setupNetwork();
1071  }
1072 
1073 #ifdef LN_SETUP_NETWORK_MT
1074  // setup network with custom options
1075  void setupNetworkMT() {
1076  std::string funcName = "setupNetworkMT()";
1078  funcName, "CONFIG.");
1079 
1080  carlsimState_ = SETUP_STATE;
1081  snn_->setupNetworkMT();
1082  }
1083 #endif
1084 
1085 
1086  // +++++++++ PUBLIC METHODS: LOGGING / PLOTTING +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
1087 
1088  const FILE* getLogFpInf() { return snn_->getLogFpInf(); }
1089  const FILE* getLogFpErr() { return snn_->getLogFpErr(); }
1090  const FILE* getLogFpDeb() { return snn_->getLogFpDeb(); }
1091  const FILE* getLogFpLog() { return snn_->getLogFpLog(); }
1092 
1093  void saveSimulation(const std::string& fileName, bool saveSynapseInfo) {
1094  FILE* fpSave = fopen(fileName.c_str(),"wb");
1095  std::string funcName = "saveSimulation()";
1097  UserErrors::assertTrue(carlsimState_ == SETUP_STATE || carlsimState_ == RUN_STATE,
1098  UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName, funcName, "SETUP or RUN.");
1099 
1100  snn_->saveSimulation(fpSave,saveSynapseInfo);
1101 
1102  fclose(fpSave);
1103  }
1104 
1105  void setLogFile(const std::string& fileName) {
1106  std::string funcName = "setLogFile("+fileName+")";
1107  UserErrors::assertTrue(loggerMode_!=CUSTOM,UserErrors::CANNOT_BE_SET_TO, funcName, "Logger mode", "CUSTOM");
1108 
1109  FILE* fpLog = NULL;
1110  std::string fileNameNonConst = fileName;
1111  std::transform(fileNameNonConst.begin(), fileNameNonConst.end(), fileNameNonConst.begin(), ::tolower);
1112  if (fileNameNonConst=="null") {
1113 #if defined(WIN32) || defined(WIN64)
1114  fpLog = fopen("nul","w");
1115 #else
1116  fpLog = fopen("/dev/null","w");
1117 #endif
1118  } else {
1119  fpLog = fopen(fileName.c_str(),"w");
1120  }
1121  UserErrors::assertTrue(fpLog!=NULL, UserErrors::FILE_CANNOT_OPEN, funcName, fileName);
1122 
1123  // change only CARLsim log file pointer (use NULL as code for leaving the others unchanged)
1124  snn_->setLogsFp(NULL, NULL, NULL, fpLog);
1125  }
1126 
1127  // set new file pointer for all files in CUSTOM mode
1128  void setLogsFpCustom(FILE* fpInf, FILE* fpErr, FILE* fpDeb, FILE* fpLog) {
1129  UserErrors::assertTrue(loggerMode_==CUSTOM,UserErrors::MUST_BE_SET_TO,"setLogsFpCustom","Logger mode","CUSTOM");
1130 
1131  snn_->setLogsFp(fpInf,fpErr,fpDeb,fpLog);
1132  }
1133 
1134 
1135  // +++++++++ PUBLIC METHODS: INTERACTING WITH A SIMULATION ++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
1136 
1137  // adds a constant bias to the weight of every synapse in the connection
1138  void biasWeights(short int connId, float bias, bool updateWeightRange) {
1139  std::stringstream funcName; funcName << "biasWeights(" << connId << "," << bias << "," << updateWeightRange <<
1140  ")";
1141  UserErrors::assertTrue(carlsimState_==SETUP_STATE || carlsimState_==RUN_STATE,
1142  UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName.str(), funcName.str(), "SETUP or RUN.");
1143  UserErrors::assertTrue(connId>=0 && connId<getNumConnections(), UserErrors::MUST_BE_IN_RANGE, funcName.str(),
1144  "connId", "[0,getNumConnections()]");
1145 
1146  snn_->biasWeights(connId, bias, updateWeightRange);
1147  }
1148 
1149  void startTesting(bool updateWeights) {
1150  std::string funcName = "startTesting()";
1151  UserErrors::assertTrue(carlsimState_==SETUP_STATE || carlsimState_==RUN_STATE,
1152  UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName, funcName, "SETUP or RUN.");
1153  snn_->startTesting(updateWeights);
1154  }
1155 
1156  void stopTesting() {
1157  std::string funcName = "stopTesting()";
1158  UserErrors::assertTrue(carlsimState_==SETUP_STATE || carlsimState_==RUN_STATE,
1159  UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName, funcName, "SETUP or RUN.");
1160  snn_->stopTesting();
1161  }
1162 
1163  // reads network state from file
1164  void loadSimulation(FILE* fid) {
1165  std::string funcName = "loadSimulation()";
1167  funcName, "CONFIG.");
1168 
1169  snn_->loadSimulation(fid);
1170  }
1171 
1172  // scales the weight of every synapse in the connection with a scaling factor
1173  void scaleWeights(short int connId, float scale, bool updateWeightRange) {
1174  std::stringstream funcName; funcName << "scaleWeights(" << connId << "," << scale << "," << updateWeightRange
1175  << ")";
1176  UserErrors::assertTrue(carlsimState_==SETUP_STATE || carlsimState_==RUN_STATE,
1177  UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName.str(), funcName.str(), "SETUP or RUN.");
1178  UserErrors::assertTrue(connId>=0 && connId<getNumConnections(), UserErrors::MUST_BE_IN_RANGE, funcName.str(),
1179  "connId", "[0,getNumConnections()]");
1180  UserErrors::assertTrue(scale>=0.0f, UserErrors::CANNOT_BE_NEGATIVE, funcName.str(), "Scaling factor");
1181 
1182  snn_->scaleWeights(connId, scale, updateWeightRange);
1183  }
1184 
1185  // set spike monitor for group and write spikes to file
1186  ConnectionMonitor* setConnectionMonitor(int grpIdPre, int grpIdPost, const std::string& fname) {
1187  std::string funcName = "setConnectionMonitor(\"" + getGroupName(grpIdPre) + "\",\"" + getGroupName(grpIdPost)
1188  + "\",\"" + fname + "\")";
1189  UserErrors::assertTrue(grpIdPre!=ALL, UserErrors::ALL_NOT_ALLOWED, funcName, "grpIdPre");
1190  UserErrors::assertTrue(grpIdPost!=ALL, UserErrors::ALL_NOT_ALLOWED, funcName, "grpIdPost");
1191  UserErrors::assertTrue(grpIdPre>=0, UserErrors::CANNOT_BE_NEGATIVE, funcName, "grpIdPre");
1192  UserErrors::assertTrue(grpIdPost>=0, UserErrors::CANNOT_BE_NEGATIVE, funcName, "grpIdPost");
1194  funcName, "SETUP.");
1195 
1196  FILE* fid;
1197  std::string fileName = fname;
1198  std::transform(fileName.begin(), fileName.end(), fileName.begin(), ::tolower);
1199  if (fileName == "null") {
1200  // user does not want a binary file created
1201  fid = NULL;
1202  } else {
1203  // try to open spike file
1204  if (fileName == "default") {
1205  fileName = "results/conn_" + snn_->getGroupName(grpIdPre) + "_" + snn_->getGroupName(grpIdPost) + ".dat";
1206  } else {
1207  fileName = fname;
1208  }
1209 
1210  fid = fopen(fileName.c_str(),"wb");
1211  if (fid == NULL) {
1212  // file could not be opened
1213  // default case: print error and exit
1214  std::string fileError = " Double-check file permissions and make sure directory exists.";
1215  UserErrors::assertTrue(false, UserErrors::FILE_CANNOT_OPEN, funcName, fileName, fileError);
1216  }
1217  }
1218 
1219  // return ConnectionMonitor object
1220  return snn_->setConnectionMonitor(grpIdPre, grpIdPost, fid);
1221 }
1222 
1223  void setExternalCurrent(int grpId, const std::vector<float>& current) {
1224  std::string funcName = "setExternalCurrent(\""+getGroupName(grpId)+"\")";
1225  UserErrors::assertTrue(grpId!=ALL, UserErrors::ALL_NOT_ALLOWED, funcName, "grpId");
1227  "current.size()", "number of neurons in the group.");
1229  UserErrors::assertTrue(carlsimState_==SETUP_STATE || carlsimState_==RUN_STATE,
1230  UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName, funcName, "SETUP or RUN.");
1231 
1232  snn_->setExternalCurrent(grpId, current);
1233  }
1234 
1235  void setExternalCurrent(int grpId, float current) {
1236  std::string funcName = "setExternalCurrent(\""+getGroupName(grpId)+"\")";
1237  UserErrors::assertTrue(grpId!=ALL, UserErrors::ALL_NOT_ALLOWED, funcName, "grpId");
1239  UserErrors::assertTrue(carlsimState_==SETUP_STATE || carlsimState_==RUN_STATE,
1240  UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName, funcName, "SETUP or RUN.");
1241 
1242  std::vector<float> vecCurrent(getGroupNumNeurons(grpId), current);
1243  snn_->setExternalCurrent(grpId, vecCurrent);
1244  }
1245 
1246  // set group monitor for a group
1247  GroupMonitor* setGroupMonitor(int grpId, const std::string& fname, const int mode) {
1248  std::string funcName = "setGroupMonitor(\""+getGroupName(grpId)+"\",\""+fname+"\")";
1249  UserErrors::assertTrue(grpId!=ALL, UserErrors::ALL_NOT_ALLOWED, funcName, "grpId"); // grpId can't be ALL
1250  UserErrors::assertTrue(grpId>=0, UserErrors::CANNOT_BE_NEGATIVE, funcName, "grpId"); // grpId can't be negative
1251  UserErrors::assertTrue(carlsimState_==CONFIG_STATE || carlsimState_==SETUP_STATE,
1252  UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName, funcName, "CONFIG or SETUP.");
1253 
1254  FILE* fid;
1255  std::string fileName = fname;
1256  std::transform(fileName.begin(), fileName.end(), fileName.begin(), ::tolower);
1257  if (fileName == "null") {
1258  // user does not want a binary file created
1259  fid = NULL;
1260  } else {
1261  // try to open spike file
1262  if (fileName == "default") {
1263  fileName = "results/grp_" + snn_->getGroupName(grpId) + ".dat";
1264  } else {
1265  fileName = fname;
1266  }
1267 
1268  fid = fopen(fileName.c_str(),"wb");
1269  if (fid == NULL) {
1270  // file could not be opened
1271  // default case: print error and exit
1272  std::string fileError = " Double-check file permissions and make sure directory exists.";
1273  UserErrors::assertTrue(false, UserErrors::FILE_CANNOT_OPEN, funcName, fileName, fileError);
1274  }
1275  }
1276 
1277  // return GroupMonitor object
1278  return snn_->setGroupMonitor(grpId, fid, mode);
1279  }
1280 
1281  // sets up a spike generator
1282  void setSpikeGenerator(int grpId, SpikeGenerator* spikeGenFunc) {
1283  std::string funcName = "setSpikeGenerator(\""+getGroupName(grpId)+"\")";
1284  UserErrors::assertTrue(grpId!=ALL, UserErrors::ALL_NOT_ALLOWED, funcName, "grpId"); // groupId can't be ALL
1286  UserErrors::assertTrue(spikeGenFunc!=NULL, UserErrors::CANNOT_BE_NULL, funcName);
1288  funcName, "CONFIG.");
1289 
1290  // SpikeGeneratorCore* SGC = new SpikeGeneratorCore(this, spikeGenFunc);
1291  SpikeGeneratorCore* SGC = new SpikeGeneratorCore(sim_, spikeGenFunc);
1292  spkGen_.push_back(SGC);
1293  snn_->setSpikeGenerator(grpId, SGC);
1294  }
1295 
1296  // set spike monitor for group and write spikes to file
1297  SpikeMonitor* setSpikeMonitor(int grpId, const std::string& fileName) {
1298  std::string funcName = "setSpikeMonitor(\""+getGroupName(grpId)+"\",\""+fileName+"\")";
1299  UserErrors::assertTrue(grpId!=ALL, UserErrors::ALL_NOT_ALLOWED, funcName, "grpId"); // grpId can't be ALL
1300  UserErrors::assertTrue(grpId>=0, UserErrors::CANNOT_BE_NEGATIVE, funcName, "grpId"); // grpId can't be negative
1301  UserErrors::assertTrue(carlsimState_==CONFIG_STATE || carlsimState_==SETUP_STATE,
1302  UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName, funcName, "CONFIG or SETUP.");
1303 
1304  FILE* fid;
1305  std::string fileNameLower = fileName;
1306  std::transform(fileNameLower.begin(), fileNameLower.end(), fileNameLower.begin(), ::tolower);
1307  if (fileNameLower == "null") {
1308  // user does not want a binary file created
1309  fid = NULL;
1310  } else {
1311  // try to open spike file
1312  if (fileNameLower == "default") {
1313  std::string fileNameDefault = "results/spk_" + snn_->getGroupName(grpId) + ".dat";
1314  fid = fopen(fileNameDefault.c_str(),"wb");
1315  if (fid==NULL) {
1316  std::string fileError = " Make sure results/ exists.";
1317  UserErrors::assertTrue(false, UserErrors::FILE_CANNOT_OPEN, funcName, fileNameDefault, fileError);
1318  }
1319  } else {
1320  fid = fopen(fileName.c_str(),"wb");
1321  if (fid==NULL) {
1322  std::string fileError = " Double-check file permissions and make sure directory exists.";
1323  UserErrors::assertTrue(false, UserErrors::FILE_CANNOT_OPEN, funcName, fileName, fileError);
1324  }
1325  }
1326  }
1327 
1328  // return SpikeMonitor object
1329  return snn_->setSpikeMonitor(grpId, fid);
1330  }
1331 
1332  // set neuron monitor for group and write neuron state values (voltage, recovery, and total current values) to file
1333  NeuronMonitor* setNeuronMonitor(int grpId, const std::string& fileName) {
1334  std::string funcName = "setNeuronMonitor(\"" + getGroupName(grpId) + "\",\"" + fileName + "\")";
1335  UserErrors::assertTrue(grpId != ALL, UserErrors::ALL_NOT_ALLOWED, funcName, "grpId"); // grpId can't be ALL
1336  UserErrors::assertTrue(grpId >= 0, UserErrors::CANNOT_BE_NEGATIVE, funcName, "grpId"); // grpId can't be negative
1337  UserErrors::assertTrue(carlsimState_ == CONFIG_STATE,
1338  UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName, funcName, "CONFIG.");
1339 
1340  FILE* fid;
1341  std::string fileNameLower = fileName;
1342  std::transform(fileNameLower.begin(), fileNameLower.end(), fileNameLower.begin(), ::tolower);
1343  if (fileNameLower == "null") {
1344  // user does not want a binary file created
1345  fid = NULL;
1346  }
1347  else {
1348  // try to open spike file
1349  if (fileNameLower == "default") {
1350  std::string fileNameDefault = "results/n_" + snn_->getGroupName(grpId) + ".dat";
1351  fid = fopen(fileNameDefault.c_str(), "wb");
1352  if (fid == NULL) {
1353  std::string fileError = " Make sure results/ exists.";
1354  UserErrors::assertTrue(false, UserErrors::FILE_CANNOT_OPEN, funcName, fileNameDefault, fileError);
1355  }
1356  }
1357  else {
1358  fid = fopen(fileName.c_str(), "wb");
1359  if (fid == NULL) {
1360  std::string fileError = " Double-check file permissions and make sure directory exists.";
1361  UserErrors::assertTrue(false, UserErrors::FILE_CANNOT_OPEN, funcName, fileName, fileError);
1362  }
1363  }
1364  }
1365 
1366  // return NeuronMonitor object
1367  return snn_->setNeuronMonitor(grpId, fid);
1368  }
1369 
1370  // assign spike rate to poisson group
1371  void setSpikeRate(int grpId, PoissonRate* spikeRate, int refPeriod) {
1372  std::string funcName = "setSpikeRate()";
1373  UserErrors::assertTrue(carlsimState_==SETUP_STATE || carlsimState_==RUN_STATE,
1374  UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName, funcName, "SETUP or RUN.");
1377  funcName, "PoissonRate length and the number of neurons in the group");
1378  // FIXME: make sure spikeRate->isOnGPU() consistent with simulation mode
1379  //UserErrors::assertTrue(!spikeRate->isOnGPU() || spikeRate->isOnGPU()&&getSimMode()==GPU_MODE,
1380  // UserErrors::CAN_ONLY_BE_CALLED_IN_MODE, funcName, "PoissonRate on GPU", "GPU_MODE.");
1381 
1382  snn_->setSpikeRate(grpId, spikeRate, refPeriod);
1383  }
1384 
1385  void setWeight(short int connId, int neurIdPre, int neurIdPost, float weight, bool updateWeightRange) {
1386  std::stringstream funcName; funcName << "setWeight(" << connId << "," << neurIdPre << "," << neurIdPost << ","
1387  << updateWeightRange << ")";
1388  UserErrors::assertTrue(carlsimState_==SETUP_STATE || carlsimState_==RUN_STATE,
1389  UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName.str(), funcName.str(), "SETUP or RUN.");
1391  funcName.str(), "connectionId", "[0,getNumConnections()]");
1392  UserErrors::assertTrue(weight>=0.0f, UserErrors::CANNOT_BE_NEGATIVE, funcName.str(), "Weight value");
1393 
1394  snn_->setWeight(connId, neurIdPre, neurIdPost, weight, updateWeightRange);
1395  }
1396 
1397 
1398  // +++++++++ PUBLIC METHODS: SETTERS / GETTERS ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
1399 
1400  CARLsimState getCARLsimState() { return carlsimState_; }
1401 
1402 #ifdef LN_GET_FIRING
1403  // write store instead of get
1404  void getFiring(std::vector<bool>& firings, int netId) {
1405  snn_->updateCurSpike(firings, netId);
1406  }
1407 #endif
1408 
1409 #ifdef LN_GET_FIRING_MT
1410  // write store instead of get
1411  void getFiringMT(std::vector<bool>& firings, int netId) {
1412  snn_->updateCurSpikeMT(firings, netId);
1413  }
1414 #endif
1415 
1416 
1417 #ifdef LN_AXON_PLAST
1418  void findWavefrontPath(std::vector<int>& path, std::vector<float>& eligibility, int netId, int grpId, int startNId, int goalNId) {
1419  snn_->findWavefrontPath(path, eligibility, netId, grpId, startNId, goalNId);
1420  }
1421 
1422  bool updateDelays(int gGrpIdPre, int gGrpIdPost, std::vector<std::tuple<int, int, uint8_t>> connDelays) {
1423  return snn_->updateDelays(gGrpIdPre, gGrpIdPost, connDelays);
1424  }
1425 
1426  void printEntrails(char* buffer, unsigned length, int gGrpIdPre, int gGrpIdPost) {
1427  return snn_->printEntrails(buffer, length,gGrpIdPre, gGrpIdPost);
1428  }
1429 #endif
1430 
1431 
1432  std::vector<float> getConductanceAMPA(int grpId) {
1433  std::string funcName = "getConductanceAMPA()";
1435  funcName, funcName, "RUN.");
1436  UserErrors::assertTrue(grpId!=ALL, UserErrors::ALL_NOT_ALLOWED, funcName, "grpId");
1437  UserErrors::assertTrue(grpId>=0 && grpId<getNumGroups(), UserErrors::MUST_BE_IN_RANGE, funcName, "grpId",
1438  "[0,getNumGroups()]");
1439 
1440  return snn_->getConductanceAMPA(grpId);
1441  }
1442 
1443  std::vector<float> getConductanceNMDA(int grpId) {
1444  std::string funcName = "getConductanceNMDA()";
1446  funcName, funcName, "RUN.");
1447  UserErrors::assertTrue(grpId!=ALL, UserErrors::ALL_NOT_ALLOWED, funcName, "grpId");
1448  UserErrors::assertTrue(grpId>=0 && grpId<getNumGroups(), UserErrors::MUST_BE_IN_RANGE, funcName, "grpId",
1449  "[0,getNumGroups()]");
1450 
1451  return snn_->getConductanceNMDA(grpId);
1452  }
1453 
1454  std::vector<float> getConductanceGABAa(int grpId) {
1455  std::string funcName = "getConductanceGABAa()";
1457  funcName, funcName, "RUN.");
1458  UserErrors::assertTrue(grpId!=ALL, UserErrors::ALL_NOT_ALLOWED, funcName, "grpId");
1459  UserErrors::assertTrue(grpId>=0 && grpId<getNumGroups(), UserErrors::MUST_BE_IN_RANGE, funcName, "grpId",
1460  "[0,getNumGroups()]");
1461 
1462  return snn_->getConductanceGABAa(grpId);
1463  }
1464 
1465  std::vector<float> getConductanceGABAb(int grpId) {
1466  std::string funcName = "getConductanceGABAb()";
1468  funcName, funcName, "RUN.");
1469  UserErrors::assertTrue(grpId!=ALL, UserErrors::ALL_NOT_ALLOWED, funcName, "grpId");
1470  UserErrors::assertTrue(grpId>=0 && grpId<getNumGroups(), UserErrors::MUST_BE_IN_RANGE, funcName, "grpId",
1471  "[0,getNumGroups()]");
1472 
1473  return snn_->getConductanceGABAb(grpId);
1474  }
1475 
1476  RangeDelay getDelayRange(short int connId) {
1477  std::stringstream funcName; funcName << "getDelayRange(" << connId << ")";
1478  UserErrors::assertTrue(connId>=0 && connId<getNumConnections(), UserErrors::MUST_BE_IN_RANGE, funcName.str(),
1479  "connId", "[0,getNumConnections()]");
1480 
1481  return snn_->getDelayRange(connId);
1482  }
1483 
1484  // \TODO bad API design (return allocated memory space)
1485  uint8_t* getDelays(int gIDpre, int gIDpost, int& Npre, int& Npost) {
1486  std::string funcName = "getDelays()";
1487  UserErrors::assertTrue(carlsimState_ == SETUP_STATE || carlsimState_ == RUN_STATE,
1488  UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName, funcName, "SETUP or RUN.");
1489  UserErrors::assertTrue(gIDpre>=0 && gIDpre<getNumGroups(), UserErrors::MUST_BE_IN_RANGE, funcName, "gIDpre",
1490  "[0,getNumGroups()]");
1491  UserErrors::assertTrue(gIDpost>=0 && gIDpost<getNumGroups(), UserErrors::MUST_BE_IN_RANGE, funcName, "gIDpre",
1492  "[0,getNumGroups()]");
1493 
1494  return snn_->getDelays(gIDpre,gIDpost,Npre,Npost);
1495  }
1496 
1497  Grid3D getGroupGrid3D(int grpId) {
1498  std::stringstream funcName; funcName << "getGroupGrid3D(" << grpId << ")";
1499  UserErrors::assertTrue(grpId!=ALL, UserErrors::ALL_NOT_ALLOWED, funcName.str(), "grpId");
1500  UserErrors::assertTrue(grpId>=0 && grpId<getNumGroups(), UserErrors::MUST_BE_IN_RANGE, funcName.str(),
1501  "grpId", "[0,getNumGroups()]");
1502 
1503  return snn_->getGroupGrid3D(grpId);
1504  }
1505 
1506  int getGroupId(std::string grpName) {
1507  return snn_->getGroupId(grpName);
1508  }
1509 
1510  std::string getGroupName(int grpId) {
1511  std::stringstream funcName; funcName << "getGroupName(" << grpId << ")";
1512  UserErrors::assertTrue(grpId==ALL || grpId>=0 && grpId<getNumGroups(), UserErrors::MUST_BE_IN_RANGE, funcName.str(),
1513  "grpId", "[0,getNumGroups()] or must be ALL.");
1514 
1515  return snn_->getGroupName(grpId);
1516  }
1517 
1518  int getGroupStartNeuronId(int grpId) {
1519  std::stringstream funcName; funcName << "getGroupStartNeuronId(" << grpId << ")";
1520  UserErrors::assertTrue(carlsimState_ == SETUP_STATE || carlsimState_ == RUN_STATE,
1521  UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName.str(), funcName.str(), "SETUP or RUN.");
1522  UserErrors::assertTrue(grpId>=0 && grpId<getNumGroups(), UserErrors::MUST_BE_IN_RANGE, funcName.str(), "grpId",
1523  "[0,getNumGroups()]");
1524 
1525  return snn_->getGroupStartNeuronId(grpId);
1526  }
1527 
1528  int getGroupEndNeuronId(int grpId) {
1529  std::stringstream funcName; funcName << "getGroupEndNeuronId(" << grpId << ")";
1530  UserErrors::assertTrue(carlsimState_ == SETUP_STATE || carlsimState_ == RUN_STATE,
1531  UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName.str(), funcName.str(), "SETUP or RUN.");
1532  UserErrors::assertTrue(grpId>=0 && grpId<getNumGroups(), UserErrors::MUST_BE_IN_RANGE, funcName.str(), "grpId",
1533  "[0,getNumGroups()]");
1534 
1535  return snn_->getGroupEndNeuronId(grpId);
1536  }
1537 
1538  int getGroupNumNeurons(int grpId) {
1539  std::stringstream funcName; funcName << "getGroupNumNeurons(" << grpId << ")";
1540  UserErrors::assertTrue(grpId>=0 && grpId<getNumGroups(), UserErrors::MUST_BE_IN_RANGE, funcName.str(), "grpId",
1541  "[0,getNumGroups()]");
1542 
1543  return snn_->getGroupNumNeurons(grpId);
1544  }
1545 
1547  std::stringstream funcName; funcName << "getNeuronLocation3D(" << neurId << ")";
1548  UserErrors::assertTrue(carlsimState_ == SETUP_STATE || carlsimState_ == RUN_STATE,
1549  UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName.str(), funcName.str(), "SETUP or RUN.");
1550  UserErrors::assertTrue(neurId!=ALL, UserErrors::ALL_NOT_ALLOWED, funcName.str(), "neurId");
1551  UserErrors::assertTrue(neurId>=0 && neurId<getNumNeurons(), UserErrors::MUST_BE_IN_RANGE, funcName.str(),
1552  "neurId", "[0,getNumNeurons()]");
1553 
1554  return snn_->getNeuronLocation3D(neurId);
1555  }
1556 
1557  Point3D getNeuronLocation3D(int grpId, int relNeurId) {
1558  std::stringstream funcName; funcName << "getNeuronLocation3D(" << grpId << "," << relNeurId << ")";
1559  UserErrors::assertTrue(relNeurId!=ALL, UserErrors::ALL_NOT_ALLOWED, funcName.str(), "neurId");
1560  UserErrors::assertTrue(grpId>=0 && grpId<getNumGroups(), UserErrors::MUST_BE_IN_RANGE, funcName.str(),
1561  "grpId", "[0,getNumGroups()]");
1563  funcName.str(), "relNeurId", "[0,getGroupNumNeurons()]");
1564 
1565  return snn_->getNeuronLocation3D(grpId, relNeurId);
1566  }
1567 
1568 
1569 
1570  int getNeuronId (int grpId, Point3D location) {
1571  std::stringstream funcName; funcName << "getNeuronId(" << grpId << "," << location << ")";
1572  // UserErrors::assertTrue(relNeurId != ALL, UserErrors::ALL_NOT_ALLOWED, funcName.str(), "neurId");
1573  UserErrors::assertTrue(grpId >= 0 && grpId<getNumGroups(), UserErrors::MUST_BE_IN_RANGE, funcName.str(),
1574  "grpId", "[0,getNumGroups()]");
1575  // UserErrors::assertTrue(relNeurId >= 0 && relNeurId<getGroupNumNeurons(grpId), UserErrors::MUST_BE_IN_RANGE,
1576  // funcName.str(), "relNeurId", "[0,getGroupNumNeurons()]");
1577 
1578  //TODO LN validate what to do if outsite the grid
1579 
1580  return snn_->getNeuronId(grpId, location);
1581  }
1582 
1583 
1584  int getNumConnections() { return snn_->getNumConnections(); }
1586 
1587  int getNumGroups() { return snn_->getNumGroups(); }
1588  int getNumNeurons() { return snn_->getNumNeurons(); }
1589  int getNumNeuronsReg() { return snn_->getNumNeuronsReg(); }
1590  int getNumNeuronsRegExc() { return snn_->getNumNeuronsRegExc(); }
1591  int getNumNeuronsRegInh() { return snn_->getNumNeuronsRegInh(); }
1592  int getNumNeuronsGen() { return snn_->getNumNeuronsGen(); }
1593  int getNumNeuronsGenExc() { return snn_->getNumNeuronsGenExc(); }
1594  int getNumNeuronsGenInh() { return snn_->getNumNeuronsGenInh(); }
1595 
1596  int getNumSynapticConnections(short int connectionId) {
1597  std::stringstream funcName; funcName << "getNumConnections(" << connectionId << ")";
1598  UserErrors::assertTrue(carlsimState_ == SETUP_STATE || carlsimState_ == RUN_STATE,
1599  UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName.str(), funcName.str(), "SETUP or RUN.");
1600  UserErrors::assertTrue(connectionId!=ALL, UserErrors::ALL_NOT_ALLOWED, funcName.str(), "connectionId");
1601  UserErrors::assertTrue(connectionId>=0 && connectionId<getNumConnections(), UserErrors::MUST_BE_IN_RANGE,
1602  funcName.str(), "connectionId", "[0,getNumSynapticConnections()]");
1603  return snn_->getNumSynapticConnections(connectionId);
1604  }
1605 
1607  std::string funcName = "getNumSynapses()";
1608  UserErrors::assertTrue(carlsimState_ == SETUP_STATE || carlsimState_ == RUN_STATE,
1609  UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName, funcName, "SETUP or RUN.");
1610 
1611  return snn_->getNumSynapses();
1612  }
1613 
1615  std::stringstream funcName; funcName << "getConnSTDPInfo(" << connId << ")";
1616  UserErrors::assertTrue(connId >= 0 && connId<getNumConnections(), UserErrors::MUST_BE_IN_RANGE, funcName.str(),
1617  "connId", "[0,getNumConnections]");
1618 
1619  return snn_->getConnSTDPInfo(connId);
1620  }
1621 
1623  std::stringstream funcName; funcName << "getGroupNeuromodulatorInfo(" << grpId << ")";
1624  UserErrors::assertTrue(grpId >= 0 && grpId<getNumGroups(), UserErrors::MUST_BE_IN_RANGE, funcName.str(),
1625  "grpId", "[0,getNumGroups()]");
1626  return snn_->getGroupNeuromodulatorInfo(grpId);
1627  }
1628 
1629  int getSimTime() { return snn_->getSimTime(); }
1630  int getSimTimeSec() { return snn_->getSimTimeSec(); }
1631  int getSimTimeMsec() { return snn_->getSimTimeMs(); }
1632 
1633  // returns pointer to existing SpikeMonitor object, NULL else
1635  std::stringstream funcName; funcName << "getSpikeMonitor(" << grpId << ")";
1636  UserErrors::assertTrue(grpId>=0 && grpId<getNumGroups(), UserErrors::MUST_BE_IN_RANGE, funcName.str(),
1637  "grpId", "[0,getNumGroups()]");
1638 
1639  return snn_->getSpikeMonitor(grpId);
1640  }
1641 
1642  RangeWeight getWeightRange(short int connId) {
1643  std::stringstream funcName; funcName << "getWeightRange(" << connId << ")";
1644  UserErrors::assertTrue(connId>=0 && connId<getNumConnections(), UserErrors::MUST_BE_IN_RANGE, funcName.str(),
1645  "connId", "[0,getNumConnections()]");
1646 
1647  return snn_->getWeightRange(connId);
1648  }
1649 
1650  bool isConnectionPlastic(short int connId) {
1651  std::stringstream funcName; funcName << "isConnectionPlastic(" << connId << ")";
1652  UserErrors::assertTrue(connId>=0 && connId<getNumConnections(), UserErrors::MUST_BE_IN_RANGE, funcName.str(),
1653  "connId", "[0,getNumConnections()]");
1654 
1655  return snn_->isConnectionPlastic(connId);
1656  }
1657 
1658  bool isGroupWithHomeostasis(int grpId) {
1659  std::stringstream funcName; funcName << "isGroupWithHomeostasis(" << grpId << ")";
1660  UserErrors::assertTrue(grpId>=0 && grpId<getNumGroups(), UserErrors::MUST_BE_IN_RANGE, funcName.str(),
1661  "connId", "[0,getNumGroups()]");
1662 
1663  return snn_->isGroupWithHomeostasis(grpId);
1664  }
1665 
1667  std::stringstream funcName; funcName << "isSimulationWithCOBA()";
1668 
1669  return snn_->isSimulationWithCOBA();
1670  }
1671 
1673  std::stringstream funcName; funcName << "isSimulationWithCUBA()";
1674 
1675  return snn_->isSimulationWithCUBA();
1676  }
1677 
1678 #ifdef LN_I_CALC_TYPES
1679 
1680  bool isGroupWith(int grpId, IcalcType icalcType) {
1681  std::stringstream funcName; funcName << "isGroupWith(" << grpId << "," << icalcType << ")"; // \todo name vs desc ?
1682 
1683  return snn_->isGroupWith(grpId, icalcType);
1684  }
1685 
1686  const IcalcType getIcalcType(int grpId) {
1687  std::stringstream funcName; funcName << "getIcalcType(" << grpId << ")"; // \todo name vs desc ?
1688 
1689  return snn_->getIcalcType(grpId);
1690  }
1691 
1692 
1693  bool getConductanceConfig(int grpId, float& dAMPA, float& rNMDA, float& dNMDA, float& dGABAa, float& rGABAb, float& dGABAb) {
1694  std::stringstream funcName; funcName << "getConductanceConfig(" << grpId << ")";
1695 
1696  if(snn_->isGroupWithCOBA(grpId)) {
1697  snn_->getConductanceConfig(grpId, dAMPA, rNMDA, dNMDA, dGABAa, rGABAb, dGABAb);
1698  return true;
1699  } else
1700  return false;
1701  }
1702 
1703  bool getConductanceConfig(int grpId, int& tdAMPA, int& trNMDA, int& tdNMDA, int& tdGABAa, int& trGABAb, int& tdGABAb) {
1704  std::stringstream funcName; funcName << "getConductanceConfig(" << grpId << ")";
1705 
1706  if (snn_->isGroupWithCOBA(grpId)) {
1707  snn_->getConductanceConfig(grpId, tdAMPA, trNMDA, tdNMDA, tdGABAa, trGABAb, tdGABAb);
1708  return true;
1709  }
1710  else
1711  return false;
1712  }
1713 
1714 
1715  bool isGroupWithCOBA(int grpId) {
1716  std::stringstream funcName; funcName << "isGroupWithCOBA(" << grpId << ")";
1717 
1718  return snn_->isGroupWithCOBA(grpId);
1719  }
1720 
1721  bool isGroupWithCUBA(int grpId) {
1722  std::stringstream funcName; funcName << "isGroupWithCUBA(" << grpId << ")";
1723 
1724  return snn_->isGroupWithCUBA(grpId);
1725  }
1726 
1727 #endif
1728 
1729 
1730  bool isExcitatoryGroup(int grpId) {
1731  std::stringstream funcName; funcName << "isExcitatoryGroup(" << grpId << ")";
1732  UserErrors::assertTrue(grpId>=0 && grpId<getNumGroups(), UserErrors::MUST_BE_IN_RANGE, funcName.str(),
1733  "connId", "[0,getNumGroups()]");
1734 
1735  return snn_->isExcitatoryGroup(grpId);
1736  }
1737 
1738  bool isInhibitoryGroup(int grpId) {
1739  std::stringstream funcName; funcName << "isInhibitoryGroup(" << grpId << ")";
1740  UserErrors::assertTrue(grpId>=0 && grpId<getNumGroups(), UserErrors::MUST_BE_IN_RANGE, funcName.str(),
1741  "connId", "[0,getNumGroups()]");
1742 
1743  return snn_->isInhibitoryGroup(grpId);
1744  }
1745 
1746  bool isPoissonGroup(int grpId) {
1747  std::stringstream funcName; funcName << "isPoissonGroup(" << grpId << ")";
1748  UserErrors::assertTrue(grpId>=0 && grpId<getNumGroups(), UserErrors::MUST_BE_IN_RANGE, funcName.str(),
1749  "connId", "[0,getNumGroups()]");
1750 
1751  return snn_->isPoissonGroup(grpId);
1752  }
1753 
1754 
1755  // +++++++++ PUBLIC METHODS: SET DEFAULTS +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
1756 
1757  // set default values for conductance decay times
1758  void setDefaultConductanceTimeConstants(int tdAMPA, int trNMDA, int tdNMDA, int tdGABAa, int trGABAb,
1759  int tdGABAb)
1760  {
1761  std::stringstream funcName; funcName << "setDefaultConductanceTimeConstants(" << tdAMPA << "," << trNMDA <<
1762  "," << tdNMDA << "," << tdGABAa << "," << trGABAb << "," << tdGABAb << ")";
1763  UserErrors::assertTrue(tdAMPA>0, UserErrors::MUST_BE_POSITIVE, funcName.str(), "tdAMPA");
1764  UserErrors::assertTrue(trNMDA>=0, UserErrors::CANNOT_BE_NEGATIVE, funcName.str(), "trNMDA");
1765  UserErrors::assertTrue(tdNMDA>0, UserErrors::MUST_BE_POSITIVE, funcName.str(), "tdNMDA");
1766  UserErrors::assertTrue(tdGABAa>0, UserErrors::MUST_BE_POSITIVE, funcName.str(), "tdGABAa");
1767  UserErrors::assertTrue(trGABAb>=0, UserErrors::CANNOT_BE_NEGATIVE, funcName.str(), "trGABAb");
1768  UserErrors::assertTrue(tdGABAb>0, UserErrors::MUST_BE_POSITIVE, funcName.str(), "tdGABAb");
1769  UserErrors::assertTrue(trNMDA!=tdNMDA, UserErrors::CANNOT_BE_IDENTICAL, funcName.str(), "trNMDA and tdNMDA");
1770  UserErrors::assertTrue(trGABAb!=tdGABAb, UserErrors::CANNOT_BE_IDENTICAL, funcName.str(),
1771  "trGABAb and tdGABAb");
1773  "CONFIG.");
1774 
1775  def_tdAMPA_ = tdAMPA;
1776  def_trNMDA_ = trNMDA;
1777  def_tdNMDA_ = tdNMDA;
1778  def_tdGABAa_ = tdGABAa;
1779  def_trGABAb_ = trGABAb;
1780  def_tdGABAb_ = tdGABAb;
1781  }
1782 
1783  void setDefaultHomeostasisParams(float homeoScale, float avgTimeScale) {
1784  std::string funcName = "setDefaultHomeostasisparams()";
1786  funcName, "CONFIG.");
1787  assert(avgTimeScale>0); // TODO make nice
1788 
1789  def_homeo_scale_ = homeoScale;
1790  def_homeo_avgTimeScale_ = avgTimeScale;
1791  }
1792 
1793  void setDefaultSaveOptions(std::string fileName, bool saveSynapseInfo) {
1794  std::string funcName = "setDefaultSaveOptions()";
1796  funcName, "CONFIG.");
1797 
1798  def_save_fileName_ = fileName;
1799  def_save_synapseInfo_ = saveSynapseInfo;
1800 
1801  // try to open save file to make sure we have permission (so the user immediately knows about the error and
1802  // doesn't have to wait until their simulation run has ended)
1803  FILE* fpTry = fopen(def_save_fileName_.c_str(),"wb");
1804  UserErrors::assertTrue(fpTry!=NULL,UserErrors::FILE_CANNOT_OPEN,"Default save file",def_save_fileName_);
1805  fclose(fpTry);
1806  }
1807 
1808  // wrapper function, set default values for E-STDP params
1809  void setDefaultSTDPparams(float alphaPlus, float tauPlus, float alphaMinus, float tauMinus, STDPType stdpType) {
1810  setDefaultESTDPparams(alphaPlus, tauPlus, alphaMinus, tauMinus, stdpType);
1811  }
1812 
1813  // set default values for E-STDP params
1814  void setDefaultESTDPparams(float alphaPlus, float tauPlus, float alphaMinus, float tauMinus, STDPType stdpType) {
1815  std::string funcName = "setDefaultESTDPparams()";
1816  UserErrors::assertTrue(carlsimState_==CONFIG_STATE, UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName, funcName, "CONFIG.");
1817  UserErrors::assertTrue(tauPlus > 0, UserErrors::MUST_BE_POSITIVE, funcName, "tauPlus");
1818  UserErrors::assertTrue(tauMinus > 0, UserErrors::MUST_BE_POSITIVE, funcName, "tauMinus");
1819  switch(stdpType) {
1820  case STANDARD:
1821  def_STDP_type_ = STANDARD;
1822  break;
1823  case DA_MOD:
1824  case SE_MOD:
1825  case AC_MOD:
1826  case NE_MOD:
1827  //def_STDP_type_ = DA_MOD;
1828  def_STDP_type_ = stdpType;
1829  break;
1830  default:
1831  stdpType=UNKNOWN_STDP;
1833  break;
1834  }
1835  def_STDP_alphaLTP_ = alphaPlus;
1836  def_STDP_tauLTP_ = tauPlus;
1837  def_STDP_alphaLTD_ = alphaMinus;
1838  def_STDP_tauLTD_ = tauMinus;
1839  }
1840 
1841  // set default values for I-STDP params
1842  void setDefaultISTDPparams(float betaLTP, float betaLTD, float lambda, float delta, STDPType stdpType) {
1843  std::string funcName = "setDefaultISTDPparams()";
1844  UserErrors::assertTrue(carlsimState_==CONFIG_STATE, UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName, funcName, "CONFIG.");
1845  UserErrors::assertTrue(betaLTP > 0, UserErrors::MUST_BE_POSITIVE, funcName);
1846  UserErrors::assertTrue(betaLTD > 0, UserErrors::MUST_BE_POSITIVE, funcName);
1849  switch(stdpType) {
1850  case STANDARD:
1851  def_STDP_type_ = STANDARD;
1852  break;
1853  case DA_MOD:
1854  //def_STDP_type_ = DA_MOD;
1855  def_STDP_type_ = stdpType;
1856  break;
1857  default:
1858  stdpType=UNKNOWN_STDP;
1860  break;
1861  }
1862  def_STDP_betaLTP_ = betaLTP;
1863  def_STDP_betaLTD_ = betaLTD;
1864  def_STDP_lambda_ = lambda;
1865  def_STDP_delta_ = delta;
1866  }
1867 
1868  // set default STP values for an EXCITATORY_NEURON or INHIBITORY_NEURON
1869  void setDefaultSTPparams(int neurType, float STP_U, float STP_tau_u, float STP_tau_x) {
1870  std::string funcName = "setDefaultSTPparams()";
1872  funcName);
1873  UserErrors::assertTrue(carlsimState_==CONFIG_STATE, UserErrors::CAN_ONLY_BE_CALLED_IN_STATE, funcName, funcName, "CONFIG.");
1874 
1875  assert(STP_tau_u>0.0f);
1876  assert(STP_tau_x>0.0f);
1877 
1878  switch (neurType) {
1879  case EXCITATORY_NEURON:
1880  def_STP_U_exc_ = STP_U;
1881  def_STP_tau_u_exc_ = STP_tau_u;
1882  def_STP_tau_x_exc_ = STP_tau_x;
1883  break;
1884  case INHIBITORY_NEURON:
1885  def_STP_U_inh_ = STP_U;
1886  def_STP_tau_u_inh_ = STP_tau_u;
1887  def_STP_tau_x_inh_ = STP_tau_x;
1888  break;
1889  default:
1890  // some error message instead of assert
1892  break;
1893  }
1894  }
1895 
1896 
1897 private:
1898  // +++++ PRIVATE METHODS ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
1899 
1900  // unsafe computations that would otherwise go in constructor
1901  void CARLsimInit() {
1902  bool gpuAllocationResult = false;
1903  std::string funcName = "CARLsimInit()";
1904 
1905  UserErrors::assertTrue(loggerMode_!=UNKNOWN_LOGGER,UserErrors::CANNOT_BE_UNKNOWN,"CARLsim()","Logger mode");
1906 
1907  // init SNN object
1908  snn_ = new SNN(netName_, preferredSimMode_, loggerMode_, randSeed_);
1909 
1910  // set default time constants for synaptic current decay
1911  // TODO: add ref
1912  setDefaultConductanceTimeConstants(5, 0, 150, 6, 0, 150);
1913 
1914  // set default values for STDP params
1915  // \deprecated
1916  // \TODO: replace with STDP structs
1917  setDefaultESTDPparams(0.001f, 20.0f, -0.0012f, 20.0f, STANDARD);
1918  setDefaultISTDPparams(0.001f, 0.0012f, 12.0f, 40.0f, STANDARD);
1919 
1920  // set default values for STP params
1921  // Misha Tsodyks and Si Wu (2013) Short-term synaptic plasticity. Scholarpedia, 8(10):3153., revision #136920
1922  setDefaultSTPparams(EXCITATORY_NEURON, 0.45f, 50.0f, 750.0f);
1923  setDefaultSTPparams(INHIBITORY_NEURON, 0.15f, 750.0f, 50.0f);
1924 
1925  // set default homeostasis params
1926  // Ref: Carlson, et al. (2013). Proc. of IJCNN 2013.
1927  setDefaultHomeostasisParams(0.1f, 10.0f);
1928 
1929  // set default save sim params
1930  // TODO: when we run executable from local dir, put save file in results/
1931  setDefaultSaveOptions("results/sim_"+netName_+".dat",false);
1932 
1933  connSyn_.clear();
1934  connComp_.clear();
1935  }
1936 
1937 
1938  // check whether grpId exists in grpIds_
1939  bool existsGrpId(int grpId) {
1940  return std::find(grpIds_.begin(), grpIds_.end(), grpId)!=grpIds_.end();
1941  }
1942 
1943  // print all user warnings, continue only after user input
1944  void handleUserWarnings() {
1945  if (userWarnings_.size()) {
1946  for (int i=0; i<userWarnings_.size(); i++) {
1947  CARLSIM_WARN("runNetwork()",userWarnings_[i].c_str());
1948  }
1949 
1950  fprintf(stdout,"Ignore warnings and continue? Y/n ");
1951  char ignoreWarn = std::cin.get();
1952  if (std::cin.fail() || ignoreWarn!='y' && ignoreWarn!='Y') {
1953  fprintf(stdout,"Exiting...\n");
1954  exit(1);
1955  }
1956  }
1957  }
1958 
1959 
1960  // +++++ PRIVATE STATIC PROPERTIES ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
1961 
1962  static bool gpuAllocation[MAX_NUM_CUDA_DEVICES];
1963  static std::string gpuOccupiedBy[MAX_NUM_CUDA_DEVICES];
1964 #if defined(WIN32) || defined(WIN64)
1965  static HANDLE gpuAllocationLock;
1966 #else
1967  static pthread_mutex_t gpuAllocationLock;
1968 #endif
1969 
1970 
1971  // +++++ PRIVATE PROPERTIES +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
1972 
1973  CARLsim* sim_;
1974  SNN* snn_;
1975  std::string netName_;
1976  int randSeed_;
1977  LoggerMode loggerMode_;
1978  SimMode preferredSimMode_;
1979  bool enablePrint_;
1980  bool copyState_;
1981 
1983  std::vector<std::vector<int> > connSyn_;
1986  std::vector<std::vector<int> > connComp_;
1987 
1988  std::map<int, int> groupPrefNetIds_;
1989 
1990  unsigned int numConnections_;
1991  std::vector<std::string> userWarnings_; // !< an accumulated list of user warnings
1992 
1993  std::vector<int> grpIds_;
1994  std::vector<SpikeGeneratorCore*> spkGen_;
1995  std::vector<ConnectionGeneratorCore*> connGen_;
1996 
1997  bool hasSetHomeoALL_;
1998  bool hasSetHomeoBaseFiringALL_;
1999  bool hasSetSTDPALL_;
2000  bool hasSetSTPALL_;
2001  bool hasSetConductances_;
2002  CARLsimState carlsimState_;
2003 
2004  int def_tdAMPA_;
2005  int def_trNMDA_;
2006  int def_tdNMDA_;
2007  int def_tdGABAa_;
2008  int def_trGABAb_;
2009  int def_tdGABAb_;
2010 
2011  // all default values for STDP
2012  STDPType def_STDP_type_;
2013  float def_STDP_alphaLTP_;
2014  float def_STDP_tauLTP_;
2015  float def_STDP_alphaLTD_;
2016  float def_STDP_tauLTD_;
2017  float def_STDP_betaLTP_;
2018  float def_STDP_betaLTD_;
2019  float def_STDP_lambda_;
2020  float def_STDP_delta_;
2021 
2022  // all default values for STP
2023  float def_STP_U_exc_;
2024  float def_STP_tau_u_exc_;
2025  float def_STP_tau_x_exc_;
2026  float def_STP_U_inh_;
2027  float def_STP_tau_u_inh_;
2028  float def_STP_tau_x_inh_;
2029 
2030  // all default values for homeostasis
2031  float def_homeo_scale_;
2032  float def_homeo_avgTimeScale_;
2033 
2034  // all default values for save file
2035  std::string def_save_fileName_;
2036  bool def_save_synapseInfo_;
2037 };
2038 
2039 
2040 
2041 
2042 // ****************************************************************************************************************** //
2043 // CARLSIM API IMPLEMENTATION
2044 // ****************************************************************************************************************** //
2045 
2046 // initialize static properties
2047 bool CARLsim::Impl::gpuAllocation[MAX_NUM_CUDA_DEVICES] = {false};
2048 std::string CARLsim::Impl::gpuOccupiedBy[MAX_NUM_CUDA_DEVICES];
2049 
2050 #if defined(WIN32) || defined(WIN64)
2051 HANDLE CARLsim::Impl::gpuAllocationLock = CreateMutex(NULL, FALSE, NULL);
2052 #else
2053 pthread_mutex_t CARLsim::Impl::gpuAllocationLock = PTHREAD_MUTEX_INITIALIZER;
2054 #endif
2055 
2056 // constructor / destructor
2057 CARLsim::CARLsim(const std::string& netName, SimMode preferredSimMode, LoggerMode loggerMode, int ithGPUs, int randSeed) :
2058 _impl( new Impl(this, netName, preferredSimMode, loggerMode, randSeed) ) {}
2059 CARLsim::~CARLsim() { delete _impl; }
2060 
2061 // connect with primitive type
2062 short int CARLsim::connect(int grpId1, int grpId2, const std::string& connType, const RangeWeight& wt, float connProb,
2063  const RangeDelay& delay, const RadiusRF& radRF, bool synWtType, float mulSynFast, float mulSynSlow) {
2064  return _impl->connect(grpId1, grpId2, connType, wt, connProb, delay, radRF, synWtType, mulSynFast, mulSynSlow);
2065 }
2066 
2067 // connect with custom ConnectionGenerator (short)
2068 // TODO: don't need two versions of this... make it (grpId1, grpId2, conn, synWtType, mulSynFast, mulSynSlow)
2069 short int CARLsim::connect(int grpId1, int grpId2, ConnectionGenerator* conn, bool synWtType) {
2070  return _impl->connect(grpId1, grpId2, conn, synWtType);
2071 }
2072 short int CARLsim::connect(int grpId1, int grpId2, ConnectionGenerator* conn, float mulSynFast, float mulSynSlow,
2073  bool synWtType)
2074 {
2075  return _impl->connect(grpId1, grpId2, conn, mulSynFast, mulSynSlow, synWtType);
2076 }
2077 
2078 short int CARLsim::connectCompartments(int grpIdLower, int grpIdUpper) {
2079  return _impl->connectCompartments(grpIdLower, grpIdUpper);
2080 }
2081 
2082 // create group with / without grid
2083 int CARLsim::createGroup(const std::string& grpName, const Grid3D& grid, int neurType, int preferredPartition, ComputingBackend preferredBackend) {
2084  return _impl->createGroup(grpName, grid, neurType, preferredPartition, preferredBackend);
2085 }
2086 int CARLsim::createGroup(const std::string& grpName, int nNeur, int neurType, int preferredPartition, ComputingBackend preferredBackend) {
2087  return _impl->createGroup(grpName, nNeur, neurType, preferredPartition, preferredBackend);
2088 }
2089 
2090 // create LIF group with / without grid
2091 int CARLsim::createGroupLIF(const std::string& grpName, const Grid3D& grid, int neurType, int preferredPartition, ComputingBackend preferredBackend) {
2092  return _impl->createGroupLIF(grpName, grid, neurType, preferredPartition, preferredBackend);
2093 }
2094 int CARLsim::createGroupLIF(const std::string& grpName, int nNeur, int neurType, int preferredPartition, ComputingBackend preferredBackend) {
2095  return _impl->createGroupLIF(grpName, nNeur, neurType, preferredPartition, preferredBackend);
2096 }
2097 
2098 // create spike gen group with / without grid
2099 int CARLsim::createSpikeGeneratorGroup(const std::string& grpName, const Grid3D& grid, int neurType, int preferredPartition, ComputingBackend preferredBackend) {
2100  return _impl->createSpikeGeneratorGroup(grpName, grid, neurType, preferredPartition, preferredBackend);
2101 }
2102 int CARLsim::createSpikeGeneratorGroup(const std::string& grpName, int nNeur, int neurType, int preferredPartition, ComputingBackend preferredBackend) {
2103  return _impl->createSpikeGeneratorGroup(grpName, nNeur, neurType, preferredPartition, preferredBackend);
2104 }
2105 
2106 void CARLsim::setCompartmentParameters(int grpId, float couplingUp, float couplingDown) {
2107  _impl->setCompartmentParameters(grpId, couplingUp, couplingDown);
2108 }
2109 
2110 #define LN_I_CALC_TYPES__REQUIRED_FOR_NETWORK_LEVEL
2111 // set conductances
2112 void CARLsim::setConductances(bool isSet) {
2113  _impl->setConductances(isSet);
2114 }
2115 void CARLsim::setConductances(bool isSet, int tdAMPA, int tdNMDA, int tdGABAa, int tdGABAb) {
2116  _impl->setConductances(isSet, tdAMPA, tdNMDA, tdGABAa, tdGABAb);
2117 }
2118 void CARLsim::setConductances(bool isSet, int tdAMPA, int trNMDA, int tdNMDA, int tdGABAa, int trGABAb, int tdGABAb) {
2119  _impl->setConductances(isSet, tdAMPA, trNMDA, tdNMDA, tdGABAa, trGABAb, tdGABAb);
2120 }
2121 
2122 #ifdef LN_I_CALC_TYPES
2123 // set conductances at group level
2124 void CARLsim::setConductances(int grpId, bool isSet) {
2125  _impl->setConductances(grpId, isSet);
2126 }
2127 
2128 void CARLsim::setConductances(int grpId, bool isSet, int tdAMPA, int tdNMDA, int tdGABAa, int tdGABAb) {
2129  _impl->setConductances(grpId, isSet, tdAMPA, tdNMDA, tdGABAa, tdGABAb);
2130 }
2131 
2132 void CARLsim::setConductances(int grpId, bool isSet, int tdAMPA, int trNMDA, int tdNMDA, int tdGABAa, int trGABAb, int tdGABAb) {
2133  _impl->setConductances(grpId, isSet, tdAMPA, trNMDA, tdNMDA, tdGABAa, trGABAb, tdGABAb);
2134 }
2135 
2136 void CARLsim::setACNE12(int grpId) {
2137  _impl->setACNE12(grpId);
2138 }
2139 
2140 void CARLsim::setNM4weighted(int grpId, IcalcType iCalc, float wDA, float w5HT, float wACh, float wNE, float wNorm, float wBase) {
2141  _impl->setNM4weighted(grpId, iCalc, wDA, w5HT, wACh, wNE, wNorm, wBase);
2142 }
2143 #endif
2144 
2145 // set homeostasis params
2146 void CARLsim::setHomeostasis(int grpId, bool isSet, float homeoScale, float avgTimeScale) {
2147  _impl->setHomeostasis(grpId, isSet, homeoScale, avgTimeScale);
2148 }
2149 void CARLsim::setHomeostasis(int grpId, bool isSet) {
2150  _impl->setHomeostasis(grpId, isSet);
2151 }
2152 void CARLsim::setHomeoBaseFiringRate(int grpId, float baseFiring, float baseFiringSD) {
2153  _impl->setHomeoBaseFiringRate(grpId, baseFiring, baseFiringSD);
2154 }
2155 
2157 {
2158  _impl->setIntegrationMethod(method, numStepsPerMs);
2159 }
2160 
2161 // set neuron params
2162 void CARLsim::setNeuronParameters(int grpId, float izh_a, float izh_a_sd, float izh_b, float izh_b_sd, float izh_c,
2163  float izh_c_sd, float izh_d, float izh_d_sd)
2164 {
2165  _impl->setNeuronParameters(grpId, izh_a, izh_a_sd, izh_b, izh_b_sd, izh_c, izh_c_sd, izh_d, izh_d_sd);
2166 }
2167 void CARLsim::setNeuronParameters(int grpId, float izh_a, float izh_b, float izh_c, float izh_d) {
2168  _impl->setNeuronParameters(grpId, izh_a, izh_b, izh_c, izh_d);
2169 }
2170 
2171 void CARLsim::setNeuronParameters(int grpId, float izh_C, float izh_k, float izh_vr, float izh_vt,
2172  float izh_a, float izh_b, float izh_vpeak, float izh_c, float izh_d)
2173 {
2174  _impl->setNeuronParameters(grpId, izh_C, izh_k, izh_vr, izh_vt, izh_a, izh_b, izh_vpeak, izh_c, izh_d);
2175 }
2176 
2177 void CARLsim::setNeuronParameters(int grpId, float izh_C, float izh_C_sd, float izh_k, float izh_k_sd,
2178  float izh_vr, float izh_vr_sd, float izh_vt, float izh_vt_sd,
2179  float izh_a, float izh_a_sd, float izh_b, float izh_b_sd,
2180  float izh_vpeak, float izh_vpeak_sd, float izh_c, float izh_c_sd,
2181  float izh_d, float izh_d_sd)
2182 {
2183  _impl->setNeuronParameters(grpId, izh_C, izh_C_sd, izh_k, izh_k_sd, izh_vr, izh_vr_sd, izh_vt, izh_vt_sd,
2184  izh_a, izh_a_sd, izh_b, izh_b_sd, izh_vpeak, izh_vpeak_sd, izh_c, izh_c_sd, izh_d, izh_d_sd);
2185 }
2186 
2187 void CARLsim::setNeuronParametersLIF(int grpId, int tau_m, int tau_ref, float vTh, float vReset, const RangeRmem& rMem)
2188 {
2189  _impl->setNeuronParametersLIF(grpId, tau_m, tau_ref, vTh, vReset, rMem);
2190 }
2191 
2193  float baseDP, float tauDP, float releaseDP, bool activeDP,
2194  float base5HT, float tau5HT, float release5HT, bool active5HT,
2195  float baseACh, float tauACh, float releaseACh, bool activeACh,
2196  float baseNE, float tauNE, float releaseNE, bool activeNE)
2197 {
2198  _impl->setNeuromodulator(grpId,
2199  baseDP, tauDP, releaseDP, activeDP,
2200  base5HT, tau5HT, release5HT, active5HT,
2201  baseACh, tauACh, releaseACh, activeACh,
2202  baseNE, tauNE, releaseNE, activeNE);
2203 }
2204 
2205 void CARLsim::setNeuromodulator(int grpId, float baseDP, float tauDP, float base5HT, float tau5HT, float baseACh,
2206  float tauACh, float baseNE, float tauNE)
2207 {
2208  _impl->setNeuromodulator(grpId, baseDP, tauDP, base5HT, tau5HT, baseACh, tauACh, baseNE, tauNE);
2209 }
2210 
2211 // sets default neuromodulators
2212 void CARLsim::setNeuromodulator(int grpId, float tauDP, float tau5HT, float tauACh, float tauNE) {
2213  _impl->setNeuromodulator(grpId, tauDP, tau5HT, tauACh, tauNE);
2214 }
2215 
2216 // Sets default STDP mode and params
2217 void CARLsim::setSTDP(int preGrpId, int postGrpId, bool isSet) { _impl->setSTDP(preGrpId, postGrpId, isSet); }
2218 
2219 // Sets STDP params for a group, custom
2220 void CARLsim::setSTDP(int preGrpId, int postGrpId, bool isSet, STDPType type, float alphaPlus, float tauPlus, float alphaMinus,
2221  float tauMinus)
2222 {
2223  _impl->setSTDP(preGrpId, postGrpId, isSet, type, alphaPlus, tauPlus, alphaMinus, tauMinus);
2224 }
2225 
2226 // Sets default E-STDP mode and parameters
2227 void CARLsim::setESTDP(int preGrpId, int postGrpId, bool isSet) { _impl->setESTDP(preGrpId, postGrpId, isSet); }
2228 
2229 // Sets E-STDP with the exponential curve
2230 void CARLsim::setESTDP(int preGrpId, int postGrpId, bool isSet, STDPType type, ExpCurve curve) {
2231  _impl->setESTDP(preGrpId, postGrpId, isSet, type, curve);
2232 }
2233 
2234 #ifdef LN_I_CALC_TYPES
2235 // Sets E-STDP with the exponential curve
2236 void CARLsim::setESTDP(int preGrpId, int postGrpId, bool isSet, STDPType type, ExpCurve curve, PkaPlcModulation modulation) {
2237  _impl->setESTDP(preGrpId, postGrpId, isSet, type, curve, modulation);
2238 }
2239 
2240 void CARLsim::setConnectionModulation(int preGrpId, int postGrpId, IcalcType icalcType) {
2241  _impl->setConnectionModulation(preGrpId, postGrpId, icalcType);
2242 }
2243 #endif
2244 
2245 // Sets E-STDP with the timing-based curve
2246 void CARLsim::setESTDP(int preGrpId, int postGrpId, bool isSet, STDPType type, TimingBasedCurve curve) {
2247  _impl->setESTDP(preGrpId, postGrpId, isSet, type, curve);
2248 }
2249 
2250 // Sets default I-STDP mode and parameters
2251 void CARLsim::setISTDP(int preGrpId, int postGrpId,bool isSet) { _impl->setESTDP(preGrpId, postGrpId, isSet); }
2252 
2253 // Sets I-STDP with the exponential curve
2254 void CARLsim::setISTDP(int preGrpId, int postGrpId, bool isSet, STDPType type, ExpCurve curve) {
2255  _impl->setISTDP(preGrpId, postGrpId, isSet, type, curve);
2256 }
2257 
2258 // Sets I-STDP with the pulse curve
2259 void CARLsim::setISTDP(int preGrpId, int postGrpId, bool isSet, STDPType type, PulseCurve curve) {
2260  _impl->setISTDP(preGrpId, postGrpId, isSet, type, curve);
2261 }
2262 
2263 // Sets STP params U, tau_u, and tau_x of a neuron group (pre-synaptically)
2264 void CARLsim::setSTP(int grpId, bool isSet, float STP_U, float STP_tau_u, float STP_tau_x) {
2265  _impl->setSTP(grpId, isSet, STP_U, STP_tau_u, STP_tau_x);
2266 }
2267 
2268 // Sets STP params U, tau_u, and tau_x of a neuron group (pre-synaptically) using default values
2269 void CARLsim::setSTP(int grpId, bool isSet) { _impl->setSTP(grpId, isSet); }
2270 
2271 #ifdef LN_I_CALC_TYPES
2272 // Sets neuromodulator targeting STP params U, tau_u, and tau_x of a neuron group (pre-synaptically)
2273 void CARLsim::setNM4STP(int grpId, float wSTP_U[], float wSTP_tau_u[], float wSTP_tau_x[]) {
2274  _impl->setNM4STP(grpId, wSTP_U, wSTP_tau_u, wSTP_tau_x);
2275 }
2276 #endif
2277 
2278 
2279 // Sets the weight and weight change update parameters
2280 void CARLsim::setWeightAndWeightChangeUpdate(UpdateInterval wtANDwtChangeUpdateInterval, bool enableWtChangeDecay,
2281  float wtChangeDecay)
2282 {
2283  _impl->setWeightAndWeightChangeUpdate(wtANDwtChangeUpdateInterval, enableWtChangeDecay, wtChangeDecay);
2284 }
2285 
2286 
2287 // run the simulation for time=(nSec*seconds + nMsec*milliseconds)
2288 int CARLsim::runNetwork(int nSec, int nMsec, bool printRunSummary) {
2289  return _impl->runNetwork(nSec, nMsec, printRunSummary);
2290 }
2291 
2292 // build the network
2294 
2295 #ifdef LN_SETUP_NETWORK_MT
2296 // build the network
2297 void CARLsim::setupNetworkMT() { _impl->setupNetworkMT(); }
2298 #endif
2299 
2300 #ifdef LN_AXON_PLAST
2301 void CARLsim::findWavefrontPath(std::vector<int>& path, std::vector<float>& eligibility, int netId, int grpId, int startNId, int goalNId) {
2302  _impl->findWavefrontPath(path, eligibility, netId, grpId, startNId, goalNId);
2303 }
2304 
2305 bool CARLsim::updateDelays(int gGrpIdPre, int gGrpIdPost, std::vector<std::tuple<int, int, uint8_t>> connDelays) {
2306  return _impl->updateDelays(gGrpIdPre, gGrpIdPost, connDelays);
2307 }
2308 
2309 void CARLsim::printEntrails(char* buffer, unsigned length, int gGrpIdPre, int gGrpIdPost) {
2310  _impl->printEntrails(buffer, length, gGrpIdPre, gGrpIdPost);
2311 }
2312 #endif
2313 
2314 
2315 const FILE* CARLsim::getLogFpInf() { return _impl->getLogFpInf(); }
2316 const FILE* CARLsim::getLogFpErr() { return _impl->getLogFpErr(); }
2317 const FILE* CARLsim::getLogFpDeb() { return _impl->getLogFpDeb(); }
2318 const FILE* CARLsim::getLogFpLog() { return _impl->getLogFpLog(); }
2319 
2320 // Saves important simulation and network infos to file.
2321 void CARLsim::saveSimulation(const std::string& fileName, bool saveSynapseInfo) {
2322  _impl->saveSimulation(fileName, saveSynapseInfo);
2323 }
2324 
2325 // Sets the name of the log file
2326 void CARLsim::setLogFile(const std::string& fileName) { _impl->setLogFile(fileName); }
2327 
2328 // Sets the file pointers for all log files in CUSTOM mode
2329 void CARLsim::setLogsFpCustom(FILE* fpInf, FILE* fpErr, FILE* fpDeb, FILE* fpLog) {
2330  _impl->setLogsFpCustom(fpInf, fpErr, fpDeb, fpLog);
2331 }
2332 
2333 
2334 // Adds a constant bias to the weight of every synapse in the connection
2335 void CARLsim::biasWeights(short int connId, float bias, bool updateWeightRange) {
2336  _impl->biasWeights(connId, bias, updateWeightRange);
2337 }
2338 
2339 // Loads a simulation (and network state) from file. The file pointer fid must point to a
2340 void CARLsim::loadSimulation(FILE* fid) { _impl->loadSimulation(fid); }
2341 
2342 // Multiplies the weight of every synapse in the connection with a scaling factor
2343 void CARLsim::scaleWeights(short int connId, float scale, bool updateWeightRange) {
2344  _impl->scaleWeights(connId, scale, updateWeightRange);
2345 }
2346 
2347 // Sets a connection monitor for a group, custom ConnectionMonitor class
2348 ConnectionMonitor* CARLsim::setConnectionMonitor(int grpIdPre, int grpIdPost, const std::string& fname) {
2349  return _impl->setConnectionMonitor(grpIdPre, grpIdPost, fname);
2350 }
2351 
2352 // Sets the amount of current (mA) to inject into a group
2353 void CARLsim::setExternalCurrent(int grpId, const std::vector<float>& current) {
2354  _impl->setExternalCurrent(grpId, current);
2355 }
2356 
2357 // Sets the amount of current (mA) to inject to each neuron in a group
2358 void CARLsim::setExternalCurrent(int grpId, float current) { _impl->setExternalCurrent(grpId, current); }
2359 
2360 // Sets a group monitor for a group, custom GroupMonitor class
2361 GroupMonitor* CARLsim::setGroupMonitor(int grpId, const std::string& fname, int mode) {
2362  return _impl->setGroupMonitor(grpId, fname, mode);
2363 }
2364 
2365 // Associates a SpikeGenerator object with a group
2366 void CARLsim::setSpikeGenerator(int grpId, SpikeGenerator* spikeGenFunc) {
2367  _impl->setSpikeGenerator(grpId, spikeGenFunc);
2368 }
2369 
2370 // Sets a Spike Monitor for a groups, prints spikes to binary file
2371 SpikeMonitor* CARLsim::setSpikeMonitor(int grpId, const std::string& fileName) {
2372  return _impl->setSpikeMonitor(grpId, fileName);
2373 }
2374 
2375 // Sets a Neuron Monitor for a groups, prints neuron state values (voltage, recovery, and total current values) to binary file
2376 NeuronMonitor* CARLsim::setNeuronMonitor(int grpId, const std::string& fileName) {
2377  return _impl->setNeuronMonitor(grpId, fileName);
2378 }
2379 
2380 // Sets a spike rate
2381 void CARLsim::setSpikeRate(int grpId, PoissonRate* spikeRate, int refPeriod) {
2382  _impl->setSpikeRate(grpId, spikeRate, refPeriod);
2383 }
2384 
2385 // Sets the weight value of a specific synapse
2386 void CARLsim::setWeight(short int connId, int neurIdPre, int neurIdPost, float weight, bool updateWeightRange) {
2387  _impl->setWeight(connId, neurIdPre, neurIdPost, weight, updateWeightRange);
2388 }
2389 
2390 // Enters a testing phase in which all weight changes are disabled
2391 void CARLsim::startTesting(bool updateWeights) { _impl->startTesting(updateWeights); }
2392 
2393 // Exits a testing phase, making weight changes possible again
2394 void CARLsim::stopTesting() { _impl->stopTesting(); }
2395 
2396 // Returns the current CARLsim state
2398 
2399 
2400 #ifdef LN_GET_FIRING
2401 // LN20201101
2402 void CARLsim::getFiring(std::vector<bool>& firing, int netId) { _impl->getFiring(firing, netId); }
2403 #endif
2404 
2405 #ifdef LN_GET_FIRING_MT
2406 // LN20201101
2407 void CARLsim::getFiringMT(std::vector<bool>& firing, int netId) { _impl->getFiringMT(firing, netId); }
2408 #endif
2409 
2410 // gets AMPA vector of a group
2411 std::vector<float> CARLsim::getConductanceAMPA(int grpId) { return _impl->getConductanceAMPA(grpId); }
2412 
2413 // gets NMDA vector of a group
2414 std::vector<float> CARLsim::getConductanceNMDA(int grpId) { return _impl->getConductanceNMDA(grpId); }
2415 
2416 // gets GABAa vector of a group
2417 std::vector<float> CARLsim::getConductanceGABAa(int grpId) { return _impl->getConductanceGABAa(grpId); }
2418 
2419 // gets GABAb vector of a group
2420 std::vector<float> CARLsim::getConductanceGABAb(int grpId) { return _impl->getConductanceGABAb(grpId); }
2421 
2422 // returns the RangeDelay struct for a specific connection ID
2423 RangeDelay CARLsim::getDelayRange(short int connId) { return _impl->getDelayRange(connId); }
2424 
2425 // gets delays
2426 uint8_t* CARLsim::getDelays(int gIDpre, int gIDpost, int& Npre, int& Npost) {
2427  return _impl->getDelays(gIDpre, gIDpost, Npre, Npost);
2428 }
2429 
2430 // returns the 3D grid struct of a group
2431 Grid3D CARLsim::getGroupGrid3D(int grpId) { return _impl->getGroupGrid3D(grpId); }
2432 
2433 int CARLsim::getGroupId(std::string grpName) { return _impl->getGroupId(grpName); }
2434 
2435 // gets group name
2436 std::string CARLsim::getGroupName(int grpId) { return _impl->getGroupName(grpId); }
2437 
2438 // returns the 3D location a neuron codes for
2439 Point3D CARLsim::getNeuronLocation3D(int neurId) { return _impl->getNeuronLocation3D(neurId); }
2440 
2441 // returns the 3D location a neuron codes for
2442 Point3D CARLsim::getNeuronLocation3D(int grpId, int relNeurId) { return _impl->getNeuronLocation3D(grpId, relNeurId); }
2443 
2444 //
2445 int CARLsim::getNeuronId(int grpId, Point3D location) { return _impl->getNeuronId(grpId, location); }
2446 
2447 
2448 // Returns the number of connections (pairs of pre-post groups) in the network
2450 
2452 
2453 // returns the number of connections associated with a connection ID
2454 int CARLsim::getNumSynapticConnections(short int connectionId) { return _impl->getNumSynapticConnections(connectionId); }
2455 
2456 // returns the number of groups in the network
2457 int CARLsim::getNumGroups() { return _impl->getNumGroups(); }
2458 
2459 // returns the total number of allocated neurons in the network
2460 int CARLsim::getNumNeurons() { return _impl->getNumNeurons(); }
2461 
2462 // returns the total number of regular (Izhikevich) neurons
2464 
2465 // returns the total number of regular (Izhikevich) excitatory neurons
2467 
2468 // returns the total number of regular (Izhikevich) inhibitory neurons
2470 
2471 // returns the total number of spike generator neurons
2473 
2474 // returns the total number of excitatory spike generator neurons
2476 
2477 // returns the total number of inhibitory spike generator neurons
2479 
2480 // returns the total number of allocated post-synaptic connections in the network
2481 int CARLsim::getNumSynapses() { return _impl->getNumSynapses(); }
2482 
2483 // returns the first neuron id of a groupd specified by grpId
2484 int CARLsim::getGroupStartNeuronId(int grpId) { return _impl->getGroupStartNeuronId(grpId); }
2485 
2486 // returns the last neuron id of a groupd specified by grpId
2487 int CARLsim::getGroupEndNeuronId(int grpId) { return _impl->getGroupEndNeuronId(grpId); }
2488 
2489 // returns the number of neurons of a group specified by grpId
2490 int CARLsim::getGroupNumNeurons(int grpId) { return _impl->getGroupNumNeurons(grpId); }
2491 
2492 // returns the stdp information of a group specified by grpId
2493 ConnSTDPInfo CARLsim::getConnSTDPInfo(int grpId) { return _impl->getConnSTDPInfo(grpId); }
2494 
2495 // returns the neuromodulator information of a group specified by grpId
2497  return _impl->getGroupNeuromodulatorInfo(grpId);
2498 }
2499 
2500 int CARLsim::getSimTime() { return _impl->getSimTime(); }
2501 
2502 int CARLsim::getSimTimeSec() { return _impl->getSimTimeSec(); }
2503 
2504 int CARLsim::getSimTimeMsec() { return _impl->getSimTimeMsec(); }
2505 
2506 // returns pointer to previously allocated SpikeMonitor object, NULL else
2507 SpikeMonitor* CARLsim::getSpikeMonitor(int grpId) { return _impl->getSpikeMonitor(grpId); }
2508 
2509 // returns the RangeWeight struct for a specific connection ID
2510 RangeWeight CARLsim::getWeightRange(short int connId) { return _impl->getWeightRange(connId); }
2511 
2512 // Returns whether a connection is fixed or plastic
2513 bool CARLsim::isConnectionPlastic(short int connId) { return _impl->isConnectionPlastic(connId); }
2514 
2515 // Returns whether a group has homeostasis enabled
2516 bool CARLsim::isGroupWithHomeostasis(int grpId) { return _impl->isGroupWithHomeostasis(grpId); }
2517 
2518 // LN Extensions ICALC \todo define constants
2519 
2521 
2523 
2524 
2525 #ifdef LN_I_CALC_TYPES
2526 
2527 bool CARLsim::isGroupWith(int grpId, IcalcType icalcType) { return _impl->isGroupWith(grpId, icalcType); }
2528 
2529 bool CARLsim::isGroupWithCOBA(int grpId) { return _impl->isGroupWithCOBA(grpId); }
2530 
2531 bool CARLsim::isGroupWithCUBA(int grpId) { return _impl->isGroupWithCUBA(grpId); }
2532 
2533 IcalcType CARLsim::getIcalcType(int grpId) { return _impl->getIcalcType(grpId); }
2534 
2535 // returns the conductance paramaters as factor / as float, how they are stored internally
2537  float& dAMPA, float& rNMDA, float& dNMDA, float& dGABAa, float& rGABAb, float& dGABAb)
2538 {
2539  return _impl->getConductanceConfig(grpId, dAMPA, rNMDA, dNMDA, dGABAa, rGABAb, dGABAb);
2540 }
2541 
2542 // returns the conductance parameters as times in ms (rounded)
2544  int& tdAMPA, int& trNMDA, int& tdNMDA, int& tdGABAa, int& trGABAb, int& tdGABAb)
2545 {
2546  return _impl->getConductanceConfig(grpId, tdAMPA, trNMDA, tdNMDA, tdGABAa, trGABAb, tdGABAb);
2547 }
2548 
2549 #endif
2550 
2551 
2552 bool CARLsim::isExcitatoryGroup(int grpId) { return _impl->isExcitatoryGroup(grpId); }
2553 
2554 bool CARLsim::isInhibitoryGroup(int grpId) { return _impl->isInhibitoryGroup(grpId); }
2555 
2556 bool CARLsim::isPoissonGroup(int grpId) { return _impl->isPoissonGroup(grpId); }
2557 
2558 void CARLsim::setDefaultConductanceTimeConstants(int tdAMPA, int trNMDA, int tdNMDA, int tdGABAa, int trGABAb,
2559  int tdGABAb)
2560 {
2561  _impl->setDefaultConductanceTimeConstants(tdAMPA, trNMDA, tdNMDA, tdGABAa, trGABAb, tdGABAb);
2562 }
2563 
2564 // Sets default homeostasis params
2565 void CARLsim::setDefaultHomeostasisParams(float homeoScale, float avgTimeScale) {
2566  _impl->setDefaultHomeostasisParams(homeoScale, avgTimeScale);
2567 }
2568 
2569 // Sets default options for save file
2570 void CARLsim::setDefaultSaveOptions(std::string fileName, bool saveSynapseInfo) {
2571  _impl->setDefaultSaveOptions(fileName, saveSynapseInfo);
2572 }
2573 
2574 // sets default STDP params
2575 void CARLsim::setDefaultSTDPparams(float alphaPlus, float tauPlus, float alphaMinus, float tauMinus, STDPType stdpType) {
2576  _impl->setDefaultSTDPparams(alphaPlus, tauPlus, alphaMinus, tauMinus, stdpType);
2577 }
2578 
2579 // sets default values for E-STDP params
2580 void CARLsim::setDefaultESTDPparams(float alphaPlus, float tauPlus, float alphaMinus, float tauMinus, STDPType stdpType) {
2581  _impl->setDefaultESTDPparams(alphaPlus, tauPlus, alphaMinus, tauMinus, stdpType);
2582 }
2583 
2584 // sets default values for I-STDP params
2585 void CARLsim::setDefaultISTDPparams(float betaLTP, float betaLTD, float lambda, float delta, STDPType stdpType) {
2586  _impl->setDefaultISTDPparams(betaLTP, betaLTD, lambda, delta, stdpType);
2587 }
2588 
2589 // Sets default values for STP params U, tau_u, and tau_x of a neuron group (pre-synaptically)
2590 void CARLsim::setDefaultSTPparams(int neurType, float STP_U, float STP_tau_u, float STP_tau_x) {
2591  _impl->setDefaultSTPparams(neurType, STP_U, STP_tau_u, STP_tau_x);
2592 }
2593 
2594 
2595 
2596 #ifdef __LN_EXT__
2597 
2598 // LN20210227 CAUTION despite included carlsim_conf.h by the consumer, with correct set value
2599 // the code is not active when entering by the Visual Studio Debugger from the consumer side.
2600 // therefor it is to be considered to pass the DEFINES over cMake ...
2601 // UPDATE: defining it in the Project Preprocessor Defines yields the same behavior
2602 // furthermore the same seems to apply to _all_ define constants, like __WIN32__ as well.
2603 // => When debugging in the external library code loaded Visual Studio, no conclusion about
2604 // the code nested in define constants must be made.
2605 // however stepping through it shows, if it is acutally active
2606 // => s.buids have the the whole source state consistant
2607 // => this is a main and essential feature -> tell this D.
2608 // Mitigration: loading the conf header containing the external library defines
2609 // show the correct values e.g. __LN__EXT__ set.
2610 // Conclusion: This has to be considered as a general Visual Studio Bug
2611 // or a missing config or a missing feature only available in the enterprise editions
2612 
2613 // LN Extension 20201017
2615  return SNN::cudaDeviceCount();
2616 }
2617 
2618 #ifndef __NO_CUDA__
2619 // LN Extension 20201017
2620 void CARLsim::cudaDeviceDescription(unsigned ithGPU, const char** desc) {
2621  SNN::cudaDeviceDescription(ithGPU, desc);
2622 }
2623 #endif
2624 
2625 #endif
2626 
bool isConnectionPlastic(short int connId)
Definition: carlsim.cpp:1650
void setSTP(int grpId, bool isSet, float STP_U, float STP_tau_u, float STP_tau_x)
Definition: carlsim.cpp:985
STDPCurve stdpCurve
the type of STDP curve
Class for generating Poisson spike trains.
Definition: poisson_rate.h:88
int getSimTime()
Definition: carlsim.cpp:1629
uint8_t * getDelays(int gIDpre, int gIDpost, int &Npre, int &Npost)
Definition: carlsim.cpp:1485
void setSTP(int grpId, bool isSet)
Definition: carlsim.cpp:961
int createGroupLIF(const std::string &grpName, int nNeur, int neurType, int preferredPartition=ANY, ComputingBackend preferredBackend=CPU_CORES)
Definition: carlsim.cpp:341
bool isGroupWithCUBA(int grpId)
Definition: carlsim.cpp:1721
STDPCurve stdpCurve
the type of STDP curve
void findWavefrontPath(std::vector< int > &path, std::vector< float > &eligibility, int netId, int grpId, int startNId, int goalNId)
Definition: carlsim.cpp:1418
static int cudaDeviceCount()
Get Info of suitable Harware for integration of CARLsim in NeuroInf-IDEs NIIDEs (LN20201017) ...
x86/x64 Multi Core Processor (LN20201016)
void setNeuronParametersLIF(int grpId, int tau_m, int tau_ref, float vTh, float vReset, double minRmem, double maxRmem)
Sets neuron parameters for a group of LIF spiking neurons.
CARLsimState getCARLsimState()
Writes population weights from gIDpre to gIDpost to file fname in binary.
Definition: carlsim.cpp:2397
int getNumGroups()
returns the number of groups in the network
Definition: carlsim.cpp:2457
int createSpikeGeneratorGroup(const std::string &grpName, const Grid3D &grid, int neurType, int preferredPartition, ComputingBackend preferredBackend)
Definition: carlsim.cpp:427
bool isPoissonGroup(int gGrpId)
Definition: snn.h:709
void setDefaultConductanceTimeConstants(int tdAMPA, int trNMDA, int tdNMDA, int tdGABAa, int trGABAb, int tdGABAb)
Sets default values for conductance time constants.
Definition: carlsim.cpp:2558
bool updateDelays(int gGrpIdPre, int gGrpIdPost, std::vector< std::tuple< int, int, uint8_t >> connDelays)
Updates the delays directly the backend memory.
Definition: carlsim.cpp:2305
SpikeMonitor * setSpikeMonitor(int grpId, const std::string &fileName)
Definition: carlsim.cpp:1297
float alphaPlus
the amplitude of the exponential curve at pre-post side
RangeWeight getWeightRange(short int connId)
Definition: carlsim.cpp:1642
int createGroup(const std::string &grpName, int nNeur, int neurType, int preferredPartition, ComputingBackend preferredBackend)
Definition: carlsim.cpp:336
void setNeuronParameters(int grpId, float izh_a, float izh_a_sd, float izh_b, float izh_b_sd, float izh_c, float izh_c_sd, float izh_d, float izh_d_sd)
Definition: carlsim.cpp:677
uint8_t * getDelays(int gIDpre, int gIDpost, int &Npre, int &Npost)
gets delays
Definition: carlsim.cpp:2426
int createGroupLIF(const std::string &grpName, const Grid3D &grid, int neurType, int preferredPartition, ComputingBackend preferredBackend)
Creates a group of LIF spiking neurons.
bool getConductanceConfig(int grpId, float &dAMPA, float &rNMDA, float &dNMDA, float &dGABAa, float &rGABAb, float &dGABAb)
Definition: carlsim.cpp:2536
RangeDelay getDelayRange(short int connId)
returns the RangeDelay struct of a connection
int getNumNeuronsGen()
Definition: snn.h:660
bool isGroupWithCOBA(int grpId)
Definition: carlsim.cpp:2529
int getGroupNumNeurons(int grpId)
returns the number of neurons of a group specified by grpId
Definition: carlsim.cpp:2490
#define EXCITATORY_NEURON
const FILE * getLogFpLog()
returns file pointer to log file
Definition: carlsim.cpp:2318
void findWavefrontPath(std::vector< int > &path, std::vector< float > &eligibility, int netId, int grpId, int startNId, int goalNId)
void setSpikeRate(int grpId, PoissonRate *spikeRate, int refPeriod)
Definition: carlsim.cpp:1371
A struct for retrieving STDP related information of a connection.
void setDefaultISTDPparams(float betaLTP, float betaLTD, float lambda, float delta, STDPType stdpType)
sets default values for I-STDP params
Definition: carlsim.cpp:2585
int getNumSynapses()
returns the total number of allocated synaptic connections in the network
Definition: carlsim.cpp:2481
void setSpikeGenerator(int grpId, SpikeGenerator *spikeGenFunc)
A SpikeCounter keeps track of the number of spikes per neuron in a group.
Definition: carlsim.cpp:2366
parameters must be identical
Definition: user_errors.h:50
int getNumNeuronsRegInh()
returns the total number of regular (Izhikevich) inhibitory neurons
Definition: carlsim.cpp:2469
int getNumNeuronsReg()
returns the total number of regular (Izhikevich) neurons
Definition: carlsim.cpp:2463
std::vector< float > getConductanceAMPA(int grpId)
gets AMPA vector of a group
Definition: carlsim.cpp:2411
#define ALL
CARLsim common definitions.
void getConductanceConfig(int grpId, float &dAMPA, float &rNMDA, float &dNMDA, float &dGABAa, float &rGABAb, float &dGABAb)
Definition: snn.h:727
void scaleWeights(short int connId, float scale, bool updateWeightRange)
Definition: carlsim.cpp:1173
GroupMonitor * setGroupMonitor(int grpId, const std::string &fname, int mode=0)
Sets a group monitor for a group, custom GroupMonitor class.
Definition: carlsim.cpp:2361
int getSimTime()
returns
Definition: carlsim.cpp:2500
const FILE * getLogFpDeb()
returns file pointer to debug log
Definition: carlsim.cpp:2317
serotonin-modulated STDP, nearest-neighbor
void setNM4weighted(int grpId, IcalcType type, float wDA=1.f, float w5HT=1.f, float wACh=1.f, float wNE=1.f, float wNorm=4.f, float wBase=1.0f)
Sets IcalcType to NM4weighted for a specific neuron group.
Definition: carlsim.cpp:2140
parameters cannot be identical
Definition: user_errors.h:34
std::vector< float > getConductanceGABAa(int grpId)
gets GABAa vector of a group
Definition: carlsim.cpp:2417
int getNumNeuronsRegInh()
Definition: carlsim.cpp:1591
int getSimTimeSec()
Definition: snn.h:668
CARLsim User Interface This class provides a user interface to the public sections of CARLsimCore sou...
Definition: carlsim.h:142
could not open file
Definition: user_errors.h:46
float alphaMinus
the amplitude of the exponential curve at post-pre side
static void cudaDeviceDescription(unsigned ithGPU, const char **desc)
void setNM4weighted(int grpId, IcalcType type, float wDA, float w5HT, float wACh, float wNE, float wNorm, float wBase)
void setLogFile(const std::string &fileName)
Sets the name of the log file.
Definition: carlsim.cpp:2326
GroupNeuromodulatorInfo getGroupNeuromodulatorInfo(int grpId)
int getNumGroups()
Definition: snn.h:655
bool isGroupWithCUBA(int grpId)
Definition: snn.h:720
void setISTDP(int preGrpId, int postGrpId, bool isSet, STDPType type, STDPCurve curve, float ab1, float ab2, float tau1, float tau2)
Set the inhibitory spike-timing-dependent plasticity (STDP) with anti-hebbian curve for a neuron grou...
A struct to assign a timing-based E-STDP curve.
std::vector< float > getConductanceGABAb(int grpId)
gets GABAb vector of a group
Definition: carlsim.cpp:2420
short int connect(int grpId1, int grpId2, ConnectionGenerator *conn, bool synWtType)
Definition: carlsim.cpp:209
parameter cannot be of type UNKNOWN
Definition: user_errors.h:43
const FILE * getLogFpErr()
returns file pointer to error log
Definition: carlsim.cpp:2316
ConnectionMonitor * setConnectionMonitor(int grpIdPre, int grpIdPost, FILE *fid)
sets up a network monitor registered with a callback to process the spikes.
void setNeuronParameters(int grpId, float izh_C, float izh_C_sd, float izh_k, float izh_k_sd, float izh_vr, float izh_vr_sd, float izh_vt, float izh_vt_sd, float izh_a, float izh_a_sd, float izh_b, float izh_b_sd, float izh_vpeak, float izh_vpeak_sd, float izh_c, float izh_c_sd, float izh_d, float izh_d_sd)
Definition: carlsim.cpp:714
~CARLsim()
Definition: carlsim.cpp:2059
int createGroup(const std::string &grpName, const Grid3D &grid, int neurType, int preferredPartition, ComputingBackend preferredBackend)
Definition: carlsim.cpp:346
IcalcType getIcalcType(int grpId)
Returns the iCalc of a group.
Definition: carlsim.cpp:2533
void setESTDP(int preGrpId, int postGrpId, bool isSet, STDPType type, TimingBasedCurve curve)
Definition: carlsim.cpp:887
UpdateInterval
Update frequency for weights.
#define CARLSIM_WARN(where, what)
bool isSimulationWithCUBA()
Definition: carlsim.cpp:1672
void setESTDP(int preGrpId, int postGrpId, bool isSet, STDPType type, ExpCurve curve)
Definition: carlsim.cpp:837
bool isGroupWithCOBA(int grpId)
Definition: snn.h:719
void setDefaultSTPparams(int neurType, float STP_U, float STP_tau_u, float STP_tau_x)
Definition: carlsim.cpp:1869
ConnSTDPInfo getConnSTDPInfo(int grpId)
returns the stdp information of a group specified by grpId
Definition: carlsim.cpp:2493
run state, where the model is stepped
void setSTDP(int preGrpId, int postGrpId, bool isSet)
Definition: carlsim.cpp:807
bool isGroupWithHomeostasis(int grpId)
Definition: carlsim.cpp:1658
int getNumNeuronsGenExc()
Definition: snn.h:661
int getNumNeuronsReg()
Definition: snn.h:657
void setISTDP(int preGrpId, int postGrpId, bool isSet, STDPType type, ExpCurve curve)
Definition: carlsim.cpp:924
CARLsimState getCARLsimState()
Definition: carlsim.cpp:1400
#define MAX_NUM_CUDA_DEVICES
int createSpikeGeneratorGroup(const std::string &grpName, int nNeur, int neurType, int preferredPartition, ComputingBackend preferredBackend)
Definition: carlsim.cpp:422
void setNeuromodulator(int grpId, float baseDP, float tauDP, float base5HT, float tau5HT, float baseACh, float tauACh, float baseNE, float tauNE)
Sets baseline concentration and decay time constant of neuromodulators (DP, 5HT, ACh, NE) for a neuron group.
bool getConductanceConfig(int grpId, int &tdAMPA, int &trNMDA, int &tdNMDA, int &tdGABAa, int &trGABAb, int &tdGABAb)
Definition: carlsim.cpp:1703
int getNeuronId(int grpId, Point3D location)
Definition: carlsim.cpp:1570
std::vector< float > getConductanceNMDA(int grpId)
void setNeuromodulator(int grpId, float baseDP, float tauDP, float releaseDP, bool activeDP, float base5HT, float tau5HT, float release5HT, bool active5HT, float baseACh, float tauACh, float releaseACh, bool activeACh, float baseNE, float tauNE, float releaseNE, bool activeNE)
Definition: carlsim.cpp:750
void loadSimulation(FILE *fid)
Loads a simulation (and network state) from file. The file pointer fid must point to a valid CARLsim ...
Definition: carlsim.cpp:2340
void setNM4STP(int grpId, float wSTP_U[], float wSTP_tau_u[], float wSTP_tau_x[])
bool isGroupWithCOBA(int grpId)
Definition: carlsim.cpp:1715
void setConnectionModulation(int preGrpId, int postGrpId, IcalcType icalcType)
Definition: carlsim.cpp:2240
bool updateDelays(int gGrpIdPre, int gGrpIdPost, std::vector< std::tuple< int, int, uint8_t >> connDelays)
void startTesting(bool shallUpdateWeights=true)
enters a testing phase, where all weight updates are disabled
SpikeMonitor * getSpikeMonitor(int grpId)
Returns the number of spikes per neuron for a certain group.
Definition: carlsim.cpp:2507
CARLsim(const std::string &netName="SNN", SimMode preferredSimMode=CPU_MODE, LoggerMode loggerMode=USER, int ithGPUs=0, int randSeed=-1)
CARLsim constructor. Creates a new instance of class CARLsim. All input arguments are optional...
Definition: carlsim.cpp:2057
int createGroup(const std::string &grpName, int nNeur, int neurType, int preferredPartition=ANY, ComputingBackend preferredBackend=CPU_CORES)
creates a group of Izhikevich spiking neurons
Definition: carlsim.cpp:2086
bool isGroupWithHomeostasis(int grpId)
returns whether group has homeostasis enabled (true) or not (false)
void setDefaultISTDPparams(float betaLTP, float betaLTD, float lambda, float delta, STDPType stdpType)
Definition: carlsim.cpp:1842
GroupNeuromodulatorInfo getGroupNeuromodulatorInfo(int grpId)
Definition: carlsim.cpp:1622
#define MAX_NUM_COMP_CONN
parameter cannot have larger vaule than some vaule
Definition: user_errors.h:37
unknown curve type
setup state, where the neural network is prepared for execution and monitors are set ...
#define SYN_FIXED
int runNetwork(int nSec, int nMsec, bool printRunSummary)
Definition: carlsim.cpp:1042
void setLogFile(const std::string &fileName)
Definition: carlsim.cpp:1105
void setDefaultHomeostasisParams(float homeoScale, float avgTimeScale)
Sets default homeostasis params.
Definition: carlsim.cpp:2565
void startTesting(bool updateWeights=true)
Enters a testing phase in which all weight changes are disabled.
Definition: carlsim.cpp:2391
a point in 3D space
int getGroupNumNeurons(int grpId)
Definition: carlsim.cpp:1538
std::vector< float > getConductanceGABAb(int grpId)
int getNumNeurons()
Definition: snn.h:656
STDPType
STDP flavors.
void scaleWeights(short int connId, float scale, bool updateWeightRange=false)
acetylcholine-modulated STDP, nearest-neighbor
const IcalcType getIcalcType(int grpId)
Definition: carlsim.cpp:1686
int getGroupEndNeuronId(int grpId)
returns the last neuron id of a groupd specified by grpId
Definition: carlsim.cpp:2487
Class SpikeMonitor.
void printEntrails(char *buffer, unsigned length, int gGrpIdPre, int gGrpIdPost)
parameter must be set to
Definition: user_errors.h:56
Impl(CARLsim *sim, const std::string &netName, SimMode prferredSimMode, LoggerMode loggerMode, int randSeed)
Definition: carlsim.cpp:83
void biasWeights(short int connId, float bias, bool updateWeightRange)
Definition: carlsim.cpp:1138
const FILE * getLogFpInf()
returns file pointer to info log
Definition: carlsim.cpp:2315
LoggerMode
Logger modes.
short int connect(int grpId1, int grpId2, const std::string &connType, const RangeWeight &wt, float connProb, const RangeDelay &delay, const RadiusRF &radRF, bool synWtType, float mulSynFast, float mulSynSlow)
Definition: carlsim.cpp:150
int createGroup(const std::string &grpName, const Grid3D &grid, int neurType, int preferredPartition, ComputingBackend preferredBackend)
Creates a group of Izhikevich spiking neurons.
void setExternalCurrent(int grpId, const std::vector< float > &current)
Definition: carlsim.cpp:1223
bool isGroupWith(int grpId, IcalcType icalcType)
Definition: carlsim.cpp:1680
void setNeuromodulator(int grpId, float tauDP, float tau5HT, float tauACh, float tauNE)
Definition: carlsim.cpp:794
used for relaying callback to ConnectionGenerator
Definition: callback_core.h:91
void setHomeoBaseFiringRate(int grpId, float baseFiring, float baseFiringSD=0.0f)
Sets the homeostatic target firing rate (enforced through homeostatic synaptic scaling) ...
Definition: carlsim.cpp:2152
bool isExcitatoryGroup(int gGrpId)
Definition: snn.h:707
int getNumNeuronsGenInh()
Definition: carlsim.cpp:1594
void setNM4weighted(int grpId, IcalcType icalc, float wDA, float w5HT, float wACh, float wNE, float wNorm, float wBase)
Definition: carlsim.cpp:593
int getNumNeuronsRegExc()
returns the total number of regular (Izhikevich) excitatory neurons
Definition: carlsim.cpp:2466
GroupMonitor * setGroupMonitor(int grpId, FILE *fid, int mode=0)
sets up a group monitor registered with a callback to process the spikes.
void setCompartmentParameters(int grpId, float couplingUp, float couplingDown)
Sets coupling constants G_u and G_d for the compartment.
Definition: carlsim.cpp:2106
symmetric pulse curve
bool isGroupWith(int grpId, IcalcType icalcType)
Definition: snn.h:718
std::vector< float > getConductanceNMDA(int grpId)
gets NMDA vector of a group
Definition: carlsim.cpp:2414
void setNeuronParameters(int grpId, float izh_C, float izh_k, float izh_vr, float izh_vt, float izh_a, float izh_b, float izh_vpeak, float izh_c, float izh_d)
Definition: carlsim.cpp:700
void setConnectionModulation(int preGrpId, int postGrpId, IcalcType icalcType)
Definition: carlsim.cpp:879
standard STDP of Bi & Poo (2001), nearest-neighbor
static void cudaDeviceDescription(unsigned ithGPU, const char **desc)
LN extension 20201017.
void setLogsFp(FILE *fpInf=NULL, FILE *fpErr=NULL, FILE *fpDeb=NULL, FILE *fpLog=NULL)
Sets the file pointers for all log files file pointer NULL means don&#39;t change it. ...
void stopTesting()
Exits a testing phase, making weight changes possible again.
Definition: carlsim.cpp:2394
void setDefaultSTDPparams(float alphaPlus, float tauPlus, float alphaMinus, float tauMinus, STDPType stdpType)
Definition: carlsim.cpp:1809
#define INHIBITORY_NEURON
void stopTesting()
Definition: carlsim.cpp:1156
void setSTDP(int preGrpId, int postGrpId, bool isSet, STDPType type, float alphaPlus, float tauPlus, float alphaMinus, float tauMinus)
Definition: carlsim.cpp:812
float alphaMinus
the amplitude of the exponential curve at post-pre side
void setNM4STP(int grpId, float wSTP_U[], float wSTP_tau_u[], float wSTP_tau_x[])
Sets neuromodulator targeting STP params U, tau_u, and tau_x of a neuron group (pre-synaptically) ...
Definition: carlsim.cpp:2273
bool isSimulationWithCOBA()
Definition: carlsim.cpp:1666
parameter cannot be set to
Definition: user_errors.h:42
bool isSimulationWithCUBA()
Returns true is the network exclusivle operate on current basis.
Definition: carlsim.cpp:2522
int getNumSynapticConnections(short int connectionId)
Definition: carlsim.cpp:1596
void setDefaultHomeostasisParams(float homeoScale, float avgTimeScale)
Definition: carlsim.cpp:1783
int getNumNeuronsGen()
returns the total number of spike generator neurons
Definition: carlsim.cpp:2472
SimMode
simulation mode
float tauPlus
the time constant of the exponential curve at pre-post side
Grid3D getGroupGrid3D(int grpId)
void setupNetwork()
build the network
parameter must be in some range
Definition: user_errors.h:51
A struct to arrange neurons on a 3D grid (a primitive cubic Bravais lattice with cubic side length 1)...
void setNeuromodulator(int grpId, float baseDP, float tauDP, float base5HT, float tau5HT, float baseACh, float tauACh, float baseNE, float tauNE)
Sets baseline concentration and decay time constant of neuromodulators (DP, 5HT, ACh, NE) for a neuron group.
Definition: carlsim.cpp:2205
bool isSimulationWithCOBA()
Definition: snn.h:763
const FILE * getLogFpInf()
Definition: carlsim.cpp:1088
void setIntegrationMethod(integrationMethod_t method, int numStepsPerMs)
Definition: carlsim.cpp:2156
int getNumGroups()
Definition: carlsim.cpp:1587
void saveSimulation(FILE *fid, bool saveSynapseInfo=false)
stores the pre and post synaptic neuron ids with the weight and delay
parameter cannot have NULL value
Definition: user_errors.h:36
int getNumNeuronsReg()
Definition: carlsim.cpp:1589
int getNumNeuronsGen()
Definition: carlsim.cpp:1592
used for relaying callback to SpikeGenerator
Definition: callback_core.h:71
void setConductances(bool isSet, int tdAMPA, int tdNMDA, int tdGABAa, int tdGABAb)
Definition: carlsim.cpp:471
bool isExcitatoryGroup(int grpId)
returns
Definition: carlsim.cpp:2552
SpikeMonitor * getSpikeMonitor(int grpId)
Returns pointer to existing SpikeMonitor object, NULL else.
NeuronMonitor * setNeuronMonitor(int gid, FILE *fid)
sets up a neuron monitor registered with a callback to process the neuron state values, there can only be one NeuronMonitor per group
void setConductances(bool isSet)
Sets default values for conduction decay and rise times or disables COBA alltogether.
Definition: carlsim.cpp:2112
std::string getGroupName(int grpId)
bool updateDelays(int gGrpIdPre, int gGrpIdPost, std::vector< std::tuple< int, int, uint8_t >> connDelays)
Definition: carlsim.cpp:1422
float betaLTD
the amplitude of inhibitory LTD
void setExternalCurrent(int grpId, float current)
Definition: carlsim.cpp:1235
bool isInhibitoryGroup(int grpId)
returns
Definition: carlsim.cpp:2554
struct to assign a pulse I-STDP curve
int getGroupId(std::string grpName)
Definition: carlsim.cpp:1506
int getMaxNumCompConnections()
Returns the maximum number of allowed compartmental connections per group.
Definition: carlsim.cpp:2451
void setNeuronParametersLIF(int grpId, int tau_m, int tau_ref=0, float vTh=1.0f, float vReset=0.0f, const RangeRmem &rMem=RangeRmem(1.0f))
Sets neuron parameters for a group of LIF spiking neurons.
Definition: carlsim.cpp:2187
void saveSimulation(const std::string &fileName, bool saveSynapseInfo)
Definition: carlsim.cpp:1093
float lambda
the range of inhibitory LTP
void setHomeostasis(int grpId, bool isSet)
Definition: carlsim.cpp:610
const FILE * getLogFpLog()
returns file pointer to log file
Definition: snn.h:602
static void assertTrue(bool statement, errorType errorIfAssertionFails, std::string errorFunc, std::string errorMsgPrefix="", std::string errorMsgSuffix="")
simple wrapper for assert statement
Definition: user_errors.cpp:15
dopamine-modulated STDP, nearest-neighbor
std::vector< float > getConductanceAMPA(int grpId)
Definition: carlsim.cpp:1432
void setConductances(int grpId, bool isSet, int tdAMPA, int trNMDA, int tdNMDA, int tdGABAa, int trGABAb, int tdGABAb)
Definition: carlsim.cpp:559
void setNeuromodulator(int grpId, float baseDP, float tauDP, float base5HT, float tau5HT, float baseACh, float tauACh, float baseNE, float tauNE)
Definition: carlsim.cpp:776
int getNumNeurons()
Definition: carlsim.cpp:1588
int getNumNeuronsRegInh()
Definition: snn.h:659
int getNumNeurons()
returns the total number of allocated neurons in the network
Definition: carlsim.cpp:2460
void setSpikeRate(int grpId, PoissonRate *spikeRate, int refPeriod=1)
Sets a spike rate.
Definition: carlsim.cpp:2381
Struct defines the minimum and maximum membrane resisatnces of the LIF neuron group.
configuration state, where the neural network is configured
int getSimTimeMsec()
returns
Definition: carlsim.cpp:2504
int getNumNeurons()
Returns the number of neurons for which to generate Poisson spike trains.
function cannot be applied to neuron type
Definition: user_errors.h:64
float betaLTP
the amplitude of inhibitory LTP
short int connect(int grpId1, int grpId2, const std::string &connType, const RangeWeight &wt, float connProb, const RangeDelay &delay=RangeDelay(1), const RadiusRF &radRF=RadiusRF(-1.0), bool synWtType=SYN_FIXED, float mulSynFast=1.0f, float mulSynSlow=1.0f)
Connects a presynaptic to a postsynaptic group using fixed/plastic weights and a range of delay value...
Definition: carlsim.cpp:2062
bool isSimulationWithCUBA()
Definition: snn.h:764
void setHomeostasis(int grpId, bool isSet, float homeoScale, float avgTimeScale)
Sets custom values for implementation of homeostatic synaptic scaling.
Definition: carlsim.cpp:2146
uint8_t * getDelays(int gGrpIdPre, int gGrpIdPost, int &numPreN, int &numPostN)
Returns the delay information for all synaptic connections between a pre-synaptic and a post-synaptic...
int getNumSynapses()
Definition: carlsim.cpp:1606
std::vector< float > getConductanceNMDA(int grpId)
Definition: carlsim.cpp:1443
void setESTDP(int preGrpId, int postGrpId, bool isSet, STDPType type, ExpCurve curve, PkaPlcModulation modulation)
Definition: carlsim.cpp:857
NeuronMonitor * setNeuronMonitor(int grpId, const std::string &fileName)
Definition: carlsim.cpp:1333
float delta
the range of inhibitory LTD
void setSpikeRate(int grpId, PoissonRate *spikeRate, int refPeriod)
Sets the Poisson spike rate for a group. For information on how to set up spikeRate, see Section Poisson spike generators in the Tutorial.
#define SYN_PLASTIC
Class GroupMonitor.
IcalcType
input current calculation
std::string getGroupName(int grpId)
gets group name
Definition: carlsim.cpp:2436
void setISTDP(int preGrpId, int postGrpId, bool isSet)
Sets default I-STDP mode and parameters.
Definition: carlsim.cpp:2251
int getGroupEndNeuronId(int gGrpId)
Definition: snn.h:640
void biasWeights(short int connId, float bias, bool updateWeightRange=false)
int getNeuronId(int grpId, Point3D location)
returns the neuron ID for a 3D location
Definition: carlsim.cpp:2445
int getNumSynapticConnections(short int connectionId)
gets number of connections associated with a connection ID
void setIntegrationMethod(integrationMethod_t method, int numStepsPerMs)
Definition: carlsim.cpp:664
int getNumNeuronsGenExc()
returns the total number of excitatory spike generator neurons
Definition: carlsim.cpp:2475
void setSTDP(int preGrpId, int postGrpId, bool isSet)
Sets default STDP mode and params.
Definition: carlsim.cpp:2217
void setCompartmentParameters(int grpId, float couplingUp, float couplingDown)
Definition: carlsim.cpp:445
int getSimTimeSec()
Definition: carlsim.cpp:1630
int createGroupLIF(const std::string &grpName, int nNeur, int neurType, int preferredPartition=ANY, ComputingBackend preferredBackend=CPU_CORES)
creates a group of Leaky-Integrate-and-Fire (LIF) spiking neurons
Definition: carlsim.cpp:2094
void setConductances(bool isSet)
Definition: carlsim.cpp:456
void setWeightAndWeightChangeUpdate(UpdateInterval wtANDwtChangeUpdateInterval, bool enableWtChangeDecay, float wtChangeDecay=0.9f)
Sets the weight and weight change update parameters.
Definition: carlsim.cpp:2280
short int connect(int gIDpre, int gIDpost, const std::string &_type, float initWt, float maxWt, float prob, uint8_t minDelay, uint8_t maxDelay, RadiusRF radius, float mulSynFast, float mulSynSlow, bool synWtType)
make from each neuron in grpId1 to &#39;numPostSynapses&#39; neurons in grpId2
Definition: snn_manager.cpp:97
int getGroupId(std::string grpName)
finds the ID of the group with name grpName
Definition: carlsim.cpp:2433
float tauPlus
the time constant of the exponential curve at pre-post side
integrationMethod_t
Integration methods.
void setNeuronParameters(int grpId, float izh_a, float izh_a_sd, float izh_b, float izh_b_sd, float izh_c, float izh_c_sd, float izh_d, float izh_d_sd)
Sets the Izhikevich parameters a, b, c, and d of a neuron group.
Point3D getNeuronLocation3D(int neurId)
returns the 3D location a neuron codes for
Definition: carlsim.cpp:2439
a range struct for synaptic delays
short int connectCompartments(int grpIdLower, int grpIdUpper)
Definition: carlsim.cpp:275
void setCompartmentParameters(int grpId, float couplingUp, float couplingDown)
Coupling constants for the compartment are set using this method.
Point3D getNeuronLocation3D(int neurId)
Definition: carlsim.cpp:1546
void setHomeoBaseFiringRate(int groupId, float baseFiring, float baseFiringSD)
Sets homeostatic target firing rate (enforced through homeostatic synaptic scaling) ...
void setConductances(bool isSet, int tdAMPA, int trNMDA, int tdNMDA, int tdGABAa, int trGABAb, int tdGABAb)
Definition: carlsim.cpp:491
void printEntrails(char *buffer, unsigned length, int gGrpIdPre, int gGrpIdPost)
Definition: carlsim.cpp:1426
bool isGroupWithCUBA(int grpId)
Definition: carlsim.cpp:2531
void biasWeights(short int connId, float bias, bool updateWeightRange=false)
Adds a constant bias to the weight of every synapse in the connection.
Definition: carlsim.cpp:2335
void setNeuronParameters(int grpId, float izh_a, float izh_b, float izh_c, float izh_d)
Definition: carlsim.cpp:690
RangeDelay getDelayRange(short int connId)
Definition: carlsim.cpp:1476
int getNumConnections()
Returns the number of connections (pairs of pre-post groups) in the network.
Definition: carlsim.cpp:2449
int getGroupStartNeuronId(int grpId)
returns the first neuron id of a groupd specified by grpId
Definition: carlsim.cpp:2484
Grid3D getGroupGrid3D(int grpId)
returns the 3D grid struct of a group
Definition: carlsim.cpp:2431
void setupNetworkMT()
featFastSetup LN 20201108
float gamma
the turn-over point
void setDefaultSTPparams(int neurType, float STP_U, float STP_tau_u, float STP_tau_x)
Sets default values for STP params U, tau_u, and tau_x of a neuron group (pre-synaptically) ...
Definition: carlsim.cpp:2590
ConnectionMonitor * setConnectionMonitor(int grpIdPre, int grpIdPost, const std::string &fname)
Sets a connection monitor for a group, custom ConnectionMonitor class.
Definition: carlsim.cpp:2348
std::vector< float > getConductanceGABAa(int grpId)
bool isPoissonGroup(int grpId)
Definition: carlsim.cpp:1746
int getNumSynapticConnections(short int connectionId)
returns the number of connections associated with a connection ID
Definition: carlsim.cpp:2454
void setConductances(int grpId, bool isSet, int tdAMPA, int tdNMDA, int tdGABAa, int tdGABAb)
Definition: carlsim.cpp:539
int createGroupLIF(const std::string &grpName, const Grid3D &grid, int neurType, int preferredPartition, ComputingBackend preferredBackend)
Definition: carlsim.cpp:384
void setWeight(short int connId, int neurIdPre, int neurIdPost, float weight, bool updateWeightRange=false)
Sets the weight value of a specific synapse.
Definition: carlsim.cpp:2386
function can only be called in certain state
Definition: user_errors.h:29
int runNetwork(int _nsec, int _nmsec, bool printRunSummary)
run the simulation for n sec
int getNumNeuronsGenInh()
returns the total number of inhibitory spike generator neurons
Definition: carlsim.cpp:2478
A struct for retrieving neuromodulator information of a group.
RangeWeight getWeightRange(short int connId)
returns RangeWeight struct of a connection
bool isSimulationWithCOBA()
Returns true is the network is COBA enabled.
Definition: carlsim.cpp:2520
void setConductances(int grpId, bool isSet)
Definition: carlsim.cpp:523
int createSpikeGeneratorGroup(const std::string &grpName, const Grid3D &grid, int neurType, int preferredPartition, ComputingBackend preferredBackend)
Creates a spike generator group (dummy-neurons, not Izhikevich spiking neurons)
Point3D getNeuronLocation3D(int neurId)
A struct to assign exponential STDP curves.
void setIntegrationMethod(integrationMethod_t method, int numStepsPerMs)
Sets the integration method and the number of integration steps per 1ms simulation time step...
NeuronMonitor * setNeuronMonitor(int grpId, const std::string &fileName)
Sets a Neuron Monitor for a groups, print voltage, recovery, and total current values to binary file...
Definition: carlsim.cpp:2376
void setNeuronParametersLIF(int grpId, int tau_m, int tau_ref, float vTh, float vReset, const RangeRmem &rMem)
Definition: carlsim.cpp:731
void startTesting(bool updateWeights)
Definition: carlsim.cpp:1149
void setDefaultConductanceTimeConstants(int tdAMPA, int trNMDA, int tdNMDA, int tdGABAa, int trGABAb, int tdGABAb)
Definition: carlsim.cpp:1758
SpikeMonitor * getSpikeMonitor(int grpId)
Definition: carlsim.cpp:1634
void setupNetwork()
Definition: carlsim.cpp:1064
int runNetwork(int nSec, int nMsec=0, bool printRunSummary=true)
run the simulation for time=(nSec*seconds + nMsec*milliseconds)
Definition: carlsim.cpp:2288
int getMaxNumCompConnections()
Definition: carlsim.cpp:1585
std::vector< float > getConductanceAMPA(int grpId)
ConnSTDPInfo getConnSTDPInfo(short int connId)
void setDefaultESTDPparams(float alphaPlus, float tauPlus, float alphaMinus, float tauMinus, STDPType stdpType)
sets default values for E-STDP params
Definition: carlsim.cpp:2580
void setESTDP(int preGrpId, int postGrpId, bool isSet)
Definition: carlsim.cpp:819
void setDefaultSTDPparams(float alphaPlus, float tauPlus, float alphaMinus, float tauMinus, STDPType stdpType)
sets default STDP params
Definition: carlsim.cpp:2575
keyword ALL is not allowed for this variable
Definition: user_errors.h:27
int getGroupStartNeuronId(int gGrpId)
Definition: snn.h:639
std::string getGroupName(int grpId)
Definition: carlsim.cpp:1510
Class ConnectionMonitor.
int getNeuronId(int gGrpId, Point3D location)
the inverse of getNeuronLocation3D
NE alpha1 receptor with DA antagonist, Avery, Dutt, Krichmar (2013)
cannot be connected twice
Definition: user_errors.h:33
void setExternalCurrent(int grpId, const std::vector< float > &current)
injects current (mA) into the soma of every neuron in the group
void setSTP(int grpId, bool isSet, float STP_U, float STP_tau_u, float STP_tau_x)
Sets STP params U, tau_u, and tau_x of a neuron group (pre-synaptically)
Definition: carlsim.cpp:2264
const FILE * getLogFpErr()
returns file pointer to error log
Definition: snn.h:598
a range struct for synaptic weight magnitudes
Contains all of CARLsim&#39;s core functionality.
Definition: snn.h:138
void setDefaultSaveOptions(std::string fileName, bool saveSynapseInfo)
Sets default options for save file.
Definition: carlsim.cpp:2570
ComputingBackend
computing backend
void setACNE12(int grpId)
Definition: carlsim.cpp:588
float tauMinus
the time constant of the exponential curve at post-pre side
static int cudaDeviceCount()
LN extension 20201017.
GroupNeuromodulatorInfo getGroupNeuromodulatorInfo(int grpId)
returns the neuromodulator information of a group specified by grpId
Definition: carlsim.cpp:2496
int getNumNeuronsGenExc()
Definition: carlsim.cpp:1593
int getGroupEndNeuronId(int grpId)
Definition: carlsim.cpp:1528
int getSimTimeSec()
returns
Definition: carlsim.cpp:2502
int getGroupStartNeuronId(int grpId)
Definition: carlsim.cpp:1518
int getSimTimeMs()
Definition: snn.h:669
GroupMonitor * setGroupMonitor(int grpId, const std::string &fname, const int mode)
Definition: carlsim.cpp:1247
void setESTDP(int preGrpId, int postGrpId, bool isSet, STDPType type, STDPCurve curve, float alphaPlus, float tauPlus, float alphaMinus, float tauMinus, float gamma)
Set the spike-timing-dependent plasticity (STDP) for a neuron group.
void printEntrails(char *buffer, unsigned length, int gGrpIdPre, int gGrpIdPost)
print entrails of SNN to string buffer
Definition: carlsim.cpp:2309
IcalcType getIcalcType(int grpId)
Definition: snn.h:724
int getNumConnections()
Definition: carlsim.cpp:1584
bool isExcitatoryGroup(int grpId)
Definition: carlsim.cpp:1730
void stopTesting()
exits a testing phase, making weight updates possible again
STDPCurve stdpCurve
the type of STDP curve
RangeDelay getDelayRange(short int connId)
returns the RangeDelay struct for a specific connection ID
Definition: carlsim.cpp:2423
short int connectCompartments(int grpIdLower, int grpIdUpper)
Custom mode, the user can set the location of all the file pointers.
void setHomeostasis(int grpId, bool isSet, float homeoScale, float avgTimeScale)
Sets the homeostasis parameters. g is the grpID, enable=true(false) enables(disables) homeostasis...
int getNumNeuronsRegExc()
Definition: snn.h:658
Point3D getNeuronLocation3D(int grpId, int relNeurId)
Definition: carlsim.cpp:1557
norepinephrine-modulated STDP, nearest-neighbor
cannot be both synaptically and compartmentally connected
Definition: user_errors.h:32
SpikeMonitor * setSpikeMonitor(int grpId, const std::string &fileName)
Sets a Spike Monitor for a groups, prints spikes to binary file.
Definition: carlsim.cpp:2371
void setWeightAndWeightChangeUpdate(UpdateInterval wtANDwtChangeUpdateInterval, bool enableWtChangeDecay, float wtChangeDecay)
Definition: carlsim.cpp:1026
#define ANY
used for create* method to specify any GPU or a specific GPU
int getNumNeuronsGenInh()
Definition: snn.h:662
void setHomeoBaseFiringRate(int grpId, float baseFiring, float baseFiringSD)
Definition: carlsim.cpp:650
const FILE * getLogFpLog()
Definition: carlsim.cpp:1091
void findWavefrontPath(std::vector< int > &path, std::vector< float > &eligibility, int netId, int grpId, int startNId, int goalNId)
Extracts the path from a spiking wave front and returns the eligibility trace.
Definition: carlsim.cpp:2301
void setSTP(int grpId, bool isSet, float STP_U, float STP_tau_u, float STP_tau_x)
Sets STP params U, tau_u, and tau_x of a neuron group (pre-synaptically) CARLsim implements the short...
void setISTDP(int preGrpId, int postGrpId, bool isSet)
Definition: carlsim.cpp:906
int getSimTimeMsec()
Definition: carlsim.cpp:1631
void setSpikeGenerator(int grpId, SpikeGeneratorCore *spikeGenFunc)
sets up a spike generator
void setWeight(short int connId, int neurIdPre, int neurIdPost, float weight, bool updateWeightRange)
Definition: carlsim.cpp:1385
void loadSimulation(FILE *fid)
Definition: carlsim.cpp:1164
standard exponential curve
int getGroupId(std::string grpName)
int getSimTime()
Definition: snn.h:667
const FILE * getLogFpDeb()
returns file pointer to debug log
Definition: snn.h:600
short int connect(int grpId1, int grpId2, ConnectionGenerator *conn, float mulSynFast, float mulSynSlow, bool synWtType)
Definition: carlsim.cpp:241
bool isConnectionPlastic(short int connId)
Returns whether a connection is fixed or plastic.
Definition: carlsim.cpp:2513
void setNM4STP(int grpId, float wSTP_U[], float wSTP_tau_u[], float wSTP_tau_x[])
Definition: carlsim.cpp:1005
NVIDIA Many CUDA Core Processor (LN20201016)
short int connectCompartments(int grpIdLower, int grpIdUpper)
make a compartmental connection between two compartmentally enabled groups Note: all compartmentally ...
Definition: carlsim.cpp:2078
CARLsimState
CARLsim states.
void setWeightAndWeightChangeUpdate(UpdateInterval wtANDwtChangeUpdateInterval, bool enableWtChangeDecay, float wtChangeDecay)
Sets the weight and weight change update parameters.
#define MAX_CONN_PER_SNN
parameter must have positive value
Definition: user_errors.h:55
bool isInhibitoryGroup(int gGrpId)
Definition: snn.h:708
SpikeMonitor * setSpikeMonitor(int gid, FILE *fid)
sets up a spike monitor registered with a callback to process the spikes, there can only be one Spike...
bool isPoissonGroup(int grpId)
returns
Definition: carlsim.cpp:2556
int getNumNeuronsRegExc()
Definition: carlsim.cpp:1590
int getNumConnections()
Definition: snn.h:652
std::vector< float > getConductanceGABAa(int grpId)
Definition: carlsim.cpp:1454
bool isGroupWith(int grpId, IcalcType icalcType)
Definition: carlsim.cpp:2527
int createSpikeGeneratorGroup(const std::string &grpName, int nNeur, int neurType, int preferredPartition=ANY, ComputingBackend preferredBackend=CPU_CORES)
creates a spike generator group
Definition: carlsim.cpp:2102
ConnectionMonitor * setConnectionMonitor(int grpIdPre, int grpIdPost, const std::string &fname)
Definition: carlsim.cpp:1186
void setESTDP(int preGrpId, int postGrpId, bool isSet)
Sets default E-STDP mode and parameters.
Definition: carlsim.cpp:2227
int getNumSynapses()
Definition: snn.h:663
void setISTDP(int preGrpId, int postGrpId, bool isSet, STDPType type, PulseCurve curve)
Definition: carlsim.cpp:943
bool isConnectionPlastic(short int connId)
returns whether synapses in connection are fixed (false) or plastic (true)
int getGroupNumNeurons(int gGrpId)
Definition: snn.h:641
void setWeight(short int connId, int neurIdPre, int neurIdPost, float weight, bool updateWeightRange=false)
sets the weight value of a specific synapse
bool getConductanceConfig(int grpId, float &dAMPA, float &rNMDA, float &dNMDA, float &dGABAa, float &rGABAb, float &dGABAb)
Definition: carlsim.cpp:1693
ConnSTDPInfo getConnSTDPInfo(int connId)
Definition: carlsim.cpp:1614
parameter cannot have negative value (opposite to "must be", but includes zero)
Definition: user_errors.h:35
const FILE * getLogFpDeb()
Definition: carlsim.cpp:1090
void setConductances(bool isSet, int tdAMPA, int trNMDA, int tdNMDA, int tdGABAa, int trGABAb, int tdGABAb)
Sets custom values for conductance decay () or disables conductances alltogether These will be applie...
void setLogsFpCustom(FILE *fpInf, FILE *fpErr, FILE *fpDeb, FILE *fpLog)
Definition: carlsim.cpp:1128
std::vector< float > getConductanceGABAb(int grpId)
Definition: carlsim.cpp:1465
void setupNetwork()
build the network
Definition: carlsim.cpp:2293
float tauMinus
the time constant of the exponential curve at post-pre side
void setDefaultSaveOptions(std::string fileName, bool saveSynapseInfo)
Definition: carlsim.cpp:1793
void setConnectionModulation(int preGrpId, int postGrpId, IcalcType icalcType)
bool isInhibitoryGroup(int grpId)
Definition: carlsim.cpp:1738
void setDefaultESTDPparams(float alphaPlus, float tauPlus, float alphaMinus, float tauMinus, STDPType stdpType)
Definition: carlsim.cpp:1814
void setSpikeGenerator(int grpId, SpikeGenerator *spikeGenFunc)
Definition: carlsim.cpp:1282
void setLogsFpCustom(FILE *fpInf=NULL, FILE *fpErr=NULL, FILE *fpDeb=NULL, FILE *fpLog=NULL)
Sets the file pointers for all log files in CUSTOM mode.
Definition: carlsim.cpp:2329
RangeWeight getWeightRange(short int connId)
returns the RangeWeight struct for a specific connection ID
Definition: carlsim.cpp:2510
const FILE * getLogFpErr()
Definition: carlsim.cpp:1089
void setNeuronParameters(int grpId, float izh_a, float izh_a_sd, float izh_b, float izh_b_sd, float izh_c, float izh_c_sd, float izh_d, float izh_d_sd)
Sets Izhikevich params a, b, c, and d with as mean +- standard deviation.
Definition: carlsim.cpp:2162
void scaleWeights(short int connId, float scale, bool updateWeightRange=false)
reset Spike Counter to zero
Definition: carlsim.cpp:2343
void loadSimulation(FILE *fid)
void setHomeostasis(int grpId, bool isSet, float homeoScale, float avgTimeScale)
Definition: carlsim.cpp:630
void saveSimulation(const std::string &fileName, bool saveSynapseInfo=true)
Saves important simulation and network infos to file.
Definition: carlsim.cpp:2321
float alphaPlus
the amplitude of the exponential curve at pre-post side
void setExternalCurrent(int grpId, const std::vector< float > &current)
Sets the amount of current (mA) to inject into a group.
Definition: carlsim.cpp:2353
void setACNE12(int grpId)
Sets IcalcType to ACNE12 for a specific neuron group.
Definition: carlsim.cpp:2136
Grid3D getGroupGrid3D(int grpId)
Definition: carlsim.cpp:1497
A struct to specify the receptive field (RF) radius in 3 dimensions.
bool isGroupWithHomeostasis(int grpId)
Returns whether a group has homeostasis enabled.
Definition: carlsim.cpp:2516
const FILE * getLogFpInf()
function writes population weights from gIDpre to gIDpost to file fname in binary.
Definition: snn.h:596