AnimatLab  2
Test
CsFiringRateStimulus.cpp
Go to the documentation of this file.
1 
7 #include "StdAfx.h"
8 #include "CsSynapseGroup.h"
9 #include "CsNeuronGroup.h"
10 #include "CsNeuralModule.h"
11 #include "CsSpikeGeneratorGroup.h"
12 #include "CsFiringRateStimulus.h"
13 
14 namespace AnimatCarlSim
15 {
16 
24 {
25  m_lpNode = NULL;
26  m_lpEval = NULL;
27  m_lpSpikeGen = NULL;
28  m_fltActiveRate = 0;
32 }
33 
41 {
42 
43 try
44 {
45  m_lpNode = NULL;
46  m_lpSpikeGen = NULL;
47  if(m_lpEval)
48  delete m_lpEval;
49 
50 }
51 catch(...)
52 {Std_TraceMsg(0, "Caught Error in desctructor of CsFiringRateStimulus\r\n", "", -1, false, true);}
53 }
54 
64 
73 void CsFiringRateStimulus::TargetNodeID(std::string strID)
74 {
75  if(Std_IsBlank(strID))
76  THROW_PARAM_ERROR(Al_Err_lInvalidCurrentType, Al_Err_strInvalidCurrentType, "ID", strID);
77  m_strTargetNodeID = strID;
78 }
79 
90 
101 void CsFiringRateStimulus::Equation(std::string strEquation)
102 {
103  m_strEquation = strEquation;
104 
105  if(!Std_IsBlank(strEquation))
106  {
107 
108  //Initialize the postfix evaluator.
109  if(m_lpEval)
110  {delete m_lpEval; m_lpEval = NULL;}
111 
112  m_lpEval = new CStdPostFixEval;
113 
114  m_lpEval->AddVariable("t");
115  m_lpEval->Equation(strEquation);
116  m_lpEval->SetVariable("t", 0);
117 
118  if(m_bIsActivated)
119  m_fltActiveRate = m_lpEval->Solve();
120  }
121  else
122  {
123  //Remove the current eval.
124  if(m_lpEval)
125  {delete m_lpEval; m_lpEval = NULL;}
126 
127  if(m_bIsActivated)
129  }
130 }
131 
132 
133 float CsFiringRateStimulus::ConstantRate() {return m_fltConstantRate;}
134 
135 void CsFiringRateStimulus::ConstantRate(float fltVal)
136 {
137  Std_IsAboveMin((float) 0, fltVal, true, "ConstantRate", true);
138  m_fltConstantRate = fltVal;
139 }
140 
141 float CsFiringRateStimulus::ActiveRate() {return m_fltActiveRate;}
142 
143 float CsFiringRateStimulus::PrevAppliedRate() {return m_fltPrevAppliedRate;}
144 
145 void CsFiringRateStimulus::Coverage(std::string strType)
146 {
147  std::string strVal = Std_CheckString(strType);
148  if(strVal == "INDIVIDUALS")
149  m_bStimWholePopulation = false;
150  else if(strVal == "WHOLEPOPULATION")
151  m_bStimWholePopulation = true;
152  else
153  THROW_PARAM_ERROR(Cs_Err_lInvalidFiringRateCoverage, Cs_Err_strInvalidFiringRateCoverage, "Coverage", strType);
154 }
155 
156 bool CsFiringRateStimulus::StimWholePopulation() {return m_bStimWholePopulation;}
157 
158 void CsFiringRateStimulus::StimWholePopulation(bool bVal) {m_bStimWholePopulation = bVal;}
159 
160 void CsFiringRateStimulus::CellsToStim(std::string strXml)
161 {
162  CStdXml oXml;
163  oXml.Deserialize(strXml);
164  oXml.FindElement("Root");
165  oXml.FindChildElement("Cells");
166 
167  LoadCellsToStim(oXml);
168 }
169 
170 void CsFiringRateStimulus::Initialize()
171 {
172  ExternalStimulus::Initialize();
173 
174  //Lets try and get the node we will dealing with.
175  m_lpNode = dynamic_cast<Node *>(m_lpSim->FindByID(m_strTargetNodeID));
176  if(!m_lpNode)
177  THROW_PARAM_ERROR(Al_Err_lNodeNotFound, Al_Err_strNodeNotFound, "ID: ", m_strTargetNodeID);
178 
179  m_lpSpikeGen = dynamic_cast<CsSpikeGeneratorGroup *>(m_lpNode);
180  if(!m_lpSpikeGen)
181  THROW_PARAM_ERROR(Cs_Err_lNotSpikeGeneratorType, Cs_Err_strNotSpikeGeneratorType, "ID: ", m_strTargetNodeID);
182 
183  if(m_lpSpikeGen && m_lpSpikeGen->GetCsModule())
184  this->StepInterval(m_lpSpikeGen->GetCsModule()->SimulationStepInterval());
185 }
186 
196 {
197  if(m_lpEval)
198  {
199  m_lpEval->SetVariable("t", (m_lpSim->Time()-m_fltStartTime) );
200  m_fltActiveRate = m_lpEval->Solve();
201  }
202  else
204 
205  return m_fltActiveRate;
206 }
207 
208 bool CsFiringRateStimulus::RateChanged()
209 {
210  if(fabs(m_fltActiveRate-m_fltPrevAppliedRate) > 0.001)
211  return true;
212  else
213  return false;
214 }
215 
216 void CsFiringRateStimulus::ApplyRateChange()
217 {
219  {
220  for(int iIdx=0; iIdx<m_lpSpikeGen->NeuronCount(); iIdx++)
221  {
222  //First remove the previous active rate from this group
223  m_lpSpikeGen->SpikeRates()->rates[iIdx] -= m_fltPrevAppliedRate;
224  //Then add the next active rate to this group
225  m_lpSpikeGen->SpikeRates()->rates[iIdx] += m_fltActiveRate;
226  }
227  }
228  else
229  {
230  for( CStdMap<int,int>::iterator ii=m_aryCellsToStim.begin(); ii!=m_aryCellsToStim.end(); ++ii)
231  {
232  int iIdx = (*ii).first;
233  if(iIdx >= 0 && iIdx < m_lpSpikeGen->NeuronCount())
234  {
235  //First remove the previous active rate from this group
236  m_lpSpikeGen->SpikeRates()->rates[iIdx] -= m_fltPrevAppliedRate;
237  //Then add the next active rate to this group
238  m_lpSpikeGen->SpikeRates()->rates[iIdx] += m_fltActiveRate;
239  }
240  }
241  }
242 
244 
245  m_lpSpikeGen->SetSpikeRatesUpdated();
246 }
247 
248 void CsFiringRateStimulus::StepSimulation()
249 {
250  //If we are using a constant rate then there is no reason to recalculate and apply
251  //Only do this if we are using an equation.
252  if(m_lpEval && m_lpSpikeGen && m_lpSpikeGen->SpikeRates())
253  {
254  //First calculate the new rate.
256 
257  if(RateChanged())
258  ApplyRateChange();
259  }
260 }
261 
262 void CsFiringRateStimulus::Activate()
263 {
264  ExternalStimulus::Activate();
265 
266  //Only apply the changes here if we are using a constant rate.
267  //If we are using a constant rate then we only apply it once in activate.
268  //If using an equation it will get applied in StepSimulation.
269  if(!m_lpEval)
270  {
272  ApplyRateChange();
273  }
274 }
275 
276 void CsFiringRateStimulus::Deactivate()
277 {
278  ExternalStimulus::Deactivate();
279 
280  //Reset the data
281  m_fltActiveRate = 0;
282 
283  //Apply this change
284  ApplyRateChange();
285 
286  //Reset our variables.
287  m_fltActiveRate = 0;
289 }
290 
291 void CsFiringRateStimulus::ResetSimulation()
292 {
293  ExternalStimulus::ResetSimulation();
294  m_fltActiveRate = 0;
296 }
297 
298 float *CsFiringRateStimulus::GetDataPointer(const std::string &strDataType)
299 {
300  float *lpData=NULL;
301  std::string strType = Std_CheckString(strDataType);
302 
303  if(strType == "ACTIVERATE")
304  lpData = &m_fltActiveRate;
305  else
306  THROW_TEXT_ERROR(Al_Err_lInvalidDataType, Al_Err_strInvalidDataType, "StimulusName: " + STR(m_strName) + " DataType: " + strDataType);
307 
308  return lpData;
309 }
310 
311 bool CsFiringRateStimulus::SetData(const std::string &strDataType, const std::string &strValue, bool bThrowError)
312 {
313  std::string strType = Std_CheckString(strDataType);
314 
315  if(ExternalStimulus::SetData(strDataType, strValue, false))
316  return true;
317 
318  if(strType == "CONSTANTRATE")
319  {
320  ConstantRate((float) atof(strValue.c_str()));
321  return true;
322  }
323 
324  if(strType == "COVERAGE")
325  {
326  Coverage(strValue);
327  return true;
328  }
329 
330  if(strType == "EQUATION")
331  {
332  Equation(strValue);
333  return true;
334  }
335 
336  if(strType == "CELLSTOSTIM")
337  {
338  CellsToStim(strValue);
339  return true;
340  }
341 
342  //If it was not one of those above then we have a problem.
343  if(bThrowError)
344  THROW_PARAM_ERROR(Al_Err_lInvalidDataType, Al_Err_strInvalidDataType, "Data Type", strDataType);
345 
346  return false;
347 }
348 
349 void CsFiringRateStimulus::QueryProperties(CStdPtrArray<TypeProperty> &aryProperties)
350 {
351  ExternalStimulus::QueryProperties(aryProperties);
352 
353  aryProperties.Add(new TypeProperty("ActiveRate", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
354 
355  aryProperties.Add(new TypeProperty("ConstantRate", AnimatPropertyType::Float, AnimatPropertyDirection::Set));
356  aryProperties.Add(new TypeProperty("Equation", AnimatPropertyType::Float, AnimatPropertyDirection::Set));
357  aryProperties.Add(new TypeProperty("Coverage", AnimatPropertyType::String, AnimatPropertyDirection::Set));
358  aryProperties.Add(new TypeProperty("CellsToStim", AnimatPropertyType::Xml, AnimatPropertyDirection::Set));
359 }
360 
361 void CsFiringRateStimulus::LoadCellsToStim(CStdXml &oXml)
362 {
363  oXml.IntoElem();
364  m_aryCellsToStim.RemoveAll();
365  int iCount = oXml.NumberOfChildren();
366  for(int iIdx=0; iIdx<iCount; iIdx++)
367  {
368  oXml.FindChildByIndex(iIdx);
369  int iNeuronIdx = oXml.GetChildInt();
370 
371  if(iNeuronIdx < 0)
372  THROW_PARAM_ERROR(Cs_Err_lInvalidNeuralIndex, Cs_Err_strInvalidNeuralIndex, "Neuron Index", iNeuronIdx);
373 
374  if(!m_aryCellsToStim.count(iNeuronIdx))
375  m_aryCellsToStim.Add(iNeuronIdx, 1);
376  }
377  oXml.OutOfElem();
378 }
379 
380 void CsFiringRateStimulus::Load(CStdXml &oXml)
381 {
382  ExternalStimulus::Load(oXml);
383 
384  oXml.IntoElem(); //Into Simulus Element
385 
386  TargetNodeID(oXml.GetChildString("TargetNodeID"));
387 
388  ConstantRate(oXml.GetChildFloat("ConstantRate", m_fltConstantRate));
389  Equation(oXml.GetChildString("Equation", ""));
390  Coverage(oXml.GetChildString("Coverage", "WholePopulation"));
391 
392  if(oXml.FindChildElement("Cells", false))
393  LoadCellsToStim(oXml);
394 
395  oXml.OutOfElem(); //OutOf Simulus Element
396 }
397 
398 } //AnimatCarlSim
399 
400 
401 
402 
Contains the classes for a firing rate neural model.
Definition: CsAdapter.cpp:14
bool m_bStimWholePopulation
Tells whether this stimulus is applied to the entire population or just individual cells...
Declares the CsNeuronGroup class.
virtual float CalculateFiringRate()
Calculates the on cycle current at this time step.
virtual unsigned int SimulationStepInterval()
Tells the number of simulation steps that other components, like stimuli, will need to use for their ...
CStdPostFixEval * m_lpEval
Pointer to the post-fix equation evaluator.
std::string m_strTargetNodeID
GUID ID of the neuron we are stimulating.
bool Std_IsAboveMin(int iMinVal, int iVal, bool bThrowError, std::string strParamName, bool bInclusiveLimit)
Tests if a number is above a minimum value.
float m_fltActiveRate
The currently active firing rate.
Declares the synapse class.
float m_fltConstantRate
The value to use for active rate if the type is constant.
float m_fltPrevAppliedRate
The previous active firing rate.
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.
Declares the current stimulus class.
virtual std::string Equation()
Gets the post-fix current equation string. If this is null then an equation is not used...
bool Std_IsBlank(std::string strVal)
Trims a string and tests if a string is blank.
std::string Std_CheckString(std::string strVal)
Converts a string to upper case and trims it.
std::string m_strEquation
The post-fix string current equation.
virtual std::string TargetNodeID()
Gets the GUID ID of the node that is being stimulated.
CsSpikeGeneratorGroup * m_lpSpikeGen
The spike generator this object is stimulating.
CStdMap< int, int > m_aryCellsToStim
An array of neuron indices for individual neurons we want to stimulate.