AnimatLab  2
Test
CsSpikingCurrentSynapse.cpp
Go to the documentation of this file.
1 
7 #include "StdAfx.h"
8 
9 #include "CsNeuronGroup.h"
10 #include "CsNeuralModule.h"
12 
13 namespace AnimatCarlSim
14 {
15 
23 {
24  m_lpFromNeuron = NULL;
25  m_lpToNeuron = NULL;
26  m_fltPulseDecay = 0;
28  m_fltPulseSign = 1;
29  m_bWholePopulation = true;
30  m_fltPulseTC = 0;
34  m_ulSpikeTestTime = 0;
35  m_iStepsPerTest = 0;
37  m_lTotalSpikesAdded = 0;
38 }
39 
47 {
48 
49 try
50 {
51  m_arySpikeTimes.RemoveAll();
52 }
53 catch(...)
54 {Std_TraceMsg(0, "Caught Error in desctructor of CsSpikingCurrentSynapse\r\n", "", -1, false, true);}
55 }
56 
57 void CsSpikingCurrentSynapse::PulseDecay(float fltVal)
58 {
59  Std_IsAboveMin((float) 0, fltVal, true, "PulseDecay");
60  m_fltPulseDecay = fltVal;
61  if(m_lpModule && m_lpModule->TimeStep() > 0)
62  {
63  float fltTm = m_lpModule->TimeStep() / (1 - exp(-m_lpModule->TimeStep() / m_fltPulseDecay));
64  m_fltPulseTC = m_lpModule->TimeStep() / fltTm;
65  }
66 }
67 
68 float CsSpikingCurrentSynapse::PulseDecay() {return m_fltPulseDecay;}
69 
70 void CsSpikingCurrentSynapse::PulseCurrent(float fltVal)
71 {
72  Std_IsAboveMin((float) 0, fltVal, true, "PulseCurrent");
73  m_fltPulseMagnitude = fabs(fltVal);
74  m_fltPulseSign = Std_Sign(fltVal);
75 }
76 
77 float CsSpikingCurrentSynapse::PulseCurrent() {return (m_fltPulseMagnitude*m_fltPulseSign);}
78 
79 void CsSpikingCurrentSynapse::Coverage(std::string strType)
80 {
81  std::string strVal = Std_CheckString(strType);
82  if(strVal == "INDIVIDUALS")
83  WholePopulation(false);
84  else if(strVal == "WHOLEPOPULATION")
85  WholePopulation(true);
86  else
87  THROW_PARAM_ERROR(Cs_Err_lInvalidFiringRateCoverage, Cs_Err_strInvalidFiringRateCoverage, "Coverage", strType);
88 }
89 
90 bool CsSpikingCurrentSynapse::WholePopulation() {return m_bWholePopulation;}
91 
92 void CsSpikingCurrentSynapse::WholePopulation(bool bVal)
93 {
94  m_bWholePopulation = bVal;
95 
96  if(m_lpFromNeuron)
97  m_lpFromNeuron->CollectFromWholePopulation(bVal);
98 }
99 
100 void CsSpikingCurrentSynapse::Cells(std::string strXml)
101 {
102  CStdXml oXml;
103  oXml.Deserialize(strXml);
104  oXml.FindElement("Root");
105  oXml.FindChildElement("Cells");
106 
107  LoadCells(oXml);
108 }
109 
110 void CsSpikingCurrentSynapse::CalculateStepsPerTest()
111 {
112  m_ulSpikeTestTime = 0;
114  m_ulSpikeTestTime = 0;
115 
116  if(m_lpModule && m_lpModule->TimeStep() > 0)
117  {
118  m_iStepsPerTest = (int) ((CARLSIM_STEP_INCREMENT/m_lpModule->TimeStep())+0.5);
120  }
121  else
122  m_iStepsPerTest = 0;
123 }
124 
126 {
127  Link::TimeStepModified();
128 
129  //Reset the exponential pulse decay constant
130  PulseDecay(m_fltPulseDecay);
131 
132  CalculateStepsPerTest();
133 }
134 
135 void CsSpikingCurrentSynapse::MonitorSpikeEventFired(int iGroupID, int iNeuronID, long lTimeIdx)
136 {
137  if(m_lpFromNeuron && m_lpFromNeuron->GroupID() == iGroupID && (m_bWholePopulation || (!m_bWholePopulation && m_aryCells.count(iNeuronID))) )
138  {
139  m_AccessSpikes.lock();
140  m_arySpikeTimes.Add(lTimeIdx);
141  m_AccessSpikes.unlock();
142 
143  //std::string strMsg = "Received Spike Group: " + STR(iGroupID) + ", Neuron: " + STR(iNeuronID) + ", Time: " + STR(lTimeIdx) + "\r\n";
144  //OutputDebugString(strMsg.c_str());
145  }
146 }
147 
148 
150 {
151  Link::Initialize();
152 
154  if(!m_lpFromNeuron)
155  THROW_PARAM_ERROR(Al_Err_lNodeNotFound, Al_Err_strNodeNotFound, "ID: ", m_strFromID);
156 
158  if(!m_lpToNeuron)
159  THROW_PARAM_ERROR(Al_Err_lNodeNotFound, Al_Err_strNodeNotFound, "ID: ", m_strToID);
160 
161  CalculateStepsPerTest();
162 
163  if(m_lpFromNeuron)
164  {
165 
166  m_lpFromNeuron->CollectFromWholePopulation(m_bWholePopulation);
167 
168  if(m_MonitoredSpikeEvent.connected())
169  m_MonitoredSpikeEvent.disconnect();
170 
171  m_MonitoredSpikeEvent = m_lpFromNeuron->MonitoredSpikeEvent.connect(boost::bind(&CsSpikingCurrentSynapse::MonitorSpikeEventFired, this, _1, _2, _3));
172  }
173 }
174 
175 #pragma region DataAccesMethods
176 
177 float *CsSpikingCurrentSynapse::GetDataPointer(const std::string &strDataType)
178 {
179  std::string strType = Std_CheckString(strDataType);
180 
181  float *lpData = NULL;
182 
183  if(strType == "APPLIEDCURRENT")
184  return &m_fltAppliedCurrent;
185  else if(strType == "DECREMENTCURRENT")
186  return &m_fltDecrementCurrent;
187 
188  return Link::GetDataPointer(strDataType);
189 }
190 
192 {
193  AnimatBase::VerifySystemPointers();
194 
195  if(!m_lpStructure)
196  THROW_PARAM_ERROR(Al_Err_lStructureNotDefined, Al_Err_strStructureNotDefined, "Link: ", m_strID);
197 
198  if(!m_lpOrganism)
199  THROW_PARAM_ERROR(Al_Err_lConvertingClassToType, Al_Err_strConvertingClassToType, "Link: ", m_strID);
200 
201  if(!m_lpModule)
202  THROW_PARAM_ERROR(Al_Err_lNeuralModuleNotDefined, Al_Err_strNeuralModuleNotDefined, "Link: ", m_strID);
203 }
204 
205 bool CsSpikingCurrentSynapse::SetData(const std::string &strDataType, const std::string &strValue, bool bThrowError)
206 {
207  std::string strType = Std_CheckString(strDataType);
208 
209  if(Link::SetData(strDataType, strValue, false))
210  return true;
211 
212  if(strType == "PULSEDECAY")
213  {
214  PulseDecay(atof(strValue.c_str()));
215  return true;
216  }
217  else if(strType == "PULSECURRENT")
218  {
219  PulseCurrent(atof(strValue.c_str()));
220  return true;
221  }
222  else if(strType == "COVERAGE")
223  {
224  Coverage(strValue);
225  return true;
226  }
227  else if(strType == "CELLS")
228  {
229  Cells(strValue);
230  return true;
231  }
232 
233 
234  //If it was not one of those above then we have a problem.
235  if(bThrowError)
236  THROW_PARAM_ERROR(Al_Err_lInvalidDataType, Al_Err_strInvalidDataType, "Data Type", strDataType);
237 
238  return false;
239 }
240 
241 void CsSpikingCurrentSynapse::QueryProperties(CStdPtrArray<TypeProperty> &aryProperties)
242 {
243  Link::QueryProperties(aryProperties);
244 
245  aryProperties.Add(new TypeProperty("AppliedCurrent", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
246  aryProperties.Add(new TypeProperty("DecrementCurrent", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
247 
248  aryProperties.Add(new TypeProperty("PulseDecay", AnimatPropertyType::Float, AnimatPropertyDirection::Set));
249  aryProperties.Add(new TypeProperty("PulseCurrent", AnimatPropertyType::Float, AnimatPropertyDirection::Set));
250  aryProperties.Add(new TypeProperty("Coverage", AnimatPropertyType::String, AnimatPropertyDirection::Set));
251  aryProperties.Add(new TypeProperty("Cells", AnimatPropertyType::Xml, AnimatPropertyDirection::Set));
252 }
253 
254 #pragma endregion
255 
257 {
258  Link::ResetSimulation();
259 
264  m_ulSpikeTestTime = 0;
265  m_lTotalSpikesAdded = 0;
266 }
267 
268 void CsSpikingCurrentSynapse::ProcessSpikes()
269 {
270  //If the steps per count is < 0 it is the first time so run it then, then count normally.
272  {
273  //std::string strMsg = "ProcessSpike Compare: Time: " + STR(m_lpSim->Time()) + ", ITime: " + STR(m_ulSpikeTestTime) + "\r\n";
274  //OutputDebugString(strMsg.c_str());
275 
276  if(m_arySpikeTimes.GetSize() > 0)
277  {
278  int iIdx=0;
279  long lNextTime = m_arySpikeTimes[iIdx];
280  bool bDone = false;
281 
282  while(lNextTime <= m_ulSpikeTestTime && !bDone)
283  {
285  m_lTotalSpikesAdded++;
286  //std::string strMsg = "Added Spike Time: " + STR(m_lpSim->Time()) + "]\r\n";
287  //OutputDebugString(strMsg.c_str());
288 
289  iIdx++;
290  if(iIdx >= m_arySpikeTimes.GetSize())
291  bDone = true;
292  else
293  lNextTime = m_arySpikeTimes[iIdx];
294  }
295 
296  if(iIdx > 0)
297  {
298  m_AccessSpikes.lock();
299  for(int iIdx2=0; iIdx2<iIdx; iIdx2++)
300  m_arySpikeTimes.RemoveAt(0);
301  m_AccessSpikes.unlock();
302  }
303  }
304 
305  m_ulSpikeTestTime++;
307  }
308  else
310 }
311 
313 {
315  {
316 
319 
320  if(m_fltCurrentMagnitude <= 0)
322 
323  ProcessSpikes();
324 
326 
328  }
329 }
330 
331 void CsSpikingCurrentSynapse::LoadCells(CStdXml &oXml)
332 {
333  oXml.IntoElem();
334  m_aryCells.RemoveAll();
335  int iCount = oXml.NumberOfChildren();
336  for(int iIdx=0; iIdx<iCount; iIdx++)
337  {
338  oXml.FindChildByIndex(iIdx);
339  int iNeuronIdx = oXml.GetChildInt();
340 
341  if(iNeuronIdx < 0)
342  THROW_PARAM_ERROR(Cs_Err_lInvalidNeuralIndex, Cs_Err_strInvalidNeuralIndex, "Neuron Index", iNeuronIdx);
343 
344  if(!m_aryCells.count(iNeuronIdx))
345  m_aryCells.Add(iNeuronIdx, 1);
346  }
347  oXml.OutOfElem();
348 }
349 
350 void CsSpikingCurrentSynapse::Load(CStdXml &oXml)
351 {
352  Link::Load(oXml);
353 
354  oXml.IntoElem(); //Into Synapse Element
355 
356  m_strFromID = oXml.GetChildString("FromID");
358  THROW_TEXT_ERROR(Std_Err_lBlankAttrib, Std_Err_strBlankAttrib, "Attribute: FromID");
359 
360  m_strToID = oXml.GetChildString("ToID");
361  if(Std_IsBlank(m_strToID))
362  THROW_TEXT_ERROR(Std_Err_lBlankAttrib, Std_Err_strBlankAttrib, "Attribute: ToID");
363 
364  PulseDecay(oXml.GetChildFloat("PulseDecay", m_fltPulseDecay));
365  PulseCurrent(oXml.GetChildFloat("PulseCurrent", m_fltPulseMagnitude));
366 
367  Coverage(oXml.GetChildString("Coverage", "WholePopulation"));
368 
369  if(oXml.FindChildElement("Cells", false))
370  LoadCells(oXml);
371 
372  oXml.OutOfElem(); //OutOf Synapse Element
373 }
374 
375 
376 } //AnimatCarlSim
377 
378 
379 
380 
381 
382 
Contains the classes for a firing rate neural model.
Definition: CsAdapter.cpp:14
float m_fltDecrementCurrent
The amount by which the current is decremented each step.
float m_fltPulseDecay
The decay rate for which a current pulse.
CStdMap< int, int > m_aryCells
An array of neuron indices for individual neurons we want to stimulate.
AnimatSim::Behavior::NeuralModule * m_lpModule
The pointer to this items parentNeuralModule. If this is not relevant for this object then this is NU...
Definition: AnimatBase.h:49
virtual float TimeStep()
Gets the time step for this moudle in time units.
Declares the CsNeuronGroup class.
float m_fltPulseSign
The sign of the current to apply for a single pulse.
int m_iStepsPerTestCount
Keeps track of how my steps we have take tiil we are ready to test again.
virtual void AddExternalNodeInput(int iTargetDataType, float fltInput)=0
Adds an external node input.
virtual void ResetSimulation()
Resets the simulation back to time 0.
Simulator * m_lpSim
The pointer to a Simulation.
Definition: AnimatBase.h:43
float m_fltAppliedCurrent
The actual applied current with sign.
boost::interprocess::interprocess_mutex m_AccessSpikes
mutex used to try and access matches variable.
virtual void StepSimulation()
Step the simulation for this object.
virtual void Initialize()
Initializes this object.
int Std_Sign(float fltVal)
Determines the sign of a number.
bool Std_IsAboveMin(int iMinVal, int iVal, bool bThrowError, std::string strParamName, bool bInclusiveLimit)
Tests if a number is above a minimum value.
AnimatSim::Environment::Structure * m_lpStructure
The pointer to this items parent Structure. If this is not relevant for this object then this is NULL...
Definition: AnimatBase.h:46
std::string m_strID
The unique Id for this object.
Definition: AnimatBase.h:55
float m_fltPulseTC
The exponential decay constant calculated from the time step and decay rate.
AnimatSim::Node * m_lpToNeuron
The pointer to post-synaptic neuron.
CsNeuronGroup * m_lpFromNeuron
The pointer to pre-synaptic neuron.
std::string m_strToID
GUID ID of the pre-synaptic neruon.
virtual void VerifySystemPointers()
Verify that system pointers have been set correctly.
Firing Rate Neuron model.
Definition: CsNeuronGroup.h:28
virtual AnimatBase * FindByID(std::string strID, bool bThrowError=true)
Searches for the object with the specified ID.
Definition: Simulator.cpp:4008
Declares the synapse class.
int m_iStepsPerTest
Keeps track of the number of steps till we need to test for spikes to process.
virtual bool SetData(const std::string &strDataType, const std::string &strValue, bool bThrowError=true)
Set a variable based on a string data type name.
void Std_TraceMsg(const int iLevel, std::string strMessage, std::string strSourceFile, int iSourceLine, bool bLogToFile, bool bPrintHeader)
Traces a message to the debugger window.
bool m_bWholePopulation
Tells whether this entire population is monitored or just individual cells.
bool m_bEnabled
Tells if this item is enabled or not. If it is not enabled then it is not run.
Definition: AnimatBase.h:40
Base class for body parts and neural network nodes.
Definition: Node.h:25
virtual void TimeStepModified()
Notification method that the time step modified has been modified. Objects should recalculate any sli...
float m_fltCurrentMagnitude
The magnitude of the current applied to the target neuron.
bool Std_IsBlank(std::string strVal)
Trims a string and tests if a string is blank.
std::string m_strFromID
GUID ID of the pre-synaptic neruon.
std::string Std_CheckString(std::string strVal)
Converts a string to upper case and trims it.
float m_fltPulseMagnitude
The magnitude amount of the current to apply for a single pulse.
virtual float * GetDataPointer(const std::string &strDataType)
Returns a float pointer to a data item of interest in this object.